163 User::LeaveIfError(err); |
162 User::LeaveIfError(err); |
164 } |
163 } |
165 } |
164 } |
166 |
165 |
167 // ---------------------------------------------------------------------------- |
166 // ---------------------------------------------------------------------------- |
|
167 // CPcsAlgorithm2::RemoveSpacesL |
|
168 // Remove leading and trailing spaces of search query |
|
169 // ---------------------------------------------------------------------------- |
|
170 void CPcsAlgorithm2::RemoveSpacesL(CPsQuery& aQuery) |
|
171 { |
|
172 PRINT ( _L("Enter CPcsAlgorithm2::RemoveSpacesL") ); |
|
173 |
|
174 // Remove all leading " " |
|
175 while ( aQuery.Count() > 0 ) |
|
176 { |
|
177 CPsQueryItem& item = aQuery.GetItemAtL(0); // First |
|
178 if ( !item.Character().IsSpace() ) |
|
179 { |
|
180 break; |
|
181 } |
|
182 aQuery.Remove(0); |
|
183 } |
|
184 |
|
185 // Remove all trailing " " |
|
186 while ( aQuery.Count() > 0 ) |
|
187 { |
|
188 CPsQueryItem& item = aQuery.GetItemAtL(aQuery.Count()-1); // Last |
|
189 if ( !item.Character().IsSpace() ) |
|
190 { |
|
191 break; |
|
192 } |
|
193 aQuery.Remove(aQuery.Count()-1); |
|
194 } |
|
195 |
|
196 PRINT ( _L("End CPcsAlgorithm2::RemoveSpacesL") ); |
|
197 } |
|
198 |
|
199 // ---------------------------------------------------------------------------- |
168 // CPcsAlgorithm2::ReplaceZeroWithSpaceL |
200 // CPcsAlgorithm2::ReplaceZeroWithSpaceL |
169 // Replace first occurance of '0' in a sequence of '0's in ITU-T with space |
201 // Replace first occurance of '0' in a sequence of '0's in ITU-T with space |
170 // ---------------------------------------------------------------------------- |
202 // ---------------------------------------------------------------------------- |
171 TBool CPcsAlgorithm2::ReplaceZeroWithSpaceL(CPsQuery& aQuery) |
203 TBool CPcsAlgorithm2::ReplaceZeroWithSpaceL(CPsQuery& aQuery) |
172 { |
204 { |
173 TChar space(KSpace); // ascii value for space |
205 PRINT ( _L("Enter CPcsAlgorithm1::ReplaceZeroWithSpaceL") ); |
174 |
206 |
175 TBool queryModified = EFalse; |
207 //PRINTQUERY ( _L("CPcsAlgorithm1::ReplaceZeroWithSpaceL (BEFORE): "), aQuery ); |
176 |
208 |
177 // Skip initial zeros in query |
209 TBool queryModified = EFalse; |
178 TInt index = 0; |
210 |
179 for (index = 0; index < aQuery.Count() |
211 /* In phones like E52 and E55, where the "0" and the " " characters are on |
180 && aQuery.GetItemAtL(index).Character().GetNumericValue() == 0; ++index) |
212 * the same key, the "0"s have to be considered as possible separators. |
181 { |
213 * |
182 } |
214 * In phones like N97 and E72, where the "0" and the " " characters are on |
183 |
215 * different keys, the "0"s must not be considered as possible separators. |
184 if (aQuery.KeyboardModeL() != EQwerty) |
216 */ |
185 { |
217 |
186 for (TInt beg = index; beg < aQuery.Count(); ++beg) |
218 // Skip initial "0"s, they are not replaced into spaces |
187 { |
219 TInt skipIndex = 0; |
188 CPsQueryItem& item = aQuery.GetItemAtL(beg); |
220 while ( (skipIndex < aQuery.Count()) && |
189 |
221 (aQuery.GetItemAtL(skipIndex).Character().GetNumericValue() == 0) ) |
190 if (item.Character().GetNumericValue() == 0 && item.Mode()== EItut) |
222 { |
191 { |
223 skipIndex++; |
192 if (beg != 0) |
224 } |
193 { |
225 |
194 CPsQueryItem& item1 = aQuery.GetItemAtL(beg - 1); |
226 // Replace remaining "0"s into spaces in case they are entered with a keyboard |
195 if (item1.Character().GetNumericValue() != 0 |
227 // that has "0" and " " on the same key. |
196 && !item1.Character().IsSpace()) |
228 const TInt queryCount = aQuery.Count(); |
197 { |
229 for ( TInt index = skipIndex; index < queryCount; index++ ) |
198 item.SetCharacter(space); |
230 { |
199 queryModified = ETrue; |
231 CPsQueryItem& item = aQuery.GetItemAtL(index); |
200 } |
232 |
201 } |
233 if ( iKeyMap->GetSpaceAndZeroOnSameKey( item.Mode() ) && |
202 else |
234 item.Character().GetNumericValue() == 0 ) |
203 { |
235 { |
204 item.SetCharacter(space); |
236 item.SetCharacter(KSpace); |
205 queryModified = ETrue; |
237 queryModified = ETrue; |
206 } |
238 } |
207 } |
239 } |
208 } |
240 |
209 } |
241 //PRINTQUERY ( _L("CPcsAlgorithm1::ReplaceZeroWithSpaceL (AFTER): "), aQuery ); |
210 |
242 |
211 return queryModified; |
243 PRINT1 ( _L("CPcsAlgorithm1::ReplaceZeroWithSpaceL: Query modified (0=not, 1=yes): %d"), queryModified ); |
|
244 |
|
245 PRINT ( _L("End CPcsAlgorithm1::ReplaceZeroWithSpaceL") ); |
|
246 |
|
247 return queryModified; |
212 } |
248 } |
213 |
249 |
214 // ---------------------------------------------------------------------------- |
250 // ---------------------------------------------------------------------------- |
215 // CPcsAlgorithm2::PerformSearchL |
251 // CPcsAlgorithm2::PerformSearchL |
216 // Search function for cache |
252 // Search function for cache |
217 // ---------------------------------------------------------------------------- |
253 // ---------------------------------------------------------------------------- |
218 void CPcsAlgorithm2::PerformSearchL(const CPsSettings& aSettings, CPsQuery& aQuery, |
254 void CPcsAlgorithm2::PerformSearchL(const CPsSettings& aSettings, |
|
255 CPsQuery& aQuery, |
219 RPointerArray<CPsClientData>& aSearchResults, |
256 RPointerArray<CPsClientData>& aSearchResults, |
220 RPointerArray<CPsPattern>& aSearchSeqs) |
257 RPointerArray<CPsPattern>& aSearchSeqs) |
221 { |
258 { |
222 PRINT ( _L("Enter CPcsAlgorithm2::PerformSearchL") ); |
259 PRINT ( _L("Enter CPcsAlgorithm2::PerformSearchL") ); |
223 |
260 |
224 __LATENCY_MARK ( _L("CPcsAlgorithm2::PerformSearchL") ); |
261 //__LATENCY_MARK ( _L("CPcsAlgorithm2::PerformSearchL") ); |
225 |
262 |
226 // Get the current language |
263 // Check aSettings |
227 TLanguage lang = User::Language(); |
264 RPointerArray<TDesC> searchUris; |
228 |
265 CleanupResetAndDestroyPushL( searchUris ); |
229 // Check if the language is supported and the keyboard mode is not qwerty. |
266 aSettings.SearchUrisL(searchUris); |
|
267 |
|
268 if ( searchUris.Count() <= 0) |
|
269 { |
|
270 PRINT ( _L("searchUris.Count() <= 0, Leave from CPcsAlgorithm1::PerformSearchL") ); |
|
271 User::Leave(KErrArgument); |
|
272 } |
|
273 CleanupStack::PopAndDestroy( &searchUris ); // ResetAndDestroy |
230 |
274 |
231 // Local arrays to hold the search results |
275 // Local arrays to hold the search results |
232 RPointerArray<CPsData> tempSearchResults; |
276 RPointerArray<CPsData> tempSearchResults; |
|
277 CleanupClosePushL( tempSearchResults ); |
233 RPointerArray<CPsData> tempSearchResults1; |
278 RPointerArray<CPsData> tempSearchResults1; |
|
279 CleanupClosePushL( tempSearchResults1 ); |
234 |
280 |
235 // -------------------- Perform the basic search -------------------------- |
281 // -------------------- Perform the basic search -------------------------- |
236 |
282 |
|
283 RemoveSpacesL(aQuery); |
|
284 PRINTQUERY ( _L("CPcsAlgorithm2::PerformSearchL: 1st search query: "), aQuery ); |
237 DoSearchL(aSettings, aQuery, tempSearchResults, aSearchSeqs); |
285 DoSearchL(aSettings, aQuery, tempSearchResults, aSearchSeqs); |
238 |
286 |
239 // ------------------------------------------------------------------------ |
287 // ------------------------------------------------------------------------ |
240 |
288 |
241 // ------------------- Perform advanced search if needed ------------------ |
289 // ---- Perform new search after "0" replacement if query is not empty ---- |
242 // Substitute "0" with space |
290 /* Examples: |
|
291 * - If the original search string is "Abc0" then we will search again with "Abc". |
|
292 * - If the original search string is "00" then we will not search again. |
|
293 */ |
243 TBool queryModified = ReplaceZeroWithSpaceL(aQuery); |
294 TBool queryModified = ReplaceZeroWithSpaceL(aQuery); |
244 |
295 RemoveSpacesL(aQuery); |
245 // If query got modified and the search query translated to more than 1 query |
296 // Perform query again if query got modified. |
246 // perform a multi search again |
|
247 if (queryModified) |
297 if (queryModified) |
248 { |
298 { |
249 // Split query |
299 PRINTQUERY ( _L("CPcsAlgorithm2::PerformSearchL: 2nd search query: "), aQuery ); |
250 RPointerArray<CPsQuery> queryList = iMultiSearchHelper->MultiQueryL(aQuery); |
300 DoSearchL(aSettings, aQuery, tempSearchResults1, aSearchSeqs); |
251 |
301 |
252 // Perform seach again |
|
253 if (queryList.Count() > 1) |
|
254 { |
|
255 DoSearchL(aSettings, aQuery, tempSearchResults1, aSearchSeqs); |
|
256 } |
|
257 |
302 |
258 // Sort rule |
303 // Sort rule |
259 TLinearOrder<CPsData> rule(CPcsAlgorithm2Utils::CompareDataBySortOrder); |
304 TLinearOrder<CPsData> rule(CPcsAlgorithm2Utils::CompareDataBySortOrder); |
260 |
305 |
261 // Avoid duplicates and add new results |
306 // Avoid duplicates and add new results |
262 TIdentityRelation<CPsData> identityRule(CPsData::CompareById); |
307 TIdentityRelation<CPsData> identityRule(CPsData::CompareById); |
|
308 const TInt tempSearchResults1Count = tempSearchResults1.Count(); |
263 if (aSettings.GetSortType() != EAlphabetical) |
309 if (aSettings.GetSortType() != EAlphabetical) |
264 { |
310 { |
265 TInt insertPos = 0; |
311 TInt insertPos = 0; |
266 for (int i = 0; i < tempSearchResults1.Count(); i++) |
312 for (TInt i = 0; i < tempSearchResults1Count; i++) |
267 { |
313 { |
268 if (tempSearchResults.Find(tempSearchResults1[i], |
314 if (tempSearchResults.Find(tempSearchResults1[i], |
269 identityRule) == KErrNotFound) |
315 identityRule) == KErrNotFound) |
270 { |
316 { |
271 tempSearchResults.Insert(tempSearchResults1[i], insertPos); |
317 tempSearchResults.Insert(tempSearchResults1[i], insertPos); |
272 insertPos++; |
318 insertPos++; |
273 } |
319 } |
274 |
|
275 } |
320 } |
276 |
|
277 } |
321 } |
278 else |
322 else |
279 { |
323 { |
280 |
324 for (TInt i = 0; i < tempSearchResults1Count; i++) |
281 for (int i = 0; i < tempSearchResults1.Count(); i++) |
|
282 { |
325 { |
283 if (tempSearchResults.Find(tempSearchResults1[i], |
326 if (tempSearchResults.Find(tempSearchResults1[i], |
284 identityRule) == KErrNotFound) |
327 identityRule) == KErrNotFound) |
285 { |
328 { |
286 tempSearchResults.InsertInOrderAllowRepeats(tempSearchResults1[i], |
329 tempSearchResults.InsertInOrderAllowRepeats(tempSearchResults1[i], |
287 rule); |
330 rule); |
288 } |
331 } |
289 } |
332 } |
290 } |
333 } |
291 |
|
292 queryList.ResetAndDestroy(); |
|
293 } |
334 } |
294 // ------------------------------------------------------------------------ |
335 // ------------------------------------------------------------------------ |
295 |
336 |
296 // ---------------------- Write result objects to the stream -------------- |
337 // ---------------------- Write result objects to the stream -------------- |
297 // Truncate the result set if required |
338 // Truncate the result set if required |
298 TInt numToDisplay = aSettings.MaxResults(); |
339 TInt maxNumToDisplay = aSettings.MaxResults(); |
299 TInt resultSet = tempSearchResults.Count(); |
340 TInt resultSetCount = tempSearchResults.Count(); |
300 |
341 TInt numToDisplay = 0; |
301 if (resultSet > numToDisplay && numToDisplay != -1) |
342 if ( maxNumToDisplay == -1 ) |
302 { |
343 { |
303 // Copy the top N contents from tempSearchResults to the results stream |
344 numToDisplay = resultSetCount; |
304 for (int i = 0; i < numToDisplay; i++) |
|
305 { |
|
306 aSearchResults.Append(WriteClientDataL(*(tempSearchResults[i]))); |
|
307 } |
|
308 |
|
309 } |
345 } |
310 else |
346 else |
311 { |
347 { |
312 // Copy all the contents from tempSearchResults to the results stream |
348 numToDisplay = Min( maxNumToDisplay, resultSetCount ); |
313 for (int i = 0; i < resultSet; i++) |
349 } |
314 { |
350 |
315 aSearchResults.Append(WriteClientDataL(*(tempSearchResults[i]))); |
351 // Copy desired number of results from tempSearchResults to the results stream |
316 } |
352 for (TInt i = 0; i < numToDisplay; i++) |
|
353 { |
|
354 aSearchResults.Append(WriteClientDataL(*(tempSearchResults[i]))); |
317 } |
355 } |
318 // ------------------------------------------------------------------------ |
356 // ------------------------------------------------------------------------ |
319 |
357 |
320 // Cleanup local results array |
358 // Cleanup local results array |
321 tempSearchResults.Reset(); // Don't destroy |
359 CleanupStack::PopAndDestroy( &tempSearchResults1 ); // Close, don't destroy |
322 tempSearchResults1.Reset(); // Don't destroy |
360 CleanupStack::PopAndDestroy( &tempSearchResults ); // Close, don't destroy |
323 |
361 |
324 __LATENCY_MARKEND ( _L("CPcsAlgorithm2::PerformSearchL") ); |
362 // __LATENCY_MARKEND ( _L("CPcsAlgorithm2::PerformSearchL") ); |
325 |
363 |
326 PRINT ( _L("End CPcsAlgorithm2::PerformSearchL") ); |
364 PRINT ( _L("End CPcsAlgorithm2::PerformSearchL") ); |
327 } |
365 } |
328 |
366 |
329 // ---------------------------------------------------------------------------- |
367 // ---------------------------------------------------------------------------- |
330 // CPcsAlgorithm2::SearchInputL |
368 // CPcsAlgorithm2::SearchInputL |
331 // Search function for input string |
369 // Search function for input string |
332 // ---------------------------------------------------------------------------- |
370 // ---------------------------------------------------------------------------- |
333 void CPcsAlgorithm2::SearchInputL(CPsQuery& aQuery, TDesC& aData, |
371 void CPcsAlgorithm2::SearchInputL(CPsQuery& aQuery, |
|
372 TDesC& aData, |
334 RPointerArray<TDesC>& aMatchSet, |
373 RPointerArray<TDesC>& aMatchSet, |
335 RArray<TPsMatchLocation>& aMatchLocation) |
374 RArray<TPsMatchLocation>& aMatchLocation) |
336 { |
375 { |
|
376 // __LATENCY_MARK ( _L("CPcsAlgorithm2::SearchInputL: ") ); |
337 PRINT ( _L("Enter CPcsAlgorithm2::SearchInputL") ); |
377 PRINT ( _L("Enter CPcsAlgorithm2::SearchInputL") ); |
338 |
378 |
339 // Get the current language |
|
340 TLanguage lang = User::Language(); |
|
341 |
|
342 // Check if the language is supported and the keyboard mode is not qwerty. |
|
343 |
|
344 // Print input query for debug |
379 // Print input query for debug |
345 aQuery.PrintQuery(); |
380 PRINTQUERY ( _L("CPcsAlgorithm2::SearchInputL: Search query: "), aQuery ); |
346 |
381 |
347 // Print received search data |
382 // Print received search data |
348 PRINT1 ( _L("Search data received = %S"), &aData); |
383 PRINT1 ( _L("Search data received = %S"), &aData); |
349 |
384 |
|
385 |
350 // -------------------- Perform the basic search -------------------------- |
386 // -------------------- Perform the basic search -------------------------- |
351 |
387 |
|
388 RemoveSpacesL(aQuery); |
352 DoSearchInputL(aQuery, aData, aMatchSet, aMatchLocation); |
389 DoSearchInputL(aQuery, aData, aMatchSet, aMatchLocation); |
353 |
390 |
354 // ------------------------------------------------------------------------ |
391 // ------------------------------------------------------------------------ |
355 |
392 |
356 // ------------------- Perform advanced search if needed ------------------ |
393 // ---- Perform new search after "0" replacement if query is not empty ---- |
357 // Substitute "0" with space |
394 /* Examples: |
|
395 * - If the original search string is "Abc0" then we will search again with "Abc". |
|
396 * - If the original search string is "00" then we will not search again. |
|
397 */ |
358 TBool queryModified = ReplaceZeroWithSpaceL(aQuery); |
398 TBool queryModified = ReplaceZeroWithSpaceL(aQuery); |
359 |
399 RemoveSpacesL(aQuery); |
360 // If query got modified and the search query translated to more than 1 query |
400 // If query got modified and the search query still contains something |
361 // perform a multi search again |
401 // perform a multi search again |
362 if (queryModified) |
402 if (queryModified && aQuery.Count() > 0 && aMatchSet.Count() == 0 && aMatchLocation.Count() == 0 ) |
363 { |
403 { |
364 RPointerArray<CPsQuery> queryList = iMultiSearchHelper->MultiQueryL(aQuery); |
404 DoSearchInputL(aQuery, aData, aMatchSet, aMatchLocation); |
365 |
|
366 if (queryList.Count() > 1) |
|
367 { |
|
368 DoSearchInputL(aQuery, aData, aMatchSet, aMatchLocation); |
|
369 } |
|
370 |
|
371 queryList.ResetAndDestroy(); |
|
372 } |
405 } |
373 // ------------------------------------------------------------------------ |
406 // ------------------------------------------------------------------------ |
|
407 |
|
408 // --- Remove overlapping items from aMatchLocation --- |
|
409 TInt i = 0; |
|
410 TBool incrementFirstCursor; |
|
411 while ( i < aMatchLocation.Count() ) |
|
412 { |
|
413 incrementFirstCursor = ETrue; |
|
414 TInt j = i+1; |
|
415 while ( j < aMatchLocation.Count() ) |
|
416 { |
|
417 if ( CPcsAlgorithm2Utils::MatchesOverlap( aMatchLocation[j], aMatchLocation[i] ) ) |
|
418 { |
|
419 // Remove match location item with smallest length if 2 items have same index |
|
420 if ( aMatchLocation[j].length <= aMatchLocation[i].length ) |
|
421 { |
|
422 aMatchLocation.Remove(j); |
|
423 continue; // Do not increment j |
|
424 } |
|
425 else |
|
426 { |
|
427 aMatchLocation.Remove(i); |
|
428 incrementFirstCursor = EFalse; // Do not increment i |
|
429 break; |
|
430 } |
|
431 } |
|
432 j++; |
|
433 } |
|
434 if ( incrementFirstCursor ) |
|
435 { |
|
436 i++; |
|
437 } |
|
438 } |
|
439 |
|
440 // --- Remove from aMatchSet items which no longer have corresponding item in aMatchLocation --- |
|
441 HBufC* dataUpper = HBufC::NewLC(aData.Length()); |
|
442 dataUpper->Des().Copy(aData); |
|
443 dataUpper->Des().UpperCase(); // Get uppercase, as aMatchSet is in upper case |
|
444 |
|
445 TInt k = 0; |
|
446 while ( k < aMatchSet.Count() ) |
|
447 { |
|
448 TBool keepMatch = EFalse; |
|
449 TInt startCursor = -1; |
|
450 |
|
451 TInt offsetCursor; |
|
452 while ( KErrNotFound != (offsetCursor = dataUpper->Mid(startCursor + 1).Find(*aMatchSet[k])) ) |
|
453 { |
|
454 // startCursor = index of match item *aMatchSet[k] into search string aData |
|
455 startCursor = offsetCursor + startCursor + 1; |
|
456 const TInt matchLocationCount = aMatchLocation.Count(); |
|
457 for ( TInt i = 0; i < matchLocationCount; i++ ) |
|
458 { |
|
459 // If match item was found in the location list, then keep it |
|
460 if ( (aMatchLocation[i].index == startCursor) && |
|
461 (aMatchLocation[i].length == aMatchSet[k]->Length()) ) |
|
462 { |
|
463 keepMatch = ETrue; |
|
464 break; |
|
465 } |
|
466 } |
|
467 } |
|
468 |
|
469 if ( keepMatch ) |
|
470 { |
|
471 k++; |
|
472 } |
|
473 else |
|
474 { |
|
475 aMatchSet.Remove(k); // Do not increment k |
|
476 } |
|
477 } |
|
478 CleanupStack::PopAndDestroy( dataUpper ); |
|
479 // --- Remove items End --- |
374 |
480 |
375 // Sort match set |
481 // Sort match set |
376 iHelper->SortSearchSeqsL(aMatchSet); |
482 iHelper->SortSearchSeqsL(aMatchSet); |
377 |
483 |
378 PRINT ( _L("End CPcsAlgorithm2::SearchInputL") ); |
484 PRINT ( _L("End CPcsAlgorithm2::SearchInputL") ); |
|
485 //__LATENCY_MARKEND ( _L("CPcsAlgorithm2::SearchInputL") ); |
379 } |
486 } |
380 |
487 |
381 // ---------------------------------------------------------------------------- |
488 // ---------------------------------------------------------------------------- |
382 // CPcsAlgorithm2::SearchMatchStringL |
489 // CPcsAlgorithm2::SearchMatchStringL |
383 // Search function for input string, result also as string |
490 // Search function for input string, result also as string |
384 // ---------------------------------------------------------------------------- |
491 // ---------------------------------------------------------------------------- |
385 void CPcsAlgorithm2::SearchMatchStringL( CPsQuery& /*aSearchQuery*/, |
492 void CPcsAlgorithm2::SearchMatchStringL( CPsQuery& /*aSearchQuery*/, |
386 TDesC& /*aSearchData*/, |
493 TDesC& /*aSearchData*/, |
387 TDes& /*aMatch*/ ) |
494 TDes& /*aMatch*/ ) |
388 { |
495 { |
389 //NOT IMPLEMENTED YET |
496 PRINT ( _L("Enter CPcsAlgorithm2::SearchMatchStringL") ); |
|
497 |
|
498 //__LATENCY_MARK ( _L("CPcsAlgorithm2::SearchMatchStringL") ); |
|
499 |
|
500 // TODO: Implementation missing |
|
501 |
|
502 //__LATENCY_MARKEND ( _L("CPcsAlgorithm2::SearchMatchStringL") ); |
|
503 |
|
504 PRINT ( _L("End CPcsAlgorithm2::SearchMatchStringL") ); |
390 } |
505 } |
391 |
506 |
392 // ---------------------------------------------------------------------------- |
507 // ---------------------------------------------------------------------------- |
393 // CPcsAlgorithm2::DoSearchL |
508 // CPcsAlgorithm2::DoSearchL |
394 // Search function helper |
509 // Search function helper |
395 // ---------------------------------------------------------------------------- |
510 // ---------------------------------------------------------------------------- |
396 void CPcsAlgorithm2::DoSearchL(const CPsSettings& aSettings, CPsQuery& aQuery, |
511 void CPcsAlgorithm2::DoSearchL( const CPsSettings& aSettings, |
397 RPointerArray<CPsData>& searchResults, |
512 CPsQuery& aQuery, |
398 RPointerArray<CPsPattern>& searchSeqs) |
513 RPointerArray<CPsData>& aSearchResults, |
|
514 RPointerArray<CPsPattern>& aSearchSeqs ) |
399 { |
515 { |
400 PRINT ( _L("Enter CPcsAlgorithm2::DoSearchL") ); |
516 PRINT ( _L("Enter CPcsAlgorithm2::DoSearchL") ); |
401 |
517 |
402 // Print query for debug |
518 //__LATENCY_MARK ( _L("CPcsAlgorithm2::DoSearchL") ); |
403 aQuery.PrintQuery(); |
519 |
404 |
|
405 // -(0)----------------- Check if group search is required --------------- |
520 // -(0)----------------- Check if group search is required --------------- |
406 RArray<TInt> contactsInGroup; |
521 RArray<TInt> contactsInGroup; |
|
522 CleanupClosePushL( contactsInGroup ); |
407 RArray<TInt> groupIdArray; |
523 RArray<TInt> groupIdArray; |
|
524 CleanupClosePushL( groupIdArray ); |
408 |
525 |
409 // Create a new settings instance |
526 // Create a new settings instance |
410 CPsSettings *tempSettings = aSettings.CloneL(); |
527 CPsSettings* tempSettings = aSettings.CloneL(); |
|
528 CleanupStack::PushL( tempSettings ); |
411 |
529 |
412 TBool isGroupSearch = IsGroupSearchL(*tempSettings, groupIdArray); |
530 TBool isGroupSearch = IsGroupSearchL(*tempSettings, groupIdArray); |
413 |
531 |
414 if (isGroupSearch) |
532 if (isGroupSearch) |
415 { |
533 { |
418 |
536 |
419 // List of contacts in this group |
537 // List of contacts in this group |
420 GetContactsInGroupL(groupIdArray[0], contactsInGroup); |
538 GetContactsInGroupL(groupIdArray[0], contactsInGroup); |
421 } |
539 } |
422 |
540 |
423 groupIdArray.Close(); |
|
424 |
|
425 // ----------------------------------------------------------------------- |
541 // ----------------------------------------------------------------------- |
426 |
542 |
427 |
543 |
428 // Extract query list. |
544 // Extract query list. |
429 RPointerArray<CPsQuery> queryList = iMultiSearchHelper->MultiQueryL(aQuery); |
545 RPointerArray<CPsQuery> queryList = iMultiSearchHelper->MultiQueryL(aQuery); |
430 |
546 CleanupResetAndDestroyPushL( queryList ); |
431 // -(1)--------------------- No query return all contacts ---------------- |
547 |
|
548 // (1)-------------------- No query return all contacts ------------------- |
432 if (queryList.Count() == 0) |
549 if (queryList.Count() == 0) |
433 { |
550 { |
434 GetAllContentsL(*tempSettings, searchResults); |
551 GetAllContentsL(*tempSettings, aSearchResults); |
435 |
552 |
436 if (isGroupSearch) |
553 if (isGroupSearch) |
437 { |
554 { |
438 FilterSearchResultsForGroupsL(contactsInGroup, searchResults); |
555 FilterSearchResultsForGroupsL(contactsInGroup, aSearchResults); |
439 } |
556 } |
440 } |
557 } |
441 // ------------------------------------------------------------------------ |
558 // ------------------------------------------------------------------------ |
442 |
559 |
443 |
560 // (2)-------------------- Perform a single query search ------------------ |
444 // -(2)------------------------ Perform a single query search ------------- |
561 else if (queryList.Count() == 1) |
445 if (queryList.Count() == 1) |
562 { |
446 { |
|
447 TInt mode = aQuery.KeyboardModeL(); |
|
448 |
|
449 CPsQuery* query = queryList[0]; |
563 CPsQuery* query = queryList[0]; |
450 |
564 |
451 iFindUtilECE->SetKeyboardMode(mode); |
565 // Search results |
452 |
566 iHelper->SearchSingleL(*tempSettings, *query, isGroupSearch, |
453 switch (mode) |
567 contactsInGroup, aSearchResults, aSearchSeqs); |
454 { |
|
455 case EItut: |
|
456 |
|
457 PRINT ( _L("Query received is in ITU-T mode") ); |
|
458 |
|
459 // Search results |
|
460 iHelper->SearchITUL(*tempSettings, *query, isGroupSearch, |
|
461 contactsInGroup, searchResults, searchSeqs); |
|
462 |
|
463 break; |
|
464 |
|
465 case EQwerty: |
|
466 |
|
467 PRINT ( _L("Query received is in QWERTY mode") ); |
|
468 |
|
469 // Search results |
|
470 iHelper->SearchQWERTYL(*tempSettings, *query, isGroupSearch, |
|
471 contactsInGroup, searchResults, searchSeqs); |
|
472 |
|
473 break; |
|
474 |
|
475 case EModeUndefined: |
|
476 |
|
477 PRINT ( _L("Query received is in Mixed mode. Keyboard swap happened.") ); |
|
478 |
|
479 // Search results |
|
480 iHelper->SearchMixedL(*tempSettings, *query, isGroupSearch, |
|
481 contactsInGroup, searchResults, searchSeqs); |
|
482 |
|
483 break; |
|
484 } |
|
485 |
|
486 } |
568 } |
487 // ------------------------------------------------------------------------ |
569 // ------------------------------------------------------------------------ |
488 |
570 |
489 |
571 // (3)-------------------- Perform a multi query search ------------------- |
490 // -(3)---------------------------- Perform a multi query search ---------- |
572 else // multiple query |
491 if (queryList.Count() > 1) // multiple query |
|
492 { |
573 { |
493 PRINT ( _L("Query received is in multiple. Performing a multi search.") ); |
574 PRINT ( _L("Query received is in multiple. Performing a multi search.") ); |
494 |
|
495 TInt mode = aQuery.KeyboardModeL(); |
|
496 iFindUtilECE->SetKeyboardMode(mode); |
|
497 |
|
498 for (int i = 0; i < queryList.Count(); i++) |
|
499 { |
|
500 TPtrC queryPtr = queryList[i]->QueryAsStringLC(); |
|
501 PRINT2 ( _L("Received Query, index = %d; value = %S"), i, &queryPtr ); |
|
502 CleanupStack::PopAndDestroy(); |
|
503 } |
|
504 |
575 |
505 // Search results |
576 // Search results |
506 iMultiSearchHelper->SearchMultiL(*tempSettings, queryList, isGroupSearch, |
577 iMultiSearchHelper->SearchMultiL(*tempSettings, queryList, isGroupSearch, |
507 contactsInGroup, searchResults, searchSeqs, |
578 contactsInGroup, aSearchResults, aSearchSeqs); |
508 mode); |
|
509 } |
579 } |
510 // ------------------------------------------------------------------------- |
580 // ------------------------------------------------------------------------- |
511 |
581 |
512 // Cleanup |
582 // Cleanup |
513 delete tempSettings; |
583 |
514 tempSettings = NULL; |
584 CleanupStack::PopAndDestroy( &queryList ); // ResetAndDestroy |
515 |
585 CleanupStack::PopAndDestroy( tempSettings ); |
516 groupIdArray.Close(); |
586 CleanupStack::PopAndDestroy( &groupIdArray ); // Close |
517 contactsInGroup.Close(); |
587 CleanupStack::PopAndDestroy( &contactsInGroup ); // Close |
518 queryList.ResetAndDestroy(); |
588 |
|
589 //__LATENCY_MARKEND ( _L("CPcsAlgorithm2::DoSearchL") ); |
519 |
590 |
520 PRINT ( _L("End CPcsAlgorithm2::DoSearchL") ); |
591 PRINT ( _L("End CPcsAlgorithm2::DoSearchL") ); |
521 } |
592 } |
522 |
593 |
523 // ---------------------------------------------------------------------------- |
594 // ---------------------------------------------------------------------------- |
524 // CPcsAlgorithm2::DoSearchInputL |
595 // CPcsAlgorithm2::DoSearchInputL |
525 // Search function helper |
596 // Search function helper |
526 // ---------------------------------------------------------------------------- |
597 // ---------------------------------------------------------------------------- |
527 void CPcsAlgorithm2::DoSearchInputL(CPsQuery& aQuery, TDesC& aData, |
598 void CPcsAlgorithm2::DoSearchInputL(CPsQuery& aQuery, |
|
599 const TDesC& aData, |
528 RPointerArray<TDesC>& aMatchSet, |
600 RPointerArray<TDesC>& aMatchSet, |
529 RArray<TPsMatchLocation>& aMatchLocation) |
601 RArray<TPsMatchLocation>& aMatchLocation) |
530 { |
602 { |
531 |
603 |
|
604 //__LATENCY_MARK ( _L("CPcsAlgorithm2::SearchInputL: ") ); |
532 PRINT ( _L("Enter CPcsAlgorithm2::DoSearchInputL") ); |
605 PRINT ( _L("Enter CPcsAlgorithm2::DoSearchInputL") ); |
533 |
606 |
534 // Check if any seperator is there in the query |
607 // Check if any seperator is there in the query |
535 RPointerArray<CPsQuery> queryList = iMultiSearchHelper->MultiQueryL(aQuery); |
608 RPointerArray<CPsQuery> queryList = iMultiSearchHelper->MultiQueryL(aQuery); |
|
609 CleanupResetAndDestroyPushL( queryList ); |
536 |
610 |
537 // No query |
611 // No query |
538 if (queryList.Count() == 0) |
612 if (queryList.Count() == 0) |
539 { |
613 { |
540 PRINT ( _L("Query received is empty") ); |
614 PRINT ( _L("Query received is empty") ); |
|
615 CleanupStack::PopAndDestroy( &queryList ); // ResetAndDestroy |
541 return; |
616 return; |
542 } |
617 } |
543 |
|
544 RPointerArray<HBufC> convertedQuery; |
|
545 iMultiSearchHelper->ConvertQueryToListL(queryList, convertedQuery); |
|
546 |
618 |
547 // Single query |
619 // Single query |
548 if (queryList.Count() == 1) |
620 if (queryList.Count() == 1) |
549 { |
621 { |
550 iHelper->SearchMatchSeqL(convertedQuery[0], aData, aMatchSet, aQuery, |
622 iHelper->SearchMatchSeqL(aQuery, aData, aMatchSet, aMatchLocation); |
551 aMatchLocation); |
|
552 |
|
553 } |
623 } |
554 |
624 |
555 if (queryList.Count() > 1) // multiple query |
625 if (queryList.Count() > 1) // multiple query |
556 { |
626 { |
557 PRINT ( _L("Query received is in multiple. Performing a multi search.") ); |
627 PRINT ( _L("Query received is in multiple. Performing a multi search.") ); |
558 |
628 |
559 for (int i = 0; i < queryList.Count(); i++) |
|
560 { |
|
561 TPtrC queryPtr = queryList[i]->QueryAsStringLC(); |
|
562 PRINT2 ( _L("Rceived Query, index = %d; value = %S"), i, &queryPtr ); |
|
563 CleanupStack::PopAndDestroy(); |
|
564 } |
|
565 |
|
566 // Search results |
629 // Search results |
567 iMultiSearchHelper->SearchMatchSeqMultiL(queryList, aData, aMatchSet, |
630 iMultiSearchHelper->SearchMatchSeqMultiL(queryList, |
|
631 aData, |
|
632 aMatchSet, |
568 aMatchLocation); |
633 aMatchLocation); |
569 |
|
570 } |
634 } |
571 |
635 |
572 // Delete all the query elements |
636 // Delete all the query elements |
573 queryList.ResetAndDestroy(); |
637 CleanupStack::PopAndDestroy( &queryList ); // ResetAndDestroy |
574 convertedQuery.ResetAndDestroy(); |
|
575 |
|
576 PRINT ( _L("End CPcsAlgorithm2::DoSearchInputL") ); |
638 PRINT ( _L("End CPcsAlgorithm2::DoSearchInputL") ); |
|
639 //__LATENCY_MARKEND ( _L("CPcsAlgorithm2::SearchInputL") ); |
|
640 |
577 } |
641 } |
578 |
642 |
579 // ---------------------------------------------------------------------------- |
643 // ---------------------------------------------------------------------------- |
580 // CPcsAlgorithm2::AddData |
644 // CPcsAlgorithm2::AddData |
581 // Add a data element to the pool |
645 // Add a data element to the pool |
820 return; |
884 return; |
821 } |
885 } |
822 |
886 |
823 // If not a cache update event, then this event is related to the initial |
887 // If not a cache update event, then this event is related to the initial |
824 // cache construction. |
888 // cache construction. |
825 TInt index = FindStoreUri(aDataStore); |
889 |
826 iPcsCache[index]->UpdateCacheStatus(aStatus); |
890 // Check if any error occurred and update the cache error |
827 |
891 if ( aStatus < 0 ) |
828 // Check if any error occurred |
892 { |
829 // If so, update the cache status, Set the property and return |
|
830 if (aStatus < 0) |
|
831 { |
|
832 SetCachingError(aDataStore, aStatus); |
893 SetCachingError(aDataStore, aStatus); |
833 //return; |
894 } |
834 } |
895 else |
835 |
896 { |
836 //store the index for firstname and lastname |
897 TInt index = FindStoreUri(aDataStore); |
837 if (aStatus == ECachingComplete) |
898 iPcsCache[index]->UpdateCacheStatus(aStatus); |
838 { |
899 } |
839 RArray<TInt> dataFields; |
900 |
840 iPcsCache[index]->GetDataFields(dataFields); |
901 TCachingStatus status = ECachingNotStarted; |
841 |
902 TUint countNotStarted = 0; |
842 for (int i = 0; i < dataFields.Count(); i++) |
903 TUint countInProgress = 0; |
843 { |
904 TUint countCompleted = 0; |
844 if (dataFields[i] == R_VPBK_FIELD_TYPE_FIRSTNAME) |
905 TUint countCompletedWithErrors = 0; |
845 { |
906 TInt cacheCount = iPcsCache.Count(); |
846 iFirstNameIndex = i; |
907 for ( TInt i = 0; i < cacheCount; i++ ) |
847 } |
908 { |
848 else if (dataFields[i] == R_VPBK_FIELD_TYPE_LASTNAME) |
909 PRINT3 ( _L("CPcsAlgorithm2::UpdateCachingStatus: URI[%d]=%S, cache status=%d"), |
849 { |
910 i, &iPcsCache[i]->GetURI(), iPcsCache[i]->GetCacheStatus() ); |
850 iLastNameIndex = i; |
911 |
851 } |
912 switch ( iPcsCache[i]->GetCacheStatus() ) |
852 } |
913 { |
853 } |
914 case ECachingNotStarted: |
854 |
915 { |
855 // No error occurred |
916 countNotStarted++; |
856 TCachingStatus status = ECachingComplete; |
917 break; |
857 TBool atLeastOneStoreCachingCompleteWithErrors(EFalse); |
918 } |
858 for (TInt i = 0; i < iPcsCache.Count(); i++) |
919 case ECachingInProgress: |
859 { |
920 { |
860 if (iPcsCache[i]->GetCacheStatus() == ECachingComplete) |
921 countInProgress++; |
861 { |
922 break; |
862 continue; |
923 } |
863 } |
924 case ECachingComplete: |
864 else if (iPcsCache[i]->GetCacheStatus() == ECachingCompleteWithErrors) |
925 { |
865 { |
926 countCompleted++; |
866 atLeastOneStoreCachingCompleteWithErrors = ETrue; |
927 break; |
867 continue; |
928 } |
868 } |
929 case ECachingCompleteWithErrors: |
869 else |
930 { |
870 { |
931 countCompletedWithErrors++; |
871 status = ECachingInProgress; |
932 break; |
872 break; |
933 } |
873 } |
934 default: |
874 } |
935 { |
875 |
936 // Default completed state |
876 if (status == ECachingComplete) |
937 countCompleted++; |
877 { |
938 break; |
878 // See if any error occurred while caching |
939 } |
879 // If so, change the status to ECachingCompleteWithErrors |
940 } |
880 if ((iCacheError != KErrNone) || (atLeastOneStoreCachingCompleteWithErrors)) |
941 } |
881 { |
942 |
882 status = ECachingCompleteWithErrors; |
943 // Calculate cumulative status according to single caches statuses |
883 } |
944 if ( countCompleted > 0 && ( countCompleted + countNotStarted ) == cacheCount ) |
884 } |
945 { |
|
946 // If at least one caching is finished |
|
947 // set status to ECachingComplete or ECachingCompleteWithErrors |
|
948 // according to iCacheError |
|
949 status = ( iCacheError == KErrNone ) ? ECachingComplete : ECachingCompleteWithErrors; |
|
950 } |
|
951 else if ( countInProgress > 0 ) |
|
952 { |
|
953 // Else if at least one caching is in progress, |
|
954 // set status to ECachingInProgress |
|
955 status = ECachingInProgress; |
|
956 } |
|
957 else if ( countCompletedWithErrors > 0 ) |
|
958 { |
|
959 // Else if at least one caching is completed with errors, |
|
960 //set status to ECachingCompleteWithErrors |
|
961 status = ECachingCompleteWithErrors; |
|
962 } |
|
963 else |
|
964 { |
|
965 // countNotStarted == cacheCount |
|
966 // status is set to default ECachingNotStarted |
|
967 } |
|
968 |
|
969 PRINT1 ( _L("CPcsAlgorithm2::UpdateCachingStatus: Cumulative caching status is %d"), |
|
970 status ); |
885 |
971 |
886 // Check if status changed |
972 // Check if status changed |
887 if (status != iCacheStatus) |
973 if ( status != iCacheStatus ) |
888 { |
974 { |
|
975 PRINT2 ( _L("CPcsAlgorithm2::UpdateCachingStatus: Cumulative caching changed: %d -> %d"), |
|
976 iCacheStatus, status ); |
|
977 |
889 iCacheStatus = status; |
978 iCacheStatus = status; |
890 RProperty::Set(KPcsInternalUidCacheStatus, EPsKeyCacheStatus, iCacheStatus ); |
979 RProperty::Set(KPcsInternalUidCacheStatus, EPsKeyCacheStatus, iCacheStatus ); |
891 } |
980 } |
892 |
981 |
893 PRINT ( _L("End CPcsAlgorithm2::UpdateCachingStatus") ); |
982 PRINT( _L("End CPcsAlgorithm2::UpdateCachingStatus") ); |
894 } |
983 } |
|
984 |
895 |
985 |
896 // ---------------------------------------------------------------------------- |
986 // ---------------------------------------------------------------------------- |
897 // CPcsAlgorithm2::SetCachingError |
987 // CPcsAlgorithm2::SetCachingError |
898 // Updates cachinge error |
988 // Updates cachinge error |
899 // ---------------------------------------------------------------------------- |
989 // ---------------------------------------------------------------------------- |
900 void CPcsAlgorithm2::SetCachingError(TDesC& aDataStore, TInt aError) |
990 void CPcsAlgorithm2::SetCachingError(const TDesC& aDataStore, TInt aError) |
901 { |
991 { |
902 PRINT2 ( _L("SetCachingError::URI %S ERROR %d"), &aDataStore, aError ); |
992 PRINT2 ( _L("SetCachingError::URI %S ERROR %d"), &aDataStore, aError ); |
903 |
993 |
904 iCacheError = aError; |
994 iCacheError = aError; |
905 RProperty::Set( KPcsInternalUidCacheStatus, EPsKeyCacheError, iCacheError ); |
995 RProperty::Set( KPcsInternalUidCacheStatus, EPsKeyCacheError, iCacheError ); |
910 // Returns all the contents of a store |
1000 // Returns all the contents of a store |
911 // ---------------------------------------------------------------------------- |
1001 // ---------------------------------------------------------------------------- |
912 void CPcsAlgorithm2::GetAllContentsL(const CPsSettings& aSettings, |
1002 void CPcsAlgorithm2::GetAllContentsL(const CPsSettings& aSettings, |
913 RPointerArray<CPsData>& aResults) |
1003 RPointerArray<CPsData>& aResults) |
914 { |
1004 { |
915 __LATENCY_MARK ( _L("CPcsAlgorithm2::GetAllContentsL") ); |
1005 //__LATENCY_MARK ( _L("CPcsAlgorithm2::GetAllContentsL") ); |
916 |
1006 |
917 PRINT ( _L("Enter CPcsAlgorithm2::GetAllContentsL") ); |
1007 PRINT ( _L("Enter CPcsAlgorithm2::GetAllContentsL") ); |
918 |
|
919 // Get the data stores |
|
920 RPointerArray<TDesC> aDataStores; |
|
921 aSettings.SearchUrisL(aDataStores); |
|
922 |
1008 |
923 // To hold array of results from different data stores |
1009 // To hold array of results from different data stores |
924 typedef RPointerArray<CPsData> CPSDATA_R_PTR_ARRAY; |
1010 typedef RPointerArray<CPsData> CPSDATA_R_PTR_ARRAY; |
925 RPointerArray<CPSDATA_R_PTR_ARRAY> iSearchResultsArr; |
1011 RPointerArray<CPSDATA_R_PTR_ARRAY> searchResultsArr; |
|
1012 CleanupResetAndDestroyPushL( searchResultsArr ); |
|
1013 // TODO: Here's still a potential memory leak if a leave happens. The child |
|
1014 // arrays of searchResultsArr are not Reset in that case. The CPsData objects |
|
1015 // may leak as well. Handling this safely is somewhat complicated because some of |
|
1016 // the CPsData objects may already be transferred to ownership of aResults array |
|
1017 // at the time the leave happens, and those items must not be deleted. |
|
1018 |
|
1019 // Get the data stores |
|
1020 RPointerArray<TDesC> dataStores; |
|
1021 CleanupResetAndDestroyPushL( dataStores ); |
|
1022 aSettings.SearchUrisL(dataStores); |
926 |
1023 |
927 // Get all contacts for each data store |
1024 // Get all contacts for each data store |
928 for (int dsIndex = 0; dsIndex < aDataStores.Count(); dsIndex++) |
1025 const TInt dataStoresCount = dataStores.Count(); |
|
1026 for (TInt dsIndex = 0; dsIndex < dataStoresCount; dsIndex++) |
929 { |
1027 { |
930 RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> (); |
1028 RPointerArray<CPsData> *temp = new (ELeave) RPointerArray<CPsData> (); |
931 iSearchResultsArr.Append(temp); |
1029 searchResultsArr.Append(temp); |
932 |
1030 |
933 TInt arrayIndex = GetCacheIndex(*(aDataStores[dsIndex])); |
1031 TInt arrayIndex = GetCacheIndex(*(dataStores[dsIndex])); |
934 if (arrayIndex < 0) |
1032 if (arrayIndex < 0) |
935 { |
1033 { |
936 continue; |
1034 continue; |
937 } |
1035 } |
938 |
1036 |
939 CPcsCache* cache = GetCache(arrayIndex); |
1037 CPcsCache* cache = GetCache(arrayIndex); |
940 |
1038 |
941 cache->GetAllContentsL(*(iSearchResultsArr[dsIndex])); |
1039 cache->GetAllContentsL(*(searchResultsArr[dsIndex])); |
942 } |
1040 } |
943 |
1041 |
944 aDataStores.ResetAndDestroy(); |
1042 CleanupStack::PopAndDestroy( &dataStores ); // ResetAndDestroy |
945 |
1043 |
946 // Merge the results from different data stores |
1044 // Merge the results from different data stores |
947 CPcsAlgorithm2Utils::FormCompleteSearchResultsL(iSearchResultsArr, aResults); |
1045 CPcsAlgorithm2Utils::FormCompleteSearchResultsL(searchResultsArr, aResults); |
948 |
1046 |
949 // Cleanup the local arrays |
1047 // Cleanup the local arrays |
950 for (TInt i = 0; i < iSearchResultsArr.Count(); i++) |
1048 const TInt seaerchResultsArrCount = searchResultsArr.Count(); |
951 { |
1049 for (TInt i = 0; i < seaerchResultsArrCount; i++) |
952 iSearchResultsArr[i]->Reset(); |
1050 { |
953 delete iSearchResultsArr[i]; |
1051 searchResultsArr[i]->Reset(); |
954 iSearchResultsArr[i] = NULL; |
1052 } |
955 } |
1053 |
956 |
1054 CleanupStack::PopAndDestroy( &searchResultsArr ); // ResetAndDestroy |
957 iSearchResultsArr.Reset(); |
|
958 |
1055 |
959 PRINT1 ( _L("Number of results = %d"), aResults.Count() ); |
1056 PRINT1 ( _L("Number of results = %d"), aResults.Count() ); |
960 |
1057 |
961 PRINT ( _L("End CPcsAlgorithm2::GetAllContentsL") ); |
1058 PRINT ( _L("End CPcsAlgorithm2::GetAllContentsL") ); |
962 |
1059 |
963 __LATENCY_MARKEND ( _L("CPcsAlgorithm2::GetAllContentsL") ); |
1060 //__LATENCY_MARKEND ( _L("CPcsAlgorithm2::GetAllContentsL") ); |
964 } |
1061 } |
965 |
1062 |
966 // ---------------------------------------------------------------------------- |
1063 // ---------------------------------------------------------------------------- |
967 // CPcsAlgorithm2::IsGroupSearchL |
1064 // CPcsAlgorithm2::IsGroupSearchL |
968 // Checks if a group search is required |
1065 // Checks if a group search is required |