phonebookengines/VirtualPhonebook/VPbkEng/src/CVPbkCompositeContactView.cpp
branchRCL_3
changeset 20 f4a778e096c2
equal deleted inserted replaced
19:5b6f26637ad3 20:f4a778e096c2
       
     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:  Composite contact view.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CVPbkCompositeContactView.h"
       
    20 #include <MVPbkFieldType.h>
       
    21 #include <CVPbkSortOrder.h>
       
    22 #include <CVPbkAsyncCallback.h>
       
    23 #include <MVPbkContactLink.h>
       
    24 #include "CVPbkEventArrayItem.h"
       
    25 #include <VPbkError.h>
       
    26 
       
    27 // Debugging headers
       
    28 #include <VPbkProfile.h>
       
    29 #include <VPbkDebug.h>
       
    30 
       
    31 /// Unnamed namespace for local definitions
       
    32 namespace {
       
    33 
       
    34 #ifdef _DEBUG
       
    35     enum TPanic
       
    36         {
       
    37         EPanicLogic_CreateBookmarkLC = 3
       
    38         };
       
    39 
       
    40     void Panic(TPanic aPanic)
       
    41         {
       
    42         _LIT(KPanicCat, "CVPbkCompositeContactView");
       
    43         User::Panic(KPanicCat, aPanic);
       
    44         }
       
    45 #endif // _DEBUG
       
    46 
       
    47 /// Observer granulatiry
       
    48 const TInt KObserverArrayGranularity = 4;
       
    49 
       
    50 /////////////////////////////////////////////////////////////////////////////
       
    51 // Event sending functions for different amount of parameters
       
    52 //
       
    53 
       
    54 // --------------------------------------------------------------------------
       
    55 // SendEventToObservers
       
    56 // --------------------------------------------------------------------------
       
    57 //
       
    58 template <class NotifyFunc>
       
    59 void SendEventToObservers( MVPbkContactViewBase& aView,
       
    60         RPointerArray<MVPbkContactViewObserver>& aObservers,
       
    61         NotifyFunc aNotifyFunc )
       
    62     {
       
    63     const TInt count = aObservers.Count();
       
    64     for (TInt i = count - 1; i >= 0; --i)
       
    65         {
       
    66         MVPbkContactViewObserver* observer = aObservers[i];
       
    67         (observer->*aNotifyFunc)(aView);
       
    68         }
       
    69     }
       
    70 
       
    71 // --------------------------------------------------------------------------
       
    72 // SendEventToObservers
       
    73 // --------------------------------------------------------------------------
       
    74 //
       
    75 template <class NotifyFunc, class ParamType1, class ParamType2>
       
    76 void SendEventToObservers( MVPbkContactViewBase& aView,
       
    77         RPointerArray<MVPbkContactViewObserver>& aObservers,
       
    78         NotifyFunc aNotifyFunc, ParamType1 aParam1, const ParamType2& aParam2 )
       
    79     {
       
    80     const TInt count = aObservers.Count();
       
    81     for (TInt i = count - 1; i >= 0; --i)
       
    82         {
       
    83         MVPbkContactViewObserver* observer = aObservers[i];
       
    84         (observer->*aNotifyFunc)(aView, aParam1, aParam2);
       
    85         }
       
    86     }
       
    87 
       
    88 } /// namespace
       
    89 
       
    90 // --------------------------------------------------------------------------
       
    91 // CVPbkCompositeContactView::CSubViewData::~CSubViewData
       
    92 // --------------------------------------------------------------------------
       
    93 //
       
    94 CVPbkCompositeContactView::CSubViewData::~CSubViewData()
       
    95     {
       
    96     delete iView;
       
    97     }
       
    98 
       
    99 // --------------------------------------------------------------------------
       
   100 // CVPbkCompositeContactView::CVPbkCompositeContactView
       
   101 // --------------------------------------------------------------------------
       
   102 //
       
   103 CVPbkCompositeContactView::CVPbkCompositeContactView() :
       
   104         iAsyncOperation( CActive::EPriorityStandard ),
       
   105         iObservers( KObserverArrayGranularity )
       
   106     {
       
   107     }
       
   108 
       
   109 // --------------------------------------------------------------------------
       
   110 // CVPbkCompositeContactView::~CVPbkCompositeContactView
       
   111 // --------------------------------------------------------------------------
       
   112 //
       
   113 CVPbkCompositeContactView::~CVPbkCompositeContactView()
       
   114     {
       
   115     delete iCompositePolicy;
       
   116     delete iSortOrder;
       
   117     iSubViews.ResetAndDestroy();
       
   118     iObservers.Close();
       
   119     iContactMapping.Reset();
       
   120     }
       
   121 
       
   122 // --------------------------------------------------------------------------
       
   123 // CVPbkCompositeContactView::BaseConstructL
       
   124 // --------------------------------------------------------------------------
       
   125 //
       
   126 void CVPbkCompositeContactView::BaseConstructL
       
   127         (const MVPbkFieldTypeList& aSortOrder)
       
   128     {
       
   129     // Create sort order
       
   130     iSortOrder = CVPbkSortOrder::NewL(aSortOrder);
       
   131 
       
   132     // Always apply internal policy
       
   133     iCompositePolicy =
       
   134             CVPbkInternalCompositeViewPolicy::NewL( *this, iObservers );
       
   135 
       
   136     // External policy's view event buffering mechanism does not work when
       
   137     // native contact views reside in a separate process, therefore we
       
   138     // always apply internal policy.
       
   139     }
       
   140 
       
   141 // --------------------------------------------------------------------------
       
   142 // CVPbkCompositeContactView::AddSubViewL
       
   143 // Adds subview to this composite view.
       
   144 // --------------------------------------------------------------------------
       
   145 //
       
   146 void CVPbkCompositeContactView::AddSubViewL(MVPbkContactViewBase* aSubView, TInt  aViewId)
       
   147     {
       
   148     CSubViewData* subViewData =
       
   149         new(ELeave) CSubViewData(CSubViewData::ENotKnown);
       
   150     CleanupStack::PushL(subViewData);
       
   151     User::LeaveIfError(iSubViews.Append(subViewData));
       
   152     CleanupStack::Pop(subViewData);
       
   153 
       
   154     subViewData->iView = aSubView;
       
   155     subViewData->iViewId = aViewId;
       
   156     }
       
   157 
       
   158 // --------------------------------------------------------------------------
       
   159 // CVPbkCompositeContactView::ActualContactCountL
       
   160 // --------------------------------------------------------------------------
       
   161 //
       
   162 TInt CVPbkCompositeContactView::ActualContactCountL() const
       
   163     {
       
   164     const TInt subViewCount = iSubViews.Count();
       
   165     TInt contactCount = 0;
       
   166     for (TInt i = 0; i < subViewCount; ++i)
       
   167         {
       
   168         if ( iSubViews[i]->iState == CSubViewData::EReady )
       
   169             {
       
   170             if ( iSubViews[i]->iView->Type() == EVPbkCompositeView )
       
   171                 {
       
   172                 // The view can be safely casted because
       
   173                 // CVPbkCompositeContactView is VPbkEng internal
       
   174                 // and EVPbkCompositeView type view is always
       
   175                 // derived from CVPbkCompositeContactView.
       
   176                 contactCount += static_cast<CVPbkCompositeContactView*>(
       
   177                     iSubViews[i]->iView )->ActualContactCountL();
       
   178                 }
       
   179             else
       
   180                 {
       
   181                 contactCount += iSubViews[i]->iView->ContactCountL();
       
   182                 }
       
   183             }
       
   184         }
       
   185     return contactCount;
       
   186     }
       
   187 
       
   188 // --------------------------------------------------------------------------
       
   189 // CVPbkCompositeContactView::ApplyInternalCompositePolicyL
       
   190 // --------------------------------------------------------------------------
       
   191 //
       
   192 void CVPbkCompositeContactView::ApplyInternalCompositePolicyL()
       
   193     {
       
   194     if ( !iCompositePolicy || !iCompositePolicy->InternalPolicy() )
       
   195         {
       
   196         MVPbkCompositeContactViewPolicy* newPolicy =
       
   197                 CVPbkInternalCompositeViewPolicy::NewL( *this, iObservers );
       
   198         delete iCompositePolicy;
       
   199         iCompositePolicy = newPolicy;
       
   200         }
       
   201     }
       
   202 
       
   203 // --------------------------------------------------------------------------
       
   204 // CVPbkCompositeContactView::Type
       
   205 // Returns view type.
       
   206 // --------------------------------------------------------------------------
       
   207 //
       
   208 TVPbkContactViewType CVPbkCompositeContactView::Type() const
       
   209     {
       
   210     return EVPbkCompositeView;
       
   211     }
       
   212 
       
   213 // --------------------------------------------------------------------------
       
   214 // CVPbkCompositeContactView::ChangeSortOrderL
       
   215 // Changes sort order.
       
   216 // --------------------------------------------------------------------------
       
   217 //
       
   218 void CVPbkCompositeContactView::ChangeSortOrderL
       
   219         (const MVPbkFieldTypeList& aSortOrder)
       
   220     {
       
   221     const TInt subViewCount = iSubViews.Count();
       
   222     for (TInt i = 0; i < subViewCount; ++i)
       
   223         {
       
   224         // All ready subviews go to unknown state because
       
   225         // they need to be re-sorted.
       
   226         // State is known again when an event comes.
       
   227         if (iSubViews[i]->iState == CSubViewData::EReady)
       
   228             {
       
   229             iSubViews[i]->iState = CSubViewData::ENotKnown;
       
   230             iSubViews[i]->iView->ChangeSortOrderL(aSortOrder);
       
   231             }
       
   232         }
       
   233 
       
   234     // Create new sort order and take it in use
       
   235     MVPbkFieldTypeList* sortOrder = CVPbkSortOrder::NewL(aSortOrder);
       
   236     delete iSortOrder;
       
   237     iSortOrder = sortOrder;
       
   238     }
       
   239 
       
   240 // --------------------------------------------------------------------------
       
   241 // CVPbkCompositeContactView::SortOrder
       
   242 // Returns current sort order.
       
   243 // --------------------------------------------------------------------------
       
   244 //
       
   245 const MVPbkFieldTypeList& CVPbkCompositeContactView::SortOrder() const
       
   246     {
       
   247     return *iSortOrder;
       
   248     }
       
   249 
       
   250 // --------------------------------------------------------------------------
       
   251 // CVPbkCompositeContactView::RefreshL
       
   252 // Refreshes all subviews
       
   253 // --------------------------------------------------------------------------
       
   254 //
       
   255 void CVPbkCompositeContactView::RefreshL()
       
   256     {
       
   257     const TInt subViewCount = iSubViews.Count();
       
   258     for (TInt i = 0; i < subViewCount; ++i)
       
   259         {
       
   260         iSubViews[i]->iView->RefreshL();
       
   261         }
       
   262     }
       
   263 
       
   264 // --------------------------------------------------------------------------
       
   265 // CVPbkCompositeContactView::ContactCountL
       
   266 // Returns contact count.
       
   267 // --------------------------------------------------------------------------
       
   268 //
       
   269 TInt CVPbkCompositeContactView::ContactCountL() const
       
   270     {
       
   271     return iCompositePolicy->ContactCountL();
       
   272     }
       
   273 
       
   274 // --------------------------------------------------------------------------
       
   275 // CVPbkCompositeContactView::ContactAtL
       
   276 // Returns contact at aIndex.
       
   277 // --------------------------------------------------------------------------
       
   278 //
       
   279 const MVPbkViewContact& CVPbkCompositeContactView::ContactAtL
       
   280         (TInt aIndex) const
       
   281     {
       
   282     __ASSERT_ALWAYS(
       
   283         aIndex >= 0, VPbkError::Panic( VPbkError::EInvalidContactIndex ) );
       
   284     if ( aIndex >= iContactMapping.Count() )
       
   285         {
       
   286         User::Leave( KErrArgument );
       
   287         }
       
   288 
       
   289     const TContactMapping& mapping = iContactMapping[aIndex];
       
   290     MVPbkContactViewBase* view = iSubViews[mapping.iViewIndex]->iView;
       
   291     return view->ContactAtL( mapping.iContactIndex );
       
   292     }
       
   293 
       
   294 // --------------------------------------------------------------------------
       
   295 // CVPbkCompositeContactView::CreateLinkLC
       
   296 // Creates link from a contact at aIndex.
       
   297 // --------------------------------------------------------------------------
       
   298 //
       
   299 MVPbkContactLink* CVPbkCompositeContactView::CreateLinkLC(TInt aIndex) const
       
   300     {
       
   301     __ASSERT_ALWAYS(
       
   302         aIndex >= 0, VPbkError::Panic( VPbkError::EInvalidContactIndex ) );
       
   303     if ( aIndex >= iContactMapping.Count() )
       
   304         {
       
   305         User::Leave( KErrArgument );
       
   306         }
       
   307 
       
   308     const TContactMapping& mapping = iContactMapping[aIndex];
       
   309     MVPbkContactViewBase* view = iSubViews[mapping.iViewIndex]->iView;
       
   310     return view->CreateLinkLC( mapping.iContactIndex );
       
   311     }
       
   312 
       
   313 // --------------------------------------------------------------------------
       
   314 // CVPbkCompositeContactView::IndexOfLinkL
       
   315 // Returns index of aContactLink.
       
   316 // --------------------------------------------------------------------------
       
   317 //
       
   318 TInt CVPbkCompositeContactView::IndexOfLinkL
       
   319         (const MVPbkContactLink& aContactLink) const
       
   320     {
       
   321     TIdentityRelation<TContactMapping> comparisonOperator
       
   322         (&CVPbkCompositeContactView::CompareMappings);
       
   323     TInt result = KErrNotFound;
       
   324 
       
   325     // Search the link from all the subviews
       
   326     const TInt subViewCount = iSubViews.Count();
       
   327     for (TInt i = 0; i < subViewCount; ++i)
       
   328         {
       
   329         // Check that the view is ready before using it.
       
   330         TInt index = KErrNotFound;
       
   331         if (iSubViews[i]->iState == CSubViewData::EReady)
       
   332             {
       
   333             index = iSubViews[i]->iView->IndexOfLinkL(aContactLink);
       
   334             }
       
   335 
       
   336         if (index != KErrNotFound)
       
   337             {
       
   338             // Establish contact mapping for view and contact index
       
   339             TContactMapping mapping;
       
   340             mapping.iViewIndex = i;
       
   341             mapping.iContactIndex = index;
       
   342             // Find the composite index by comparing the two mappings
       
   343             result = iContactMapping.Find(mapping, comparisonOperator);
       
   344             break;
       
   345             }
       
   346         }
       
   347     return result;
       
   348     }
       
   349 
       
   350 // --------------------------------------------------------------------------
       
   351 // CVPbkCompositeContactView::AddObserverL
       
   352 // --------------------------------------------------------------------------
       
   353 //
       
   354 void CVPbkCompositeContactView::AddObserverL
       
   355         (MVPbkContactViewObserver& aObserver)
       
   356     {
       
   357     // Add the observer only if it is not already added
       
   358     TInt err( iObservers.InsertInAddressOrder(&aObserver) );
       
   359     if ( err != KErrNone && err != KErrAlreadyExists)
       
   360         {
       
   361         User::Leave( err );
       
   362         }
       
   363 
       
   364     TRAP(err,
       
   365         {
       
   366         VPbkEngUtils::MAsyncCallback* notifyObserver =
       
   367             VPbkEngUtils::CreateAsyncCallbackLC(
       
   368                 *this,
       
   369                 &CVPbkCompositeContactView::DoAddObserverL,
       
   370                 &CVPbkCompositeContactView::AddObserverError,
       
   371                 aObserver);
       
   372         iAsyncOperation.CallbackL(notifyObserver);
       
   373         CleanupStack::Pop(notifyObserver);
       
   374         });
       
   375 
       
   376     if (err != KErrNone)
       
   377         {
       
   378         RemoveObserver(aObserver);
       
   379         User::Leave(err);
       
   380         }
       
   381     }
       
   382 
       
   383 // --------------------------------------------------------------------------
       
   384 // CVPbkCompositeContactView::RemoveObserver
       
   385 // --------------------------------------------------------------------------
       
   386 //
       
   387 void CVPbkCompositeContactView::RemoveObserver
       
   388         (MVPbkContactViewObserver& aObserver)
       
   389     {
       
   390     const TInt index = iObservers.FindInAddressOrder( &aObserver );
       
   391     if (index != KErrNotFound)
       
   392         {
       
   393         iObservers.Remove(index);
       
   394         }
       
   395     }
       
   396 
       
   397 // --------------------------------------------------------------------------
       
   398 // CVPbkCompositeContactView::MatchContactStore
       
   399 // Check does any of the subviews match given contact store.
       
   400 // --------------------------------------------------------------------------
       
   401 //
       
   402 TBool CVPbkCompositeContactView::MatchContactStore
       
   403         (const TDesC& aContactStoreUri) const
       
   404     {
       
   405     const TInt count = iSubViews.Count();
       
   406     TBool result = EFalse;
       
   407     for (TInt i = 0; i < count && !result; ++i)
       
   408         {
       
   409         result = iSubViews[i]->iView->MatchContactStore(aContactStoreUri);
       
   410         }
       
   411     return result;
       
   412     }
       
   413 
       
   414 // --------------------------------------------------------------------------
       
   415 // CVPbkCompositeContactView::MatchContactStoreDomain
       
   416 // Check does any of the subviews match given contact store domain.
       
   417 // --------------------------------------------------------------------------
       
   418 //
       
   419 
       
   420  TBool CVPbkCompositeContactView::MatchContactStoreDomain
       
   421         (const TDesC& aContactStoreDomain) const
       
   422     {
       
   423     const TInt count = iSubViews.Count();
       
   424     TBool result = EFalse;
       
   425     for (TInt i = 0; i < count && !result; ++i)
       
   426         {
       
   427         result = iSubViews[i]->iView->MatchContactStoreDomain
       
   428             (aContactStoreDomain);
       
   429         }
       
   430     return result;
       
   431     }
       
   432 
       
   433 // --------------------------------------------------------------------------
       
   434 // CVPbkCompositeContactView::CreateBookmarkLC
       
   435 // Creates a bookmark for given index.
       
   436 // --------------------------------------------------------------------------
       
   437 //
       
   438 MVPbkContactBookmark* CVPbkCompositeContactView::CreateBookmarkLC
       
   439         (TInt aIndex) const
       
   440     {
       
   441     __ASSERT_ALWAYS( aIndex >= 0,
       
   442         VPbkError::Panic( VPbkError::EInvalidContactIndex ) );
       
   443     __ASSERT_DEBUG(ContactCountL() > aIndex,
       
   444             Panic(EPanicLogic_CreateBookmarkLC));
       
   445 
       
   446     const TContactMapping& mapping = iContactMapping[aIndex];
       
   447     MVPbkContactViewBase* view = iSubViews[mapping.iViewIndex]->iView;
       
   448     return view->CreateBookmarkLC( mapping.iContactIndex );
       
   449     }
       
   450 
       
   451 // --------------------------------------------------------------------------
       
   452 // CVPbkCompositeContactView::IndexOfBookmarkL
       
   453 // Returns the index of given bookmark.
       
   454 // --------------------------------------------------------------------------
       
   455 //
       
   456 TInt CVPbkCompositeContactView::IndexOfBookmarkL
       
   457         (const MVPbkContactBookmark& aContactBookmark) const
       
   458     {
       
   459     TIdentityRelation<TContactMapping> comparisonOperator(
       
   460         &CVPbkCompositeContactView::CompareMappings);
       
   461     TInt result = KErrNotFound;
       
   462 
       
   463     // Search the bookmark from all the subviews
       
   464     const TInt subViewCount = iSubViews.Count();
       
   465     for (TInt i = 0; i < subViewCount; ++i)
       
   466         {
       
   467         // Check that the view is ready before using it.
       
   468         TInt index(KErrNotFound);
       
   469         if (iSubViews[i]->iState == CSubViewData::EReady)
       
   470             {
       
   471             index = iSubViews[i]->iView->IndexOfBookmarkL(aContactBookmark);
       
   472             }
       
   473 
       
   474         if (index != KErrNotFound)
       
   475             {
       
   476             // Establish contact mapping for view and contact index
       
   477             TContactMapping mapping;
       
   478             mapping.iViewIndex = i;
       
   479             mapping.iContactIndex = index;
       
   480             // Find the composite index by comparing the two mappings
       
   481             result = iContactMapping.Find(mapping, comparisonOperator);
       
   482             break;
       
   483             }
       
   484         }
       
   485     return result;
       
   486     }
       
   487 
       
   488 // --------------------------------------------------------------------------
       
   489 // CVPbkCompositeContactView::ViewFiltering
       
   490 // --------------------------------------------------------------------------
       
   491 //
       
   492 MVPbkContactViewFiltering* CVPbkCompositeContactView::ViewFiltering()
       
   493     {
       
   494     // Composite views support filtering and is also a filtered view.
       
   495     // The subclass must implement the interface.
       
   496     return this;
       
   497     }
       
   498 
       
   499 TAny* CVPbkCompositeContactView::ContactViewBaseExtension(TUid aExtensionUid)
       
   500     {
       
   501     MVPbkContactViewBaseChildAccessExtension* extChild = NULL;
       
   502     if ( aExtensionUid == TUid::Uid(KVPbkViewBaseExtChildAccess) )
       
   503         {
       
   504         extChild = this;
       
   505         }
       
   506     return extChild;
       
   507     }
       
   508 
       
   509 // --------------------------------------------------------------------------
       
   510 // CVPbkCompositeContactView::ContactViewReady
       
   511 // --------------------------------------------------------------------------
       
   512 //
       
   513 void CVPbkCompositeContactView::ContactViewReady(MVPbkContactViewBase& aView)
       
   514     {
       
   515     TRAPD( res, HandleContactViewReadyL( aView ) );
       
   516     if ( res != KErrNone )
       
   517         {
       
   518         // There was an error when building a composite. Reset composite
       
   519         // inform client that this view unavailable and there is an error
       
   520         ResetContactMapping();
       
   521         SendViewUnavailableEvent();
       
   522         SendViewErrorEvent( res, EFalse );
       
   523         }
       
   524     }
       
   525 
       
   526 // --------------------------------------------------------------------------
       
   527 // CVPbkCompositeContactView::ContactViewUnavailable
       
   528 // --------------------------------------------------------------------------
       
   529 //
       
   530 void CVPbkCompositeContactView::ContactViewUnavailable
       
   531         (MVPbkContactViewBase& aView)
       
   532     {
       
   533     TRAPD( res, HandleContactViewUnavailableL( aView ) );
       
   534     if ( res != KErrNone )
       
   535         {
       
   536         // There was an error when building a composite. Reset composite
       
   537         // inform client that this view unavailable and there is an error
       
   538         ResetContactMapping();
       
   539         SendViewUnavailableEvent();
       
   540         SendViewErrorEvent( res, EFalse );
       
   541         }
       
   542     }
       
   543 
       
   544 // --------------------------------------------------------------------------
       
   545 // CVPbkCompositeContactView::ContactAddedToView
       
   546 // --------------------------------------------------------------------------
       
   547 //
       
   548 void CVPbkCompositeContactView::ContactAddedToView
       
   549         (MVPbkContactViewBase& aView, TInt aIndex,
       
   550         const MVPbkContactLink& aContactLink)
       
   551     {
       
   552     TInt compositeIndex = HandleContactAddition(aView, aIndex);
       
   553 
       
   554     TRAPD( error, iCompositePolicy->HandleViewEventsL(
       
   555         CVPbkEventArrayItem::EAdded, aView, compositeIndex, aContactLink ) );
       
   556     if ( error != KErrNone )
       
   557         {
       
   558         // If error occurs reset policy
       
   559         iCompositePolicy->Reset();
       
   560         SendViewErrorEvent( error, EFalse );
       
   561         }
       
   562     }
       
   563 
       
   564 // --------------------------------------------------------------------------
       
   565 // CVPbkCompositeContactView::ContactRemovedFromView
       
   566 // --------------------------------------------------------------------------
       
   567 //
       
   568 void CVPbkCompositeContactView::ContactRemovedFromView
       
   569         (MVPbkContactViewBase& aView, TInt aIndex,
       
   570         const MVPbkContactLink& aContactLink)
       
   571     {
       
   572     TInt compositeIndex( KErrNotFound );
       
   573     compositeIndex = HandleContactRemoval(aView, aIndex);
       
   574     TRAPD( error, iCompositePolicy->HandleViewEventsL(
       
   575         CVPbkEventArrayItem::ERemoved, aView, compositeIndex,
       
   576             aContactLink ) );
       
   577     if ( error != KErrNone )
       
   578         {
       
   579         // If error occurs reset policy
       
   580         iCompositePolicy->Reset();
       
   581         SendViewErrorEvent( error, EFalse );
       
   582         }
       
   583     }
       
   584 
       
   585 // --------------------------------------------------------------------------
       
   586 // CVPbkCompositeContactView::ContactViewError
       
   587 // --------------------------------------------------------------------------
       
   588 //
       
   589 void CVPbkCompositeContactView::ContactViewError
       
   590         (MVPbkContactViewBase& /*aView*/, TInt aError, TBool aErrorNotified)
       
   591     {
       
   592     SendViewErrorEvent( aError, aErrorNotified );
       
   593     }
       
   594 
       
   595 // --------------------------------------------------------------------------
       
   596 // CVPbkCompositeContactView::ContactViewObserverExtension
       
   597 // --------------------------------------------------------------------------
       
   598 //
       
   599 TAny* CVPbkCompositeContactView::ContactViewObserverExtension( TUid aExtensionUid )
       
   600     {
       
   601     if( aExtensionUid == KVPbkContactViewObserverExtension2Uid )
       
   602         {
       
   603         return static_cast<MVPbkContactViewObserverExtension*>( this );
       
   604         }
       
   605     return NULL;
       
   606     }
       
   607 
       
   608 // --------------------------------------------------------------------------
       
   609 // CVPbkCompositeContactView::FilteredContactRemovedFromView
       
   610 // --------------------------------------------------------------------------
       
   611 //
       
   612 void CVPbkCompositeContactView::FilteredContactRemovedFromView(
       
   613 		MVPbkContactViewBase& aView )
       
   614     {
       
   615     const TInt count = iObservers.Count();
       
   616 
       
   617     for( TInt i = 0; i < count; i++ )
       
   618         {
       
   619         MVPbkContactViewObserver* observer = iObservers[i];
       
   620 
       
   621         TAny* extension = observer->ContactViewObserverExtension(
       
   622               KVPbkContactViewObserverExtension2Uid );
       
   623 
       
   624         if( extension )
       
   625             {
       
   626             MVPbkContactViewObserverExtension* contactViewExtension =
       
   627                   static_cast<MVPbkContactViewObserverExtension*>( extension );
       
   628 
       
   629             if( contactViewExtension )
       
   630                 {
       
   631                 contactViewExtension->FilteredContactRemovedFromView( aView );
       
   632                 }
       
   633             }
       
   634         }
       
   635     }
       
   636 
       
   637 // --------------------------------------------------------------------------
       
   638 // CVPbkCompositeContactView::UpdateFilterL
       
   639 // --------------------------------------------------------------------------
       
   640 //
       
   641 void CVPbkCompositeContactView::UpdateFilterL(
       
   642         const MDesCArray& aFindWords,
       
   643         const MVPbkContactBookmarkCollection* aAlwaysIncludedContacts )
       
   644     {
       
   645     const TInt count = iSubViews.Count();
       
   646     for( TInt i = 0; i < count; ++i )
       
   647         {
       
   648         MVPbkContactViewFiltering* filtering =
       
   649             iSubViews[i]->iView->ViewFiltering();
       
   650         // Check if the subview supports filtering.
       
   651         if ( filtering )
       
   652             {
       
   653             // Filtering supported
       
   654             filtering->UpdateFilterL( aFindWords, aAlwaysIncludedContacts );
       
   655             // Set state to unknown. NOTE: this set so that the composite
       
   656             // becomes ready state when all subviews have notified something.
       
   657             // Otherwise the composite would notify its own observers every
       
   658             // time a subview notifies composite. This is not wanted because
       
   659             // client must get only one notification after update.
       
   660             // On the other hand a client can still use this view while it's
       
   661             // updating itself so in that point of view the composite is not
       
   662             // in unknown state but in update state.
       
   663             iSubViews[i]->iState = CSubViewData::ENotKnown;
       
   664             }
       
   665         }
       
   666     }
       
   667 
       
   668 TInt CVPbkCompositeContactView::ChildViewCount() const
       
   669     {
       
   670     return iSubViews.Count();
       
   671     }
       
   672 
       
   673 MVPbkContactViewBase& CVPbkCompositeContactView::ChildViewAt( TInt aIndex )
       
   674     {
       
   675     return *iSubViews[aIndex]->iView;
       
   676     }
       
   677 
       
   678 MVPbkContactViewBase* CVPbkCompositeContactView::GetChildViewById( TInt aId)
       
   679     {
       
   680     MVPbkContactViewBase* view = NULL;
       
   681     const TInt count = iSubViews.Count();
       
   682     for (TInt i = 0; i < count; ++i)
       
   683         {
       
   684         view=iSubViews[i]->iView;
       
   685         if (iSubViews[i]->iViewId == aId)
       
   686            {
       
   687            return view;
       
   688            }
       
   689         }
       
   690     return NULL;
       
   691     }
       
   692 
       
   693 TInt CVPbkCompositeContactView::GetViewId()
       
   694     {
       
   695      return iViewId;
       
   696     }
       
   697 // --------------------------------------------------------------------------
       
   698 // CVPbkCompositeContactView::SendViewReadyEvent
       
   699 // --------------------------------------------------------------------------
       
   700 //
       
   701 void CVPbkCompositeContactView::SendViewReadyEvent()
       
   702     {
       
   703     VPBK_DEBUG_PRINT( VPBK_DEBUG_STRING(
       
   704         "CVPbkCompositeContactView::SendViewReadyEvent(0x%x)"), this );
       
   705     // Cancel operation to avoid unnecessary event sending in DoAddObserverL
       
   706     iAsyncOperation.Purge();
       
   707     SendEventToObservers( *this, iObservers,
       
   708         &MVPbkContactViewObserver::ContactViewReady );
       
   709     }
       
   710 
       
   711 // --------------------------------------------------------------------------
       
   712 // CVPbkCompositeContactView::SendViewUnavailableEvent
       
   713 // --------------------------------------------------------------------------
       
   714 //
       
   715 void CVPbkCompositeContactView::SendViewUnavailableEvent()
       
   716     {
       
   717     VPBK_DEBUG_PRINT( VPBK_DEBUG_STRING(
       
   718         "CVPbkCompositeContactView::SendViewUnavailableEvent(0x%x)"), this );
       
   719     // Cancel operation to avoid unnecessary event sending in DoAddObserverL
       
   720     iAsyncOperation.Purge();
       
   721     SendEventToObservers( *this, iObservers,
       
   722         &MVPbkContactViewObserver::ContactViewUnavailable );
       
   723     }
       
   724 
       
   725 // --------------------------------------------------------------------------
       
   726 // CVPbkCompositeContactView::SendViewErrorEvent
       
   727 // --------------------------------------------------------------------------
       
   728 //
       
   729 void CVPbkCompositeContactView::SendViewErrorEvent( TInt aError,
       
   730         TBool aErrorNotified )
       
   731     {
       
   732     SendEventToObservers(*this, iObservers,
       
   733         &MVPbkContactViewObserver::ContactViewError, aError, aErrorNotified);
       
   734     }
       
   735 
       
   736 // --------------------------------------------------------------------------
       
   737 // CVPbkCompositeContactView::CompareMappings
       
   738 // --------------------------------------------------------------------------
       
   739 //
       
   740 TBool CVPbkCompositeContactView::CompareMappings
       
   741         (const TContactMapping& aLhs, const TContactMapping& aRhs)
       
   742     {
       
   743     // Mappings match if both the contact index and the view index match
       
   744     return (aLhs.iContactIndex == aRhs.iContactIndex &&
       
   745             aLhs.iViewIndex == aRhs.iViewIndex);
       
   746     }
       
   747 
       
   748 // --------------------------------------------------------------------------
       
   749 // CVPbkCompositeContactView::IsCompositeReady
       
   750 // --------------------------------------------------------------------------
       
   751 //
       
   752 TBool CVPbkCompositeContactView::IsCompositeReady() const
       
   753     {
       
   754     // Composite view is ready if states of all sub views are known and
       
   755     // at least one of them is ready.
       
   756     return AllSubViewsKnown() && AnySubViewReady();
       
   757     }
       
   758 
       
   759 // --------------------------------------------------------------------------
       
   760 // CVPbkCompositeContactView::CompositePolicy
       
   761 // --------------------------------------------------------------------------
       
   762 //
       
   763 MVPbkCompositeContactViewPolicy&
       
   764         CVPbkCompositeContactView::CompositePolicy() const
       
   765     {
       
   766     return *iCompositePolicy;
       
   767     }
       
   768 
       
   769 // --------------------------------------------------------------------------
       
   770 // CVPbkCompositeContactView::FindSubViewIndex
       
   771 // --------------------------------------------------------------------------
       
   772 //
       
   773 TInt CVPbkCompositeContactView::FindSubViewIndex
       
   774         (MVPbkContactViewBase& aView) const
       
   775     {
       
   776     TInt result = KErrNotFound;
       
   777     const TInt count = iSubViews.Count();
       
   778     for (TInt i = 0; i < count; ++i)
       
   779         {
       
   780         if (iSubViews[i]->iView == &aView)
       
   781             {
       
   782             result = i;
       
   783             break;
       
   784             }
       
   785         }
       
   786     return result;
       
   787     }
       
   788 
       
   789 // --------------------------------------------------------------------------
       
   790 // CVPbkCompositeContactView::AllSubViewsKnown
       
   791 // Returns true if all the subviews are known.
       
   792 // --------------------------------------------------------------------------
       
   793 //
       
   794 TBool CVPbkCompositeContactView::AllSubViewsKnown() const
       
   795     {
       
   796     TBool ret = ETrue;
       
   797     const TInt count = iSubViews.Count();
       
   798     for (TInt i = 0; i < count; ++i)
       
   799         {
       
   800         if (iSubViews[i]->iState == CSubViewData::ENotKnown)
       
   801             {
       
   802             ret = EFalse;
       
   803             break;
       
   804             }
       
   805         }
       
   806     return ret;
       
   807     }
       
   808 
       
   809 // --------------------------------------------------------------------------
       
   810 // CVPbkCompositeContactView::AnySubViewReady
       
   811 // Returns true if any of the subviews is ready.
       
   812 // --------------------------------------------------------------------------
       
   813 //
       
   814 TBool CVPbkCompositeContactView::AnySubViewReady() const
       
   815     {
       
   816     TBool ret = EFalse;
       
   817     const TInt count = iSubViews.Count();
       
   818     for (TInt i = 0; i < count; ++i)
       
   819         {
       
   820         if (iSubViews[i]->iState == CSubViewData::EReady)
       
   821             {
       
   822             ret = ETrue;
       
   823             break;
       
   824             }
       
   825         }
       
   826 
       
   827     return ret;
       
   828     }
       
   829 
       
   830 // --------------------------------------------------------------------------
       
   831 // CVPbkCompositeContactView::ResetContactMapping
       
   832 // --------------------------------------------------------------------------
       
   833 //
       
   834 void CVPbkCompositeContactView::ResetContactMapping()
       
   835     {
       
   836     iContactMapping.Reset();
       
   837     }
       
   838 
       
   839 // --------------------------------------------------------------------------
       
   840 // CVPbkCompositeContactView::RemoveContactMappingsFromView
       
   841 // --------------------------------------------------------------------------
       
   842 //
       
   843 void CVPbkCompositeContactView::RemoveContactMappingsFromView(
       
   844         MVPbkContactViewBase& aView )
       
   845     {
       
   846     TInt subviewIndex = FindSubViewIndex( aView );
       
   847     if ( subviewIndex != KErrNotFound )
       
   848         {
       
   849         const TInt count = iContactMapping.Count();
       
   850         for ( TInt i = count - 1; i >= 0; --i )
       
   851             {
       
   852             if ( iContactMapping[i].iViewIndex == subviewIndex )
       
   853                 {
       
   854                 iContactMapping.Remove( i );
       
   855                 }
       
   856             }
       
   857         }
       
   858     }
       
   859 
       
   860 // --------------------------------------------------------------------------
       
   861 // CVPbkCompositeContactView::HandleContactViewReadyL
       
   862 // --------------------------------------------------------------------------
       
   863 //
       
   864 void CVPbkCompositeContactView::HandleContactViewReadyL(
       
   865         MVPbkContactViewBase& aView )
       
   866     {
       
   867     VPBK_DEBUG_PRINT( VPBK_DEBUG_STRING(
       
   868         "CVPbkCompositeContactView::HandleContactViewReadyL(0x%x)"), this );
       
   869 
       
   870     // Find matching subview and set its state to ready
       
   871     TInt subViewIndex = FindSubViewIndex(aView);
       
   872     if (subViewIndex != KErrNotFound)
       
   873         {
       
   874         iSubViews[subViewIndex]->iState = CSubViewData::EReady;
       
   875         }
       
   876 
       
   877     // Check that composite's sort order up to date with subviews.
       
   878     UpdateSortOrderL();
       
   879 
       
   880     // If composite is ready, build view mapping and notify observers
       
   881     if ( IsCompositeReady() )
       
   882         {
       
   883         VPBK_PROFILE_START(VPbkProfile::ECompositeContactViewMapping);
       
   884         DoBuildContactMappingL();
       
   885         VPBK_PROFILE_END(VPbkProfile::ECompositeContactViewMapping);
       
   886         SendViewReadyEvent();
       
   887         }
       
   888     }
       
   889 
       
   890 // --------------------------------------------------------------------------
       
   891 // CVPbkCompositeContactView::HandleContactViewUnavailableL
       
   892 // --------------------------------------------------------------------------
       
   893 //
       
   894 void CVPbkCompositeContactView::HandleContactViewUnavailableL(
       
   895         MVPbkContactViewBase& aView )
       
   896     {
       
   897     VPBK_DEBUG_PRINT( VPBK_DEBUG_STRING(
       
   898         "CVPbkCompositeContactView::ContactViewUnavailable(0x%x)"), this );
       
   899 
       
   900     // Find matching subview and set its state
       
   901     TInt subViewIndex = FindSubViewIndex(aView);
       
   902     if (subViewIndex != KErrNotFound)
       
   903         {
       
   904         iSubViews[subViewIndex]->iState = CSubViewData::EUnavailable;
       
   905         }
       
   906 
       
   907     if ( IsCompositeReady() )
       
   908         {
       
   909         // Composite is still in ready state. The mapping must be updated
       
   910         // because one of the subviews became unavailable.
       
   911         DoBuildContactMappingL();
       
   912         // Call observers so that they know about update.
       
   913         SendViewReadyEvent();
       
   914         }
       
   915     else
       
   916         {
       
   917         if ( AllSubViewsKnown() )
       
   918             {
       
   919             // Composite is unavailable. Notify observers.
       
   920             ResetContactMapping();
       
   921             SendViewUnavailableEvent();
       
   922             }
       
   923         else
       
   924             {
       
   925             // Composite is still under construction.
       
   926 
       
   927             // Dont't send event here because the state of the composite is
       
   928             // not yet known and sending event can cause problems for client
       
   929             // e.g unwanted changes in the UI state.
       
   930             RemoveContactMappingsFromView( aView );
       
   931             }
       
   932         }
       
   933     }
       
   934 
       
   935 // --------------------------------------------------------------------------
       
   936 // CVPbkCompositeContactView::CVPbkCompositeContactView
       
   937 // --------------------------------------------------------------------------
       
   938 //
       
   939 TInt CVPbkCompositeContactView::HandleContactRemoval
       
   940         ( MVPbkContactViewBase& aView, TInt aIndex )
       
   941     {
       
   942     TInt index = KErrNotFound;
       
   943 
       
   944     // Find correct subview
       
   945     TInt subViewIndex = FindSubViewIndex( aView );
       
   946     if ( subViewIndex != KErrNotFound )
       
   947         {
       
   948         TIdentityRelation<TContactMapping> comparisonOperator
       
   949             ( &CVPbkCompositeContactView::CompareMappings );
       
   950         // Establish contact mapping for view and contact index
       
   951         TContactMapping mapping;
       
   952         mapping.iViewIndex = subViewIndex;
       
   953         mapping.iContactIndex = aIndex;
       
   954         // Find the composite index by comparing the two mappings
       
   955         index = iContactMapping.Find( mapping, comparisonOperator );
       
   956 
       
   957         if ( index > KErrNotFound )
       
   958             {
       
   959             // Loop through the rest of the contacts of the subview
       
   960             // and modify their global contact mapping information
       
   961             for (TInt i = 0; i < iContactMapping.Count(); ++i )
       
   962                 {
       
   963                 // Adjust the iContactIndex in the same view except the deleted one.
       
   964                 if ( ( iContactMapping[i].iViewIndex == subViewIndex ) 
       
   965                    && ( iContactMapping[i].iContactIndex >= aIndex )
       
   966                    && ( i != index ) )
       
   967                     {
       
   968                     // Subtract one because one contact was deleted, the index
       
   969                     // from the list which is bigger than the deleted one needs to be adjusted.
       
   970                     --iContactMapping[i].iContactIndex;
       
   971                     }
       
   972                 }
       
   973             // Finally remove the deleted index from global mapping
       
   974             iContactMapping.Remove( index );
       
   975             }
       
   976         else
       
   977             {
       
   978             // mapping inconsistent with the underlying view, rebuild it
       
   979             DoBuildContactMappingL();
       
   980             }
       
   981         }
       
   982     return index;
       
   983     }
       
   984 
       
   985 // --------------------------------------------------------------------------
       
   986 // CVPbkCompositeContactView::HandleContactAddition
       
   987 // --------------------------------------------------------------------------
       
   988 //
       
   989 TInt CVPbkCompositeContactView::HandleContactAddition
       
   990         (MVPbkContactViewBase& aView, TInt aIndex)
       
   991     {
       
   992     TInt index = KErrNotFound;
       
   993 
       
   994     // Find correct subview
       
   995     TInt subViewIndex = FindSubViewIndex(aView);
       
   996     if (subViewIndex != KErrNotFound)
       
   997         {
       
   998         TRAPD( err, index = DoHandleContactAdditionL
       
   999             ( subViewIndex, aIndex ) );
       
  1000         if (err != KErrNone)
       
  1001             {
       
  1002             index = err;
       
  1003             }
       
  1004         else
       
  1005             {
       
  1006         	  // We have to fix the indexes of all the succeeding
       
  1007             // contacts in the view where the contact addition took place
       
  1008             for ( TInt i = 0; i < iContactMapping.Count(); ++i )
       
  1009                 {
       
  1010                 // Adjust the iContactIndex in the same view except the added one.
       
  1011                 if ( ( iContactMapping[i].iViewIndex == subViewIndex ) 
       
  1012                    && ( iContactMapping[i].iContactIndex >= aIndex )
       
  1013                    && ( i != index ) )
       
  1014                     {
       
  1015                     // plus one because one contact was added, the index
       
  1016                     // from the list which is bigger than the deleted one needs to be adjusted.
       
  1017                     ++iContactMapping[i].iContactIndex;
       
  1018                     }
       
  1019                 }
       
  1020         	}
       
  1021         }
       
  1022     return index;
       
  1023     }
       
  1024 
       
  1025 // --------------------------------------------------------------------------
       
  1026 // CVPbkCompositeContactView::DoAddObserverL
       
  1027 // Notifies composite view readiness to observer.
       
  1028 // --------------------------------------------------------------------------
       
  1029 //
       
  1030 void CVPbkCompositeContactView::DoAddObserverL
       
  1031         (MVPbkContactViewObserver& aObserver)
       
  1032     {
       
  1033     // Check if aObserver is still observer of this view and the view is ready.
       
  1034     // View is considered to be ready if all subviews are ready (iIsReady)
       
  1035     // or if there are no subviews
       
  1036     if ( iObservers.FindInAddressOrder( &aObserver ) != KErrNotFound )
       
  1037         {
       
  1038         if( IsCompositeReady() )
       
  1039             {
       
  1040             // If this view is ready and there was no error tell it to the observer
       
  1041             aObserver.ContactViewReady(*this);
       
  1042             }
       
  1043         else if ( AllSubViewsKnown() )
       
  1044             {
       
  1045             // All subviews are known but the composite is not ready ->
       
  1046             // view is unavailable.
       
  1047             aObserver.ContactViewUnavailable( *this );
       
  1048             }
       
  1049         // If this view was not ready and there was no error, observer will
       
  1050         // be called back in HandleContactViewEvent
       
  1051         }
       
  1052     }
       
  1053 
       
  1054 // --------------------------------------------------------------------------
       
  1055 // CVPbkCompositeContactView::AddObserverError
       
  1056 // Notifies composite view problems to observer.
       
  1057 // --------------------------------------------------------------------------
       
  1058 //
       
  1059 void CVPbkCompositeContactView::AddObserverError
       
  1060         (MVPbkContactViewObserver& aObserver, TInt aError)
       
  1061     {
       
  1062     // Check if aObserver is still observer of this view
       
  1063     if (iObservers.FindInAddressOrder( &aObserver ) != KErrNotFound)
       
  1064         {
       
  1065         aObserver.ContactViewError(*this, aError, EFalse);
       
  1066         }
       
  1067     }
       
  1068 
       
  1069 // --------------------------------------------------------------------------
       
  1070 // CVPbkCompositeContactView::UpdateSortOrderL
       
  1071 // --------------------------------------------------------------------------
       
  1072 //
       
  1073 void CVPbkCompositeContactView::UpdateSortOrderL()
       
  1074     {
       
  1075     const MVPbkFieldTypeList* sortOrder = NULL;
       
  1076 
       
  1077     // Inspect the sort order of subviews. If all ready subviews have
       
  1078     // same sort order then update composite's sort order.
       
  1079     // This is done because subviews can be shared views whose sort order
       
  1080     // is not changed to client's sort order when a new handle is created.
       
  1081     TBool subViewsHaveSameOrder = ETrue;
       
  1082     const TInt count = iSubViews.Count();
       
  1083     for ( TInt i = 0; i < count && subViewsHaveSameOrder; ++i )
       
  1084         {
       
  1085         if ( iSubViews[i]->iState == CSubViewData::EReady )
       
  1086             {
       
  1087             const MVPbkFieldTypeList& curViewsOrder =
       
  1088                     iSubViews[i]->iView->SortOrder();
       
  1089             if ( sortOrder )
       
  1090                 {
       
  1091                 subViewsHaveSameOrder =
       
  1092                     VPbkFieldTypeList::IsSame( *sortOrder, curViewsOrder );
       
  1093                 }
       
  1094             sortOrder = &curViewsOrder;
       
  1095             }
       
  1096         }
       
  1097 
       
  1098     if ( subViewsHaveSameOrder && sortOrder &&
       
  1099          !VPbkFieldTypeList::IsSame( *sortOrder, *iSortOrder ) )
       
  1100         {
       
  1101         CVPbkSortOrder* newOrder = CVPbkSortOrder::NewL( *sortOrder );
       
  1102         delete iSortOrder;
       
  1103         iSortOrder = newOrder;
       
  1104         }
       
  1105     }
       
  1106 
       
  1107 void CVPbkCompositeContactView::SetViewId(TInt aViewId)
       
  1108     {
       
  1109     iViewId = aViewId;
       
  1110     }
       
  1111 // --------------------------------------------------------------------------
       
  1112 // CVPbkExternalCompositeViewPolicy::CVPbkExternalCompositeViewPolicy
       
  1113 // --------------------------------------------------------------------------
       
  1114 //
       
  1115 CVPbkExternalCompositeViewPolicy::CVPbkExternalCompositeViewPolicy(
       
  1116         CVPbkCompositeContactView& aCompositeView,
       
  1117         RPointerArray<MVPbkContactViewObserver>& aObservers )
       
  1118         :   iCompositeView( aCompositeView ),
       
  1119             iObservers( aObservers )
       
  1120     {
       
  1121     }
       
  1122 
       
  1123 // --------------------------------------------------------------------------
       
  1124 // CVPbkExternalCompositeViewPolicy::NewL
       
  1125 // --------------------------------------------------------------------------
       
  1126 //
       
  1127 CVPbkExternalCompositeViewPolicy* CVPbkExternalCompositeViewPolicy::NewL(
       
  1128         CVPbkCompositeContactView& aCompositeView,
       
  1129         RPointerArray<MVPbkContactViewObserver>& aObservers )
       
  1130     {
       
  1131     CVPbkExternalCompositeViewPolicy* self =
       
  1132         new ( ELeave ) CVPbkExternalCompositeViewPolicy( aCompositeView,
       
  1133             aObservers );
       
  1134     return self;
       
  1135     }
       
  1136 
       
  1137 // --------------------------------------------------------------------------
       
  1138 // CVPbkExternalCompositeViewPolicy::~CVPbkExternalCompositeViewPolicy
       
  1139 // --------------------------------------------------------------------------
       
  1140 //
       
  1141 CVPbkExternalCompositeViewPolicy::~CVPbkExternalCompositeViewPolicy()
       
  1142     {
       
  1143     iEventArray.ResetAndDestroy();
       
  1144     }
       
  1145 
       
  1146 // --------------------------------------------------------------------------
       
  1147 // CVPbkExternalCompositeViewPolicy::HandleViewEventsL
       
  1148 // --------------------------------------------------------------------------
       
  1149 //
       
  1150 void CVPbkExternalCompositeViewPolicy::HandleViewEventsL(
       
  1151         CVPbkEventArrayItem::TViewEventType aEvent,
       
  1152         MVPbkContactViewBase& /*aSubview*/,
       
  1153         TInt aIndex, const
       
  1154         MVPbkContactLink& aContactLink )
       
  1155     {
       
  1156     // Append all view events to proper event array.
       
  1157     CVPbkEventArrayItem* item =
       
  1158         CVPbkEventArrayItem::NewLC( aIndex, aContactLink, aEvent );
       
  1159 
       
  1160     iEventArray.AppendL( item );
       
  1161     CleanupStack::Pop(); // item
       
  1162 
       
  1163     // Check if the composite is up to date. Note that if the underlying
       
  1164     // native store view resides in a separate process or thread,
       
  1165     // this check may "accidentally" pass whilst the native view is still
       
  1166     // updating itself. This means that the composite might fall out of sync
       
  1167     // anytime after this check and it will then mean severe problems to the
       
  1168     // client, since if it asks for ContactCountL the answer will
       
  1169     // be zero, as the sync check is implemented in
       
  1170     // CVPbkExternalCompositeViewPolicy::ContactCountL too.
       
  1171     // The count of zero might be in severe contradiction with the
       
  1172     // view events the client just received.
       
  1173     // If the native view resides in the  same process, there are no risks.
       
  1174     if (iCompositeView.CompositeContactCountL() ==
       
  1175             iCompositeView.ActualContactCountL() )
       
  1176         {
       
  1177         // Composite mapping is valid according to contact counts. Flush
       
  1178         // the event cache.
       
  1179         TInt eventCount( iEventArray.Count() );
       
  1180 
       
  1181         for( TInt i = 0; i < eventCount; ++i )
       
  1182             {
       
  1183             if ( iEventArray[ i ]->Event() == CVPbkEventArrayItem::ERemoved )
       
  1184                 {
       
  1185                 SendEventToObservers( iCompositeView, iObservers,
       
  1186                     &MVPbkContactViewObserver::ContactRemovedFromView,
       
  1187                     iEventArray[ i ]->Index(),
       
  1188                     *iEventArray[ i ]->Link() );
       
  1189                 }
       
  1190             else
       
  1191                 {
       
  1192                 SendEventToObservers( iCompositeView, iObservers,
       
  1193                     &MVPbkContactViewObserver::ContactAddedToView,
       
  1194                     iEventArray[ i ]->Index(),
       
  1195                     *iEventArray[ i ]->Link() );
       
  1196                 }
       
  1197             }
       
  1198         iEventArray.ResetAndDestroy();
       
  1199         }
       
  1200     }
       
  1201 
       
  1202 // --------------------------------------------------------------------------
       
  1203 // CVPbkExternalCompositeViewPolicy::Reset
       
  1204 // --------------------------------------------------------------------------
       
  1205 //
       
  1206 void CVPbkExternalCompositeViewPolicy::Reset()
       
  1207     {
       
  1208     iEventArray.ResetAndDestroy();
       
  1209     }
       
  1210 
       
  1211 // --------------------------------------------------------------------------
       
  1212 // CVPbkExternalCompositeViewPolicy::ContactCountL
       
  1213 // --------------------------------------------------------------------------
       
  1214 //
       
  1215 TInt CVPbkExternalCompositeViewPolicy::ContactCountL() const
       
  1216     {
       
  1217     TInt compositeCount = iCompositeView.CompositeContactCountL();
       
  1218 
       
  1219     if ( compositeCount != iCompositeView.ActualContactCountL() )
       
  1220         {
       
  1221         // If composite count is different as the contact count in subviews
       
  1222         // it means that composite hasn't got all view events yet and its
       
  1223         // contact mapping is not in valid state. It's too heavy to build
       
  1224         // the whole mapping so zero is returned to inform client that
       
  1225         // it must not call ContactAtL because it can panic.
       
  1226         compositeCount = 0;
       
  1227         }
       
  1228     return compositeCount;
       
  1229     }
       
  1230 
       
  1231 // --------------------------------------------------------------------------
       
  1232 // CVPbkExternalCompositeViewPolicy::InternalPolicy
       
  1233 // --------------------------------------------------------------------------
       
  1234 //
       
  1235 TBool CVPbkExternalCompositeViewPolicy::InternalPolicy() const
       
  1236     {
       
  1237     return EFalse;
       
  1238     }
       
  1239 
       
  1240 // --------------------------------------------------------------------------
       
  1241 // CVPbkInternalCompositeViewPolicy::CVPbkInternalCompositeViewPolicy
       
  1242 // --------------------------------------------------------------------------
       
  1243 //
       
  1244 CVPbkInternalCompositeViewPolicy::CVPbkInternalCompositeViewPolicy(
       
  1245         CVPbkCompositeContactView& aCompositeView,
       
  1246         RPointerArray<MVPbkContactViewObserver>& aObservers )
       
  1247         :   iCompositeView( aCompositeView ),
       
  1248             iObservers( aObservers )
       
  1249     {
       
  1250     }
       
  1251 
       
  1252 // --------------------------------------------------------------------------
       
  1253 // CVPbkInternalCompositeViewPolicy::NewL
       
  1254 // --------------------------------------------------------------------------
       
  1255 //
       
  1256 CVPbkInternalCompositeViewPolicy* CVPbkInternalCompositeViewPolicy::NewL(
       
  1257         CVPbkCompositeContactView& aCompositeView,
       
  1258         RPointerArray<MVPbkContactViewObserver>& aObservers )
       
  1259     {
       
  1260     CVPbkInternalCompositeViewPolicy* self =
       
  1261         new ( ELeave ) CVPbkInternalCompositeViewPolicy( aCompositeView,
       
  1262             aObservers );
       
  1263     return self;
       
  1264     }
       
  1265 
       
  1266 // --------------------------------------------------------------------------
       
  1267 // CVPbkInternalCompositeViewPolicy::HandleViewEventsL
       
  1268 // --------------------------------------------------------------------------
       
  1269 //
       
  1270 void CVPbkInternalCompositeViewPolicy::HandleViewEventsL(
       
  1271         CVPbkEventArrayItem::TViewEventType aEvent,
       
  1272         MVPbkContactViewBase& /*aSubview*/,
       
  1273         TInt aIndex, const
       
  1274         MVPbkContactLink& aContactLink )
       
  1275     {
       
  1276     if ( aEvent == CVPbkEventArrayItem::ERemoved )
       
  1277         {
       
  1278         SendEventToObservers( iCompositeView, iObservers,
       
  1279             &MVPbkContactViewObserver::ContactRemovedFromView,
       
  1280             aIndex,
       
  1281             aContactLink );
       
  1282         }
       
  1283     else
       
  1284         {
       
  1285         SendEventToObservers( iCompositeView, iObservers,
       
  1286             &MVPbkContactViewObserver::ContactAddedToView,
       
  1287             aIndex,
       
  1288             aContactLink );
       
  1289         }
       
  1290     }
       
  1291 
       
  1292 // --------------------------------------------------------------------------
       
  1293 // CVPbkInternalCompositeViewPolicy::Reset
       
  1294 // --------------------------------------------------------------------------
       
  1295 //
       
  1296 void CVPbkInternalCompositeViewPolicy::Reset()
       
  1297     {
       
  1298     // No cached data to reset
       
  1299     }
       
  1300 
       
  1301 // --------------------------------------------------------------------------
       
  1302 // CVPbkInternalCompositeViewPolicy::ContactCountL
       
  1303 // --------------------------------------------------------------------------
       
  1304 //
       
  1305 TInt CVPbkInternalCompositeViewPolicy::ContactCountL() const
       
  1306     {
       
  1307     return iCompositeView.CompositeContactCountL();
       
  1308     }
       
  1309 
       
  1310 // --------------------------------------------------------------------------
       
  1311 // CVPbkInternalCompositeViewPolicy::InternalPolicy
       
  1312 // --------------------------------------------------------------------------
       
  1313 //
       
  1314 TBool CVPbkInternalCompositeViewPolicy::InternalPolicy() const
       
  1315     {
       
  1316     return ETrue;
       
  1317     }
       
  1318 
       
  1319 // End of File