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