predictivesearch/PcsAlgorithm/Algorithm2/src/CPcsAlgorithm2Helper.cpp
changeset 0 e686773b3f54
child 7 b3431bff8c19
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 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: Predictive Contact Search Algorithm 1 helper class
       
    15 *
       
    16 */
       
    17 
       
    18 // INCLUDES
       
    19 #include <FindUtil.h>
       
    20 #include "FindUtilChineseECE.h"
       
    21 #include "CPcsAlgorithm2.h"
       
    22 #include "CPcsAlgorithm2Helper.h"
       
    23 #include "CPcsAlgorithm2Utils.h"
       
    24 #include "CPcsDebug.h"
       
    25 #include "CPcsCache.h"
       
    26 #include "CPcsKeyMap.h"
       
    27 #include "CPsData.h"
       
    28 #include "CWords.h"
       
    29 #include "CPsQuery.h"
       
    30 #include "CPsQueryItem.h"
       
    31 #include "CPsDataPluginInterface.h"
       
    32 #include "CPcsPoolElement.h"
       
    33 
       
    34 // Compare functions
       
    35 TBool Compare1(const TDesC& aFirst, const TDesC& aSecond)
       
    36     {
       
    37     return aFirst == aSecond;
       
    38     }
       
    39 
       
    40 TBool Compare2(const TDesC& aFirst, const TDesC& aSecond)
       
    41     {
       
    42     return CPcsAlgorithm2Utils::MyCompareC(aFirst, aSecond);
       
    43     }
       
    44 
       
    45 // ============================== MEMBER FUNCTIONS ============================
       
    46 
       
    47 // ----------------------------------------------------------------------------
       
    48 // CPcsAlgorithm2Helper::NewL
       
    49 // Two Phase Construction
       
    50 // ----------------------------------------------------------------------------
       
    51 CPcsAlgorithm2Helper* CPcsAlgorithm2Helper::NewL(CPcsAlgorithm2* aAlgorithm)
       
    52     {
       
    53     PRINT ( _L("Enter CPcsAlgorithm2Helper::NewL") );
       
    54 
       
    55     CPcsAlgorithm2Helper* self = new (ELeave) CPcsAlgorithm2Helper();
       
    56     CleanupStack::PushL(self);
       
    57     self->ConstructL(aAlgorithm);
       
    58     CleanupStack::Pop(self);
       
    59 
       
    60     PRINT ( _L("End CPcsAlgorithm2Helper::NewL") );
       
    61 
       
    62     return self;
       
    63     }
       
    64 
       
    65 // ----------------------------------------------------------------------------
       
    66 // CPcsAlgorithm2Helper::CPcsAlgorithm2Helper
       
    67 // Two Phase Construction
       
    68 // ----------------------------------------------------------------------------
       
    69 CPcsAlgorithm2Helper::CPcsAlgorithm2Helper()
       
    70     {
       
    71     PRINT ( _L("Enter CPcsAlgorithm2Helper::CPcsAlgorithm2") );
       
    72     PRINT ( _L("End CPcsAlgorithm2Helper::CPcsAlgorithm2") );
       
    73     }
       
    74 
       
    75 // ----------------------------------------------------------------------------
       
    76 // CPcsAlgorithm2Helper::ConstructL
       
    77 // Two Phase Construction
       
    78 // ----------------------------------------------------------------------------
       
    79 void CPcsAlgorithm2Helper::ConstructL(CPcsAlgorithm2* aAlgorithm)
       
    80     {
       
    81     PRINT ( _L("Enter CPcsAlgorithm2Helper::ConstructL") );
       
    82 
       
    83     iAlgorithm = aAlgorithm;
       
    84     keyMap = iAlgorithm->GetKeyMap();
       
    85 
       
    86     PRINT ( _L("End CPcsAlgorithm2Helper::ConstructL") );
       
    87     }
       
    88 
       
    89 // ----------------------------------------------------------------------------
       
    90 // CPcsAlgorithm2Helper::CPcsAlgorithm2Helper
       
    91 // Destructor
       
    92 // ----------------------------------------------------------------------------
       
    93 CPcsAlgorithm2Helper::~CPcsAlgorithm2Helper()
       
    94     {
       
    95     PRINT ( _L("Enter CPcsAlgorithm2Helper::~CPcsAlgorithm2Helper") );
       
    96     iSearchResultsArr.ResetAndDestroy();
       
    97     PRINT ( _L("End CPcsAlgorithm2Helper::~CPcsAlgorithm2Helper") );
       
    98     }
       
    99 
       
   100 // ----------------------------------------------------------------------------
       
   101 // CPcsAlgorithm2Helper::SearchMixedL
       
   102 // Search function for input with both ITU-T and QWERTY mode
       
   103 // ----------------------------------------------------------------------------
       
   104 void CPcsAlgorithm2Helper::SearchMixedL(const CPsSettings& aSettings,
       
   105                                         CPsQuery& aPsQuery, TBool isSearchInGroup,
       
   106                                         RArray<TInt>& aContactsInGroup,
       
   107                                         RPointerArray<CPsData>& searchResults,
       
   108                                         RPointerArray<CPsPattern>& searchSeqs)
       
   109     {
       
   110     __LATENCY_MARK ( _L("CPcsAlgorithm2Helper::SearchMixedL") );
       
   111 
       
   112     PRINT ( _L("Enter CPcsAlgorithm2Helper::SearchMixedL") );
       
   113 
       
   114     // Create filtering helper for the required sort type
       
   115     TSortType sortType = aSettings.GetSortType();
       
   116     CPcsAlgorithm2FilterHelper* filterHelper =
       
   117             CPcsAlgorithm2FilterHelper::NewL(sortType);
       
   118 
       
   119     // Convert the search condition to numeric key string
       
   120     TBuf<KPsQueryMaxLen> numericKeyStr;
       
   121     TPtrC queryPtr = aPsQuery.QueryAsStringLC();
       
   122     keyMap->GetNumericKeyString(queryPtr, numericKeyStr);
       
   123     PRINT2 ( _L("Numeric Key String for %S = %S"), &queryPtr, &numericKeyStr );
       
   124 
       
   125     // Reset the result set array for new search
       
   126     iSearchResultsArr.ResetAndDestroy();
       
   127 
       
   128     // Get the data stores
       
   129     RPointerArray<TDesC> aDataStores;
       
   130     aSettings.SearchUrisL(aDataStores);
       
   131 
       
   132     // Get the required display fields from the client
       
   133     RArray<TInt> requiredDataFields;
       
   134     aSettings.DisplayFieldsL(requiredDataFields);
       
   135 
       
   136     // Search based on first key str
       
   137     TInt numValue = keyMap->PoolIdForCharacter(numericKeyStr[0]);
       
   138 
       
   139     // Perform search for each required data store
       
   140     RPointerArray<CPcsPoolElement> elements;
       
   141 
       
   142     for (int dsIndex = 0; dsIndex < aDataStores.Count(); dsIndex++)
       
   143         {
       
   144 
       
   145         RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
       
   146         iSearchResultsArr.Append(temp);
       
   147 
       
   148         // Get the contents for this data store
       
   149         TInt arrayIndex = iAlgorithm->GetCacheIndex(*(aDataStores[dsIndex]));
       
   150         if (arrayIndex < 0)
       
   151             {
       
   152             continue;
       
   153             }
       
   154         CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
       
   155         cache->GetContactsForKeyL(numValue, elements);
       
   156 
       
   157         // Perform filtering
       
   158         FilterResultsMixedL(filterHelper, elements, aPsQuery,
       
   159                             isSearchInGroup, aContactsInGroup);
       
   160 
       
   161         // If alphabetical sorting, get the results for this datastore               
       
   162         if (sortType == EAlphabetical)
       
   163             {
       
   164             filterHelper->GetResults(*(iSearchResultsArr[dsIndex]));
       
   165             }
       
   166 
       
   167         elements.Reset();
       
   168         }
       
   169 
       
   170     aDataStores.ResetAndDestroy();
       
   171     requiredDataFields.Reset();
       
   172 
       
   173     // If alphabetical sorting, merge the result sets of all datastores
       
   174     if (sortType == EAlphabetical)
       
   175         {
       
   176         // Form the complete searchResults array
       
   177         CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iSearchResultsArr,
       
   178                                                         searchResults);
       
   179         }
       
   180     else
       
   181         {
       
   182         // Results are already sorted pattern based
       
   183         filterHelper->GetResults(searchResults);
       
   184         }
       
   185 
       
   186     // Get the sorted match sequence list
       
   187     filterHelper->GetPatternsL(searchSeqs);
       
   188 
       
   189     PRINT1 ( _L("Number of search results = %d"), searchResults.Count() );
       
   190 
       
   191     // Cleanup         
       
   192     for (TInt i = 0; i < iSearchResultsArr.Count(); i++)
       
   193         {
       
   194         iSearchResultsArr[i]->Reset();
       
   195         delete iSearchResultsArr[i];
       
   196         iSearchResultsArr[i] = NULL;
       
   197         }
       
   198 
       
   199     iSearchResultsArr.Reset();
       
   200 
       
   201     CleanupStack::PopAndDestroy(); // query
       
   202     delete filterHelper;
       
   203 
       
   204     PRINT ( _L("End CPcsAlgorithm2Helper::SearchMixedL") );
       
   205 
       
   206     __LATENCY_MARKEND ( _L("CPcsAlgorithm2Helper::SearchMixedL") );
       
   207     }
       
   208 
       
   209 // ----------------------------------------------------------------------------
       
   210 // CPcsAlgorithm2Helper::SearchITUL
       
   211 // Search function for ITU-T style
       
   212 // ----------------------------------------------------------------------------
       
   213 void CPcsAlgorithm2Helper::SearchITUL(const CPsSettings& aSettings,
       
   214                                       CPsQuery& aPsQuery, TBool isSearchInGroup,
       
   215                                       RArray<TInt>& aContactsInGroup,
       
   216                                       RPointerArray<CPsData>& searchResults,
       
   217                                       RPointerArray<CPsPattern>& searchSeqs)
       
   218     {
       
   219     __LATENCY_MARK ( _L("CPcsAlgorithm2Helper::SearchITUL") );
       
   220 
       
   221     PRINT ( _L("Enter CPcsAlgorithm2Helper::SearchITUL") );
       
   222 
       
   223     // Create filtering helper for the required sort type
       
   224     TSortType sortType = aSettings.GetSortType();
       
   225     CPcsAlgorithm2FilterHelper* filterHelper =
       
   226             CPcsAlgorithm2FilterHelper::NewL(sortType);
       
   227 
       
   228     // Convert the search condition to numeric key string
       
   229     TBuf<KPsQueryMaxLen> numericKeyStr;
       
   230     TPtrC queryPtr = aPsQuery.QueryAsStringLC();
       
   231     keyMap->GetNumericKeyString(queryPtr, numericKeyStr);
       
   232     PRINT2 ( _L("Numeric Key String for %S = %S"), &queryPtr, &numericKeyStr );
       
   233     TInt numValue = keyMap->PoolIdForCharacter(numericKeyStr[0]);
       
   234 
       
   235     // Reset the result set array for new search
       
   236     iSearchResultsArr.ResetAndDestroy();
       
   237 
       
   238     // Get the data stores
       
   239     RPointerArray<TDesC> aDataStores;
       
   240     aSettings.SearchUrisL(aDataStores);
       
   241 
       
   242     // Get the required display fields from the client
       
   243     RArray<TInt> requiredDataFields;
       
   244     aSettings.DisplayFieldsL(requiredDataFields);
       
   245 
       
   246     // Perform search for each required data store
       
   247     RPointerArray<CPcsPoolElement> elements;
       
   248 
       
   249     for (int dsIndex = 0; dsIndex < aDataStores.Count(); dsIndex++)
       
   250         {
       
   251         RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
       
   252         iSearchResultsArr.Append(temp);
       
   253 
       
   254         // Get the contents for this data store
       
   255         TInt arrayIndex = iAlgorithm->GetCacheIndex(*(aDataStores[dsIndex]));
       
   256         if (arrayIndex < 0)
       
   257             {
       
   258             continue;
       
   259             }
       
   260         CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
       
   261         cache->GetContactsForKeyL(numValue, elements);
       
   262 
       
   263         // Perform filtering
       
   264         FilterResultsL(filterHelper, elements, numericKeyStr,
       
   265                        isSearchInGroup, aContactsInGroup);
       
   266 
       
   267         // If alphabetical sorting, get the results for this datastore               
       
   268         if (sortType == EAlphabetical)
       
   269             {
       
   270             filterHelper->GetResults(*(iSearchResultsArr[dsIndex]));
       
   271             }
       
   272 
       
   273         elements.Reset();
       
   274         }
       
   275 
       
   276     aDataStores.ResetAndDestroy();
       
   277     requiredDataFields.Reset();
       
   278 
       
   279     // If alphabetical sorting, merge the result sets of all datastores
       
   280     if (sortType == EAlphabetical)
       
   281         {
       
   282         // Merge the result sets of individual datastores alphabetically
       
   283         CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iSearchResultsArr,
       
   284                                                         searchResults);
       
   285         }
       
   286     else
       
   287         {
       
   288         // Results are already sorted pattern based 
       
   289         filterHelper->GetResults(searchResults);
       
   290         }
       
   291 
       
   292     // Get the sorted match sequence list
       
   293     filterHelper->GetPatternsL(searchSeqs);
       
   294 
       
   295     PRINT1 ( _L("Number of search results = %d"), searchResults.Count() );
       
   296 
       
   297     // Cleanup
       
   298     for (TInt i = 0; i < iSearchResultsArr.Count(); i++)
       
   299         {
       
   300         iSearchResultsArr[i]->Reset();
       
   301         delete iSearchResultsArr[i];
       
   302         iSearchResultsArr[i] = NULL;
       
   303         }
       
   304     iSearchResultsArr.Reset();
       
   305 
       
   306     CleanupStack::PopAndDestroy(); // query
       
   307     delete filterHelper;
       
   308 
       
   309     PRINT ( _L("End CPcsAlgorithm2Helper::SearchITUL") );
       
   310     __LATENCY_MARKEND ( _L("CPcsAlgorithm2Helper::SearchITUL") );
       
   311     }
       
   312 
       
   313 // ----------------------------------------------------------------------------
       
   314 // CPcsAlgorithm2Helper::SearchQWERTYL
       
   315 // Search function for QWERTY style
       
   316 // ----------------------------------------------------------------------------
       
   317 void CPcsAlgorithm2Helper::SearchQWERTYL(const CPsSettings& aSettings,
       
   318                                          CPsQuery& aPsQuery, TBool isSearchInGroup,
       
   319                                          RArray<TInt>& aContactsInGroup,
       
   320                                          RPointerArray<CPsData>& searchResults,
       
   321                                          RPointerArray<CPsPattern>& searchSeqs)
       
   322     {
       
   323     __LATENCY_MARK ( _L("CPcsAlgorithm2Helper::SearchQWERTYL") );
       
   324     PRINT ( _L("Enter CPcsAlgorithm2Helper::SearchQWERTYL") );
       
   325 
       
   326     // te filtering helper for the required sort type
       
   327     TSortType sortType = aSettings.GetSortType();
       
   328     CPcsAlgorithm2FilterHelper* filterHelper =
       
   329             CPcsAlgorithm2FilterHelper::NewL(sortType);
       
   330 
       
   331     // Convert the search condition to numeric key string
       
   332     TBuf<KPsQueryMaxLen> numericKeyStr;
       
   333     TPtrC queryPtr = aPsQuery.QueryAsStringLC();
       
   334 
       
   335     TChar queryChar;
       
   336 
       
   337     // Handle Chinese word search case: extract the first char of one of its spelling
       
   338     // which will be used as search string
       
   339     if (iAlgorithm->FindUtilECE()->IsChineseWord(queryPtr))
       
   340         {
       
   341         RPointerArray<HBufC> spellList;
       
   342         if (iAlgorithm->FindUtilECE()->T9ChineseTranslationL(queryPtr[0], spellList))
       
   343             {
       
   344             queryChar = *(spellList[0]->Ptr());
       
   345             }
       
   346         else
       
   347             {
       
   348             queryChar = queryPtr[0];
       
   349             }
       
   350         spellList.ResetAndDestroy();
       
   351         }
       
   352     else
       
   353         {
       
   354         queryChar = queryPtr[0];
       
   355         }
       
   356 
       
   357     TInt numValue = keyMap->PoolIdForCharacter(queryChar);
       
   358     // Reset the result set array for new search
       
   359     iSearchResultsArr.ResetAndDestroy();
       
   360 
       
   361     // Get the data stores  
       
   362     RPointerArray<TDesC> aDataStores;
       
   363     aSettings.SearchUrisL(aDataStores);
       
   364 
       
   365     // Get the required display fields from the client
       
   366     RArray<TInt> requiredDataFields;
       
   367     aSettings.DisplayFieldsL(requiredDataFields);
       
   368 
       
   369     // Perform search for each of the required data stores
       
   370     RPointerArray<CPcsPoolElement> elements;
       
   371 
       
   372     for (int dsIndex = 0; dsIndex < aDataStores.Count(); dsIndex++)
       
   373         {
       
   374 
       
   375         RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> ();
       
   376         iSearchResultsArr.Append(temp);
       
   377 
       
   378         // Get the contents for this data store
       
   379         TInt arrayIndex = iAlgorithm->GetCacheIndex(*(aDataStores[dsIndex]));
       
   380         if (arrayIndex < 0)
       
   381             {
       
   382             continue;
       
   383             }
       
   384         CPcsCache* cache = iAlgorithm->GetCache(arrayIndex);
       
   385         cache->GetContactsForKeyL(numValue, elements);
       
   386 
       
   387         // Perform filtering
       
   388         FilterResultsQwertyL(filterHelper, elements, queryPtr,
       
   389                              isSearchInGroup, aContactsInGroup);
       
   390 
       
   391         // If alphabetical sorting, get the results for this datastore               
       
   392         if (sortType == EAlphabetical)
       
   393             {
       
   394             filterHelper->GetResults(*(iSearchResultsArr[dsIndex]));
       
   395             }
       
   396 
       
   397         elements.Reset();
       
   398         }
       
   399     aDataStores.ResetAndDestroy();
       
   400     requiredDataFields.Reset();
       
   401 
       
   402     // If alphabetical sorting, merge the result sets of all datastores
       
   403     if (sortType == EAlphabetical)
       
   404         {
       
   405         // Form the complete searchResults array
       
   406         CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iSearchResultsArr,
       
   407                                                         searchResults);
       
   408         }
       
   409     else
       
   410         {
       
   411         // Results are already sorted pattern based
       
   412         filterHelper->GetResults(searchResults);
       
   413         }
       
   414 
       
   415     // Get the sorted match sequence list
       
   416     filterHelper->GetPatternsL(searchSeqs);
       
   417 
       
   418     PRINT1 ( _L("Number of search results = %d"), searchResults.Count() );
       
   419 
       
   420     // Cleanup             
       
   421     for (TInt i = 0; i < iSearchResultsArr.Count(); i++)
       
   422         {
       
   423         iSearchResultsArr[i]->Reset();
       
   424         delete iSearchResultsArr[i];
       
   425         iSearchResultsArr[i] = NULL;
       
   426         }
       
   427     iSearchResultsArr.Reset();
       
   428 
       
   429     CleanupStack::PopAndDestroy(); // query
       
   430     delete filterHelper;
       
   431 
       
   432     PRINT ( _L("End CPcsAlgorithm2Helper::SearchQWERTYL") );
       
   433     __LATENCY_MARKEND ( _L("CPcsAlgorithm2Helper::SearchQWERTYL") );
       
   434     }
       
   435 
       
   436 // ----------------------------------------------------------------------------
       
   437 // CPcsAlgorithm2Helper::SearchMatchSeqL
       
   438 // Funciton to search matching sequences in the input text
       
   439 // ----------------------------------------------------------------------------
       
   440 void CPcsAlgorithm2Helper::SearchMatchSeqL(HBufC* /*aQuery*/, TDesC& aData,
       
   441                                            RPointerArray<TDesC>& /*aMatchSet*/, 
       
   442                                            CPsQuery& /*aPsQuery*/,
       
   443                                            RArray<TPsMatchLocation>& aMatchLocation)
       
   444     {
       
   445     PRINT ( _L("Enter CPcsAlgorithm2Helper::SearchMatchSeqL") );
       
   446 
       
   447     // Convert the data into words		     
       
   448     TLex lex(aData);
       
   449 
       
   450     // First word
       
   451     TPtrC token = lex.NextToken();
       
   452 
       
   453     TInt beg = lex.Offset() - token.Length(); // start index of match sequence
       
   454 
       
   455     // Search thru multiple words
       
   456     while (token.Length() != 0)
       
   457         {
       
   458         TPsMatchLocation tempLocation;
       
   459 
       
   460         // check for directionality of the text
       
   461         TBool found(EFalse);
       
   462         TBidiText::TDirectionality dir = TBidiText::TextDirectionality(token, &found);
       
   463 
       
   464         tempLocation.index = beg;
       
   465         tempLocation.length = 0;
       
   466         tempLocation.direction = dir;
       
   467 
       
   468         // Add the match location to the data structure array
       
   469         aMatchLocation.Append(tempLocation);
       
   470 
       
   471         // Next word
       
   472         token.Set(lex.NextToken());
       
   473         beg = lex.Offset() - token.Length(); // start index of next word
       
   474         }
       
   475 
       
   476     PRINT ( _L("End CPcsAlgorithm2Helper::SearchMatchSeqL") );
       
   477     }
       
   478 
       
   479 // ----------------------------------------------------------------------------
       
   480 // CPcsAlgorithm2::FilterResultsL
       
   481 // Subset search function
       
   482 // ----------------------------------------------------------------------------
       
   483 void CPcsAlgorithm2Helper::FilterResultsL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper, 
       
   484                                           RPointerArray<CPcsPoolElement>& searchSet, 
       
   485                                           const TDesC& searchQuery,
       
   486                                           TBool isSearchInGroup, 
       
   487                                           RArray<TInt>& aContactsInGroup)
       
   488     {
       
   489     __LATENCY_MARK ( _L("CPcsAlgorithm2Helper::FilterResultsL") );
       
   490     PRINT ( _L("Enter CPcsAlgorithm2Helper::FilterResultsL") );
       
   491 
       
   492     // Convert the search condition to numeric key string
       
   493     TBuf<KPsQueryMaxLen> tmpSearchQuery;
       
   494     keyMap->GetNumericKeyString(searchQuery, tmpSearchQuery);
       
   495     
       
   496     //Holds the first char of first name of a contact
       
   497     TBuf<10> firstChar;   
       
   498 
       
   499     PRINT2 ( _L("Numeric Key String for %S = %S"), &searchQuery, &tmpSearchQuery );
       
   500 
       
   501     // Parse thru each search set elements and filter the results
       
   502     for (int index = 0; index < searchSet.Count(); index++)
       
   503         {
       
   504         CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (searchSet[index]);
       
   505         CPsData* psData = poolElement->GetPsData();
       
   506         psData->ClearDataMatches();
       
   507         RPointerArray<TDesC> tempMatchSeq;
       
   508 
       
   509         // Search thru multiple words
       
   510         TBuf<KBufferMaxLen> token;
       
   511         TBuf<KBufferMaxLen> firstName;
       
   512         TBuf<KBufferMaxLen> lastName;
       
   513         lastName.Append(psData->Data(iAlgorithm->GetLastNameIndex())->Des());
       
   514         firstName.Append(psData->Data(iAlgorithm->GetFirstNameIndex())->Des());
       
   515 
       
   516         CFindUtilChineseECE* pFindUtilEce = iAlgorithm->FindUtilECE();
       
   517         TBool matched  = 0;
       
   518 
       
   519         // If has Chinese word and the first name doesn't start with Chinese character, then should add a space
       
   520         // before the first name, otherwise intitial letter searching will not function
       
   521         if( pFindUtilEce->IsChineseWord(lastName) || pFindUtilEce->IsChineseWord(firstName))
       
   522             {
       
   523             token.Append(lastName);
       
   524             if (firstName.Length())
       
   525                 {
       
   526                 firstChar.Zero();
       
   527                 firstChar.Append(firstName[0]);
       
   528                 if (!pFindUtilEce->IsChineseWord(firstChar) )
       
   529                     {
       
   530                     token.Append(KSpace);
       
   531                     }
       
   532                 token.Append(firstName);
       
   533                 }
       
   534 
       
   535             if (token.Length() != 0)
       
   536                 {
       
   537                 matched = iAlgorithm->FindUtil()->Interface()->
       
   538                     MatchRefineL(token, tmpSearchQuery, ECustomConverter, iAlgorithm);
       
   539 
       
   540                 if (matched)
       
   541                     {
       
   542                     psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
       
   543                     psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
       
   544                     }
       
   545                 }
       
   546             }
       
   547         else
       
   548             {
       
   549             // If contact name only has western word, then should send 
       
   550             // "first name","last name" and "last name + first name" to FindUtil to do the search
       
   551             const TInt lastnameLen = lastName.Length();
       
   552             const TInt firstnameLen = firstName.Length();
       
   553             if(lastnameLen)
       
   554                 {
       
   555                 matched = iAlgorithm->FindUtil()->Interface()->
       
   556                     MatchRefineL(lastName, tmpSearchQuery, ECustomConverter, iAlgorithm);
       
   557 
       
   558                 if (matched)
       
   559                     {
       
   560                     psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
       
   561                     }
       
   562                 }
       
   563 
       
   564             if(!matched && firstnameLen)
       
   565                 {
       
   566                 matched = iAlgorithm->FindUtil()->Interface()->
       
   567                     MatchRefineL(firstName, tmpSearchQuery, ECustomConverter, iAlgorithm);
       
   568 
       
   569                 if (matched)
       
   570                     {
       
   571                     psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
       
   572                     }
       
   573                 }
       
   574             
       
   575             token.Append(lastName);
       
   576             token.Append(firstName);
       
   577             if (!matched && lastnameLen && firstnameLen)
       
   578                 {
       
   579                 matched = iAlgorithm->FindUtil()->Interface()->
       
   580                     MatchRefineL(token, tmpSearchQuery, ECustomConverter, iAlgorithm);
       
   581 
       
   582                 if (matched)
       
   583                     {
       
   584                     psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
       
   585                     psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
       
   586                     }
       
   587                 }
       
   588             }
       
   589 
       
   590         if (matched)
       
   591             {
       
   592             // Extract matched character sequence, don't need to be accurate for Chinese variant
       
   593             const TInt len = 1;  
       
   594             HBufC* seq = HBufC::NewLC(len);
       
   595             *seq = token.Mid(0, len);
       
   596             seq->Des().UpperCase();
       
   597 
       
   598             TIdentityRelation<TDesC> rule(Compare1);
       
   599             if (tempMatchSeq.Find(seq, rule) == KErrNotFound)
       
   600                 {
       
   601                 tempMatchSeq.Append(seq);
       
   602                 CleanupStack::Pop();
       
   603                 }
       
   604             else
       
   605                 {
       
   606                 CleanupStack::PopAndDestroy();
       
   607                 }
       
   608                 
       
   609 
       
   610             // Add the result        
       
   611             if (isSearchInGroup)
       
   612                 {
       
   613                 if (aContactsInGroup.Find(psData->Id()) != KErrNotFound)
       
   614                     {
       
   615                     aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
       
   616                     }
       
   617                 }
       
   618             else
       
   619                 {
       
   620                 aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
       
   621                 }
       
   622             }
       
   623 
       
   624         // Cleanup the match sequence array as 
       
   625         // they are stored in pattern details structure
       
   626         tempMatchSeq.ResetAndDestroy();
       
   627         }
       
   628 
       
   629     PRINT ( _L("End CPcsAlgorithm2Helper::FilterResultsL") );
       
   630     __LATENCY_MARKEND ( _L("CPcsAlgorithm2Helper::FilterResultsL") );
       
   631     }
       
   632 
       
   633 // ----------------------------------------------------------------------------
       
   634 // CPcsAlgorithm2Helper::FilterResultsQwertyL
       
   635 // Subset search function 
       
   636 // ----------------------------------------------------------------------------
       
   637 void CPcsAlgorithm2Helper::FilterResultsQwertyL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper, 
       
   638                                                 RPointerArray<CPcsPoolElement>& searchSet, 
       
   639                                                 const TDesC& searchQuery,TBool isSearchInGroup, 
       
   640                                                 RArray<TInt>& aContactsInGroup)
       
   641     {
       
   642     PRINT ( _L("Enter CPcsAlgorithm2::FilterResultsQwertyL") );
       
   643 
       
   644     TBuf<50> tmpSearchQuery = searchQuery;
       
   645     tmpSearchQuery.LowerCase();
       
   646     
       
   647     //Holds the first char of first name of a contact
       
   648     TBuf<10> firstChar;
       
   649 
       
   650     // Parse thru each search set elements and filter the results    
       
   651     for (int index = 0; index < searchSet.Count(); index++)
       
   652         {
       
   653         CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (searchSet[index]);
       
   654         CPsData* psData = poolElement->GetPsData();
       
   655         psData->ClearDataMatches();
       
   656         RPointerArray<TDesC> tempMatchSeq;
       
   657 
       
   658         // Parse thru each data and filter the results
       
   659         TBuf<KBufferMaxLen> token;
       
   660         TBuf<KBufferMaxLen> firstName;
       
   661         TBuf<KBufferMaxLen> lastName;
       
   662         lastName.Append(psData->Data(iAlgorithm->GetLastNameIndex())->Des());
       
   663         firstName.Append(psData->Data(iAlgorithm->GetFirstNameIndex())->Des());
       
   664 
       
   665         CFindUtilChineseECE* pFindUtilEce = iAlgorithm->FindUtilECE();
       
   666         TBool matched  = 0;
       
   667 
       
   668         // If has Chinese word and the first name doesn't start with Chinese character, then should add a space
       
   669         // before the first name, otherwise intitial letter searching will not function
       
   670         if( pFindUtilEce->IsChineseWord(lastName) || pFindUtilEce->IsChineseWord(firstName))
       
   671             {
       
   672             token.Append(lastName);
       
   673             if (firstName.Length())
       
   674                 {
       
   675                 firstChar.Zero();
       
   676                 firstChar.Append(firstName[0]);
       
   677                 if (!pFindUtilEce->IsChineseWord(firstChar) )
       
   678                     {
       
   679                     token.Append(KSpace);
       
   680                     }
       
   681                 token.Append(firstName);
       
   682                 }
       
   683 
       
   684             if (token.Length() != 0)
       
   685                 {
       
   686                 matched = iAlgorithm->FindUtil()->Interface()->MatchRefineL(token, tmpSearchQuery);
       
   687 
       
   688                 if (matched)
       
   689                     {
       
   690                     psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
       
   691                     psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
       
   692                     }
       
   693                 }
       
   694             }
       
   695         else
       
   696             {
       
   697             // If contact name only has western word, then should send 
       
   698             // "first name","last name" and "last name + first name" to FindUtil to do the search
       
   699             const TInt lastnameLen = lastName.Length();
       
   700             const TInt firstnameLen = firstName.Length();
       
   701             if(lastnameLen)
       
   702                 {
       
   703                 matched = iAlgorithm->FindUtil()->Interface()->MatchRefineL(lastName, tmpSearchQuery);
       
   704 
       
   705                 if (matched)
       
   706                     {
       
   707                     psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
       
   708                     }
       
   709                 }
       
   710 
       
   711             if(!matched && firstnameLen)
       
   712                 {
       
   713                 matched = iAlgorithm->FindUtil()->Interface()->MatchRefineL(firstName, tmpSearchQuery);
       
   714 
       
   715                 if (matched)
       
   716                     {
       
   717                     psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
       
   718                     }
       
   719                 }
       
   720             
       
   721             token.Append(lastName);
       
   722             token.Append(firstName);
       
   723             if (!matched && lastnameLen && firstnameLen)
       
   724                 {
       
   725                 matched = iAlgorithm->FindUtil()->Interface()->MatchRefineL(token, tmpSearchQuery);
       
   726 
       
   727                 if (matched)
       
   728                     {
       
   729                     psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
       
   730                     psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
       
   731                     }
       
   732                 }
       
   733             }
       
   734         
       
   735         if (matched)
       
   736             {
       
   737             // Extract matched character sequence, don't need to be accurate for Chinese variant
       
   738             const TInt len = 1;
       
   739             HBufC* seq = HBufC::NewLC(len);
       
   740             *seq = token.Mid(0, len);
       
   741             seq->Des().UpperCase();
       
   742 
       
   743             TIdentityRelation<TDesC> rule(Compare1);
       
   744             if (tempMatchSeq.Find(seq, rule) == KErrNotFound)
       
   745                 {
       
   746                 tempMatchSeq.Append(seq);
       
   747                 CleanupStack::Pop();
       
   748                 }
       
   749             else
       
   750                 {
       
   751                 CleanupStack::PopAndDestroy();
       
   752                 }
       
   753             
       
   754             // Add the result
       
   755             if (isSearchInGroup)
       
   756                 {
       
   757                 if (aContactsInGroup.Find(psData->Id()) != KErrNotFound)
       
   758                     {
       
   759                     aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
       
   760                     }
       
   761                 }
       
   762             else
       
   763                 {
       
   764                 aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
       
   765                 }
       
   766             }
       
   767 
       
   768         // Cleanup the match sequence array as 
       
   769         // they are stored in pattern details structure
       
   770         tempMatchSeq.ResetAndDestroy();
       
   771         }
       
   772 
       
   773     PRINT ( _L("End CPcsAlgorithm2Helper::FilterResultsQwertyL") );
       
   774     }
       
   775 
       
   776 // ----------------------------------------------------------------------------
       
   777 // CPcsAlgorithm2Helper::FilterResultsMixedL
       
   778 // Subset search function
       
   779 // ----------------------------------------------------------------------------
       
   780 void CPcsAlgorithm2Helper::FilterResultsMixedL(CPcsAlgorithm2FilterHelper* aAlgorithmFilterHelper, 
       
   781                                                RPointerArray<CPcsPoolElement>& searchSet, 
       
   782                                                CPsQuery& searchQuery, TBool isSearchInGroup,
       
   783                                                RArray<TInt>& aContactsInGroup)
       
   784     {
       
   785     PRINT ( _L("Enter CPcsAlgorithm2::FilterResultsMixedL") );
       
   786 
       
   787     // Convert the search query to alpha numeric string
       
   788     TBuf<50> tmpSearchQuery;
       
   789     ExtractQueryL(searchQuery, tmpSearchQuery);
       
   790     tmpSearchQuery.LowerCase();
       
   791     TBuf<10> firstChar;
       
   792 
       
   793     // Parse thru each search set elements and filter the results    
       
   794     for (int index = 0; index < searchSet.Count(); index++)
       
   795         {
       
   796         CPcsPoolElement* poolElement = static_cast<CPcsPoolElement*> (searchSet[index]);
       
   797         CPsData* psData = poolElement->GetPsData();
       
   798         psData->ClearDataMatches();
       
   799         RPointerArray<TDesC> tempMatchSeq;
       
   800 
       
   801         // Parse thru each data and filter the results
       
   802         TBuf<255> token;
       
   803         TBuf<KBufferMaxLen> firstName;
       
   804         TBuf<KBufferMaxLen> lastName;
       
   805         lastName.Append(psData->Data(iAlgorithm->GetLastNameIndex())->Des());
       
   806         firstName.Append(psData->Data(iAlgorithm->GetFirstNameIndex())->Des());
       
   807 
       
   808         CFindUtilChineseECE* pFindUtilEce = iAlgorithm->FindUtilECE();
       
   809         TBool matched  = 0;
       
   810 
       
   811         // If has Chinese word and the first name doesn't start with Chinese character, then should add a space
       
   812         // before the first name, otherwise intitial letter searching will not function
       
   813         if( pFindUtilEce->IsChineseWord(lastName) || pFindUtilEce->IsChineseWord(firstName))
       
   814             {
       
   815             token.Append(lastName);
       
   816             if (firstName.Length())
       
   817                 {
       
   818                 firstChar.Zero();
       
   819                 firstChar.Append(firstName[0]);
       
   820                 if (!pFindUtilEce->IsChineseWord(firstChar) )
       
   821                     {
       
   822                     token.Append(KSpace);
       
   823                     }
       
   824                 token.Append(firstName);
       
   825                 }
       
   826 
       
   827             if (token.Length() != 0)
       
   828                 {
       
   829                 matched = pFindUtilEce->MatchRefineL(token, searchQuery);
       
   830 
       
   831                 if (matched)
       
   832                     {
       
   833                     psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
       
   834                     psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
       
   835                     }
       
   836                 }
       
   837             }
       
   838         else
       
   839             {
       
   840             // If contact name only has western word, then should send 
       
   841             // "first name","last name" and "last name + first name" to FindUtil to do the search
       
   842             const TInt lastnameLen = lastName.Length();
       
   843             const TInt firstnameLen = firstName.Length();
       
   844             if(lastnameLen)
       
   845                 {
       
   846                 matched = pFindUtilEce->MatchRefineL(lastName, searchQuery);
       
   847 
       
   848                 if (matched)
       
   849                     {
       
   850                     psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
       
   851                     }
       
   852                 }
       
   853 
       
   854             if(!matched && firstnameLen)
       
   855                 {
       
   856                 matched = pFindUtilEce->MatchRefineL(firstName, searchQuery);
       
   857 
       
   858                 if (matched)
       
   859                     {
       
   860                     psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
       
   861                     }
       
   862                 }
       
   863             
       
   864             token.Append(lastName);
       
   865             token.Append(firstName);
       
   866             if (!matched && lastnameLen && firstnameLen)
       
   867                 {
       
   868                 matched = pFindUtilEce->MatchRefineL(token, searchQuery);
       
   869 
       
   870                 if (matched)
       
   871                     {
       
   872                     psData->SetDataMatch(iAlgorithm->GetLastNameIndex());
       
   873                     psData->SetDataMatch(iAlgorithm->GetFirstNameIndex());
       
   874                     }
       
   875                 }
       
   876             }
       
   877 
       
   878         if (matched)
       
   879             {
       
   880             // Extract matched character sequence, don't need to be accurate for Chinese variant
       
   881             const TInt len = 1;       
       
   882         
       
   883             HBufC* seq = HBufC::NewLC(len);
       
   884             *seq = token.Mid(0, len);
       
   885             seq->Des().UpperCase();
       
   886 
       
   887             TIdentityRelation<TDesC> rule(Compare1);
       
   888             if (tempMatchSeq.Find(seq, rule) == KErrNotFound)
       
   889                 {
       
   890                 tempMatchSeq.Append(seq);
       
   891                 CleanupStack::Pop();
       
   892                 }
       
   893             else
       
   894                 {
       
   895                 CleanupStack::PopAndDestroy();
       
   896                 }
       
   897             
       
   898             // Add the result
       
   899             if (isSearchInGroup)
       
   900                 {
       
   901                 if (aContactsInGroup.Find(psData->Id()) != KErrNotFound)
       
   902                     {
       
   903                     aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
       
   904                     }
       
   905                 }
       
   906             else
       
   907                 {
       
   908                 aAlgorithmFilterHelper->AddL(psData, tempMatchSeq);
       
   909                 }
       
   910             }
       
   911 
       
   912         // Cleanup the match sequence array as 
       
   913         // they are stored in pattern details structure
       
   914         tempMatchSeq.ResetAndDestroy();
       
   915         }
       
   916 
       
   917     PRINT ( _L("End CPcsAlgorithm2Helper::FilterResultsMixedL") );
       
   918     }
       
   919 
       
   920 // ----------------------------------------------------------------------------
       
   921 // CPcsAlgorithm2Helper::SortSearchSeqsL()
       
   922 // 
       
   923 // ----------------------------------------------------------------------------
       
   924 void CPcsAlgorithm2Helper::SortSearchSeqsL(RPointerArray<TDesC>& aSearchSeqs)
       
   925     {
       
   926     // Sort the search seqs
       
   927     TLinearOrder<TDesC> rule(Compare2);
       
   928     aSearchSeqs.Sort(rule);
       
   929     }
       
   930 
       
   931 // ----------------------------------------------------------------------------
       
   932 // CPcsAlgorithm2Helper::ExtractQueryL()
       
   933 // Required for mixed mode search.
       
   934 // ----------------------------------------------------------------------------
       
   935 void CPcsAlgorithm2Helper::ExtractQueryL(CPsQuery& aQuery, TDes& aOutput)
       
   936     {
       
   937     for (int i = 0; i < aQuery.Count(); i++)
       
   938         {
       
   939         if (aQuery.GetItemAtL(i).Mode() == EItut)
       
   940             {
       
   941             TBuf<KPsQueryMaxLen> outBuf;
       
   942             keyMap->GetNumericKeyString(aQuery.QueryAsStringLC(), outBuf);
       
   943             aOutput.Append(outBuf[i]);
       
   944             CleanupStack::PopAndDestroy();
       
   945             }
       
   946         else
       
   947             {
       
   948             aOutput.Append(aQuery.GetItemAtL(i).Character());
       
   949             }
       
   950         }
       
   951     }
       
   952 
       
   953 // ----------------------------------------------------------------------------
       
   954 // CPcsAlgorithm2Helper::ExtractQueryL()
       
   955 // Required for mixed mode search.
       
   956 // ----------------------------------------------------------------------------
       
   957 void CPcsAlgorithm2Helper::ExtractQueryL(TDesC& aInput, CPsQuery& aQuery, TDes& aOutput)
       
   958     {
       
   959     TInt len = -1;
       
   960 
       
   961     if (aInput.Length() > aQuery.Count())
       
   962         {
       
   963         len = aQuery.Count();
       
   964         }
       
   965     else
       
   966         {
       
   967         len = aInput.Length();
       
   968         }
       
   969 
       
   970     for (int i = 0; i < len; i++)
       
   971         {
       
   972         if (aQuery.GetItemAtL(i).Mode() == EItut)
       
   973             {
       
   974             TBuf<KPsQueryMaxLen> outBuf;
       
   975             keyMap->GetNumericKeyString(aInput, outBuf);
       
   976             aOutput.Append(outBuf[i]);
       
   977             }
       
   978         else
       
   979             {
       
   980             aOutput.Append(aInput[i]);
       
   981             }
       
   982         }
       
   983     }
       
   984 
       
   985 // ----------------------------------------------------------------------------
       
   986 // CPcsAlgorithm2Helper::FilterDataFieldsL()
       
   987 // Constructs a bit pattern using the required/supported data fields
       
   988 // For example, 6, 4 and 27 are supported fields <-- 00000111
       
   989 //              6 and 4 are required fields      <-- 00000011
       
   990 // Bit pattern returned is 00000011.
       
   991 // ----------------------------------------------------------------------------
       
   992 TUint8 CPcsAlgorithm2Helper::FilterDataFieldsL(RArray<TInt>& aRequiredDataFields, 
       
   993                                                RArray<TInt>& aSupportedDataFields)
       
   994     {
       
   995     TUint8 filteredMatch = 0x0;
       
   996 
       
   997     for (int i = 0; i < aSupportedDataFields.Count(); i++)
       
   998         {
       
   999         for (int j = 0; j < aRequiredDataFields.Count(); j++)
       
  1000             {
       
  1001             if (aSupportedDataFields[i] == aRequiredDataFields[j])
       
  1002                 {
       
  1003                 TReal val;
       
  1004                 Math::Pow(val, 2, i);
       
  1005 
       
  1006                 filteredMatch |= (TUint8) val;
       
  1007                 }
       
  1008             }
       
  1009         }
       
  1010 
       
  1011     return filteredMatch;
       
  1012     }
       
  1013 
       
  1014 // End of file
       
  1015 
       
  1016