searchfw/coresearchfw/utilities/src/searchtextsearcher.cpp
changeset 0 f979ecb2b13e
equal deleted inserted replaced
-1:000000000000 0:f979ecb2b13e
       
     1 /*
       
     2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:   Class handling the search of several keywords in a block of 
       
    15 *                text.
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 
       
    21 #include <utf.h>
       
    22 
       
    23 #include <searchtextsearcherobserver.h>
       
    24 #include <searchsinglecondition.h>
       
    25 #include <searchcondition.h>
       
    26 #include <searchfield.h>
       
    27 #include <searchtextsearcher.h>
       
    28 #include "searchkeywordstatus.h"
       
    29 #include "searchalgorithm.h"
       
    30 
       
    31 #include <featmgr.h>
       
    32 
       
    33 _LIT(KColon,":");
       
    34 const  TInt KNumberDataLength( 50 );
       
    35 const  TInt KTimeDataLength( 50 );
       
    36 const  TInt KArrayGranularity( 2 );
       
    37 const  TInt KSingleKeywordInArray( 1 ); 
       
    38 
       
    39 
       
    40 // -----------------------------------------------------------------------------
       
    41 // CSearchTextSearcher::NewL()
       
    42 // Symbian C++ 2  phase construction
       
    43 // -----------------------------------------------------------------------------
       
    44 //
       
    45 EXPORT_C CSearchTextSearcher*  CSearchTextSearcher::NewL( 
       
    46 		MSearchTextSearcherObserver& aObserver )
       
    47     {
       
    48     CSearchTextSearcher* self = CSearchTextSearcher::NewLC( aObserver );
       
    49     CleanupStack::Pop( self );
       
    50     return self;
       
    51     }
       
    52 
       
    53 // -----------------------------------------------------------------------------
       
    54 // CSearchTextSearcher::NewLC()
       
    55 // Symbian C++ 2  phase construction
       
    56 // -----------------------------------------------------------------------------
       
    57 //
       
    58 EXPORT_C CSearchTextSearcher*  CSearchTextSearcher::NewLC( 
       
    59 		MSearchTextSearcherObserver&  aObserver )
       
    60     {
       
    61     CSearchTextSearcher* self = new( ELeave ) CSearchTextSearcher( aObserver );
       
    62     CleanupStack::PushL( self );
       
    63     ( *self ).ConstructL();
       
    64     return self;
       
    65     }    
       
    66     
       
    67 // -----------------------------------------------------------------------------
       
    68 // CSearchTextSearcher::~CSearchTextSearcher()
       
    69 // C++ destructor
       
    70 // -----------------------------------------------------------------------------
       
    71 //
       
    72 CSearchTextSearcher::~CSearchTextSearcher()
       
    73     {
       
    74     iKeywordSearchStatusArray.Close();
       
    75     
       
    76     if ( iSearchKeywords8 )
       
    77         {
       
    78         iSearchKeywords8->Reset();
       
    79         delete iSearchKeywords8;
       
    80         iSearchKeywords8 = NULL;
       
    81         }
       
    82     
       
    83     if ( iHaveParameters != TRUE )
       
    84         {
       
    85         iSearchKeywords16->Reset();
       
    86         delete iSearchKeywords16;
       
    87         iSearchKeywords16 = NULL;
       
    88         }
       
    89   
       
    90     if ( iSearchAlgorithm )
       
    91         {
       
    92         delete iSearchAlgorithm;     
       
    93         iSearchAlgorithm = NULL;
       
    94         }
       
    95         iClause.Reset();
       
    96         iClause.Close();
       
    97         FeatureManager::UnInitializeLib();
       
    98     }
       
    99     
       
   100 // -----------------------------------------------------------------------------
       
   101 // CSearchTextSearcher::Cleanup()
       
   102 // Cleanup Method
       
   103 // -----------------------------------------------------------------------------
       
   104 //
       
   105 EXPORT_C void CSearchTextSearcher::Cleanup()
       
   106     {
       
   107     iKeywordSearchStatusArray.Reset();
       
   108     for ( TInt i = 0; i < iKeywordSearchStatusArray.Count() ; i++ )
       
   109         {
       
   110         iKeywordSearchStatusArray[i].iFound = EFalse;
       
   111         iKeywordSearchStatusArray[i].iFoundAtNthPosition = KErrNotFound;
       
   112         }
       
   113     }
       
   114 // -----------------------------------------------------------------------------
       
   115 // CSearchTextSearcher::SetParametersL()
       
   116 // Sets the search parameters for the search.
       
   117 // -----------------------------------------------------------------------------
       
   118 //
       
   119 EXPORT_C void CSearchTextSearcher::SetParametersL( const MDesCArray& aKeywords,
       
   120               CSearchTextSearcher::TSearchCriteriaOperator 
       
   121               aOperator, TBool aCaseSensitive )
       
   122     {
       
   123     iSearchKeywords = static_cast<const CDesC16Array*>( &aKeywords );
       
   124     iOperator = aOperator;
       
   125     iCaseSensitive = aCaseSensitive;
       
   126       
       
   127     //convert from 16 - 8 bits for keyword
       
   128     iSearchKeywords8->Reset();
       
   129     iCount = iSearchKeywords->MdcaCount();
       
   130     
       
   131     DoUftTo8BitConversionL( *iSearchKeywords );    
       
   132     
       
   133     //initialize keyword status
       
   134     iKeywordSearchStatusArray.Reset();
       
   135     for ( TInt i = 0 ;i < iCount ; i++ )
       
   136         {
       
   137         TKeywordSearchStatus status;
       
   138         status.iFound  = EFalse;
       
   139         status.iFoundAtNthPosition = KErrNotFound;
       
   140         iKeywordSearchStatusArray.AppendL( status ); 
       
   141         }
       
   142     //Set it here to indicate client has called this method   
       
   143     iHaveParameters = ETrue; 
       
   144     if ( iCount == KSingleKeywordInArray) 
       
   145         {
       
   146           iIsBooleanCondition = EFalse;
       
   147         }
       
   148     else
       
   149         {
       
   150           iIsBooleanCondition = ETrue;
       
   151           //SetCriteriaOperator(); not to be called here , dont have clause yet          
       
   152         }    
       
   153     
       
   154     }
       
   155 
       
   156 // -----------------------------------------------------------------------------
       
   157 // CSearchTextSearcher::SetParametersL()
       
   158 // Sets the search parameters based on conditions for the search.
       
   159 // -----------------------------------------------------------------------------
       
   160 //
       
   161 EXPORT_C void CSearchTextSearcher::SetParametersL( const CSearchCondition& 
       
   162                                                                 aCondition )
       
   163     {
       
   164     if ( iHaveParameters )
       
   165         {
       
   166         return;
       
   167         }
       
   168     else
       
   169         {
       
   170         iSearchKeywords16 = new( ELeave ) CDesC16ArrayFlat( KArrayGranularity );     
       
   171         }
       
   172         
       
   173     switch( aCondition.Type() )
       
   174         {
       
   175         case CSearchCondition::EConditionTypeSimple:
       
   176             {
       
   177             iOperator = ESearchCriteriaAND; 
       
   178             iIsBooleanCondition = EFalse;
       
   179             SetSingleConditionDataL( 
       
   180             *(static_cast<const CSearchSingleCondition*>( &aCondition ) ) );
       
   181             }
       
   182             break;
       
   183         case CSearchCondition::EConditionTypeBoolean:
       
   184             {
       
   185             iOperator = ESearchCriteriaAND; 
       
   186             iIsBooleanCondition = ETrue;
       
   187             RPointerArray<CSearchCondition> conditions;
       
   188             (static_cast<const CSearchBooleanCondition*>( &aCondition ) )->
       
   189             GetConditions( conditions,iClause );
       
   190             
       
   191             for ( TInt i = 0; i < conditions.Count() ; i++ )
       
   192                 {
       
   193                 SetSingleConditionDataL( 
       
   194                 *(static_cast<const CSearchSingleCondition*>( conditions[i] ) ) );
       
   195                 }
       
   196             iCount = iSearchKeywords16->Count(); 
       
   197             conditions.Reset();
       
   198             conditions.Close();
       
   199             
       
   200             SetCriteriaOperator( );  
       
   201             }
       
   202             break;
       
   203             
       
   204         default:
       
   205             break;  
       
   206         }
       
   207       
       
   208     DoUftTo8BitConversionL( *iSearchKeywords16 );  
       
   209     }
       
   210     
       
   211 // -----------------------------------------------------------------------------
       
   212 // CSearchTextSearcher::SearchL()
       
   213 // Starts the text search with the previous supplied parameters set 
       
   214 // by SetParametersL. 16 bit version.
       
   215 // -----------------------------------------------------------------------------
       
   216 //
       
   217 EXPORT_C void CSearchTextSearcher::SearchL( const TDesC16& aToBeSearchedDes )
       
   218     {
       
   219     iKeywordSearchStatusArray.Reset();
       
   220 	for ( TInt i = 0 ;i < iCount ; i++ )
       
   221 	    {
       
   222 		TKeywordSearchStatus status;
       
   223 		status.iFound  = EFalse;
       
   224 		status.iFoundAtNthPosition = KErrNotFound;
       
   225 		iKeywordSearchStatusArray.AppendL( status ); 
       
   226 	    }
       
   227     
       
   228     if ( iHaveParameters )
       
   229         {
       
   230          DoStringCompareWithKeywordsL( aToBeSearchedDes,*iSearchKeywords,
       
   231               iKeywordSearchStatusArray,iOperator,iCaseSensitive ); 
       
   232         }
       
   233     else
       
   234         {
       
   235         DoStringCompareWithKeywordsL( aToBeSearchedDes,*iSearchKeywords16,
       
   236               iKeywordSearchStatusArray,iOperator,iCaseSensitive );
       
   237         }
       
   238     }
       
   239 
       
   240 
       
   241 // -----------------------------------------------------------------------------
       
   242 // CSearchTextSearcher::SearchL()
       
   243 // Starts the text search with the previous supplied parameters set by
       
   244 // SetParametersL.  8 bit version.
       
   245 // -----------------------------------------------------------------------------
       
   246 //
       
   247 EXPORT_C void CSearchTextSearcher::SearchL ( const TDesC8& aToBeSearchedDes )
       
   248     {
       
   249     DoStringCompareWithKeywordsL( aToBeSearchedDes,*iSearchKeywords8,
       
   250             iKeywordSearchStatusArray,iOperator,iCaseSensitive );
       
   251     }  
       
   252 
       
   253 // -----------------------------------------------------------------------------
       
   254 // Set whether searching for the email
       
   255 // -----------------------------------------------------------------------------
       
   256 //      
       
   257 EXPORT_C void CSearchTextSearcher::SearchEmailAddress ( TBool aSearchEmail ) 
       
   258     {
       
   259 	iSearchAlgorithm->SearchEmailAddress ( aSearchEmail );
       
   260     }
       
   261 
       
   262 // -----------------------------------------------------------------------------
       
   263 // Return the search keyword
       
   264 // -----------------------------------------------------------------------------
       
   265 //
       
   266 EXPORT_C CDesC16ArrayFlat* CSearchTextSearcher::SearchKeyword()
       
   267     {
       
   268     return iSearchKeywords16; 	
       
   269     }
       
   270 
       
   271 // -----------------------------------------------------------------------------
       
   272 // CSearchTextSearcher::CSearchTextSearcher()
       
   273 // C++ default constructor
       
   274 // -----------------------------------------------------------------------------
       
   275 //
       
   276 CSearchTextSearcher::CSearchTextSearcher(
       
   277        MSearchTextSearcherObserver& aObserver )
       
   278 :   iObserver( aObserver ) 
       
   279     {
       
   280     
       
   281     }
       
   282    
       
   283 // -----------------------------------------------------------------------------
       
   284 // CSearchTextSearcher::ConstructL()
       
   285 // Symbian 2nd phase construction
       
   286 // -----------------------------------------------------------------------------
       
   287 //
       
   288 void CSearchTextSearcher::ConstructL()
       
   289     {
       
   290     iSearchKeywords8 = new(ELeave) CDesC8ArrayFlat( KArrayGranularity ); 
       
   291     iSearchAlgorithm = CSearchAlgorithm::NewL();
       
   292     iSearchAlgorithm->SearchEmailAddress( ETrue );
       
   293     iHaveParameters = EFalse;
       
   294     iSameCondition  = EFalse;
       
   295     iIsBooleanCondition = EFalse;
       
   296     FeatureManager::InitializeLibL();
       
   297     }
       
   298     
       
   299 // -----------------------------------------------------------------------------
       
   300 // CSearchTextSearcher::DoStringCompareWithKeywords()
       
   301 // Compares the to be searched string with the list of keywords, 16 bit version. 
       
   302 // -----------------------------------------------------------------------------
       
   303 //
       
   304 TBool CSearchTextSearcher::DoStringCompareWithKeywordsL (
       
   305 			 const TDesC& aToBeSearchedDes,
       
   306              const CDesC16Array& aKeywords, 
       
   307              RArray<TKeywordSearchStatus>& aKeywordSearchStatusArray,
       
   308              CSearchTextSearcher::TSearchCriteriaOperator aOperator,
       
   309              TBool aCaseSensitive )
       
   310     {
       
   311     iSearchAlgorithm->SearchL( aToBeSearchedDes,aKeywords,
       
   312                               aKeywordSearchStatusArray,
       
   313                               aOperator,
       
   314                               aCaseSensitive );
       
   315     if ( aKeywordSearchStatusArray.Count() >= 0 )
       
   316         {
       
   317         if ( iIsBooleanCondition )
       
   318             {
       
   319             CheckForBooleanClausesL( aKeywordSearchStatusArray );   
       
   320             }
       
   321         else
       
   322             {
       
   323             if ( !aKeywordSearchStatusArray[0].iFound )
       
   324                 {
       
   325                 iObserver.HitL( KErrNotFound );
       
   326                 }
       
   327             else
       
   328                 {
       
   329                 iObserver.HitL( aKeywordSearchStatusArray[0].iFoundAtNthPosition );
       
   330                 }   
       
   331             }
       
   332         }
       
   333       
       
   334    return TRUE;                           
       
   335    }
       
   336       
       
   337      
       
   338 // -----------------------------------------------------------------------------
       
   339 // CSearchTextSearcher::DoStringCompareWithKeywords()
       
   340 // Compares the to be searched string with the list of keywords, 8 bit version. 
       
   341 // -----------------------------------------------------------------------------
       
   342 //
       
   343 TBool CSearchTextSearcher::DoStringCompareWithKeywordsL (
       
   344           const TDesC8& aToBeSearchedDes,
       
   345           const CDesC8Array& aKeywords, 
       
   346           RArray<TKeywordSearchStatus>& aKeywordSearchStatusArray,
       
   347           CSearchTextSearcher::TSearchCriteriaOperator  aOperator,
       
   348           TBool aCaseSensitive )
       
   349     {
       
   350     iSearchAlgorithm->SearchL( aToBeSearchedDes,aKeywords,
       
   351              aKeywordSearchStatusArray,aOperator, aCaseSensitive );
       
   352     if ( aKeywordSearchStatusArray.Count() >= 0 )
       
   353         {
       
   354         if ( iIsBooleanCondition )
       
   355             {
       
   356             CheckForBooleanClausesL( aKeywordSearchStatusArray );   
       
   357             }
       
   358         else
       
   359             {
       
   360             if ( !aKeywordSearchStatusArray[0].iFound )
       
   361                 {
       
   362                 iObserver.HitL( KErrNotFound );
       
   363                 }
       
   364             else
       
   365                 {
       
   366                 iObserver.HitL( aKeywordSearchStatusArray[0].iFoundAtNthPosition );
       
   367                 }   
       
   368             }
       
   369         }
       
   370     return TRUE; 
       
   371     }
       
   372      
       
   373  // -----------------------------------------------------------------------------
       
   374 // CSearchTextSearcher::SetSingleConditionDataL()
       
   375 // Sets the singlecondition data for the search.
       
   376 // -----------------------------------------------------------------------------
       
   377 //    
       
   378 void  CSearchTextSearcher::SetSingleConditionDataL ( const 
       
   379           CSearchSingleCondition& aSingleCondition )
       
   380     {
       
   381     const CSearchField& field = aSingleCondition.Term();
       
   382     switch ( field.DataType() )
       
   383         { 
       
   384         case ESearchFieldDataTypeUnknown:
       
   385             break;
       
   386         case ESearchFieldDataTypeTInt:
       
   387             {
       
   388             TInt intData;
       
   389             field.GetData( intData );
       
   390             HBufC* pbuf = HBufC::NewLC( KNumberDataLength );
       
   391             pbuf->Des().AppendNum( intData );
       
   392             iSearchKeywords16->AppendL( pbuf->Des() );
       
   393             CleanupStack::PopAndDestroy( pbuf );
       
   394             }
       
   395             break;
       
   396         case ESearchFieldDataTypeTReal:
       
   397             {  
       
   398             TReal realData;
       
   399             TRealFormat  realFormat( KRealFormatGeneral,KDefaultRealWidth );
       
   400             field.GetData( realData );
       
   401             HBufC* pbuf = HBufC::NewLC( KNumberDataLength );
       
   402             pbuf->Des().AppendNum( realData,realFormat );
       
   403             iSearchKeywords16->AppendL( pbuf->Des() );
       
   404             CleanupStack::PopAndDestroy( pbuf );
       
   405             }
       
   406             break;
       
   407         case ESearchFieldDataTypeTTime:
       
   408             {
       
   409             TTime timeData;
       
   410             field.GetData( timeData );
       
   411             TDateTime dateTime = timeData.DateTime();
       
   412                    
       
   413             HBufC* pbuf = HBufC::NewLC( KTimeDataLength) ;
       
   414                    
       
   415             //Set Time and inset into array
       
   416             pbuf->Des().AppendNum( dateTime.Hour() );
       
   417             pbuf->Des().Append( KColon );
       
   418             pbuf->Des().AppendNum( dateTime.Minute() );
       
   419             pbuf->Des().Append( KColon );
       
   420             pbuf->Des().AppendNum( dateTime.Second() );
       
   421             iSearchKeywords16->AppendL( pbuf->Des() );
       
   422             CleanupStack::PopAndDestroy( pbuf );
       
   423             }
       
   424             break;
       
   425         case ESearchFieldDataTypeTDesC:
       
   426             {
       
   427             TPtrC8  ptr;
       
   428             field.GetData( ptr );
       
   429             HBufC*  dataDes = HBufC::NewLC( ptr.Length() );
       
   430             TPtr  pdata = dataDes->Des();
       
   431             CnvUtfConverter::ConvertToUnicodeFromUtf8( pdata , ptr  );
       
   432             
       
   433             if ( FeatureManager::FeatureSupported( KFeatureIdJapanese ) ||
       
   434                  FeatureManager::FeatureSupported( KFeatureIdChinese )  ||
       
   435                  FeatureManager::FeatureSupported( KFeatureIdThai ) )
       
   436                 {
       
   437                 HBufC* tempBuffer = HBufC::NewLC( ptr.Length() + 1);
       
   438                 TPtr pDataTemp = tempBuffer->Des();
       
   439                 _LIT(KStar, "*");
       
   440                 pDataTemp.Zero();
       
   441                 pDataTemp.Append(KStar);
       
   442                 pDataTemp.Append(pdata);
       
   443                             
       
   444                 iSearchKeywords16->AppendL( pDataTemp );
       
   445                 CleanupStack::PopAndDestroy( tempBuffer );
       
   446                 }
       
   447             else
       
   448                 {
       
   449                 iSearchKeywords16->AppendL( pdata );
       
   450                 }
       
   451             
       
   452             CleanupStack::PopAndDestroy( dataDes );
       
   453             }
       
   454             break;
       
   455         case ESearchFieldDataTypeCustom:
       
   456             break;
       
   457         default:
       
   458             break;
       
   459         }
       
   460     }
       
   461 
       
   462 
       
   463 // -----------------------------------------------------------------------------
       
   464 // CSearchTextSearcher::DoUftTo8BitConvertionL()
       
   465 // 16 - 8 bit conversion 
       
   466 // -----------------------------------------------------------------------------
       
   467 //
       
   468 void CSearchTextSearcher::DoUftTo8BitConversionL ( const MDesCArray& aKeywords )
       
   469     {
       
   470     for ( TInt i = 0 ;i < aKeywords.MdcaCount() ; i++ )
       
   471         {
       
   472         HBufC8* pBuf = HBufC8::NewLC( aKeywords.MdcaPoint( i ).Length() );
       
   473         TPtr8 ptr8 = pBuf->Des();
       
   474         CnvUtfConverter::ConvertFromUnicodeToUtf8( ptr8 ,aKeywords.MdcaPoint( i ) );
       
   475         iSearchKeywords8->AppendL( ptr8 );
       
   476         CleanupStack::PopAndDestroy( pBuf );
       
   477         }
       
   478     }
       
   479 
       
   480 
       
   481 // -----------------------------------------------------------------------------
       
   482 // CSearchTextSearcher::SetCriteriaOperator()
       
   483 // -----------------------------------------------------------------------------
       
   484 //
       
   485 void CSearchTextSearcher::SetCriteriaOperator()
       
   486     {
       
   487     
       
   488     RArray<CSearchBooleanCondition::TBooleanClause>& clause = iClause;
       
   489     
       
   490     TInt condition = iBooleanClause = clause[0]; // take first clause out 
       
   491     
       
   492     TInt nextclause= 0; 
       
   493     for ( TInt i = 0 ;i < clause.Count() ; i++ )
       
   494         {
       
   495         if ( i>0 )
       
   496             { 
       
   497             nextclause = clause[i];
       
   498             condition ^=nextclause; //check if all are 
       
   499             				//the same clause category ( ANDs or ORs )
       
   500             if ( condition )
       
   501                 {
       
   502                 iIntermediateClause = clause[i];
       
   503                 break;
       
   504                 }
       
   505             }
       
   506         }
       
   507      if ( !condition ) // iSameCondition is initially set to FALSE 
       
   508         {
       
   509         iSameCondition = TRUE;
       
   510         }
       
   511    
       
   512     }    
       
   513      
       
   514 // -----------------------------------------------------------------------------
       
   515 // CSearchTextSearcher::CheckForBooleanClausesL()
       
   516 // Compares the to be searched string with the list of keywords, 8 bit version. 
       
   517 // -----------------------------------------------------------------------------
       
   518 //
       
   519 void CSearchTextSearcher::CheckForBooleanClausesL( RArray<TKeywordSearchStatus>& 
       
   520                                                             aKeywordSearchStatusArray )
       
   521     {
       
   522     
       
   523     TBool ifNoneFound = ETrue;
       
   524     TInt  recordFirstPos   = 0;   
       
   525     
       
   526     for ( TInt i = 0 ; i < iCount && i < aKeywordSearchStatusArray.Count() ; i++ )
       
   527         {
       
   528         if (  iBooleanClause == CSearchBooleanCondition::EBooleanMust
       
   529         		 && iSameCondition )
       
   530             {
       
   531             if ( !aKeywordSearchStatusArray[i].iFound )
       
   532                 {
       
   533                 ifNoneFound = ETrue;
       
   534                 break;
       
   535                 }
       
   536             else
       
   537                 {
       
   538                 ifNoneFound = EFalse;
       
   539                 if ( !recordFirstPos )
       
   540                     {
       
   541                     recordFirstPos = 
       
   542                        aKeywordSearchStatusArray[i].iFoundAtNthPosition;	
       
   543                     }
       
   544                 //iObserver.HitL( 
       
   545                 //	aKeywordSearchStatusArray[i].iFoundAtNthPosition );    
       
   546                 }
       
   547             }
       
   548         else if ( iBooleanClause == CSearchBooleanCondition::EBooleanShould 
       
   549         			&&  iSameCondition )
       
   550             {
       
   551             if ( !aKeywordSearchStatusArray[i].iFound )
       
   552                 {
       
   553                 //Do nothing ,just pass on
       
   554                 }
       
   555             else
       
   556                 {
       
   557                 ifNoneFound = EFalse;
       
   558                 iObserver.HitL(
       
   559                 	 aKeywordSearchStatusArray[i].iFoundAtNthPosition );
       
   560                 }    
       
   561             }
       
   562         else //if( !iSameCondition ) 
       
   563             {
       
   564             if ( !aKeywordSearchStatusArray[i].iFound )
       
   565                 {
       
   566                 if ( iBooleanClause  == CSearchBooleanCondition::EBooleanMust )
       
   567                     {
       
   568                     ifNoneFound = ETrue;
       
   569                     //break;  
       
   570                     }
       
   571                 else if( iBooleanClause  == 
       
   572                          CSearchBooleanCondition::EBooleanShould 
       
   573                          && iIntermediateClause == 
       
   574                          CSearchBooleanCondition::EBooleanMust )
       
   575                     {
       
   576                     ifNoneFound = ETrue;
       
   577                     //break;     
       
   578                    } 
       
   579                 }
       
   580             else 
       
   581                 {
       
   582                 ifNoneFound = EFalse;
       
   583                 iObserver.HitL( aKeywordSearchStatusArray[i].iFoundAtNthPosition );
       
   584                 }
       
   585             }
       
   586         }
       
   587     
       
   588     if ( !ifNoneFound && iBooleanClause == 
       
   589            CSearchBooleanCondition::EBooleanMust ) 
       
   590         {
       
   591         iObserver.HitL( recordFirstPos ); 
       
   592         }
       
   593     }