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 |