phonebookui/Phonebook2/UIControls/src/cpbk2predictiveviewstack.cpp
changeset 0 e686773b3f54
child 12 5072fb0f5b46
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     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