uiutils/Findutil/src/FindUtilThai.cpp
changeset 0 2f259fa3e83a
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2002-2004 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:         Thai Find Utilities implementation file.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 
       
    26 #include "FindUtilThai.h"
       
    27 const TInt KLitTab('\t');
       
    28 const TInt KLitSpace(' ');
       
    29 const TInt KLitHyphen('-');
       
    30 const TInt KLitLineFeed(8233);
       
    31 const TInt KLitStar('*');
       
    32 const TInt KMatchingBufferLength(256);
       
    33 
       
    34 namespace {
       
    35 
       
    36 // ---------------------------------------------------------------------------
       
    37 // IsFindWordSeparator
       
    38 // ---------------------------------------------------------------------------
       
    39 //
       
    40 inline TBool IsFindWordSeparator(TChar aCh)
       
    41     {
       
    42     return aCh == KLitSpace || aCh == KLitHyphen || aCh == KLitTab || aCh == KLitLineFeed;
       
    43     }
       
    44 
       
    45 void ReplaceCharacters(TDes &aDes, const TDesC &aChars, TChar aReplacement)
       
    46     //
       
    47     // Running time O(aDes.Length() * aChars.Length())
       
    48     // Does not change length of the string.
       
    49     // 
       
    50     {
       
    51     TInt src = 0;
       
    52     TInt srclength = aDes.Length();
       
    53     while(src < srclength)
       
    54         {
       
    55         TChar c = aDes[src];
       
    56         if (aChars.LocateF(c) != KErrNotFound)
       
    57             aDes[src] = TUint16(aReplacement);
       
    58         ++src;
       
    59         }
       
    60     }
       
    61 
       
    62 inline TInt MyFindC(const TDesC &aItemString, const TDesC &aSearchText)
       
    63     {
       
    64     TBuf<200> searchText;
       
    65     TBuf<200> itemString;
       
    66     searchText.Append(aSearchText);
       
    67     // The replacecharacters are to disable regexp matching provided
       
    68     // by MatchC().
       
    69 	_LIT(KQuestion,"?");
       
    70 	_LIT(KStar,"*");
       
    71     ReplaceCharacters(searchText, KQuestion, TChar('\t'));
       
    72     ReplaceCharacters(searchText, KStar, TChar('\r'));
       
    73     searchText.Append(KStar);
       
    74     if (aItemString.Length() < 200)
       
    75         itemString.Append(aItemString);
       
    76     else
       
    77         itemString.Append(aItemString.Left(200));
       
    78     ReplaceCharacters(itemString, KQuestion, TChar('\t'));
       
    79     ReplaceCharacters(itemString, KStar, TChar('\r'));
       
    80 
       
    81 
       
    82     TInt length = itemString.Length();
       
    83     for(int i=0;i<length;i++)
       
    84         {
       
    85         if (i==0 || IsFindWordSeparator(aItemString[i-1]))
       
    86             {
       
    87             if (itemString.Mid(i).MatchC(searchText) != KErrNotFound)
       
    88                 {
       
    89                 return i;
       
    90                 }
       
    91             }
       
    92         }
       
    93     return KErrNotFound;
       
    94     }
       
    95 
       
    96 inline TBool IsFindMatch(const TDesC& aItemString, const TDesC& aSearchText)
       
    97     {
       
    98     TPtrC itemptr = aItemString;
       
    99     TPtrC searchptr = aSearchText;
       
   100 
       
   101     TBool match = EFalse;
       
   102     
       
   103     for(;;) 
       
   104         {
       
   105         // Loop invariant: itemptr is next character from ' ' or '-'
       
   106         // Loop invariant: seachptr is at beginning of searched item
       
   107     
       
   108         TInt val = MyFindC(itemptr,searchptr);
       
   109         if (val == 0)
       
   110             {
       
   111             match = ETrue;
       
   112             break;
       
   113             }
       
   114         if (val != KErrNotFound && IsFindWordSeparator(itemptr[val-1]))
       
   115             {
       
   116             match = ETrue;
       
   117             break;
       
   118             }
       
   119 
       
   120         // find the word separator characters from list item
       
   121         TInt spacepos = itemptr.LocateF(TChar(' '));
       
   122         TInt minuspos = itemptr.LocateF(TChar('-'));
       
   123         TInt tabpos = itemptr.LocateF(TChar('\t'));
       
   124         if (spacepos != KErrNotFound)
       
   125             {
       
   126             itemptr.Set(itemptr.Mid(spacepos+1));
       
   127             }
       
   128         else if (minuspos != KErrNotFound)
       
   129             {
       
   130             itemptr.Set(itemptr.Mid(minuspos+1));
       
   131             }
       
   132         else if (tabpos != KErrNotFound)
       
   133             {
       
   134             itemptr.Set(itemptr.Mid(tabpos+1));
       
   135             }
       
   136         else
       
   137             {
       
   138             match = EFalse;
       
   139             break;
       
   140             }
       
   141         if (itemptr.Length() == 0)
       
   142             {
       
   143             match = EFalse;
       
   144             break;
       
   145             }
       
   146 
       
   147         }
       
   148     return match;
       
   149     }
       
   150 
       
   151 }
       
   152 
       
   153 // ============================ MEMBER FUNCTIONS ===============================
       
   154 
       
   155 // -----------------------------------------------------------------------------
       
   156 // CFindUtilThai::CFindUtilThai
       
   157 // C++ default constructor can NOT contain any code, that
       
   158 // might leave.
       
   159 // -----------------------------------------------------------------------------
       
   160 //
       
   161 CFindUtilThai::CFindUtilThai()
       
   162     {
       
   163     }
       
   164 
       
   165 // Destructor
       
   166 CFindUtilThai::~CFindUtilThai()
       
   167     {
       
   168     }
       
   169 
       
   170 // -----------------------------------------------------------------------------
       
   171 // CFindUtilThai::Match
       
   172 // (other items were commented in a header).
       
   173 // -----------------------------------------------------------------------------
       
   174 //
       
   175 
       
   176 TBool CFindUtilThai::Match(const TDesC& aContactsField, const TDesC& aWord)
       
   177     {
       
   178     if (!aContactsField.Length())
       
   179         {
       
   180         return EFalse;
       
   181         }
       
   182     
       
   183     if (aContactsField.MatchC(aWord) != KErrNotFound)
       
   184         {
       
   185         return ETrue;
       
   186         }
       
   187     else if (aContactsField.MatchF(aWord) != KErrNotFound)
       
   188         {
       
   189         return ETrue;
       
   190         }
       
   191     return EFalse;
       
   192     }
       
   193 
       
   194 // -----------------------------------------------------------------------------
       
   195 // CFindUtilThai::MatchRefineL
       
   196 // (other items were commented in a header).
       
   197 // -----------------------------------------------------------------------------
       
   198 //
       
   199 TBool CFindUtilThai::MatchRefineL( const TDesC& aItemString, const TDesC& aSearchText)
       
   200     {
       
   201     if ( aItemString.Length() == 0 )
       
   202         {
       
   203         return EFalse;
       
   204         }
       
   205 
       
   206     if ( aSearchText.Length() == 0 )
       
   207         {
       
   208         return ETrue;
       
   209         }
       
   210 
       
   211     return IsFindMatch(aItemString, aSearchText);
       
   212     }
       
   213 
       
   214 // -----------------------------------------------------------------------------
       
   215 // CFindUtilThai::IsWordValidForMatching
       
   216 // (other items were commented in a header).
       
   217 // -----------------------------------------------------------------------------
       
   218 //
       
   219 TBool CFindUtilThai::IsWordValidForMatching(const TDesC& /*aWord*/)
       
   220     {
       
   221     return ETrue;
       
   222     }
       
   223 
       
   224 
       
   225 // ========================= FOR ADAPTIVE FIND ================================
       
   226 
       
   227 /**
       
   228  * Update next characters if find pane state was changed.
       
   229  *
       
   230  * @since 5.0
       
   231  * @param aNextChars reference to the next characters for the adaptive search grid
       
   232  * @param aCh Criteria from the search field.    
       
   233  */
       
   234 inline void UpdateNextCharsL( HBufC*& aNextChars, TChar aCh )
       
   235 	{
       
   236 	if( ( aNextChars->Locate(aCh.GetLowerCase() ) == KErrNotFound ) &&
       
   237     	( aNextChars->Locate(aCh.GetUpperCase() ) == KErrNotFound ) )
       
   238 		{				
       
   239 		if( aNextChars->Des().Length() == aNextChars->Des().MaxLength() )
       
   240 			{
       
   241 			aNextChars = aNextChars->ReAllocL( aNextChars->Des().MaxLength()+10 );
       
   242 			TInt length1 = aNextChars->Des().Length();
       
   243 			TInt maxlength1 = aNextChars->Des().MaxLength();
       
   244 			}		
       
   245 		aNextChars->Des().Append( aCh );			
       
   246 		}
       
   247 	}
       
   248 
       
   249 /**
       
   250  * Update next chars from the list box item text, when search field is empty.
       
   251  * This need to be done for update next characters for adaptive grid
       
   252  * works faster then calling IsAdaptiveFindMatch().   
       
   253  *
       
   254  * @since 5.0
       
   255  * @param aNextChars reference to the next characters for the adaptive search grid
       
   256  * @param aItemString List box item text.
       
   257  */
       
   258 inline void UpdateNextCharsFromString( HBufC*& aNextChars, const TDesC& aItemString )
       
   259 	{   
       
   260 	 TInt itemStringLength = aItemString.Length();
       
   261 	 
       
   262 	 for( TInt i = 0; i < itemStringLength; i++ )
       
   263         {
       
   264         if ( i == 0 || IsFindWordSeparator( aItemString[i-1] ) )
       
   265             {            
       
   266             TRAP_IGNORE( UpdateNextCharsL( aNextChars, aItemString[i] ) );   	   		
       
   267             }
       
   268 		}
       
   269 	}
       
   270 
       
   271 /**
       
   272  * Checks the current character for special character from Thai language . 
       
   273  *
       
   274  * @since 5.0
       
   275  * @return @c ETrue If tone mark or diatric from Thai language otherwise EFalse. 
       
   276  */	
       
   277 inline TBool IsThaiSpecialCharacter( TChar aCh )
       
   278     {    
       
   279     if( ( aCh > 0xE46 && aCh < 0xE4F ) ||  aCh == 0xE3A )
       
   280 		{
       
   281 		return ETrue;
       
   282 		}       
       
   283 	return EFalse;
       
   284     }
       
   285     
       
   286 /**    
       
   287  * Checks if @c aItemText matches @c aSearchText in the sense described in
       
   288  * S60.  Calls UpdateNextCharsL() if findutil is not supported.
       
   289  *
       
   290  * @since 5.0
       
   291  * @param aItemText list box item text.
       
   292  * @param aSearchText search text.
       
   293  * @param aNextChars reference to the next characters for the adaptive search grid
       
   294  * 
       
   295  * @return @c ETrue if list box item text @c aItemText matches @c 
       
   296  *         aSearchText otherwise @c EFalse.
       
   297  */
       
   298 inline TBool IsAdaptiveFindMatch( const TDesC& aItemString, 
       
   299 	const TDesC& aSearchText, HBufC*& aNextChars )
       
   300 	{	    	
       
   301 	HBufC16* searchText = NULL;
       
   302 	TRAPD( error, searchText = HBufC16::NewL( KMatchingBufferLength ) );
       
   303 	if ( error == KErrNone )
       
   304 	    {
       
   305 	    TInt itemStringLength = aItemString.Length();
       
   306         TInt searchTextLength = aSearchText.Length();    
       
   307         
       
   308         if ( searchTextLength < KMatchingBufferLength )
       
   309         	{
       
   310         	searchText->Des().Append( aSearchText );
       
   311         	}
       
   312         else
       
   313         	{
       
   314         	searchText->Des().Append( aSearchText.Left(KMatchingBufferLength-1) );
       
   315         	}    
       
   316     	
       
   317         searchText->Des().Append( KLitStar );
       
   318        
       
   319         TInt all_result = KErrNotFound;
       
   320         for( TInt i = 0; i < itemStringLength; i++ )
       
   321             {
       
   322             if ( i==0 || IsFindWordSeparator( aItemString[i-1] ) )
       
   323                 {
       
   324                 TInt result = aItemString.Mid(i).MatchF( searchText->Des() );
       
   325                 
       
   326                 if( result != KErrNotFound ) 
       
   327                     {
       
   328                     all_result = result;
       
   329                     if( i < (itemStringLength-searchTextLength) )                	   	       	   		
       
   330                         {
       
   331                         if( !(IsThaiSpecialCharacter( aItemString[i+searchTextLength])) )
       
   332                             {
       
   333                             TRAP_IGNORE( UpdateNextCharsL( aNextChars, aItemString[i+searchTextLength]) );
       
   334                             }            	   
       
   335                         }
       
   336                     }                                                                  	   	
       
   337                 } // if (i==0 ..)        
       
   338       	    } // for	 
       
   339 	    
       
   340   	    if( all_result != KErrNotFound )
       
   341             {
       
   342             delete searchText;
       
   343             return ETrue;
       
   344            	}    
       
   345         else 
       
   346             {
       
   347             delete searchText;
       
   348             return EFalse;
       
   349             }
       
   350         	            		
       
   351          } // if (error == KErrNone)   
       
   352     delete searchText;                 
       
   353     return EFalse;
       
   354 	}
       
   355 	
       
   356 
       
   357 // -----------------------------------------------------------------------------
       
   358 // CFindUtilWestern::MatchAdaptiveRefineL
       
   359 // (other items were commented in a header).
       
   360 // -----------------------------------------------------------------------------
       
   361 //  
       
   362 TBool CFindUtilThai::MatchAdaptiveRefineL( const TDesC& aItemString, 
       
   363 	const TDesC& aSearchText, HBufC*& aNextChars )
       
   364 	{
       
   365     if ( aItemString.Length() == 0 )
       
   366         {
       
   367         return EFalse;
       
   368         }
       
   369     if ( aSearchText.Length() == 0 )
       
   370         {        
       
   371         UpdateNextCharsFromString( aNextChars, aItemString );
       
   372         return ETrue;
       
   373         }        
       
   374     return IsAdaptiveFindMatch( aItemString, aSearchText, aNextChars );		
       
   375 	}
       
   376 	
       
   377 // ---------------------------------------------------------
       
   378 // Match arithmetic for accurate search, special conversion 
       
   379 // for aItemString is implemented with MFindStringConverter
       
   380 // before the final match
       
   381 // ---------------------------------------------------------
       
   382 //
       
   383 TBool CFindUtilThai::MatchRefineL( const TDesC& /*aItemString*/, const TDesC& /*aSearchText*/, 
       
   384                                    TMatchPolicy /*aPolicy*/, MFindStringConverter* /*aConverter*/)
       
   385     {
       
   386     return EFalse;
       
   387     }	
       
   388 
       
   389 // ========================== OTHER EXPORTED FUNCTIONS =========================
       
   390 
       
   391 // -----------------------------------------------------------------------------
       
   392 // FindUtilFactoryFunctionL
       
   393 // Factory function at first ordinal
       
   394 // Returns: MFindUtil: It returns MFindUtil I/F.
       
   395 // -----------------------------------------------------------------------------
       
   396 //
       
   397 // Factory function at first ordinal
       
   398 EXPORT_C MFindUtil* FindUtilFactoryFunctionL()
       
   399     {
       
   400     return new( ELeave ) CFindUtilThai();
       
   401     }
       
   402 
       
   403 // end of file