|
1 /* |
|
2 * Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Phonebook 2 Predictive search view stack |
|
15 * |
|
16 */ |
|
17 |
|
18 #include "CPbk2ContactPositionInfo.h" |
|
19 #include "cpbk2predictiveviewstack.h" |
|
20 |
|
21 // Phonebook 2 / Virtual Phonebook |
|
22 #include <MVPbkContactViewFiltering.h> |
|
23 #include <CVPbkContactFindPolicy.h> |
|
24 #include <VPbkEng.rsg> |
|
25 #include <MVPbkViewContact.h> |
|
26 #include <CVPbkContactIdConverter.h> |
|
27 #include <MPbk2AppUi.h> |
|
28 #include <MPbk2ApplicationServices.h> |
|
29 #include <VPbkContactStoreUris.h> |
|
30 #include <centralrepository.h> |
|
31 #include <Phonebook2PrivateCRKeys.h> |
|
32 #include <CVPbkTopContactManager.h> |
|
33 #include "cpbk2filteredviewstack.h" |
|
34 #include <CPbk2StoreConfiguration.h> |
|
35 #include <MVPbkContactBookmarkCollection.h> |
|
36 #include <CVPbkContactIdConverter.h> |
|
37 #include "CPbk2PredictiveSearchFilter.h" |
|
38 #include <MPbk2ContactNameFormatter.h> |
|
39 #include <MPbk2ContactNameFormatter2.h> |
|
40 |
|
41 // Predictive seard engine headers |
|
42 #include <CPsSettings.h> |
|
43 #include <CPsQueryItem.h> |
|
44 #include <CPsData.h> |
|
45 #include <CPsRequestHandler.h> |
|
46 |
|
47 // Debugging headers |
|
48 #include <Pbk2Debug.h> |
|
49 #include <bidivisual.h> |
|
50 #include <fepbase.h> |
|
51 #include "Phonebook2PrivateCRKeys.h" |
|
52 |
|
53 |
|
54 // System includes |
|
55 #include <aknsfld.h> |
|
56 #include <featmgr.h> |
|
57 // CONSTANTS |
|
58 const TInt Kspace = ' '; |
|
59 _LIT(KPsGroupDBSuffix, "?id=%d"); |
|
60 |
|
61 /// Unnamed namespace for local definitions |
|
62 namespace { |
|
63 |
|
64 |
|
65 |
|
66 |
|
67 // -------------------------------------------------------------------------- |
|
68 // SendEventToObservers |
|
69 // Sends events to the array of observes that take MVPbkContactViewBase. |
|
70 // as a parameter. |
|
71 // |
|
72 // @param aView The parameter for the NotifyFunc. |
|
73 // @param aObservers An array of MVPbkContactViewObservers. |
|
74 // @param aNotifyFunc A member function pointer of the |
|
75 // MVPbkContactViewObserver. |
|
76 // -------------------------------------------------------------------------- |
|
77 // |
|
78 template <class Observer, class NotifyFunc> |
|
79 void SendEventToObservers( MVPbkContactViewBase& aView, |
|
80 RPointerArray<Observer>& aObservers, |
|
81 NotifyFunc aNotifyFunc ) |
|
82 { |
|
83 const TInt count = aObservers.Count(); |
|
84 for (TInt i = count-1; i >= 0 ; --i) |
|
85 { |
|
86 Observer* observer = aObservers[i]; |
|
87 (observer->*aNotifyFunc)(aView); |
|
88 } |
|
89 } |
|
90 |
|
91 // -------------------------------------------------------------------------- |
|
92 // SendEventToObservers |
|
93 // Sends events to the array of MVPbkContactViewObserver. |
|
94 // Used for MVPbkContactViewObserver functions that have two extra parameters |
|
95 // in addition to MVPbkContactViewBase. |
|
96 // |
|
97 // @param aView The first parameter for the NotifyFunc. |
|
98 // @param aObservers An array of MVPbkContactViewObserver. |
|
99 // @param aNotifyFunc A member function pointer of the |
|
100 // MVPbkContactViewObserver. |
|
101 // @param aParam1 The second parameter for the aNotifyFunc. |
|
102 // @param aParam2 The third parameter for the aNotifyFunc. |
|
103 // -------------------------------------------------------------------------- |
|
104 // |
|
105 template <class Observer, class FuncPtr, class ParamType1, class ParamType2> |
|
106 void SendEventToObservers( MVPbkContactViewBase& aView, |
|
107 RPointerArray<Observer>& aObservers, |
|
108 FuncPtr aNotifyFunc, |
|
109 ParamType1 aParam1, ParamType2& aParam2) |
|
110 { |
|
111 const TInt count = aObservers.Count(); |
|
112 for (TInt i = count-1; i >= 0 ; --i) |
|
113 { |
|
114 Observer* observer = aObservers[i]; |
|
115 (observer->*aNotifyFunc)(aView, aParam1, aParam2); |
|
116 } |
|
117 } |
|
118 |
|
119 } /// namespace |
|
120 |
|
121 TInt CPbk2ContactPositionInfo::CompareByPosition( |
|
122 const CPbk2ContactPositionInfo& aFirst, |
|
123 const CPbk2ContactPositionInfo& aSecond ) |
|
124 { |
|
125 if( aFirst.iPos < aSecond.iPos ) |
|
126 { |
|
127 return -1; |
|
128 } |
|
129 else if( aFirst.iPos == aSecond.iPos ) |
|
130 { |
|
131 return 0; |
|
132 } |
|
133 else |
|
134 { |
|
135 return 1; |
|
136 } |
|
137 } |
|
138 |
|
139 // -------------------------------------------------------------------------- |
|
140 // CPbk2PredictiveViewStack::CPbk2PredictiveViewStack |
|
141 // -------------------------------------------------------------------------- |
|
142 CPbk2PredictiveViewStack::CPbk2PredictiveViewStack( CPbk2PredictiveSearchFilter& aSearchFilter, |
|
143 MPbk2ContactNameFormatter& aNameformatter ): |
|
144 CActive( EPriorityStandard ), iSearchFilter( aSearchFilter ), |
|
145 iNameformatter(aNameformatter), |
|
146 iNonMatchedMarkedContactStartIndex(KErrNotFound), |
|
147 iNonMatchedMarkedContactEndIndex(KErrNotFound) |
|
148 { |
|
149 CActiveScheduler::Add( this ); |
|
150 } |
|
151 |
|
152 // -------------------------------------------------------------------------- |
|
153 // CPbk2PredictiveViewStack::~CPbk2PredictiveViewStack |
|
154 // -------------------------------------------------------------------------- |
|
155 // |
|
156 CPbk2PredictiveViewStack::~CPbk2PredictiveViewStack() |
|
157 { |
|
158 Cancel(); |
|
159 iBidiPatterns.ResetAndDestroy(); |
|
160 iPatternsCollection.ResetAndDestroy(); |
|
161 iStackObservers.Reset(); |
|
162 iViewObservers.Reset(); |
|
163 delete iConverterDefaultStore; |
|
164 delete iPsQuery; |
|
165 delete iPsHandler; |
|
166 delete iCurrentGroupLink; |
|
167 if ( iBaseView ) |
|
168 { |
|
169 iBaseView->RemoveObserver( *this ); |
|
170 } |
|
171 |
|
172 if( iPredictiveSearchResultContactLinkArrray ) |
|
173 { |
|
174 iPredictiveSearchResultContactLinkArrray->ResetAndDestroy(); |
|
175 delete iPredictiveSearchResultContactLinkArrray; |
|
176 } |
|
177 |
|
178 iTopContactPositionInfoArray.ResetAndDestroy(); |
|
179 iMarkedContactsPositionInfoArray.ResetAndDestroy(); |
|
180 |
|
181 delete iTopContactManager; |
|
182 iSearchText.Close(); |
|
183 if(iFeatureManagerInitilized) |
|
184 { |
|
185 FeatureManager::UnInitializeLib(); |
|
186 } |
|
187 } |
|
188 |
|
189 // -------------------------------------------------------------------------- |
|
190 // CPbk2PredictiveViewStack::NewL |
|
191 // -------------------------------------------------------------------------- |
|
192 // |
|
193 CPbk2PredictiveViewStack* CPbk2PredictiveViewStack::NewL( |
|
194 MVPbkContactViewBase& aBaseView, |
|
195 CPbk2PredictiveSearchFilter& aSearchFilter, |
|
196 MPbk2ContactNameFormatter& aNameformatter ) |
|
197 { |
|
198 CPbk2PredictiveViewStack* self = new ( ELeave ) CPbk2PredictiveViewStack( aSearchFilter, |
|
199 aNameformatter ); |
|
200 CleanupStack::PushL( self ); |
|
201 self->ConstructL( aBaseView ); |
|
202 CleanupStack::Pop( self ); |
|
203 return self; |
|
204 } |
|
205 |
|
206 // -------------------------------------------------------------------------- |
|
207 // CPbk2PredictiveViewStack::ConstructL |
|
208 // -------------------------------------------------------------------------- |
|
209 // |
|
210 void CPbk2PredictiveViewStack::ConstructL( MVPbkContactViewBase& aBaseView ) |
|
211 { |
|
212 PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING( |
|
213 "CPbk2PredictiveViewStack::ConstructL")); |
|
214 |
|
215 iSearchedState = EFalse; |
|
216 iViewReady = EFalse; |
|
217 iBaseView = &aBaseView; |
|
218 |
|
219 // Initialize feature manager |
|
220 FeatureManager::InitializeLibL(); |
|
221 iFeatureManagerInitilized = ETrue; |
|
222 // Initilize the PCS engine |
|
223 InitializePCSEngineL(); |
|
224 |
|
225 CVPbkContactManager& manager = Phonebook2::Pbk2AppUi()-> |
|
226 ApplicationServices().ContactManager(); |
|
227 |
|
228 iTopContactManager = CVPbkTopContactManager::NewL( manager ); |
|
229 |
|
230 // Arrary for holding the search result links |
|
231 iPredictiveSearchResultContactLinkArrray = CVPbkContactLinkArray::NewL(); |
|
232 |
|
233 // Start listening view events |
|
234 iBaseView->AddObserverL( *this ); |
|
235 } |
|
236 |
|
237 // -------------------------------------------------------------------------- |
|
238 // CPbk2PredictiveViewStack::UpdateFilterL |
|
239 // -------------------------------------------------------------------------- |
|
240 // |
|
241 void CPbk2PredictiveViewStack::UpdateFilterL( const MDesCArray& aFindStrings, |
|
242 const MVPbkContactBookmarkCollection* aAlwaysincluded, |
|
243 TBool aAlwaysIncludedChanged ) |
|
244 { |
|
245 if ( aAlwaysIncludedChanged ) |
|
246 { |
|
247 // iBookMarkCollection is not owned |
|
248 iBookMarkCollection = |
|
249 const_cast<MVPbkContactBookmarkCollection*>( aAlwaysincluded ); |
|
250 } |
|
251 |
|
252 iPredictiveSearch = iSearchFilter.IsPredictiveActivated(); |
|
253 |
|
254 TKeyboardModes pcsKeyboardMode( EItut ); |
|
255 if ( iPredictiveSearch ) |
|
256 { |
|
257 pcsKeyboardMode = EItut; |
|
258 } |
|
259 else |
|
260 { |
|
261 pcsKeyboardMode = EQwerty; |
|
262 } |
|
263 |
|
264 // During filtering if there were multitaps, Fep transacton is broken |
|
265 // and search box sends canceletion of last tap, we ignore this. |
|
266 if( iPredictiveSearch && iSearchFilter.IsFiltering() ) |
|
267 { |
|
268 return; |
|
269 } |
|
270 |
|
271 RBuf searchText; |
|
272 iSearchFilter.GetSearchTextL( searchText ); |
|
273 CleanupClosePushL( searchText ); |
|
274 // Events go on up and down key, it is not good do search always twice |
|
275 TInt compareSearchText = iSearchText.Compare(searchText); |
|
276 |
|
277 iSearchText.Close(); |
|
278 iSearchText.CreateL(searchText.Length()); |
|
279 iSearchText = searchText; |
|
280 |
|
281 CleanupStack::PopAndDestroy(&searchText); |
|
282 |
|
283 if( compareSearchText == 0 ) |
|
284 { |
|
285 return; |
|
286 } |
|
287 |
|
288 if( !aFindStrings.MdcaCount() ) |
|
289 { |
|
290 if( compareSearchText == 1 ) |
|
291 { |
|
292 if( !iSearchText.Length() ) |
|
293 { |
|
294 Reset(); |
|
295 } |
|
296 else |
|
297 { |
|
298 ClearSearch(); |
|
299 } |
|
300 } |
|
301 return; |
|
302 } |
|
303 |
|
304 // Delete the previous query |
|
305 delete iPsQuery; |
|
306 iPsQuery = NULL; |
|
307 |
|
308 // Create the new search query |
|
309 iPsQuery = CPsQuery::NewL(); |
|
310 |
|
311 // Combine the search strings and create the PCS query |
|
312 for ( TInt j = 0; j < aFindStrings.MdcaCount(); j++ ) |
|
313 { |
|
314 HBufC* searchString = aFindStrings.MdcaPoint(j).AllocL(); |
|
315 TPtrC searchStringPtr(*searchString); |
|
316 CleanupStack::PushL( searchString ); |
|
317 |
|
318 for ( TInt i = 0; i < searchStringPtr.Length(); i++ ) |
|
319 { |
|
320 // Add a query item |
|
321 CPsQueryItem* item = CPsQueryItem::NewL(); |
|
322 item->SetCharacter(searchStringPtr[i]); |
|
323 |
|
324 TInt qwertyNumber = KErrCancel; |
|
325 if( iPredictiveSearch ) |
|
326 { |
|
327 TLex numberVal( searchStringPtr.Mid(i, 1) ); |
|
328 TInt num = 0; |
|
329 qwertyNumber = numberVal.Val(num); |
|
330 } |
|
331 if( qwertyNumber == KErrNone ) |
|
332 { |
|
333 // Set qwerty search mode (in predictive search we can tap numbers only by long tap) |
|
334 item->SetMode( EQwerty ); |
|
335 } |
|
336 else |
|
337 { |
|
338 // Set current search mode |
|
339 item->SetMode( pcsKeyboardMode ); |
|
340 } |
|
341 |
|
342 iPsQuery->AppendL(*item); |
|
343 } |
|
344 |
|
345 //Add a space in between two words |
|
346 if(aFindStrings.MdcaCount() > 1) |
|
347 { |
|
348 CPsQueryItem* item = CPsQueryItem::NewL(); |
|
349 item->SetCharacter(Kspace); |
|
350 item->SetMode(EItut); |
|
351 iPsQuery->AppendL(*item); |
|
352 } |
|
353 |
|
354 //Cleanup |
|
355 CleanupStack::PopAndDestroy( searchString); |
|
356 } |
|
357 |
|
358 //Send the search query to the PCS engine |
|
359 iPsHandler->SearchL(*iPsQuery); |
|
360 } |
|
361 |
|
362 // -------------------------------------------------------------------------- |
|
363 // CPbk2PredictiveViewStack::Reset |
|
364 // -------------------------------------------------------------------------- |
|
365 // |
|
366 void CPbk2PredictiveViewStack::Reset() |
|
367 { |
|
368 PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING( |
|
369 "CPbk2PredictiveViewStack::Reset: topview(0x%x), current stack level = %d")); |
|
370 TRAP_IGNORE(iSearchFilter.ResetL()); |
|
371 iPsHandler->CancelSearch(); |
|
372 ClearSearch(); |
|
373 } |
|
374 |
|
375 // -------------------------------------------------------------------------- |
|
376 // CPbk2PredictiveViewStack::ClearSearch |
|
377 // -------------------------------------------------------------------------- |
|
378 // |
|
379 void CPbk2PredictiveViewStack::ClearSearch() |
|
380 { |
|
381 iNonMatchedMarkedContactStartIndex = KErrNotFound; |
|
382 iNonMatchedMarkedContactEndIndex = KErrNotFound; |
|
383 iSearchedState = EFalse; |
|
384 iPredictiveSearchResultContactLinkArrray->ResetAndDestroy(); |
|
385 iTopContactPositionInfoArray.ResetAndDestroy(); |
|
386 iSearchText.Close(); |
|
387 SendTopViewChangedEvent( *iBaseView ); |
|
388 } |
|
389 |
|
390 // -------------------------------------------------------------------------- |
|
391 // CPbk2PredictiveViewStack::BaseView |
|
392 // -------------------------------------------------------------------------- |
|
393 // |
|
394 MVPbkContactViewBase& CPbk2PredictiveViewStack::BaseView() const |
|
395 { |
|
396 return *iBaseView; |
|
397 } |
|
398 |
|
399 // -------------------------------------------------------------------------- |
|
400 // CPbk2PredictiveViewStack::SetNewBaseViewL |
|
401 // -------------------------------------------------------------------------- |
|
402 // |
|
403 void CPbk2PredictiveViewStack::SetNewBaseViewL( |
|
404 MVPbkContactViewBase& aBaseView ) |
|
405 { |
|
406 Reset(); |
|
407 |
|
408 // Remove observering the old base view |
|
409 if ( iBaseView ) |
|
410 { |
|
411 iBaseView->RemoveObserver( *this ); |
|
412 } |
|
413 |
|
414 iBaseView = &aBaseView; |
|
415 |
|
416 // Start listening to new base view |
|
417 iBaseView->AddObserverL( *this ); |
|
418 } |
|
419 |
|
420 // -------------------------------------------------------------------------- |
|
421 // CPbk2PredictiveViewStack::Level |
|
422 // -------------------------------------------------------------------------- |
|
423 // |
|
424 TInt CPbk2PredictiveViewStack::Level() const |
|
425 { |
|
426 if ( iSearchedState ) |
|
427 { |
|
428 return 1; |
|
429 } |
|
430 |
|
431 return 0; |
|
432 } |
|
433 |
|
434 |
|
435 // -------------------------------------------------------------------------- |
|
436 // CPbk2FilteredViewStack::AddStackObserverL |
|
437 // -------------------------------------------------------------------------- |
|
438 void CPbk2PredictiveViewStack::AddStackObserverL( |
|
439 MPbk2FilteredViewStackObserver& aStackObserver ) |
|
440 { |
|
441 iStackObservers.AppendL( &aStackObserver ); |
|
442 } |
|
443 |
|
444 // -------------------------------------------------------------------------- |
|
445 // CPbk2FilteredViewStack::RemoveStackObserver |
|
446 // -------------------------------------------------------------------------- |
|
447 // |
|
448 void CPbk2PredictiveViewStack::RemoveStackObserver( |
|
449 MPbk2FilteredViewStackObserver& aStackObserver ) |
|
450 { |
|
451 TInt index = iStackObservers.Find( &aStackObserver ); |
|
452 if ( index != KErrNotFound ) |
|
453 { |
|
454 iStackObservers.Remove( index ); |
|
455 } |
|
456 } |
|
457 |
|
458 // -------------------------------------------------------------------------- |
|
459 // CPbk2PredictiveViewStack::Type |
|
460 // -------------------------------------------------------------------------- |
|
461 // |
|
462 TVPbkContactViewType CPbk2PredictiveViewStack::Type() const |
|
463 { |
|
464 return iBaseView->Type(); |
|
465 } |
|
466 |
|
467 // -------------------------------------------------------------------------- |
|
468 // CPbk2PredictiveViewStack::ChangeSortOrderL |
|
469 // -------------------------------------------------------------------------- |
|
470 // |
|
471 void CPbk2PredictiveViewStack::ChangeSortOrderL( |
|
472 const MVPbkFieldTypeList& aSortOrder ) |
|
473 { |
|
474 return iBaseView->ChangeSortOrderL( aSortOrder ); |
|
475 } |
|
476 |
|
477 // -------------------------------------------------------------------------- |
|
478 // CPbk2PredictiveViewStack::SortOrder |
|
479 // -------------------------------------------------------------------------- |
|
480 // |
|
481 const MVPbkFieldTypeList& CPbk2PredictiveViewStack::SortOrder() const |
|
482 { |
|
483 return iBaseView->SortOrder(); |
|
484 } |
|
485 |
|
486 // -------------------------------------------------------------------------- |
|
487 // CPbk2PredictiveViewStack::RefreshL |
|
488 // -------------------------------------------------------------------------- |
|
489 // |
|
490 void CPbk2PredictiveViewStack::RefreshL() |
|
491 { |
|
492 return iBaseView->RefreshL(); |
|
493 } |
|
494 |
|
495 // -------------------------------------------------------------------------- |
|
496 // CPbk2PredictiveViewStack::ContactCountL |
|
497 // -------------------------------------------------------------------------- |
|
498 // |
|
499 TInt CPbk2PredictiveViewStack::ContactCountL() const |
|
500 { |
|
501 TInt count; |
|
502 if ( iSearchedState ) |
|
503 { |
|
504 count = iPredictiveSearchResultContactLinkArrray->Count(); |
|
505 } |
|
506 else |
|
507 { |
|
508 count = iBaseView->ContactCountL(); |
|
509 } |
|
510 return count; |
|
511 } |
|
512 |
|
513 // -------------------------------------------------------------------------- |
|
514 // CPbk2PredictiveViewStack::ContactAtL |
|
515 // -------------------------------------------------------------------------- |
|
516 // |
|
517 const MVPbkViewContact& CPbk2PredictiveViewStack::ContactAtL |
|
518 ( TInt aIndex ) const |
|
519 { |
|
520 TInt ret = BaseViewIndex( aIndex); |
|
521 User::LeaveIfError( ret ); |
|
522 return iBaseView->ContactAtL( ret ); |
|
523 } |
|
524 |
|
525 // -------------------------------------------------------------------------- |
|
526 // CPbk2PredictiveViewStack::CreateLinkLC |
|
527 // -------------------------------------------------------------------------- |
|
528 // |
|
529 MVPbkContactLink* CPbk2PredictiveViewStack::CreateLinkLC( TInt aIndex ) const |
|
530 { |
|
531 TInt ret = BaseViewIndex( aIndex); |
|
532 User::LeaveIfError( ret ); |
|
533 return iBaseView->CreateLinkLC( ret ); |
|
534 } |
|
535 |
|
536 // -------------------------------------------------------------------------- |
|
537 // CPbk2PredictiveViewStack::IndexOfLinkL |
|
538 // -------------------------------------------------------------------------- |
|
539 // |
|
540 TInt CPbk2PredictiveViewStack::IndexOfLinkL( |
|
541 const MVPbkContactLink& aContactLink ) const |
|
542 { |
|
543 TInt ret = KErrNotFound; |
|
544 |
|
545 if ( iSearchedState ) |
|
546 { |
|
547 ret = iPredictiveSearchResultContactLinkArrray->Find( aContactLink ); |
|
548 } |
|
549 else |
|
550 { |
|
551 // Just return the index in the baseview |
|
552 ret = iBaseView->IndexOfLinkL( aContactLink ); |
|
553 } |
|
554 |
|
555 return ret; |
|
556 } |
|
557 |
|
558 // -------------------------------------------------------------------------- |
|
559 // CPbk2PredictiveViewStack::AddObserverL |
|
560 // -------------------------------------------------------------------------- |
|
561 // |
|
562 void CPbk2PredictiveViewStack::AddObserverL |
|
563 ( MVPbkContactViewObserver& aObserver ) |
|
564 { |
|
565 PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING( |
|
566 "CPbk2PredictiveViewStack::AddObserverL - IN")); |
|
567 |
|
568 if ( IsActive() ) |
|
569 { |
|
570 Cancel(); |
|
571 } |
|
572 |
|
573 TRequestStatus* status = &iStatus; |
|
574 User::RequestComplete( status, KErrNone ); |
|
575 SetActive(); |
|
576 |
|
577 // Events are sent in reverse order so insert to first position. |
|
578 iViewObservers.InsertL( &aObserver, 0 ); |
|
579 |
|
580 PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING( |
|
581 "CPbk2PredictiveViewStack::AddObserverL - OUT")); |
|
582 } |
|
583 |
|
584 // -------------------------------------------------------------------------- |
|
585 // CPbk2PredictiveViewStack::RemoveObserver |
|
586 // -------------------------------------------------------------------------- |
|
587 // |
|
588 void CPbk2PredictiveViewStack::RemoveObserver( |
|
589 MVPbkContactViewObserver& aObserver ) |
|
590 { |
|
591 PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING( |
|
592 "CPbk2PredictiveViewStack::RemoveObserver - IN")); |
|
593 |
|
594 TInt index = iViewObservers.Find( &aObserver ); |
|
595 if ( index != KErrNotFound ) |
|
596 { |
|
597 iViewObservers.Remove( index ); |
|
598 } |
|
599 |
|
600 PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING( |
|
601 "CPbk2PredictiveViewStack::RemoveObserver - OUT")); |
|
602 } |
|
603 |
|
604 // -------------------------------------------------------------------------- |
|
605 // CPbk2PredictiveViewStack::MatchContactStore |
|
606 // -------------------------------------------------------------------------- |
|
607 // |
|
608 TBool CPbk2PredictiveViewStack::MatchContactStore( |
|
609 const TDesC& aContactStoreUri ) const |
|
610 { |
|
611 return iBaseView->MatchContactStore( aContactStoreUri ); |
|
612 } |
|
613 |
|
614 // -------------------------------------------------------------------------- |
|
615 // CPbk2PredictiveViewStack::MatchContactStoreDomain |
|
616 // -------------------------------------------------------------------------- |
|
617 // |
|
618 TBool CPbk2PredictiveViewStack::MatchContactStoreDomain( |
|
619 const TDesC& aContactStoreDomain ) const |
|
620 { |
|
621 return iBaseView->MatchContactStoreDomain( aContactStoreDomain ); |
|
622 } |
|
623 |
|
624 // -------------------------------------------------------------------------- |
|
625 // CPbk2PredictiveViewStack::CreateBookmarkLC |
|
626 // -------------------------------------------------------------------------- |
|
627 // |
|
628 MVPbkContactBookmark* CPbk2PredictiveViewStack::CreateBookmarkLC( |
|
629 TInt aIndex ) const |
|
630 { |
|
631 return iBaseView->CreateBookmarkLC( BaseViewIndex( aIndex ) ); |
|
632 } |
|
633 |
|
634 // -------------------------------------------------------------------------- |
|
635 // CPbk2PredictiveViewStack::IndexOfBookmarkL |
|
636 // -------------------------------------------------------------------------- |
|
637 // |
|
638 TInt CPbk2PredictiveViewStack::IndexOfBookmarkL( |
|
639 const MVPbkContactBookmark& aContactBookmark ) const |
|
640 { |
|
641 TInt ret = KErrNotFound; |
|
642 |
|
643 if ( iSearchedState ) |
|
644 { |
|
645 TInt indexInBaseView = iBaseView->IndexOfBookmarkL( aContactBookmark ); |
|
646 const MVPbkViewContact& contact = iBaseView->ContactAtL( indexInBaseView ); |
|
647 |
|
648 TInt countInSearchedResult = iPredictiveSearchResultContactLinkArrray->Count(); |
|
649 |
|
650 for ( TInt i = 0; i < countInSearchedResult && ret == KErrNotFound; i++ ) |
|
651 { |
|
652 const MVPbkContactLink& link = iPredictiveSearchResultContactLinkArrray->At( i ); |
|
653 if ( link.RefersTo( contact ) ) |
|
654 { |
|
655 ret = i; |
|
656 } |
|
657 } |
|
658 } |
|
659 else |
|
660 { |
|
661 ret = iBaseView->IndexOfBookmarkL( aContactBookmark ); |
|
662 } |
|
663 |
|
664 return ret; |
|
665 } |
|
666 |
|
667 // -------------------------------------------------------------------------- |
|
668 // CPbk2PredictiveViewStack::ViewFiltering |
|
669 // -------------------------------------------------------------------------- |
|
670 // |
|
671 MVPbkContactViewFiltering* CPbk2PredictiveViewStack::ViewFiltering() |
|
672 { |
|
673 // The stack itself doesn't support filtering |
|
674 return NULL; |
|
675 } |
|
676 |
|
677 // -------------------------------------------------------------------------- |
|
678 // CPbk2PredictiveViewStack::ContactViewReady |
|
679 // -------------------------------------------------------------------------- |
|
680 // |
|
681 void CPbk2PredictiveViewStack::ContactViewReady( MVPbkContactViewBase& /*aView*/ ) |
|
682 { |
|
683 iViewReady = ETrue; |
|
684 SendBaseViewChangedEvent(); |
|
685 |
|
686 SendEventToObservers( *this, iViewObservers, |
|
687 &MVPbkContactViewObserver::ContactViewReady ); |
|
688 } |
|
689 |
|
690 // -------------------------------------------------------------------------- |
|
691 // CPbk2PredictiveViewStack::ContactViewUnavailable |
|
692 // -------------------------------------------------------------------------- |
|
693 // |
|
694 void CPbk2PredictiveViewStack::ContactViewUnavailable( |
|
695 MVPbkContactViewBase& /*aView*/ ) |
|
696 { |
|
697 iViewReady = EFalse; |
|
698 SendEventToObservers( *this, iViewObservers, |
|
699 &MVPbkContactViewObserver::ContactViewUnavailable ); |
|
700 } |
|
701 |
|
702 // -------------------------------------------------------------------------- |
|
703 // CPbk2PredictiveViewStack::ContactAddedToView |
|
704 // -------------------------------------------------------------------------- |
|
705 // |
|
706 void CPbk2PredictiveViewStack::ContactAddedToView |
|
707 ( MVPbkContactViewBase& aView, TInt aIndex, |
|
708 const MVPbkContactLink& aContactLink ) |
|
709 { |
|
710 // Reset since we need to return to base view |
|
711 // when a new contact is added |
|
712 Reset(); |
|
713 |
|
714 //Send observer events |
|
715 if ( iBaseView == &aView ) |
|
716 { |
|
717 SendEventToObservers( *this, iStackObservers, |
|
718 &MPbk2FilteredViewStackObserver::ContactAddedToBaseView, aIndex, |
|
719 aContactLink ); |
|
720 |
|
721 // Always forward only top view events to clients |
|
722 SendEventToObservers( *this, iViewObservers, |
|
723 &MVPbkContactViewObserver::ContactAddedToView, aIndex, |
|
724 aContactLink ); |
|
725 } |
|
726 } |
|
727 |
|
728 // -------------------------------------------------------------------------- |
|
729 // CPbk2PredictiveViewStack::ContactRemovedFromView |
|
730 // -------------------------------------------------------------------------- |
|
731 // |
|
732 void CPbk2PredictiveViewStack::ContactRemovedFromView |
|
733 ( MVPbkContactViewBase& aView, TInt aIndex, |
|
734 const MVPbkContactLink& aContactLink ) |
|
735 { |
|
736 TRAP_IGNORE ( HandleContactDeletionL( aView, aIndex,aContactLink ) ) |
|
737 |
|
738 //Send observer events |
|
739 if ( iBaseView == &aView ) |
|
740 { |
|
741 // Always forward top view events to clients |
|
742 SendEventToObservers( *this, iViewObservers, |
|
743 &MVPbkContactViewObserver::ContactRemovedFromView, aIndex, |
|
744 aContactLink ); |
|
745 } |
|
746 } |
|
747 |
|
748 // -------------------------------------------------------------------------- |
|
749 // CPbk2PredictiveViewStack::ContactViewError |
|
750 // -------------------------------------------------------------------------- |
|
751 // |
|
752 void CPbk2PredictiveViewStack::ContactViewError |
|
753 ( MVPbkContactViewBase& aView, TInt aError, TBool aErrorNotified ) |
|
754 { |
|
755 iViewReady = EFalse; |
|
756 //Send observer events |
|
757 if ( iBaseView == &aView ) |
|
758 { |
|
759 // Always forward only top view events to clients |
|
760 SendEventToObservers( *this, iViewObservers, |
|
761 &MVPbkContactViewObserver::ContactViewError, aError, |
|
762 aErrorNotified ); |
|
763 } |
|
764 } |
|
765 |
|
766 // -------------------------------------------------------------------------- |
|
767 // CPbk2PredictiveViewStack::HandlePsResultsUpdate |
|
768 // -------------------------------------------------------------------------- |
|
769 void CPbk2PredictiveViewStack::HandlePsResultsUpdate( |
|
770 RPointerArray<CPsClientData>& aSearchResults, |
|
771 RPointerArray<CPsPattern>& searchSeqs ) |
|
772 { |
|
773 //set the searched state to indicate that |
|
774 // predictive search view is now active |
|
775 iSearchedState = ETrue; |
|
776 |
|
777 // update pattern array |
|
778 TRAP_IGNORE( CreatePatternsL(searchSeqs) ); |
|
779 |
|
780 //Clean up the data stored during previous search |
|
781 iPredictiveSearchResultContactLinkArrray->ResetAndDestroy(); |
|
782 iTopContactPositionInfoArray.ResetAndDestroy(); |
|
783 |
|
784 //Calculate the search result indexes |
|
785 TRAPD( err, CalculateSearchResultIndexesL( aSearchResults ) ); |
|
786 if ( err != KErrNone ) |
|
787 { |
|
788 Reset(); |
|
789 } |
|
790 else |
|
791 { |
|
792 if ( !aSearchResults.Count() ) |
|
793 { |
|
794 TRAP_IGNORE( SendPSNoResultsEventL() ); |
|
795 } |
|
796 } |
|
797 |
|
798 SendTopViewChangedEvent( *this ); |
|
799 } |
|
800 |
|
801 // -------------------------------------------------------------------------- |
|
802 // CPbk2PredictiveViewStack::HandlePsError |
|
803 // -------------------------------------------------------------------------- |
|
804 void CPbk2PredictiveViewStack::HandlePsError( TInt /*aErrorCode*/ ) |
|
805 { |
|
806 Reset(); |
|
807 TRAP_IGNORE( InitializePCSEngineL() ); |
|
808 } |
|
809 |
|
810 // -------------------------------------------------------------------------- |
|
811 // CPbk2PredictiveViewStack::CachingStatus |
|
812 // -------------------------------------------------------------------------- |
|
813 void CPbk2PredictiveViewStack::CachingStatus( TCachingStatus& /*aStatus*/, |
|
814 TInt& /*aError*/) |
|
815 { |
|
816 } |
|
817 |
|
818 // -------------------------------------------------------------------------- |
|
819 // CPbk2PredictiveViewStack::RunL |
|
820 // -------------------------------------------------------------------------- |
|
821 // |
|
822 void CPbk2PredictiveViewStack::RunL() |
|
823 { |
|
824 PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING( |
|
825 "CPbk2PredictiveViewStack::RunL - IN")); |
|
826 |
|
827 if ( iViewReady ) |
|
828 { |
|
829 iViewObservers[0]->ContactViewReady( *this ); |
|
830 } |
|
831 |
|
832 PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING( |
|
833 "CPbk2PredictiveViewStack::RunL - OUT")); |
|
834 } |
|
835 |
|
836 // -------------------------------------------------------------------------- |
|
837 // CPbk2PredictiveViewStack::DoCancel |
|
838 // -------------------------------------------------------------------------- |
|
839 // |
|
840 void CPbk2PredictiveViewStack::DoCancel() |
|
841 { |
|
842 // Nothing to cancel |
|
843 } |
|
844 |
|
845 // -------------------------------------------------------------------------- |
|
846 // CPbk2PredictiveViewStack::RunError |
|
847 // -------------------------------------------------------------------------- |
|
848 // |
|
849 TInt CPbk2PredictiveViewStack::RunError( TInt aError ) |
|
850 { |
|
851 iViewObservers[0]->ContactViewError( *this, aError, ETrue ); |
|
852 return KErrNone; |
|
853 } |
|
854 |
|
855 // -------------------------------------------------------------------------- |
|
856 // CPbk2PredictiveViewStack::CalculateSearchResultIndexesL |
|
857 // -------------------------------------------------------------------------- |
|
858 void CPbk2PredictiveViewStack::CalculateSearchResultIndexesL( |
|
859 RPointerArray<CPsClientData>& aSearchResults ) |
|
860 { |
|
861 __ASSERT_ALWAYS( iTopContactManager, User::Leave( KErrGeneral ) ); |
|
862 |
|
863 //Holds the Matched Char Seq of the First Item in the |
|
864 //Nameslist View w.r.t the initiated Predictive Search |
|
865 TBuf<KSearchFieldLength> matchSeqChr; |
|
866 |
|
867 CVPbkContactManager& cntManager = Phonebook2::Pbk2AppUi()-> |
|
868 ApplicationServices().ContactManager(); |
|
869 |
|
870 const TInt resultCount = aSearchResults.Count(); |
|
871 for( TInt n = 0 ; n < resultCount ; ++n ) |
|
872 { |
|
873 // Store the view index of search results |
|
874 CPsClientData* result = aSearchResults[n]; |
|
875 MVPbkContactLink* contactLink = iPsHandler->ConvertToVpbkLinkLC(*result,cntManager); |
|
876 |
|
877 //Get the index in the base view |
|
878 // We need to check if base view contains this contact |
|
879 TInt posInBaseView = iBaseView->IndexOfLinkL( *contactLink ); |
|
880 if ( posInBaseView != KErrNotFound ) |
|
881 { |
|
882 const MVPbkViewContact& contact = iBaseView->ContactAtL( posInBaseView ); |
|
883 TBuf< KPsQueryMaxLen > result; |
|
884 iSearchFilter.LookupL( contact, *this, iNameformatter, result ); |
|
885 |
|
886 if( result.Length() <= 0 ) |
|
887 { |
|
888 CleanupStack::Pop(); //contactLink |
|
889 continue; |
|
890 } |
|
891 |
|
892 TBool topcontact = iTopContactManager->IsTopContact( contact ); |
|
893 if ( topcontact ) |
|
894 { |
|
895 // ownership of contactLink is transfered, CPbk2TopContactPositionInfo |
|
896 // also keeps the contactLink' position from iBaseView |
|
897 CPbk2ContactPositionInfo* topContactPosInfo = |
|
898 CPbk2ContactPositionInfo::NewLC( contactLink, posInBaseView ); |
|
899 |
|
900 iTopContactPositionInfoArray.AppendL( topContactPosInfo ); |
|
901 CleanupStack::Pop( topContactPosInfo ); |
|
902 } |
|
903 else |
|
904 { |
|
905 iPredictiveSearchResultContactLinkArrray->AppendL( contactLink ); |
|
906 } |
|
907 CleanupStack::Pop(); //contactLink |
|
908 } |
|
909 else |
|
910 { |
|
911 CleanupStack::PopAndDestroy(); //contactLink |
|
912 } |
|
913 } |
|
914 |
|
915 iNonMatchedMarkedContactStartIndex = KErrNotFound; |
|
916 iNonMatchedMarkedContactEndIndex = KErrNotFound; |
|
917 |
|
918 //save marked contacts info to iMarkedContactsPositionInfoArray |
|
919 if ( iBookMarkCollection ) |
|
920 { |
|
921 SaveBookmarkContatsInfoL(); |
|
922 SortbyPositionInMainView( iMarkedContactsPositionInfoArray ); |
|
923 iNonMatchedMarkedContactStartIndex = 0; |
|
924 iNonMatchedMarkedContactEndIndex = iMarkedContactsPositionInfoArray.Count() - 1; |
|
925 MoveArrayToSearchedResultTopL( iMarkedContactsPositionInfoArray ); |
|
926 } |
|
927 |
|
928 // add those top contacts to top of the iPredictiveSearchResultContactLinkArrray, |
|
929 // the order follows top contact orders in name list |
|
930 SortbyPositionInMainView( iTopContactPositionInfoArray ); |
|
931 if ( iNonMatchedMarkedContactStartIndex != KErrNotFound ) |
|
932 { |
|
933 iNonMatchedMarkedContactStartIndex += iTopContactPositionInfoArray.Count(); |
|
934 iNonMatchedMarkedContactEndIndex += iTopContactPositionInfoArray.Count(); |
|
935 } |
|
936 MoveArrayToSearchedResultTopL( iTopContactPositionInfoArray ); |
|
937 } |
|
938 |
|
939 // -------------------------------------------------------------------------- |
|
940 // CPbk2PredictiveViewStack::InitializePCSEngineL |
|
941 // -------------------------------------------------------------------------- |
|
942 void CPbk2PredictiveViewStack::InitializePCSEngineL() |
|
943 { |
|
944 if(iPsHandler) |
|
945 { |
|
946 delete iPsHandler; |
|
947 iPsHandler = NULL; |
|
948 } |
|
949 // Create async request handle for predictive search engine |
|
950 iPsHandler = CPSRequestHandler::NewL(); |
|
951 iPsHandler->AddObserverL( this ); |
|
952 |
|
953 // If the iCurrentGroupLink is set, then no need to re-do the settings.It is already done. |
|
954 if(iCurrentGroupLink) |
|
955 { |
|
956 return; |
|
957 } |
|
958 |
|
959 RPointerArray<TDesC> databases; |
|
960 if ( iBaseView->MatchContactStore( VPbkContactStoreUris::SimGlobalFdnUri() ) ) |
|
961 { |
|
962 //FDN view, initialize PS with FDN contacts only |
|
963 databases.AppendL(VPbkContactStoreUris::SimGlobalFdnUri().AllocL()); |
|
964 } |
|
965 else |
|
966 { |
|
967 CPbk2StoreConfiguration& config = Phonebook2::Pbk2AppUi()->ApplicationServices().StoreConfiguration(); |
|
968 CVPbkContactStoreUriArray* stores = config.SearchStoreConfigurationL(); |
|
969 CleanupStack::PushL(stores); |
|
970 TInt count = stores->Count(); |
|
971 for ( TInt i = 0; i < count; ++i) |
|
972 { |
|
973 TVPbkContactStoreUriPtr uriPtr = stores->operator[](i); |
|
974 databases.AppendL(uriPtr.UriDes().AllocL()); |
|
975 } |
|
976 CleanupStack::PopAndDestroy(); //stores |
|
977 } |
|
978 |
|
979 |
|
980 SetPsSettingL(databases); |
|
981 |
|
982 databases.ResetAndDestroy(); |
|
983 |
|
984 } |
|
985 |
|
986 // -------------------------------------------------------------------------- |
|
987 // Maps from the search subset position index to base view index. |
|
988 // @param aSearchResultIndex Index within scope of search result set. |
|
989 // @return Index of the contact in base view. |
|
990 // -------------------------------------------------------------------------- |
|
991 TInt CPbk2PredictiveViewStack::BaseViewIndex( TInt aSearchResultIndex ) const |
|
992 { |
|
993 // If search is not active, the argument is actually already a base view index. |
|
994 TInt index = aSearchResultIndex; |
|
995 if ( iSearchedState ) |
|
996 { |
|
997 TRAP_IGNORE( index = |
|
998 iBaseView->IndexOfLinkL( |
|
999 iPredictiveSearchResultContactLinkArrray->At( aSearchResultIndex ) ) ); |
|
1000 } |
|
1001 |
|
1002 return index; |
|
1003 } |
|
1004 |
|
1005 // -------------------------------------------------------------------------- |
|
1006 // CPbk2PredictiveViewStack::HandleContactDeletionL |
|
1007 // -------------------------------------------------------------------------- |
|
1008 void CPbk2PredictiveViewStack::HandleContactDeletionL( MVPbkContactViewBase& /*aView*/, |
|
1009 TInt /*aIndex*/, const MVPbkContactLink& aContactLink ) |
|
1010 { |
|
1011 |
|
1012 TInt removedContactPos = iPredictiveSearchResultContactLinkArrray->Find(aContactLink); |
|
1013 if(removedContactPos != KErrNotFound) |
|
1014 { |
|
1015 //Remove the link from iPredictiveSearchResultContactLinkArrray |
|
1016 iPredictiveSearchResultContactLinkArrray->Remove(removedContactPos); |
|
1017 } |
|
1018 |
|
1019 if (iPredictiveSearchResultContactLinkArrray->Count() == 0) |
|
1020 { |
|
1021 //clear patterns collection |
|
1022 iPatternsCollection.ResetAndDestroy(); |
|
1023 // back to name list view |
|
1024 iSearchFilter.FindPaneResetL(); |
|
1025 // Reset() must be called after iSearchFilter.FindPaneResetL() |
|
1026 // as it will make some judgment by the content of FindBox. |
|
1027 Reset(); |
|
1028 } |
|
1029 |
|
1030 } |
|
1031 |
|
1032 // -------------------------------------------------------------------------- |
|
1033 // CPbk2PredictiveViewStack::SendTopViewChangedEvent |
|
1034 // -------------------------------------------------------------------------- |
|
1035 void CPbk2PredictiveViewStack::SendTopViewChangedEvent |
|
1036 ( MVPbkContactViewBase& aOldTopView ) |
|
1037 { |
|
1038 const TInt count = iStackObservers.Count(); |
|
1039 for ( TInt i = count - 1; i >= 0; --i ) |
|
1040 { |
|
1041 TRAPD( res, iStackObservers[i]->TopViewChangedL( aOldTopView ) ); |
|
1042 if ( res != KErrNone ) |
|
1043 { |
|
1044 PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING |
|
1045 ("CPbk2FilteredViewStack::SendTopViewChangedEvent:error %d"), |
|
1046 res ); |
|
1047 iStackObservers[i]->ViewStackError( res ); |
|
1048 } |
|
1049 } |
|
1050 } |
|
1051 |
|
1052 // -------------------------------------------------------------------------- |
|
1053 // CPbk2FilteredViewStack::SendTopViewUpdatedEvent |
|
1054 // -------------------------------------------------------------------------- |
|
1055 // |
|
1056 void CPbk2PredictiveViewStack::SendTopViewUpdatedEvent() |
|
1057 { |
|
1058 const TInt count = iStackObservers.Count(); |
|
1059 for ( TInt i = count - 1; i >= 0; --i ) |
|
1060 { |
|
1061 TRAPD( res, iStackObservers[i]->TopViewUpdatedL() ); |
|
1062 if ( res != KErrNone ) |
|
1063 { |
|
1064 PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING |
|
1065 ("CPbk2FilteredViewStack::SendTopViewUpdatedEvent:error %d"), |
|
1066 res ); |
|
1067 iStackObservers[i]->ViewStackError( res ); |
|
1068 } |
|
1069 } |
|
1070 } |
|
1071 |
|
1072 // -------------------------------------------------------------------------- |
|
1073 // CPbk2FilteredViewStack::SendBaseViewChangedEvent |
|
1074 // -------------------------------------------------------------------------- |
|
1075 // |
|
1076 void CPbk2PredictiveViewStack::SendBaseViewChangedEvent() |
|
1077 { |
|
1078 const TInt count = iStackObservers.Count(); |
|
1079 for ( TInt i = count - 1; i >= 0; --i ) |
|
1080 { |
|
1081 TRAPD( res, iStackObservers[i]->BaseViewChangedL() ); |
|
1082 if ( res != KErrNone ) |
|
1083 { |
|
1084 PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING |
|
1085 ("CPbk2FilteredViewStack::SendBaseViewChangedEvent:error %d"), |
|
1086 res ); |
|
1087 iStackObservers[i]->ViewStackError( res ); |
|
1088 } |
|
1089 } |
|
1090 } |
|
1091 |
|
1092 |
|
1093 // --------------------------------------------------------------------------- |
|
1094 // CPbk2PredictiveViewStack::LastPCSQuery |
|
1095 // --------------------------------------------------------------------------- |
|
1096 const CPsQuery* CPbk2PredictiveViewStack::LastPCSQuery() const |
|
1097 { |
|
1098 return iSearchedState?iPsQuery:NULL; |
|
1099 } |
|
1100 |
|
1101 |
|
1102 // --------------------------------------------------------------------------- |
|
1103 // CPbk2PredictiveViewStack::PSHandler |
|
1104 // --------------------------------------------------------------------------- |
|
1105 CPSRequestHandler* CPbk2PredictiveViewStack::PSHandler() const |
|
1106 { |
|
1107 return iPsHandler; |
|
1108 } |
|
1109 |
|
1110 // --------------------------------------------------------------------------- |
|
1111 // CPbk2PredictiveViewStack::CreatePatternsL() |
|
1112 // --------------------------------------------------------------------------- |
|
1113 void CPbk2PredictiveViewStack::CreatePatternsL(RPointerArray<CPsPattern>& searchSeqs) |
|
1114 { |
|
1115 iPatternsCollection.ResetAndDestroy(); |
|
1116 iBidiPatterns.ResetAndDestroy(); |
|
1117 TBidirectionalState::TRunInfo* runInfoArray = new (ELeave)TBidirectionalState::TRunInfo[4]; |
|
1118 |
|
1119 for (TInt i = 0; i < searchSeqs.Count(); i++) |
|
1120 { |
|
1121 //create standard pattern |
|
1122 TInt nIndex = searchSeqs[i]->FirstIndex(); |
|
1123 TDesC& patternText = searchSeqs[i]->Pattern(); |
|
1124 CPsPattern* pattern = CPsPattern::NewL(); |
|
1125 iPatternsCollection.Append(pattern); |
|
1126 pattern->SetFirstIndex( nIndex ); |
|
1127 pattern->SetPatternL( patternText ); |
|
1128 |
|
1129 //create bidirectional pattern |
|
1130 HBufC* bidiPattern = HBufC::NewLC( patternText.Length() + TBidiLogicalToVisual::KMinCharAvailable ); |
|
1131 TPtr tmpPtr2 = bidiPattern->Des(); |
|
1132 TBidiLogicalToVisual converter2( patternText, runInfoArray, /*runInfoArrayMaxLength*/4 ) ; |
|
1133 converter2.Reorder(); |
|
1134 converter2.GetVisualLine( tmpPtr2, 0, patternText.Length(), TChar(0xffff) ); |
|
1135 iBidiPatterns.Append( bidiPattern ); |
|
1136 CleanupStack::Pop( bidiPattern ); |
|
1137 } |
|
1138 delete runInfoArray; |
|
1139 } |
|
1140 |
|
1141 // --------------------------------------------------------------------------- |
|
1142 // CPbk2PredictiveViewStack::GetMatchingPartsL() |
|
1143 // Main assumption to use this method only for bidirectional |
|
1144 // languages and patterns |
|
1145 // --------------------------------------------------------------------------- |
|
1146 void CPbk2PredictiveViewStack::GetMatchingPartsL( const TDesC& aSearchData, |
|
1147 RArray<TPsMatchLocation>& aMatchLocation) const |
|
1148 { |
|
1149 // If list of mathes empty just return |
|
1150 if ( iPatternsCollection.Count() == 0 ) |
|
1151 { |
|
1152 return; |
|
1153 } |
|
1154 //This method is implemented for bidirectional languages only |
|
1155 RBuf parserText; |
|
1156 parserText.CreateL(aSearchData); |
|
1157 parserText.CleanupClosePushL(); |
|
1158 TLex lexParser(parserText); |
|
1159 TPtrC ptr; |
|
1160 //parse for all words in contact information |
|
1161 TInt currentPos = 0; |
|
1162 lexParser.SkipSpace(); |
|
1163 currentPos = lexParser.Offset(); |
|
1164 for (ptr.Set(lexParser.NextToken()); ptr.Length(); ptr.Set(lexParser.NextToken()) ) |
|
1165 { |
|
1166 //loop by all patterns |
|
1167 for (TInt j = iBidiPatterns.Count() - 1; j >= 0; j--) |
|
1168 { |
|
1169 HBufC* pattern = iBidiPatterns[j]; |
|
1170 TInt pos = ptr.Find(pattern->Des()); |
|
1171 if ( pos != KErrNotFound) |
|
1172 { |
|
1173 //check if pattern is in th end of the string |
|
1174 if ( (pos + pattern->Length()) == ptr.Length() ) |
|
1175 { |
|
1176 // add math to output array |
|
1177 TPsMatchLocation location; |
|
1178 location.index = currentPos + pos; |
|
1179 location.length = pattern->Length(); |
|
1180 location.direction = TBidiText::ELeftToRight; |
|
1181 aMatchLocation.Append(location); |
|
1182 break; |
|
1183 } |
|
1184 } |
|
1185 } |
|
1186 lexParser.SkipSpace(); |
|
1187 currentPos = lexParser.Offset(); |
|
1188 } |
|
1189 CleanupStack::PopAndDestroy();//parserText |
|
1190 } |
|
1191 |
|
1192 // -------------------------------------------------------------------------- |
|
1193 // CPbk2PredictiveViewStack::SetCurrentGroupLinkL |
|
1194 // -------------------------------------------------------------------------- |
|
1195 // |
|
1196 void CPbk2PredictiveViewStack::SetCurrentGroupLinkL( MVPbkContactLink* aGroupLinktoSet) |
|
1197 { |
|
1198 |
|
1199 //Create contactid converter instance for default store if not already exists |
|
1200 if(!iConverterDefaultStore) |
|
1201 { |
|
1202 CVPbkContactManager& manager = Phonebook2::Pbk2AppUi()-> |
|
1203 ApplicationServices().ContactManager(); |
|
1204 MVPbkContactStore* defaultStore = manager.ContactStoresL().Find( |
|
1205 VPbkContactStoreUris::DefaultCntDbUri() ); |
|
1206 __ASSERT_DEBUG( defaultStore, User::Panic(_L("Pbk2 vstack"), 52)); |
|
1207 |
|
1208 iConverterDefaultStore = CVPbkContactIdConverter::NewL( *defaultStore ); |
|
1209 } |
|
1210 //Delete the existing group link |
|
1211 if(iCurrentGroupLink) |
|
1212 { |
|
1213 delete iCurrentGroupLink; |
|
1214 iCurrentGroupLink = NULL; |
|
1215 } |
|
1216 |
|
1217 |
|
1218 iCurrentGroupLink = aGroupLinktoSet->CloneLC(); |
|
1219 CleanupStack::Pop(); |
|
1220 |
|
1221 if(iCurrentGroupLink) |
|
1222 { |
|
1223 RPointerArray<TDesC> databases; |
|
1224 RBuf storeUrl; |
|
1225 //CleanupResetAndDestroyPushL( databases ); |
|
1226 // Set max size for group URI |
|
1227 TInt32 maxLength = sizeof(TInt32) + KVPbkDefaultGrpDbURI().Size() + |
|
1228 KPsGroupDBSuffix().Size() + 2; |
|
1229 storeUrl.CreateL(KVPbkDefaultGrpDbURI(), maxLength); |
|
1230 storeUrl.CleanupClosePushL(); |
|
1231 |
|
1232 //get group id and create the url to be passed to ps engine |
|
1233 TInt32 id = iConverterDefaultStore->LinkToIdentifier(*iCurrentGroupLink); |
|
1234 storeUrl.AppendFormat(KPsGroupDBSuffix, NULL, id); |
|
1235 databases.AppendL(storeUrl.AllocL()); |
|
1236 CleanupStack::PopAndDestroy(&storeUrl); |
|
1237 |
|
1238 // Perform the search settings |
|
1239 SetPsSettingL(databases); |
|
1240 |
|
1241 databases.ResetAndDestroy(); |
|
1242 } |
|
1243 |
|
1244 } |
|
1245 |
|
1246 // -------------------------------------------------------------------------- |
|
1247 // CPbk2PredictiveViewStack::SetPsSettingL |
|
1248 // -------------------------------------------------------------------------- |
|
1249 // |
|
1250 void CPbk2PredictiveViewStack::SetPsSettingL( RPointerArray<TDesC>& aDatabases) |
|
1251 { |
|
1252 // Perform search settings |
|
1253 CPsSettings* psSettings = CPsSettings::NewL(); |
|
1254 CleanupStack::PushL( psSettings ); |
|
1255 psSettings->SetSearchUrisL(aDatabases); |
|
1256 |
|
1257 RArray<TInt> displayFields; |
|
1258 displayFields.AppendL(R_VPBK_FIELD_TYPE_FIRSTNAME); // Firstname |
|
1259 displayFields.AppendL(R_VPBK_FIELD_TYPE_LASTNAME); // Lastname |
|
1260 displayFields.AppendL(R_VPBK_FIELD_TYPE_COMPANYNAME);// Companyname |
|
1261 |
|
1262 psSettings->SetDisplayFieldsL(displayFields); |
|
1263 |
|
1264 iPsHandler->SetSearchSettingsL(*psSettings); |
|
1265 |
|
1266 //Clean up |
|
1267 CleanupStack::PopAndDestroy(psSettings); |
|
1268 displayFields.Close(); |
|
1269 } |
|
1270 |
|
1271 // -------------------------------------------------------------------------- |
|
1272 // CPbk2PredictiveViewStack::SaveBookmarkContatsInfoL |
|
1273 // -------------------------------------------------------------------------- |
|
1274 // |
|
1275 void CPbk2PredictiveViewStack::SaveBookmarkContatsInfoL() |
|
1276 { |
|
1277 TInt count = iBookMarkCollection->Count(); |
|
1278 |
|
1279 for ( TInt i = count-1; i >= 0; i-- ) |
|
1280 { |
|
1281 const MVPbkContactBookmark& contactBookmark = |
|
1282 iBookMarkCollection->At( i ); |
|
1283 TInt indexInBaseView = iBaseView->IndexOfBookmarkL( contactBookmark ); |
|
1284 |
|
1285 if ( indexInBaseView != KErrNotFound ) |
|
1286 { |
|
1287 MVPbkContactLink* link = iBaseView->CreateLinkLC( indexInBaseView ); |
|
1288 |
|
1289 // find from Searched result |
|
1290 TInt indexInSearchedResult = iPredictiveSearchResultContactLinkArrray->Find( *link ); |
|
1291 |
|
1292 TInt matchingTopContactIndex = MatchingTopContactFind( indexInBaseView ); |
|
1293 |
|
1294 if ( indexInSearchedResult == KErrNotFound && |
|
1295 matchingTopContactIndex == KErrNotFound ) |
|
1296 { |
|
1297 const MVPbkViewContact& contact = iBaseView->ContactAtL( indexInBaseView ); |
|
1298 |
|
1299 CPbk2ContactPositionInfo* positionInfo = CPbk2ContactPositionInfo::NewLC( link, indexInBaseView ); |
|
1300 CleanupStack::Pop( positionInfo ); |
|
1301 CleanupStack::Pop(); // link |
|
1302 CleanupStack::PushL( positionInfo ); |
|
1303 |
|
1304 // non matching marked top contacts |
|
1305 if ( iTopContactManager->IsTopContact( contact ) ) |
|
1306 { |
|
1307 iTopContactPositionInfoArray.AppendL( positionInfo ); |
|
1308 } |
|
1309 else |
|
1310 { |
|
1311 // non matching marked contacts(non top) |
|
1312 iMarkedContactsPositionInfoArray.AppendL( positionInfo ); |
|
1313 } |
|
1314 |
|
1315 CleanupStack::Pop( positionInfo ); |
|
1316 } |
|
1317 else |
|
1318 { |
|
1319 CleanupStack::PopAndDestroy(); // link |
|
1320 } |
|
1321 } |
|
1322 } |
|
1323 } |
|
1324 |
|
1325 // -------------------------------------------------------------------------- |
|
1326 // CPbk2PredictiveViewStack::MoveArrayToSearchedResultTopL |
|
1327 // -------------------------------------------------------------------------- |
|
1328 // |
|
1329 void CPbk2PredictiveViewStack::MoveArrayToSearchedResultTopL( |
|
1330 RPointerArray<CPbk2ContactPositionInfo>& aContactInfoArray ) |
|
1331 { |
|
1332 TInt posZero = 0; |
|
1333 TInt count = aContactInfoArray.Count(); |
|
1334 |
|
1335 for( TInt i = count-1; i >=0; i-- ) |
|
1336 { |
|
1337 CPbk2ContactPositionInfo* positionInfo = aContactInfoArray[ i ]; |
|
1338 |
|
1339 // ownership of contactLink is transferred |
|
1340 MVPbkContactLink* contactLink = positionInfo->ContactLink(); |
|
1341 CleanupStack::PushL( contactLink ); |
|
1342 // always insert to the top of iPredictiveSearchResultContactLinkArrray |
|
1343 iPredictiveSearchResultContactLinkArrray->InsertL( contactLink, posZero ); |
|
1344 CleanupStack::Pop( contactLink ); |
|
1345 // remove positionInfo from iTopContactPositionInfoArray |
|
1346 aContactInfoArray.Remove( i ); |
|
1347 delete positionInfo; |
|
1348 } |
|
1349 } |
|
1350 |
|
1351 // -------------------------------------------------------------------------- |
|
1352 // CPbk2PredictiveViewStack::MatchingTopContactFind |
|
1353 // -------------------------------------------------------------------------- |
|
1354 // |
|
1355 TInt CPbk2PredictiveViewStack::MatchingTopContactFind( const TInt aIndexInBaseView ) |
|
1356 { |
|
1357 TInt ret = KErrNotFound; |
|
1358 |
|
1359 TInt topContactCount = iTopContactPositionInfoArray.Count(); |
|
1360 for( TInt i = 0; i < topContactCount && ret == KErrNotFound; i++ ) |
|
1361 { |
|
1362 CPbk2ContactPositionInfo* topContactPositionInfo = |
|
1363 iTopContactPositionInfoArray[i]; |
|
1364 |
|
1365 if ( aIndexInBaseView == topContactPositionInfo->Position() ) |
|
1366 { |
|
1367 ret = i; |
|
1368 } |
|
1369 } |
|
1370 return ret; |
|
1371 } |
|
1372 |
|
1373 // -------------------------------------------------------------------------- |
|
1374 // CPbk2PredictiveViewStack::SortbyPositionInMainView |
|
1375 // -------------------------------------------------------------------------- |
|
1376 // |
|
1377 void CPbk2PredictiveViewStack::SortbyPositionInMainView( |
|
1378 RPointerArray<CPbk2ContactPositionInfo>& aContactInfoArray ) |
|
1379 { |
|
1380 TLinearOrder< CPbk2ContactPositionInfo > |
|
1381 position( *CPbk2ContactPositionInfo::CompareByPosition ); |
|
1382 aContactInfoArray.Sort( position ); |
|
1383 } |
|
1384 |
|
1385 // -------------------------------------------------------------------------- |
|
1386 // CPbk2FilteredViewStack::SendPSNoResultsEventL |
|
1387 // -------------------------------------------------------------------------- |
|
1388 // |
|
1389 void CPbk2PredictiveViewStack::SendPSNoResultsEventL() |
|
1390 { |
|
1391 CPsQuery* lastQuery = const_cast<CPsQuery*> (LastPCSQuery()); |
|
1392 if ( lastQuery ) |
|
1393 { |
|
1394 TDesC& strQuery = lastQuery->QueryAsStringLC(); |
|
1395 //Send the matched char Sequence of the first item |
|
1396 //to the Search Pane filter |
|
1397 iSearchFilter.HandlePSNoMatchL( strQuery, KNullDesC ); |
|
1398 CleanupStack::PopAndDestroy(); // QueryAsStringLC |
|
1399 } |
|
1400 } |
|
1401 |
|
1402 // -------------------------------------------------------------------------- |
|
1403 // CPbk2FilteredViewStack::IsNonMatchingMarkedContact |
|
1404 // -------------------------------------------------------------------------- |
|
1405 // |
|
1406 TBool CPbk2PredictiveViewStack::IsNonMatchingMarkedContact( const TInt aIndex ) |
|
1407 { |
|
1408 TBool ret = EFalse; |
|
1409 |
|
1410 if ( aIndex >= iNonMatchedMarkedContactStartIndex && |
|
1411 aIndex <= iNonMatchedMarkedContactEndIndex ) |
|
1412 { |
|
1413 ret = ETrue; |
|
1414 } |
|
1415 return ret; |
|
1416 } |
|
1417 |
|
1418 // End of File |