phonebookengines/VirtualPhonebook/VPbkSimStore/src/CFindViewBase.cpp
changeset 0 e686773b3f54
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2002-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:  Sim store filtered contact view implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CFindViewBase.h"
       
    20 
       
    21 #include "CRefineView.h"
       
    22 #include "CContactStore.h"
       
    23 #include "CContactLink.h"
       
    24 #include "CContactView.h"
       
    25 #include "CViewContact.h"
       
    26 
       
    27 // Virtual Phonebook
       
    28 #include <VPbkError.h>
       
    29 #include <MVPbkSimContact.h>
       
    30 #include <CVPbkSimContact.h>
       
    31 #include <CVPbkSimCntField.h>
       
    32 #include <MVPbkSimStoreOperation.h>
       
    33 #include <CVPbkAsyncCallback.h>
       
    34 #include <CVPbkFieldTypeRefsList.h>
       
    35 #include <CVPbkContactFieldIterator.h>
       
    36 #include <MVPbkContactNameConstructionPolicy.h>
       
    37 #include <MVPbkContactFindPolicy.h>
       
    38 #include <VPbkSendEventUtility.h>
       
    39 
       
    40 // System includes
       
    41 #include <cntviewbase.h>
       
    42 #include <featmgr.h>
       
    43 
       
    44 namespace VPbkSimStore {
       
    45 
       
    46 #ifdef _DEBUG
       
    47 enum TCFindViewBasePanicCode
       
    48     {
       
    49     EPreCond_SetFindStringsL = 1    
       
    50     };
       
    51 
       
    52 void Panic( TCFindViewBasePanicCode aPanicCode )
       
    53     {
       
    54     _LIT( KPanicText, "CFindViewBase" );
       
    55     User::Panic( KPanicText, aPanicCode );
       
    56     }
       
    57 #endif // _DEBUG
       
    58 
       
    59 const TInt KGranularity( 4 );
       
    60 
       
    61 // --------------------------------------------------------------------------
       
    62 // CFindViewBase::CFindViewBase
       
    63 // --------------------------------------------------------------------------
       
    64 //
       
    65 CFindViewBase::CFindViewBase( MParentViewForFiltering& aParentView,
       
    66         CContactView& aAllContactsView,
       
    67         TBool aOwnsMatchedContacts ) 
       
    68         :   iParentView( aParentView ),
       
    69             iAllContactsView( aAllContactsView ),
       
    70             iOwnsContacts( aOwnsMatchedContacts )
       
    71     {
       
    72     }
       
    73 
       
    74 // --------------------------------------------------------------------------
       
    75 // CFindViewBase::BaseConstructL
       
    76 // --------------------------------------------------------------------------
       
    77 //
       
    78 void CFindViewBase::BaseConstructL( 
       
    79         MVPbkContactViewObserver& aExternalViewObserver,
       
    80         const MDesCArray& aFindStrings,
       
    81         MVPbkContactFindPolicy& aFindPolicy )
       
    82     {                        
       
    83     iObserverOp = 
       
    84         CVPbkAsyncObjectOperation<MVPbkContactViewObserver>::NewL();
       
    85     iFilterObsOp = 
       
    86         CVPbkAsyncObjectOperation<MFilteredViewSupportObserver>::NewL();
       
    87     
       
    88     // Copy find words
       
    89     iFindStrings = new(ELeave)CDesCArrayFlat( KGranularity );
       
    90     SetFindStringsL( aFindStrings );
       
    91     
       
    92     iCurrentContact = CViewContact::NewL( iAllContactsView, SortOrder() );
       
    93     
       
    94     // Assign contact find policy
       
    95     iContactFindPolicy = &aFindPolicy;
       
    96     
       
    97     //Create field type list
       
    98     iFieldTypeRefsList = CVPbkFieldTypeRefsList::NewL();
       
    99     
       
   100     // Append the observer who created the view. Events must be always send
       
   101     // to this observer first.
       
   102     iObservers.AppendL( &aExternalViewObserver );
       
   103     }
       
   104 
       
   105 // --------------------------------------------------------------------------
       
   106 // CFindViewBase::~CFindViewBase
       
   107 // --------------------------------------------------------------------------
       
   108 //
       
   109 CFindViewBase::~CFindViewBase()
       
   110     {   
       
   111     delete iObserverOp;
       
   112     delete iFilterObsOp;
       
   113     iObservers.Close();
       
   114     iFilteringObservers.Close();
       
   115     ResetContacts();
       
   116     delete iCurrentContact;
       
   117     delete iFindStrings;
       
   118     delete iFieldTypeRefsList;
       
   119     iParentView.RemoveFilteringObserver( *this );
       
   120     }
       
   121 
       
   122 // --------------------------------------------------------------------------
       
   123 // CFindViewBase::ActivateContactMatchL
       
   124 // --------------------------------------------------------------------------
       
   125 //
       
   126 void CFindViewBase::ActivateContactMatchL()
       
   127     {
       
   128     // If used from update then we must renew the observing
       
   129     iParentView.RemoveFilteringObserver( *this );
       
   130     // Get the state of the parent view asynchrnounsly
       
   131     iParentView.AddFilteringObserverL( *this );
       
   132     }
       
   133     
       
   134 // --------------------------------------------------------------------------
       
   135 // CFindViewBase::ParentObject
       
   136 // --------------------------------------------------------------------------
       
   137 //    
       
   138 MVPbkObjectHierarchy& CFindViewBase::ParentObject() const
       
   139     {
       
   140     return iParentView.ParentObject();
       
   141     }
       
   142 
       
   143 // --------------------------------------------------------------------------
       
   144 // CFindViewBase::RefreshL
       
   145 // --------------------------------------------------------------------------
       
   146 //    
       
   147 void CFindViewBase::RefreshL()
       
   148     {
       
   149     iParentView.RefreshL();
       
   150     }
       
   151 
       
   152 // --------------------------------------------------------------------------
       
   153 // CFindViewBase::ContactCountL
       
   154 // --------------------------------------------------------------------------
       
   155 //
       
   156 TInt CFindViewBase::ContactCountL() const
       
   157     {    
       
   158     return iMatchedContacts.Count();
       
   159     }
       
   160 
       
   161 // --------------------------------------------------------------------------
       
   162 // CFindViewBase::ContactAtL
       
   163 // --------------------------------------------------------------------------
       
   164 //
       
   165 const MVPbkViewContact& CFindViewBase::ContactAtL( 
       
   166         TInt aIndex ) const
       
   167     {    
       
   168     __ASSERT_ALWAYS( aIndex >= 0, 
       
   169         VPbkError::Panic( VPbkError::EInvalidContactIndex ) );
       
   170     if ( aIndex >= iMatchedContacts.Count() )
       
   171         {
       
   172         User::Leave( KErrArgument );
       
   173         }
       
   174 
       
   175     iCurrentContact->SetSimContactL( *iMatchedContacts[ aIndex ] );
       
   176     return *iCurrentContact;     
       
   177     }    
       
   178 
       
   179 // --------------------------------------------------------------------------
       
   180 // CFindViewBase::CreateLinkLC
       
   181 // --------------------------------------------------------------------------
       
   182 //
       
   183 MVPbkContactLink* CFindViewBase::CreateLinkLC(
       
   184         TInt aIndex ) const
       
   185     {
       
   186     __ASSERT_ALWAYS( aIndex >= 0, 
       
   187         VPbkError::Panic(VPbkError::EInvalidContactIndex) );
       
   188     if ( aIndex >= iMatchedContacts.Count() )
       
   189         {
       
   190         User::Leave( KErrArgument );
       
   191         }
       
   192         
       
   193     TInt simIndex = iMatchedContacts[aIndex]->SimIndex();
       
   194     return CContactLink::NewLC( iAllContactsView.Store(), simIndex );
       
   195     }
       
   196 
       
   197 // --------------------------------------------------------------------------
       
   198 // CFindViewBase::IndexOfLinkL
       
   199 // --------------------------------------------------------------------------
       
   200 //    
       
   201 TInt CFindViewBase::IndexOfLinkL(
       
   202         const MVPbkContactLink& aContactLink ) const
       
   203     {
       
   204     if ( &aContactLink.ContactStore() == &iAllContactsView.Store() )
       
   205         {
       
   206         TInt simIndex = 
       
   207             static_cast<const CContactLink&>( aContactLink ).SimIndex();
       
   208                     
       
   209         const TInt count( iMatchedContacts.Count() );
       
   210         for ( TInt i(0); i < count; ++i )
       
   211             {
       
   212             if ( iMatchedContacts[i]->SimIndex() == simIndex )
       
   213                 {
       
   214                 return i;
       
   215                 }
       
   216             }
       
   217         }
       
   218     return KErrNotFound;
       
   219     }
       
   220 
       
   221 // --------------------------------------------------------------------------
       
   222 // CFindViewBase::Type
       
   223 // --------------------------------------------------------------------------
       
   224 //    
       
   225 TVPbkContactViewType CFindViewBase::Type() const
       
   226     {
       
   227     return iParentView.Type();
       
   228     }
       
   229 
       
   230 // --------------------------------------------------------------------------
       
   231 // CFindViewBase::ChangeSortOrderL
       
   232 // --------------------------------------------------------------------------
       
   233 //    
       
   234 void CFindViewBase::ChangeSortOrderL(
       
   235         const MVPbkFieldTypeList& aSortOrder )
       
   236     {
       
   237     iParentView.ChangeSortOrderL( aSortOrder );
       
   238     }
       
   239 
       
   240 // --------------------------------------------------------------------------
       
   241 // CFindViewBase::SortOrder
       
   242 // --------------------------------------------------------------------------
       
   243 //    
       
   244 const MVPbkFieldTypeList& CFindViewBase::SortOrder() const
       
   245     {
       
   246     return iParentView.SortOrder();
       
   247     }
       
   248 
       
   249 // --------------------------------------------------------------------------
       
   250 // CFindViewBase::AddObserverL
       
   251 // --------------------------------------------------------------------------
       
   252 //    
       
   253 void CFindViewBase::AddObserverL(
       
   254         MVPbkContactViewObserver& aObserver )
       
   255     {
       
   256     CVPbkAsyncObjectCallback<MVPbkContactViewObserver>* callback =
       
   257         VPbkEngUtils::CreateAsyncObjectCallbackLC(
       
   258             *this, 
       
   259             &CFindViewBase::DoAddObserver,
       
   260             &CFindViewBase::DoAddObserverError,
       
   261             aObserver);
       
   262     iObserverOp->CallbackL( callback );
       
   263     CleanupStack::Pop( callback );
       
   264     
       
   265     // Insert to first position because events are send in reverse order.
       
   266     // Events must be send in the same order as the observers were added.
       
   267     iObservers.InsertL( &aObserver, 0 );
       
   268     }
       
   269 
       
   270 // --------------------------------------------------------------------------
       
   271 // CFindViewBase::RemoveObserver
       
   272 // --------------------------------------------------------------------------
       
   273 //    
       
   274 void CFindViewBase::RemoveObserver(
       
   275         MVPbkContactViewObserver& aObserver )
       
   276     {
       
   277     iObserverOp->CancelCallback( &aObserver );
       
   278     const TInt index = iObservers.Find( &aObserver );
       
   279     if ( index != KErrNotFound )
       
   280         {
       
   281         iObservers.Remove( index );
       
   282         }
       
   283     }
       
   284 
       
   285 // --------------------------------------------------------------------------
       
   286 // CFindViewBase::MatchContactStore
       
   287 // --------------------------------------------------------------------------
       
   288 //    
       
   289 TBool CFindViewBase::MatchContactStore(
       
   290         const TDesC& aContactStoreUri ) const
       
   291     {
       
   292     return iParentView.MatchContactStore( aContactStoreUri );
       
   293     }
       
   294 
       
   295 // --------------------------------------------------------------------------
       
   296 // CFindViewBase::MatchContactStoreDomain
       
   297 // --------------------------------------------------------------------------
       
   298 //    
       
   299 TBool CFindViewBase::MatchContactStoreDomain(
       
   300         const TDesC& aContactStoreDomain ) const      
       
   301     {
       
   302     return iParentView.MatchContactStoreDomain( aContactStoreDomain );
       
   303     }
       
   304     
       
   305 // --------------------------------------------------------------------------
       
   306 // CFindViewBase::CreateBookmarkLC
       
   307 // --------------------------------------------------------------------------
       
   308 // 
       
   309 MVPbkContactBookmark* CFindViewBase::CreateBookmarkLC(
       
   310         TInt aIndex ) const
       
   311     {
       
   312     __ASSERT_ALWAYS( aIndex >= 0, 
       
   313         VPbkError::Panic(VPbkError::EInvalidContactIndex) );
       
   314     if ( aIndex >= iMatchedContacts.Count() )
       
   315         {
       
   316         User::Leave( KErrArgument );
       
   317         }
       
   318         
       
   319     TInt simIndex = iMatchedContacts[aIndex]->SimIndex();
       
   320     return CContactLink::NewLC( iAllContactsView.Store(), simIndex );
       
   321     }
       
   322 
       
   323 // --------------------------------------------------------------------------
       
   324 // CFindViewBase::IndexOfBookmarkL
       
   325 // --------------------------------------------------------------------------
       
   326 //     
       
   327 TInt CFindViewBase::IndexOfBookmarkL(
       
   328         const MVPbkContactBookmark& aContactBookmark ) const
       
   329     {
       
   330     // Bookmark is implemented as a link in this store
       
   331     const CContactLink* link = 
       
   332         dynamic_cast<const CContactLink*>( &aContactBookmark );
       
   333     if ( link && ( &link->ContactStore() == &iAllContactsView.Store() ) )
       
   334         {
       
   335         TInt simIndex = link->SimIndex();
       
   336                     
       
   337         const TInt count( iMatchedContacts.Count() );
       
   338         for ( TInt i(0); i < count; ++i )
       
   339             {
       
   340             if ( iMatchedContacts[i]->SimIndex() == simIndex )
       
   341                 {
       
   342                 return i;
       
   343                 }
       
   344             }        
       
   345         }
       
   346         
       
   347 
       
   348     return KErrNotFound;
       
   349     }    
       
   350 
       
   351 // --------------------------------------------------------------------------
       
   352 // CFindViewBase::AddFilteringObserverL
       
   353 // --------------------------------------------------------------------------
       
   354 //    
       
   355 void CFindViewBase::AddFilteringObserverL( 
       
   356         MFilteredViewSupportObserver& aObserver )
       
   357     {
       
   358     // Insert observer in callback function. That ensures that the observer
       
   359     // will always get the event asynchronously.
       
   360     
       
   361     CVPbkAsyncObjectCallback<MFilteredViewSupportObserver>* callback =
       
   362         VPbkEngUtils::CreateAsyncObjectCallbackLC(
       
   363             *this, 
       
   364             &CFindViewBase::DoAddFilteringObserverL,
       
   365             &CFindViewBase::DoAddFilteringObserverError,
       
   366             aObserver);
       
   367     
       
   368     iFilterObsOp->CallbackL( callback );
       
   369     CleanupStack::Pop( callback );
       
   370     }
       
   371 
       
   372 // --------------------------------------------------------------------------
       
   373 // CFindViewBase::RemoveFilteringObserver
       
   374 // --------------------------------------------------------------------------
       
   375 //    
       
   376 void CFindViewBase::RemoveFilteringObserver( 
       
   377         MFilteredViewSupportObserver& aObserver )
       
   378     {
       
   379     iFilterObsOp->CancelCallback( &aObserver );
       
   380     const TInt index( iFilteringObservers.Find( &aObserver ) );
       
   381     if ( index != KErrNotFound )
       
   382         {
       
   383         iFilteringObservers.Remove( index );
       
   384         }
       
   385     }
       
   386 
       
   387 // --------------------------------------------------------------------------
       
   388 // CFindViewBase::ViewFiltering
       
   389 // --------------------------------------------------------------------------
       
   390 // 
       
   391 MVPbkContactViewFiltering* CFindViewBase::ViewFiltering()
       
   392     {
       
   393     // Find view supports further filtering using CRefineView
       
   394     return this;
       
   395     }
       
   396     
       
   397 // --------------------------------------------------------------------------
       
   398 // CFindViewBase::CreateFilteredViewLC
       
   399 // --------------------------------------------------------------------------
       
   400 // 
       
   401 MVPbkContactViewBase* CFindViewBase::CreateFilteredViewLC( 
       
   402         MVPbkContactViewObserver& aObserver,
       
   403         const MDesCArray& aFindWords,
       
   404         const MVPbkContactBookmarkCollection* /*aAlwaysIncludedContacts*/ )
       
   405     {
       
   406     // NOTE: aAlwaysIncludedContacts is commented because in VPbkSimStore
       
   407     // filtered views are linked. CFindView->CRefineView->CRefineView etc.
       
   408     // Only the CFindView saves the always included contacts and they
       
   409     // are used also by all CRefineView instances through 
       
   410     // MAlwaysIncludedContacts interface.
       
   411     CRefineView* refineView = CRefineView::NewLC( aFindWords, *this, 
       
   412         iAllContactsView, aObserver, *iContactFindPolicy, *this );
       
   413     refineView->ActivateContactMatchL();
       
   414     return refineView;
       
   415     }   
       
   416     
       
   417 // --------------------------------------------------------------------------
       
   418 // CFindViewBase::ContactViewUnavailable
       
   419 // --------------------------------------------------------------------------
       
   420 //    
       
   421 void CFindViewBase::ContactViewUnavailable(
       
   422         MVPbkContactViewBase& aView )
       
   423     {
       
   424     if ( &iParentView == &aView )
       
   425         {
       
   426         SendViewStateEventToObservers();
       
   427         }
       
   428     }
       
   429 
       
   430 // --------------------------------------------------------------------------
       
   431 // CFindViewBase::ContactAddedToView
       
   432 // --------------------------------------------------------------------------
       
   433 //    
       
   434 void CFindViewBase::ContactAddedToView(
       
   435         MVPbkContactViewBase& aView, 
       
   436         TInt aIndex, 
       
   437         const MVPbkContactLink& aContactLink )
       
   438     {
       
   439     TRAPD( error, HandleContactAddedToViewL( aView, aIndex, aContactLink ) );
       
   440     if ( error != KErrNone )
       
   441         {
       
   442         ContactViewError( aView, error, EFalse );
       
   443         }
       
   444     }
       
   445 
       
   446 // --------------------------------------------------------------------------
       
   447 // CFindViewBase::ContactRemovedFromView
       
   448 // --------------------------------------------------------------------------
       
   449 //    
       
   450 void CFindViewBase::ContactRemovedFromView(
       
   451         MVPbkContactViewBase& aView, 
       
   452         TInt aIndex, 
       
   453         const MVPbkContactLink& aContactLink )
       
   454     {
       
   455     TRAPD( error, HandleContactRemovedFromViewL( aView, aIndex, aContactLink ) );
       
   456     if ( error != KErrNone )
       
   457         {
       
   458         ContactViewError( aView, error, EFalse );
       
   459         }
       
   460     }
       
   461 
       
   462 // --------------------------------------------------------------------------
       
   463 // CFindViewBase::ContactViewError
       
   464 // --------------------------------------------------------------------------
       
   465 //    
       
   466 void CFindViewBase::ContactViewError(
       
   467         MVPbkContactViewBase& /*aView*/, 
       
   468         TInt aError, 
       
   469         TBool aErrorNotified )
       
   470     {
       
   471     // This function can be called from the parent view or from the subclass.
       
   472     // In both cases this view is not usable anymore.
       
   473     iViewReady = EFalse;
       
   474     ResetContacts();
       
   475     
       
   476     // Send first to external observers...
       
   477     VPbkEng::SendEventToObservers( *this, aError, aErrorNotified, iObservers, 
       
   478         &MVPbkContactViewObserver::ContactViewError );
       
   479     // ...then to internal. This ensures that events come first from lower
       
   480     // level find view.
       
   481     VPbkEng::SendEventToObservers( *this, aError, aErrorNotified, 
       
   482         iFilteringObservers, &MVPbkContactViewObserver::ContactViewError );
       
   483     }     
       
   484 
       
   485 // --------------------------------------------------------------------------
       
   486 // CFindViewBase::ContactViewUnavailableForFiltering
       
   487 // --------------------------------------------------------------------------
       
   488 //    
       
   489 void CFindViewBase::ContactViewUnavailableForFiltering( 
       
   490         MParentViewForFiltering& aView )
       
   491     {
       
   492     if ( &iParentView == &aView )
       
   493         {
       
   494         iViewReady = EFalse;
       
   495         ResetContacts();
       
   496         // Send events first to filtered views that are built on this
       
   497         // view so that they can update them selves before notifying
       
   498         // any external observers.
       
   499         // Parent view will call ContactViewUnvailable after this and then
       
   500         // the external observers will get the view event too.
       
   501         VPbkEng::SendViewEventToObservers( *this, iFilteringObservers, 
       
   502         &MFilteredViewSupportObserver::ContactViewUnavailableForFiltering,
       
   503         &MVPbkContactViewObserver::ContactViewError );
       
   504         }
       
   505     }
       
   506     
       
   507 // --------------------------------------------------------------------------
       
   508 // CFindViewBase::MatchContactsL
       
   509 // --------------------------------------------------------------------------
       
   510 //
       
   511 void CFindViewBase::MatchContactsL()
       
   512     {
       
   513     // Destroy old matches
       
   514     ResetContacts();
       
   515     // Do the match
       
   516     MatchL( iMatchedContacts );
       
   517     iViewReady = ETrue;
       
   518     // Send events to filtered views that are built on this
       
   519     // view so that they can update them selves before notifying
       
   520     // any external observers.
       
   521     // It's subclass responsibility to call SendViewStateEventToObservers
       
   522     // when external observers are allowed to get view event.
       
   523     VPbkEng::SendViewEventToObservers( *this, iFilteringObservers, 
       
   524         &MFilteredViewSupportObserver::ContactViewReadyForFiltering,
       
   525         &MVPbkContactViewObserver::ContactViewError );
       
   526     }
       
   527     
       
   528 // --------------------------------------------------------------------------
       
   529 // CFindViewBase::IsMatchL
       
   530 // --------------------------------------------------------------------------
       
   531 //
       
   532 TBool  CFindViewBase::IsMatchL( const MVPbkViewContact& aViewContact )
       
   533     {
       
   534     return iContactFindPolicy->MatchContactNameL( *iFindStrings,
       
   535                                                   aViewContact );
       
   536     }
       
   537 
       
   538 // --------------------------------------------------------------------------
       
   539 // CFindViewBase::FindStrings
       
   540 // --------------------------------------------------------------------------
       
   541 //
       
   542 const MDesCArray& CFindViewBase::FindStrings() const
       
   543     {
       
   544     return *iFindStrings;
       
   545     }
       
   546 
       
   547 // --------------------------------------------------------------------------
       
   548 // CFindViewBase::SetFindStringsL
       
   549 // --------------------------------------------------------------------------
       
   550 //                
       
   551 void CFindViewBase::SetFindStringsL( const MDesCArray& aFindStrings )
       
   552     {
       
   553     __ASSERT_DEBUG( iFindStrings, Panic( EPreCond_SetFindStringsL ) );
       
   554     
       
   555     iFindStrings->Reset();
       
   556     const TInt count( aFindStrings.MdcaCount() );
       
   557     for ( TInt i(0); i < count; ++i )
       
   558         {
       
   559         iFindStrings->AppendL( aFindStrings.MdcaPoint( i ) );
       
   560         }
       
   561     }
       
   562 
       
   563 // -------------------------------------------------------------------------
       
   564 // CFindViewBase::SendViewStateEventToObservers
       
   565 // --------------------------------------------------------------------------
       
   566 //
       
   567 void CFindViewBase::SendViewStateEventToObservers()
       
   568     {
       
   569     // Cancel any new AddObserverL callbacks to avoid duplicate event
       
   570     // sending.
       
   571     iObserverOp->Purge();
       
   572     
       
   573     void (MVPbkContactViewObserver::*notifyFunc)(MVPbkContactViewBase&);
       
   574     notifyFunc = &MVPbkContactViewObserver::ContactViewReady;
       
   575     
       
   576     if ( !iViewReady )
       
   577         {
       
   578         notifyFunc = &MVPbkContactViewObserver::ContactViewUnavailable;
       
   579         }
       
   580     
       
   581     VPbkEng::SendViewEventToObservers( *this, iObservers, 
       
   582         notifyFunc, &MVPbkContactViewObserver::ContactViewError );
       
   583     VPbkEng::SendViewEventToObservers( *this, iFilteringObservers, 
       
   584         notifyFunc, &MVPbkContactViewObserver::ContactViewError );
       
   585     }
       
   586 
       
   587 // --------------------------------------------------------------------------
       
   588 // CFindViewBase::DoAddObserver
       
   589 // --------------------------------------------------------------------------
       
   590 //                
       
   591 void CFindViewBase::DoAddObserver( MVPbkContactViewObserver& aObserver )
       
   592     {
       
   593     if (iViewReady)
       
   594         {
       
   595         // If this view is ready and there was no error,
       
   596         // tell it to the observer
       
   597         aObserver.ContactViewReady( *this );
       
   598         }
       
   599     else
       
   600         {
       
   601         aObserver.ContactViewUnavailable( *this );
       
   602         }
       
   603     }
       
   604 
       
   605 // --------------------------------------------------------------------------
       
   606 // CFindViewBase::DoAddObserverError
       
   607 // --------------------------------------------------------------------------
       
   608 //                
       
   609 void CFindViewBase::DoAddObserverError( 
       
   610         MVPbkContactViewObserver& /*aObserver*/, TInt /*aError*/ )
       
   611     {
       
   612     // Empty implementation
       
   613     }
       
   614 
       
   615 // --------------------------------------------------------------------------
       
   616 // CFindViewBase::DoAddFilteringObserverL
       
   617 // --------------------------------------------------------------------------
       
   618 //                
       
   619 void CFindViewBase::DoAddFilteringObserverL( 
       
   620         MFilteredViewSupportObserver& aObserver )
       
   621     {
       
   622     // Insert to first position because events are send in reverse order.
       
   623     iFilteringObservers.InsertL( &aObserver, 0 );
       
   624     
       
   625     if (iViewReady)
       
   626         {
       
   627         aObserver.ContactViewReadyForFiltering( *this );
       
   628         aObserver.ContactViewReady( *this );
       
   629         }
       
   630     else
       
   631         {
       
   632         aObserver.ContactViewUnavailableForFiltering( *this );
       
   633         aObserver.ContactViewUnavailable( *this );
       
   634         }
       
   635     }
       
   636 
       
   637 // --------------------------------------------------------------------------
       
   638 // CFindViewBase::DoAddFilteringObserverError
       
   639 // --------------------------------------------------------------------------
       
   640 //                
       
   641 void CFindViewBase::DoAddFilteringObserverError( 
       
   642         MFilteredViewSupportObserver& aObserver, TInt aError )
       
   643     {
       
   644     aObserver.ContactViewError( *this, aError, EFalse );
       
   645     }
       
   646 
       
   647 // --------------------------------------------------------------------------
       
   648 // CFindViewBase::HandleContactAddedToViewL
       
   649 // --------------------------------------------------------------------------
       
   650 //                
       
   651 void CFindViewBase::HandleContactAddedToViewL( MVPbkContactViewBase& aView,
       
   652         TInt aIndex, const MVPbkContactLink& aContactLink )
       
   653     {
       
   654     if ( &iParentView == &aView )
       
   655         {
       
   656         // Let sub class do the addition if needed
       
   657         DoContactAddedToViewL( aView, aIndex, aContactLink, 
       
   658             iMatchedContacts );
       
   659         
       
   660         // Get the index of the new contact in this view.
       
   661         TInt index( IndexOfLinkL( aContactLink ) );  
       
   662         if ( index != KErrNotFound )
       
   663             {
       
   664             VPbkEng::SendViewEventToObservers( *this, index, aContactLink,
       
   665                 iObservers, 
       
   666                 &MVPbkContactViewObserver::ContactAddedToView, 
       
   667                 &MVPbkContactViewObserver::ContactViewError );
       
   668             VPbkEng::SendViewEventToObservers( *this, index, aContactLink,
       
   669                 iFilteringObservers, 
       
   670                 &MVPbkContactViewObserver::ContactAddedToView, 
       
   671                 &MVPbkContactViewObserver::ContactViewError );
       
   672             }
       
   673         }
       
   674     }
       
   675 
       
   676 // --------------------------------------------------------------------------
       
   677 // CFindViewBase::HandleContactRemovedFromViewL
       
   678 // --------------------------------------------------------------------------
       
   679 //    
       
   680 void CFindViewBase::HandleContactRemovedFromViewL( 
       
   681         MVPbkContactViewBase& aView, TInt /*aIndex*/, const 
       
   682         MVPbkContactLink& aContactLink )
       
   683     {
       
   684     if ( &iParentView == &aView )
       
   685         {
       
   686         // We know that link is always VPbkSimStore::CContactLink
       
   687         const CContactLink& link = 
       
   688             static_cast<const CContactLink&>(aContactLink);
       
   689         
       
   690         TInt index = KErrNotFound;
       
   691         MVPbkSimContact* removedContact = NULL;
       
   692         const TInt simIndex = link.SimIndex();
       
   693         const TInt count( iMatchedContacts.Count() );    
       
   694         for ( TInt i= 0; i < count && !removedContact; ++i  )
       
   695             {                                                      
       
   696             MVPbkSimContact* contact = iMatchedContacts[i];        
       
   697             
       
   698             // Filter away the removed contact
       
   699             if ( contact->SimIndex() == simIndex )
       
   700                 {
       
   701                 // Remove contact from the array
       
   702                 iMatchedContacts.Remove( i );
       
   703                 // Save the removed index for the observers
       
   704                 index = i;
       
   705                 // At this point nobody owns removedContact.
       
   706                 removedContact = contact;
       
   707                 }   
       
   708             } 
       
   709         TBool takeCareOfOwnership = (removedContact && iOwnsContacts);
       
   710         
       
   711         // Notice: we can not delete the contact instance before
       
   712         // all observers have received the event. This is because
       
   713         // in case of CRefineView, iMatchedContacts contains references 
       
   714         // to MVPbkSimContact instances. If we delete the contact
       
   715         // before notifying observer then the there will be invalid
       
   716         // pointer.
       
   717         if ( takeCareOfOwnership )
       
   718             {
       
   719             CleanupDeletePushL( removedContact );
       
   720             }
       
   721         
       
   722         if ( index != KErrNotFound )            
       
   723             {
       
   724             VPbkEng::SendViewEventToObservers( *this, index, aContactLink,
       
   725                 iObservers, 
       
   726                 &MVPbkContactViewObserver::ContactRemovedFromView, 
       
   727                 &MVPbkContactViewObserver::ContactViewError );
       
   728             VPbkEng::SendViewEventToObservers( *this, index, aContactLink,
       
   729                 iFilteringObservers, 
       
   730                 &MVPbkContactViewObserver::ContactRemovedFromView, 
       
   731                 &MVPbkContactViewObserver::ContactViewError );
       
   732             }
       
   733             
       
   734         if ( takeCareOfOwnership)
       
   735             {
       
   736             // After all observers have received the Removed -event, it's
       
   737             // safe to actually destroy the contact.
       
   738             CleanupStack::PopAndDestroy(); // removedContact
       
   739             }
       
   740         }
       
   741     }
       
   742     
       
   743 
       
   744 // --------------------------------------------------------------------------
       
   745 // CFindViewBase::ResetContacts
       
   746 // --------------------------------------------------------------------------
       
   747 //    
       
   748 void CFindViewBase::ResetContacts()
       
   749     {
       
   750     if ( iOwnsContacts )
       
   751         {
       
   752         iMatchedContacts.ResetAndDestroy();    
       
   753         }
       
   754     else
       
   755         {
       
   756         iMatchedContacts.Reset();
       
   757         }
       
   758     }
       
   759 } // namespace VPbkSimStore 
       
   760 // End of File