phonebookengines/VirtualPhonebook/VPbkCntModel/src/CViewBase.cpp
branchRCL_3
changeset 63 f4a778e096c2
child 64 c1e8ba0c2b16
equal deleted inserted replaced
62:5b6f26637ad3 63: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:  Contacts Model store contact view implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "CViewBase.h"
       
    20 
       
    21 // INCLUDES
       
    22 
       
    23 // VPbkCntModel
       
    24 #include "CContactStore.h"
       
    25 #include "CFieldFactory.h"
       
    26 #include "CContact.h"
       
    27 #include "CFieldTypeList.h"
       
    28 #include "CContactLink.h"
       
    29 #include "CContactBookmark.h"
       
    30 #include "CFindView.h"
       
    31 #include "VPbkCntModelRemoteViewPreferences.h"
       
    32 #include "CSortOrderAcquirerList.h"
       
    33 
       
    34 // VPbkEng
       
    35 #include <MVPbkContactViewObserver.h>
       
    36 #include <MVPbkFieldType.h>
       
    37 #include <VPbkError.h>
       
    38 #include <CVPbkSortOrder.h>
       
    39 #include <CVPbkAsyncCallback.h>
       
    40 #include <VPbkPrivateUid.h>     // KFindPluingUID
       
    41 #include <VPbkSendEventUtility.h>
       
    42 #include <CVPbkContactViewDefinition.h>
       
    43 #include <MVPbkContactStoreProperties.h>
       
    44 
       
    45 // System includes
       
    46 #include <cntitem.h>
       
    47 
       
    48 // Debugging headers
       
    49 #include <VPbkDebug.h>
       
    50 
       
    51 namespace VPbkCntModel {
       
    52 
       
    53 // CONSTANTS
       
    54 
       
    55 const TInt KObserverArrayGranularity = 4;
       
    56     
       
    57 // --------------------------------------------------------------------------
       
    58 // CViewBase::CViewBase
       
    59 // --------------------------------------------------------------------------
       
    60 //
       
    61 CViewBase::CViewBase( CContactStore& aParentStore ) :
       
    62         iObservers( KObserverArrayGranularity ),
       
    63         iParentStore( aParentStore )
       
    64     {
       
    65     }
       
    66 
       
    67 // --------------------------------------------------------------------------
       
    68 // CViewBase::~CViewBase
       
    69 // --------------------------------------------------------------------------
       
    70 //
       
    71 CViewBase::~CViewBase()
       
    72     {
       
    73     delete iObserverOp;
       
    74     delete iFilterObsOp;
       
    75     delete iEventLink;
       
    76     if (iView)
       
    77         {
       
    78         iView->Close(*this);
       
    79         }
       
    80     delete iCurrentContact;
       
    81     iObservers.Close();
       
    82     iFilteringObservers.Close();
       
    83     delete iViewDefinition;
       
    84     delete iSortOrder;
       
    85     iParentStore.RemoveObserver(*this);
       
    86     }
       
    87 
       
    88 // --------------------------------------------------------------------------
       
    89 // CViewBase::ConstructL
       
    90 // --------------------------------------------------------------------------
       
    91 //
       
    92 void CViewBase::ConstructL(
       
    93         const CVPbkContactViewDefinition& aViewDefinition,
       
    94         MVPbkContactViewObserver& aObserver,
       
    95         const MVPbkFieldTypeList& aSortOrder )
       
    96     {
       
    97     iParentStore.AddObserverL(*this);
       
    98     iSortOrder = CVPbkSortOrder::NewL(aSortOrder);
       
    99     iViewDefinition = CVPbkContactViewDefinition::NewL( aViewDefinition );
       
   100 
       
   101     if ( iParentStore.IsOpened() )
       
   102         {
       
   103         InitializeViewL( aViewDefinition, aSortOrder );
       
   104         }
       
   105 
       
   106     iObserverOp =
       
   107         CVPbkAsyncObjectOperation<MVPbkContactViewObserver>::NewL();
       
   108     iFilterObsOp =
       
   109         CVPbkAsyncObjectOperation<MFilteredViewSupportObserver>::NewL();
       
   110 
       
   111     AddObserverL(aObserver);
       
   112     }
       
   113 
       
   114 // --------------------------------------------------------------------------
       
   115 // CViewBase::ConstructL
       
   116 // --------------------------------------------------------------------------
       
   117 //
       
   118 void CViewBase::ConstructL(
       
   119         const CVPbkContactViewDefinition& aViewDefinition,
       
   120         const MVPbkFieldTypeList& aSortOrder )
       
   121     {
       
   122     iParentStore.AddObserverL(*this);
       
   123     iSortOrder = CVPbkSortOrder::NewL(aSortOrder);
       
   124     iViewDefinition = CVPbkContactViewDefinition::NewL( aViewDefinition );
       
   125 
       
   126     if ( iParentStore.IsOpened() )
       
   127         {
       
   128         InitializeViewL( aViewDefinition, aSortOrder );
       
   129         }
       
   130 
       
   131     iObserverOp =
       
   132         CVPbkAsyncObjectOperation<MVPbkContactViewObserver>::NewL();
       
   133     iFilterObsOp =
       
   134         CVPbkAsyncObjectOperation<MFilteredViewSupportObserver>::NewL();
       
   135     }
       
   136 
       
   137 // --------------------------------------------------------------------------
       
   138 // CViewBase::ChangeSortOrderL
       
   139 // --------------------------------------------------------------------------
       
   140 //
       
   141 void CViewBase::ChangeSortOrderL(const MVPbkFieldTypeList& aSortOrder)
       
   142     {
       
   143     // If this view is a remote view in Contacts server a strict policy
       
   144     // must be applied for changing sortorder. Shared views are used
       
   145     // widely in S60 applications so their sortorder must be controlled
       
   146     // by S60 Phonebook application.
       
   147     LeaveIfIncorrectSortOrderL( aSortOrder );
       
   148     
       
   149     CVPbkSortOrder* newSortOrder = CVPbkSortOrder::NewL(aSortOrder);
       
   150     CleanupStack::PushL(newSortOrder);
       
   151 
       
   152     RContactViewSortOrder viewSortOrder = CreateSortOrderL(aSortOrder);
       
   153     CleanupClosePushL(viewSortOrder);
       
   154 
       
   155     if ( !DoChangeSortOrderL( *iViewDefinition, viewSortOrder ) )
       
   156         {
       
   157         TeardownView();
       
   158         InitializeViewL( *iViewDefinition, aSortOrder );
       
   159         }
       
   160     
       
   161     CleanupStack::PopAndDestroy(); // viewSortOrder
       
   162     CleanupStack::Pop(); // newSortOrder
       
   163 
       
   164     delete iSortOrder;
       
   165     iSortOrder = newSortOrder;
       
   166     }
       
   167 
       
   168 // --------------------------------------------------------------------------
       
   169 // CViewBase::SortOrder
       
   170 // --------------------------------------------------------------------------
       
   171 //
       
   172 const MVPbkFieldTypeList& CViewBase::SortOrder() const
       
   173     {
       
   174     return *iSortOrder;
       
   175     }
       
   176 
       
   177 // --------------------------------------------------------------------------
       
   178 // CViewBase::RefreshL
       
   179 // --------------------------------------------------------------------------
       
   180 //
       
   181 void CViewBase::RefreshL()
       
   182     {
       
   183     // make the view sort itself again to refresh contents
       
   184     RContactViewSortOrder viewSortOrder = CreateSortOrderL(*iSortOrder);
       
   185     CleanupClosePushL(viewSortOrder);
       
   186 
       
   187     DoChangeSortOrderL( *iViewDefinition, viewSortOrder );
       
   188 
       
   189     CleanupStack::PopAndDestroy(); // viewSortOrder
       
   190     }
       
   191 
       
   192 // --------------------------------------------------------------------------
       
   193 // CViewBase::ContactCountL
       
   194 // --------------------------------------------------------------------------
       
   195 //
       
   196 TInt CViewBase::ContactCountL() const
       
   197     {
       
   198     TInt result = 0;
       
   199     if (iViewReady)
       
   200         {
       
   201         result = iView->CountL();
       
   202         }
       
   203     return result;
       
   204     }
       
   205 
       
   206 // --------------------------------------------------------------------------
       
   207 // CViewBase::ContactAtL
       
   208 // --------------------------------------------------------------------------
       
   209 //
       
   210 const MVPbkViewContact& CViewBase::ContactAtL(TInt aIndex) const
       
   211     {
       
   212     __ASSERT_ALWAYS( aIndex >= 0,
       
   213         VPbkError::Panic( VPbkError::EInvalidContactIndex ) );
       
   214     if ( aIndex >= ContactCountL() )
       
   215         {
       
   216         User::Leave( KErrArgument );
       
   217         }
       
   218 
       
   219     const ::CViewContact& viewContact = iView->ContactAtL(aIndex);
       
   220     iCurrentContact->SetViewContact(viewContact);
       
   221     return *iCurrentContact;
       
   222     }
       
   223 
       
   224 // --------------------------------------------------------------------------
       
   225 // CViewBase::CreateLinkLC
       
   226 // --------------------------------------------------------------------------
       
   227 //
       
   228 MVPbkContactLink* CViewBase::CreateLinkLC(TInt aIndex) const
       
   229     {
       
   230     __ASSERT_ALWAYS( aIndex >= 0,
       
   231         VPbkError::Panic( VPbkError::EInvalidContactIndex ) );
       
   232     if ( aIndex >= ContactCountL() )
       
   233         {
       
   234         User::Leave( KErrArgument );
       
   235         }
       
   236 
       
   237     TContactItemId contactId = iView->AtL(aIndex);
       
   238     return CContactLink::NewLC(iParentStore, contactId);
       
   239     }
       
   240 
       
   241 // --------------------------------------------------------------------------
       
   242 // CViewBase::IndexOfLinkL
       
   243 // --------------------------------------------------------------------------
       
   244 //
       
   245 TInt CViewBase::IndexOfLinkL(const MVPbkContactLink& aContactLink) const
       
   246     {
       
   247     TInt result = KErrNotFound;
       
   248 
       
   249     if (&aContactLink.ContactStore() == &ContactStore() && iView )
       
   250         {
       
   251         const CContactLink& link = static_cast<const CContactLink&>(aContactLink);
       
   252         result = iView->FindL(link.ContactId());
       
   253         }
       
   254 
       
   255     return result;
       
   256     }
       
   257 
       
   258 // --------------------------------------------------------------------------
       
   259 // CViewBase::AddObserverL
       
   260 // --------------------------------------------------------------------------
       
   261 //
       
   262 void CViewBase::AddObserverL(MVPbkContactViewObserver& aObserver)
       
   263     {
       
   264     CVPbkAsyncObjectCallback<MVPbkContactViewObserver>* callback =
       
   265         VPbkEngUtils::CreateAsyncObjectCallbackLC(
       
   266             *this,
       
   267             &CViewBase::DoAddObserverL,
       
   268             &CViewBase::AddObserverError,
       
   269             aObserver);
       
   270     iObserverOp->CallbackL( callback );
       
   271     CleanupStack::Pop( callback );
       
   272 
       
   273     /// Insert to first position because event are send in reverse order.
       
   274     /// Last inserted gets notifcation last.
       
   275     iObservers.InsertL( &aObserver, 0 );
       
   276     }
       
   277 
       
   278 // --------------------------------------------------------------------------
       
   279 // CViewBase::RemoveObserver
       
   280 // --------------------------------------------------------------------------
       
   281 //
       
   282 void CViewBase::RemoveObserver(MVPbkContactViewObserver& aObserver)
       
   283     {
       
   284     iObserverOp->CancelCallback( &aObserver );
       
   285     const TInt index( iObservers.Find( &aObserver ) );
       
   286     if (index != KErrNotFound)
       
   287         {
       
   288         iObservers.Remove(index);
       
   289         }
       
   290     }
       
   291 
       
   292 // --------------------------------------------------------------------------
       
   293 // CViewBase::MatchContactStore
       
   294 // --------------------------------------------------------------------------
       
   295 //
       
   296 TBool CViewBase::MatchContactStore(const TDesC& aContactStoreUri) const
       
   297     {
       
   298     return iParentStore.MatchContactStore(aContactStoreUri);
       
   299     }
       
   300 
       
   301 // --------------------------------------------------------------------------
       
   302 // CViewBase::MatchContactStoreDomain
       
   303 // --------------------------------------------------------------------------
       
   304 //
       
   305 TBool CViewBase::MatchContactStoreDomain
       
   306         ( const TDesC& aContactStoreDomain ) const
       
   307     {
       
   308     return iParentStore.MatchContactStoreDomain( aContactStoreDomain );
       
   309     }
       
   310 
       
   311 // --------------------------------------------------------------------------
       
   312 // CViewBase::CreateBookmarkLC
       
   313 // --------------------------------------------------------------------------
       
   314 //
       
   315 MVPbkContactBookmark* CViewBase::CreateBookmarkLC(TInt aIndex) const
       
   316     {
       
   317     __ASSERT_ALWAYS( aIndex >= 0,
       
   318         VPbkError::Panic( VPbkError::EInvalidContactIndex ) );
       
   319 
       
   320     TContactItemId contactId = iView->AtL(aIndex);
       
   321     // Link implements also the bookmark interface in this store
       
   322     return CContactBookmark::NewLC( contactId, iParentStore );
       
   323     }
       
   324 
       
   325 // --------------------------------------------------------------------------
       
   326 // CViewBase::IndexOfBookmarkL
       
   327 // --------------------------------------------------------------------------
       
   328 //
       
   329 TInt CViewBase::IndexOfBookmarkL(
       
   330         const MVPbkContactBookmark& aContactBookmark) const
       
   331     {
       
   332     TInt result = KErrNotFound;
       
   333     // Bookmark is implemeted as a link in this store
       
   334     const CContactBookmark* bookmark =
       
   335         dynamic_cast<const CContactBookmark*>(&aContactBookmark);
       
   336     if (bookmark &&
       
   337         &bookmark->ContactStore() == &ContactStore() )
       
   338         {
       
   339         result = iView->FindL( bookmark->ContactId() );
       
   340         }
       
   341 
       
   342     return result;
       
   343     }
       
   344 
       
   345 // --------------------------------------------------------------------------
       
   346 // CViewBase::AddFilteringObserverL
       
   347 // --------------------------------------------------------------------------
       
   348 //
       
   349 void CViewBase::AddFilteringObserverL(
       
   350         MFilteredViewSupportObserver& aObserver )
       
   351     {
       
   352     // Insert observer in callback function. That ensures that the observer
       
   353     // will always get the event asynchronously.
       
   354 
       
   355     CVPbkAsyncObjectCallback<MFilteredViewSupportObserver>* callback =
       
   356         VPbkEngUtils::CreateAsyncObjectCallbackLC(
       
   357             *this,
       
   358             &CViewBase::DoAddFilteringObserverL,
       
   359             &CViewBase::DoAddFilteringObserverError,
       
   360             aObserver);
       
   361 
       
   362     iFilterObsOp->CallbackL( callback );
       
   363     CleanupStack::Pop( callback );
       
   364     }
       
   365 
       
   366 // --------------------------------------------------------------------------
       
   367 // CViewBase::RemoveFilteringObserver
       
   368 // --------------------------------------------------------------------------
       
   369 //
       
   370 void CViewBase::RemoveFilteringObserver(
       
   371         MFilteredViewSupportObserver& aObserver )
       
   372     {
       
   373     iFilterObsOp->CancelCallback( &aObserver );
       
   374     const TInt index( iFilteringObservers.Find( &aObserver ) );
       
   375     if ( index != KErrNotFound )
       
   376         {
       
   377         iFilteringObservers.Remove( index );
       
   378         }
       
   379     }
       
   380 
       
   381 // --------------------------------------------------------------------------
       
   382 // CViewBase::ViewFiltering
       
   383 // --------------------------------------------------------------------------
       
   384 //
       
   385 MVPbkContactViewFiltering* CViewBase::ViewFiltering()
       
   386     {
       
   387     // Both contact view and group view support filtering
       
   388     return this;
       
   389     }
       
   390 
       
   391 // --------------------------------------------------------------------------
       
   392 // CViewBase::CreateFilteredViewLC
       
   393 // --------------------------------------------------------------------------
       
   394 //
       
   395 MVPbkContactViewBase* CViewBase::CreateFilteredViewLC(
       
   396         MVPbkContactViewObserver& aObserver,
       
   397         const MDesCArray& aFindWords,
       
   398         const MVPbkContactBookmarkCollection* aAlwaysIncludedContacts )
       
   399     {
       
   400     CFindView* findView = CFindView::NewLC( aFindWords, *this, aObserver,
       
   401             aAlwaysIncludedContacts, Store().ContactStoreDomainFsSession() );
       
   402     findView->ActivateContactMatchL();
       
   403     return findView;
       
   404     }
       
   405 
       
   406 // --------------------------------------------------------------------------
       
   407 // CViewBase::UpdateFilterL
       
   408 // --------------------------------------------------------------------------
       
   409 //
       
   410 void CViewBase::UpdateFilterL(
       
   411         const MDesCArray& /*aFindWords*/,
       
   412         const MVPbkContactBookmarkCollection* /*aAlwaysIncludedContacts*/ )
       
   413     {
       
   414     // CViewBase implementations are "all contacts" views and not itself
       
   415     // filtered views. Only creating a filtered view is supported.
       
   416     User::Leave( KErrNotSupported );
       
   417     }
       
   418 
       
   419 // --------------------------------------------------------------------------
       
   420 // CViewBase::ParentObject
       
   421 // --------------------------------------------------------------------------
       
   422 //
       
   423 MVPbkObjectHierarchy& CViewBase::ParentObject() const
       
   424     {
       
   425     return iParentStore;
       
   426     }
       
   427 
       
   428 // --------------------------------------------------------------------------
       
   429 // CViewBase::StoreReady
       
   430 // --------------------------------------------------------------------------
       
   431 //
       
   432 void CViewBase::StoreReady( MVPbkContactStore& /*aContactStore*/ )
       
   433     {
       
   434     if ( !iViewReady )
       
   435         {
       
   436         TeardownView();
       
   437         TRAPD( error, InitializeViewL( *iViewDefinition, *iSortOrder ) );
       
   438 
       
   439         if ( error != KErrNone )
       
   440             {
       
   441             iViewReady = EFalse;
       
   442             SendViewErrorEvent( error );
       
   443             }
       
   444         }
       
   445     }
       
   446 
       
   447 // --------------------------------------------------------------------------
       
   448 // CViewBase::StoreUnavailable
       
   449 // --------------------------------------------------------------------------
       
   450 //
       
   451 void CViewBase::StoreUnavailable
       
   452         ( MVPbkContactStore& /*aContactStore*/, TInt /*aReason*/ )
       
   453     {
       
   454     TeardownView();
       
   455     iViewReady = EFalse;
       
   456     SendViewStateEvent();
       
   457     }
       
   458 
       
   459 // --------------------------------------------------------------------------
       
   460 // CViewBase::HandleStoreEventL
       
   461 // --------------------------------------------------------------------------
       
   462 //
       
   463 void CViewBase::HandleStoreEventL(
       
   464         MVPbkContactStore& /*aContactStore*/,
       
   465         TVPbkContactStoreEvent /*aStoreEvent*/)
       
   466     {
       
   467     // No need to handle this here, events are received from the view
       
   468     }
       
   469 
       
   470 // --------------------------------------------------------------------------
       
   471 // CViewBase::HandleContactViewEvent
       
   472 // --------------------------------------------------------------------------
       
   473 //
       
   474 void CViewBase::HandleContactViewEvent
       
   475         ( const CContactViewBase& /*aView*/,
       
   476           const TContactViewEvent& aEvent )
       
   477     {
       
   478     switch ( aEvent.iEventType )
       
   479         {
       
   480         case TContactViewEvent::EUnavailable:
       
   481             {
       
   482             VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   483                 ("CViewBase::HandleContactViewEvent(0x%x) EUnavailable"),
       
   484                 this );
       
   485 
       
   486             iViewReady = EFalse;
       
   487             SendViewStateEvent();
       
   488             break;
       
   489             }
       
   490         case TContactViewEvent::EReady:
       
   491             {
       
   492             VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   493                 ("CViewBase::HandleContactViewEvent(0x%x) EReady"),
       
   494                 this);
       
   495 
       
   496             iViewReady = ETrue;
       
   497             SendViewStateEvent();
       
   498             break;
       
   499             }
       
   500         case TContactViewEvent::EItemAdded:
       
   501             {
       
   502             VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   503                 ("CViewBase::HandleContactViewEvent(0x%x) EItemAdded\
       
   504                  index %d id %d"), this, aEvent.iInt, aEvent.iContactId);
       
   505             iViewReady = ETrue;
       
   506             iEventLink->SetContactId(aEvent.iContactId);
       
   507             VPbkEng::SendViewEventToObservers( *this, aEvent.iInt, *iEventLink,
       
   508                 iObservers, &MVPbkContactViewObserver::ContactAddedToView,
       
   509                 &MVPbkContactViewObserver::ContactViewError );
       
   510             VPbkEng::SendViewEventToObservers( *this, aEvent.iInt, *iEventLink,
       
   511                 iFilteringObservers,
       
   512                 &MVPbkContactViewObserver::ContactAddedToView,
       
   513                 &MVPbkContactViewObserver::ContactViewError );
       
   514             break;
       
   515             }
       
   516         case TContactViewEvent::EItemRemoved:
       
   517             {
       
   518             VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   519                 ("CViewBase::HandleContactViewEvent(0x%x) EItemRemoved\
       
   520                 index %d id %d"),
       
   521                 this, aEvent.iInt, aEvent.iContactId);
       
   522 
       
   523             iViewReady = ETrue;
       
   524             iEventLink->SetContactId( aEvent.iContactId );
       
   525             VPbkEng::SendViewEventToObservers( *this, aEvent.iInt, *iEventLink,
       
   526                 iObservers,
       
   527                 &MVPbkContactViewObserver::ContactRemovedFromView,
       
   528                 &MVPbkContactViewObserver::ContactViewError );
       
   529             VPbkEng::SendViewEventToObservers( *this, aEvent.iInt, *iEventLink,
       
   530                 iFilteringObservers,
       
   531                 &MVPbkContactViewObserver::ContactRemovedFromView,
       
   532                 &MVPbkContactViewObserver::ContactViewError );
       
   533             break;
       
   534             }
       
   535         case TContactViewEvent::ESortOrderChanged:
       
   536             {
       
   537             VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   538                 ("CViewBase::HandleContactViewEvent(0x%x) ESortOrderChanged"),
       
   539                 this);
       
   540 
       
   541             iViewReady = ETrue;
       
   542             // Update the new sort order to the view contact
       
   543             TRAPD( res, DoUpdateTypeListL() );
       
   544             if ( res != KErrNone )
       
   545                 {
       
   546                 SendViewErrorEvent( res );
       
   547                 }
       
   548             else
       
   549                 {
       
   550                 SendViewStateEvent();
       
   551                 }
       
   552             break;
       
   553             }
       
   554         case TContactViewEvent::ESortError:
       
   555             {
       
   556             VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   557                 ("CViewBase::HandleContactViewEvent(0x%x) ESortError"),
       
   558                 this);
       
   559 
       
   560             iViewReady = EFalse;
       
   561             SendViewErrorEvent( aEvent.iInt );
       
   562             break;
       
   563             }
       
   564         case TContactViewEvent::EServerError:
       
   565             {
       
   566             VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   567                 ("CViewBase::HandleContactViewEvent(0x%x) EServerError"),
       
   568                 this);
       
   569 
       
   570             iViewReady = EFalse;
       
   571             SendViewErrorEvent( aEvent.iInt );
       
   572             break;
       
   573             }
       
   574 
       
   575         case TContactViewEvent::EIndexingError:
       
   576             {
       
   577             VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   578                 ("CViewBase::HandleContactViewEvent(0x%x) EIndexingError"),
       
   579                 this);
       
   580 
       
   581             iViewReady = EFalse;
       
   582             SendViewErrorEvent( aEvent.iInt );
       
   583             break;
       
   584             }
       
   585         case TContactViewEvent::EGroupChanged: // FALLTHROUGH
       
   586             {
       
   587             VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   588                 ("CViewBase::HandleContactViewEvent(0x%x) EGroupChanged"),
       
   589                 this);
       
   590 
       
   591             // We don't send any events because EItemRemoved and/or
       
   592             // EItemAdded events are generated and those handle the UI
       
   593             // refreshing. If the view is not ready we are expecting
       
   594             // EReady event from CntModel to refresh the view.
       
   595             }
       
   596         default:
       
   597             {
       
   598             // Default is: do nothing
       
   599             VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   600                 ("CViewBase::HandleContactViewEvent(0x%x) eventType %d"),
       
   601                 this, aEvent.iEventType );
       
   602             break;
       
   603             }
       
   604         }
       
   605     }
       
   606 
       
   607 // --------------------------------------------------------------------------
       
   608 // CViewBase::HandleCustomContactViewEvent
       
   609 // --------------------------------------------------------------------------
       
   610 //
       
   611 void CViewBase::HandleCustomContactViewEvent
       
   612         ( const CContactViewBase& aView,
       
   613           const TContactViewEvent& aEvent )
       
   614     {
       
   615     VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
       
   616         ("CViewBase::HandleCustomContactViewEvent(0x%x)"), &aView);
       
   617 
       
   618     // This function needs to behave like HandleContactViewEvent function
       
   619     // above, but without notifying observers. The observers will be notified
       
   620     // later, with the succeeding HandleContactViewEvent call.
       
   621     switch ( aEvent.iEventType )
       
   622         {
       
   623         case TContactViewEvent::EReady:             // FALLTHROUGH
       
   624         case TContactViewEvent::EItemAdded:         // FALLTHROUGH
       
   625         case TContactViewEvent::EItemRemoved:       // FALLTHROUGH
       
   626         case TContactViewEvent::ESortOrderChanged:  // FALLTHROUGH
       
   627         case TContactViewEvent::EGroupChanged:      // FALLTHROUGH
       
   628             {
       
   629             iViewReady = ETrue;
       
   630             break;
       
   631             }
       
   632 
       
   633         case TContactViewEvent::EUnavailable:       // FALLTHROUGH
       
   634         case TContactViewEvent::ESortError:         // FALLTHROUGH
       
   635         case TContactViewEvent::EServerError:       // FALLTHROUGH
       
   636         case TContactViewEvent::EIndexingError:     // FALLTHROUGH
       
   637             {
       
   638             iViewReady = EFalse;
       
   639             break;
       
   640             }
       
   641         default:
       
   642             {
       
   643             // Do nothing
       
   644             break;
       
   645             }
       
   646         }
       
   647     }
       
   648 
       
   649 // --------------------------------------------------------------------------
       
   650 // CViewBase::CreateSortOrderL
       
   651 // --------------------------------------------------------------------------
       
   652 //
       
   653 RContactViewSortOrder CViewBase::CreateSortOrderL
       
   654         ( const MVPbkFieldTypeList& aSortOrder )
       
   655     {
       
   656     RContactViewSortOrder sortOrder;
       
   657     CleanupClosePushL(sortOrder);
       
   658 
       
   659     const TInt count = aSortOrder.FieldTypeCount();
       
   660     for (TInt i = 0; i < count; ++i)
       
   661         {
       
   662         const MVPbkFieldType& fieldType = aSortOrder.FieldTypeAt(i);
       
   663         // Ignores all field types that are not supported by this store
       
   664         const CContactItemField* field =
       
   665             iParentStore.FieldFactory().FindField(fieldType);
       
   666         if (field)
       
   667             {
       
   668             sortOrder.AppendL(field->ContentType().FieldType(0));
       
   669             }
       
   670         }
       
   671     CleanupStack::Pop(); // sortOrder
       
   672 
       
   673     return sortOrder;
       
   674     }
       
   675 
       
   676 // --------------------------------------------------------------------------
       
   677 // CViewBase::DoUpdateTypeListL
       
   678 // --------------------------------------------------------------------------
       
   679 //
       
   680 void CViewBase::DoUpdateTypeListL()
       
   681     {
       
   682     MVPbkFieldTypeList* typeList = CFieldTypeList::NewLC
       
   683         (iView->SortOrderL(), iParentStore.FieldTypeMap());
       
   684     iCurrentContact->SetTypeListL(*typeList);
       
   685 
       
   686     CVPbkSortOrder* sortOrder = CVPbkSortOrder::NewL(*typeList);
       
   687     delete iSortOrder;
       
   688     iSortOrder = sortOrder;
       
   689     CleanupStack::PopAndDestroy(); // typeList
       
   690     }
       
   691 
       
   692 // --------------------------------------------------------------------------
       
   693 // CViewBase::DoAddObserverL
       
   694 // --------------------------------------------------------------------------
       
   695 //
       
   696 void CViewBase::DoAddObserverL(MVPbkContactViewObserver& aObserver)
       
   697     {
       
   698     // Check if aObserver is still observer of this view
       
   699     if ( iObservers.Find( &aObserver ) != KErrNotFound )
       
   700         {
       
   701         if (iViewReady)
       
   702             {
       
   703             // If this view is ready and there was no error,
       
   704             // tell it to the observer
       
   705             aObserver.ContactViewReady(*this);
       
   706             }
       
   707         else if (!iViewReady && !iParentStore.IsOpened())
       
   708             {
       
   709             aObserver.ContactViewUnavailable(*this);
       
   710             }
       
   711         // If this view was not ready and there was no error, observer will
       
   712         // be called back in HandleContactViewEvent
       
   713         }
       
   714     }
       
   715 
       
   716 // --------------------------------------------------------------------------
       
   717 // CViewBase::AddObserverError
       
   718 // --------------------------------------------------------------------------
       
   719 //
       
   720 void CViewBase::AddObserverError(MVPbkContactViewObserver& aObserver, TInt aError)
       
   721     {
       
   722     // Check if aObserver is still observer of this view
       
   723     if ( iObservers.Find( &aObserver ) != KErrNotFound)
       
   724         {
       
   725         aObserver.ContactViewError(*this, aError, EFalse);
       
   726         }
       
   727     }
       
   728 
       
   729 // --------------------------------------------------------------------------
       
   730 // CViewBase::DoAddFilteringObserverL
       
   731 // --------------------------------------------------------------------------
       
   732 //
       
   733 void CViewBase::DoAddFilteringObserverL(
       
   734         MFilteredViewSupportObserver& aObserver )
       
   735     {
       
   736     /// Insert to first position because event are send in reverse order.
       
   737     /// Last inserted gets notifcation last.
       
   738     iFilteringObservers.InsertL( &aObserver, 0 );
       
   739 
       
   740     if (iViewReady)
       
   741         {
       
   742         // If this view is ready and there was no error.
       
   743         // Build filtered view first using the internal interface
       
   744         aObserver.ContactViewReadyForFiltering( *this );
       
   745         // Then let the filtered view to send event to its external
       
   746         // observers.
       
   747         // aObserver.ContactViewReady( *this ); // removed to function CFindViewBase::ContactViewReadyForFiltering(...)
       
   748         }
       
   749     else if (!iViewReady && !iParentStore.IsOpened())
       
   750         {
       
   751         aObserver.ContactViewUnavailableForFiltering( *this );
       
   752         aObserver.ContactViewUnavailable( *this );
       
   753         }
       
   754     }
       
   755 
       
   756 // --------------------------------------------------------------------------
       
   757 // CViewBase::DoAddFilteringObserverError
       
   758 // --------------------------------------------------------------------------
       
   759 //
       
   760 void CViewBase::DoAddFilteringObserverError(
       
   761         MFilteredViewSupportObserver& aObserver, TInt aError )
       
   762     {
       
   763     // See DoAddFilteringObserverL. If it leaves then adding the aObserver
       
   764     // failed.
       
   765     aObserver.ContactViewError(*this, aError, EFalse);
       
   766     }
       
   767 
       
   768 // --------------------------------------------------------------------------
       
   769 // CViewBase::InitializeViewL
       
   770 // --------------------------------------------------------------------------
       
   771 //
       
   772 void CViewBase::InitializeViewL( 
       
   773         const CVPbkContactViewDefinition& aViewDefinition,
       
   774         const MVPbkFieldTypeList& aSortOrder )
       
   775     {
       
   776     
       
   777     CViewContact* vievContact = CViewContact::NewL( *this, aSortOrder );
       
   778     if ( iCurrentContact )
       
   779         {
       
   780         delete iCurrentContact;
       
   781         iCurrentContact = NULL;
       
   782         }
       
   783     iCurrentContact = vievContact;
       
   784     vievContact = NULL;
       
   785     
       
   786     RContactViewSortOrder viewSortOrder = CreateSortOrderL( aSortOrder );
       
   787     CleanupClosePushL( viewSortOrder );
       
   788 
       
   789     // Let sub class create the concrete view to iView
       
   790     DoInitializeViewL( aViewDefinition, viewSortOrder );
       
   791     // Update sort order because shared view can have a different
       
   792     // sort order compared to aSortOrder. Creating a new remote view
       
   793     // handle to Contacts Model shared view doesn't change the sort order
       
   794     // in Contacts Server shared view.
       
   795     if ( iView )
       
   796         {
       
   797         DoUpdateTypeListL();
       
   798     
       
   799         // Set find plugin uid, without this cntmodel find does not work with
       
   800         // all variants.
       
   801         iView->SetViewFindConfigPlugin( TUid::Uid( KFindPluginUID ) );
       
   802         }
       
   803 
       
   804     CleanupStack::PopAndDestroy(); // viewSortOrder
       
   805 
       
   806     CContactLink* contactLink= CContactLink::NewLC( iParentStore, KNullContactId );
       
   807     CleanupStack::Pop( contactLink );
       
   808     if ( iEventLink )
       
   809         {
       
   810         delete iEventLink;
       
   811         iEventLink = NULL;
       
   812         }
       
   813     iEventLink = contactLink;
       
   814     contactLink = NULL;
       
   815     }
       
   816 
       
   817 // --------------------------------------------------------------------------
       
   818 // CViewBase::TeardownView
       
   819 // --------------------------------------------------------------------------
       
   820 //
       
   821 void CViewBase::TeardownView()
       
   822     {
       
   823     delete iCurrentContact;
       
   824     iCurrentContact = NULL;
       
   825 
       
   826     if (iView)
       
   827         {
       
   828         iView->Close(*this);
       
   829         iView = NULL;
       
   830         }
       
   831 
       
   832     delete iEventLink;
       
   833     iEventLink = NULL;
       
   834 
       
   835     DoTeardownView();
       
   836     }
       
   837 
       
   838 // --------------------------------------------------------------------------
       
   839 // CViewBase::SendViewErrorEvent
       
   840 // --------------------------------------------------------------------------
       
   841 //
       
   842 void CViewBase::SendViewErrorEvent( TInt aError )
       
   843     {
       
   844     // Cancel async operation to avoid double message sending
       
   845     // to observer in DoAddObserverL
       
   846     PurgeAsyncOperations();
       
   847 
       
   848     /// Then report the failure to client so that in handle it.
       
   849     TBool errorIsNotified = EFalse;
       
   850     VPbkEng::SendEventToObservers( *this, aError, errorIsNotified,
       
   851         iObservers, &MVPbkContactViewObserver::ContactViewError );
       
   852     VPbkEng::SendEventToObservers( *this, aError, errorIsNotified,
       
   853         iFilteringObservers, &MVPbkContactViewObserver::ContactViewError );
       
   854     }
       
   855 
       
   856 // --------------------------------------------------------------------------
       
   857 // CViewBase::SendViewStateEvent
       
   858 // --------------------------------------------------------------------------
       
   859 //
       
   860 void CViewBase::SendViewStateEvent()
       
   861     {
       
   862     // Cancel async operation to avoid double message sending
       
   863     // to observer in DoAddObserverL
       
   864     PurgeAsyncOperations();
       
   865 
       
   866     void (MVPbkContactViewObserver::*obsNotifyFunc)(
       
   867             MVPbkContactViewBase&) =
       
   868                 &MVPbkContactViewObserver::ContactViewReady;
       
   869     void (MFilteredViewSupportObserver::*filtObsNotifyFunc)(
       
   870             MParentViewForFiltering&) =
       
   871                 &MFilteredViewSupportObserver::ContactViewReadyForFiltering;
       
   872 
       
   873     if ( !iViewReady )
       
   874         {
       
   875         obsNotifyFunc = &MVPbkContactViewObserver::ContactViewUnavailable;
       
   876         filtObsNotifyFunc =
       
   877             &MFilteredViewSupportObserver::ContactViewUnavailableForFiltering;
       
   878         }
       
   879 
       
   880     // Due to filtered view stack it must be ensured that internal filtered
       
   881     // views know first about changes because CRefineViews have pointers to
       
   882     // contacts that must not be invalidated.
       
   883     // On the other hand the events to external observers must come
       
   884     // first from lowest view in the view stack.
       
   885     // See MVPbkContactViewFiltering interface.
       
   886     VPbkEng::SendViewEventToObservers( *this, iFilteringObservers,
       
   887         filtObsNotifyFunc, &MVPbkContactViewObserver::ContactViewError );
       
   888     VPbkEng::SendViewEventToObservers( *this, iObservers,
       
   889         obsNotifyFunc, &MVPbkContactViewObserver::ContactViewError );
       
   890     VPbkEng::SendViewEventToObservers( *this, iFilteringObservers,
       
   891         obsNotifyFunc, &MVPbkContactViewObserver::ContactViewError );
       
   892     }
       
   893 
       
   894 // --------------------------------------------------------------------------
       
   895 // CViewBase::PurgeAsyncOperations
       
   896 // --------------------------------------------------------------------------
       
   897 //
       
   898 void CViewBase::PurgeAsyncOperations()
       
   899     {
       
   900     // Purge only iObserverOp callbacks because observers are added
       
   901     // already in AddObserverL. iFilterObsOp must not be purged because
       
   902     // filtering observers are added in a call back DoAddFilteringObserverL.
       
   903     iObserverOp->Purge();
       
   904     }
       
   905 
       
   906 // --------------------------------------------------------------------------
       
   907 // CViewBase::LeaveIfIncorrectSortOrderL
       
   908 // --------------------------------------------------------------------------
       
   909 //
       
   910 void CViewBase::LeaveIfIncorrectSortOrderL( 
       
   911         const MVPbkFieldTypeList& aSortOrder )
       
   912     {
       
   913     if ( RemoteViewDefinition( *iViewDefinition ) )
       
   914         {
       
   915         // Get allowed sort orders via ECOM
       
   916         CVPbkSortOrderAcquirer::TSortOrderAcquirerParam param(
       
   917             iParentStore.MasterFieldTypeList() );
       
   918         CSortOrderAcquirerList* ecomList = 
       
   919                 CSortOrderAcquirerList::NewLC(param);
       
   920     
       
   921         const TInt count = ecomList->Count();
       
   922         for ( TInt i = 0; i < count; ++i )
       
   923             {
       
   924             CVPbkSortOrderAcquirer& acquirer = ecomList->At( i );
       
   925             // Sort order is incorrect if
       
   926             // 1) acquirer is for this store
       
   927             // 2) this is a shared view and acquirer is for the
       
   928             //    same named view.
       
   929             // 3) aSortOrder is not same as acquirer's sort order.
       
   930             if ( acquirer.ApplySortOrderToStoreL( 
       
   931                     iParentStore.StoreProperties().Uri() ) &&
       
   932                  ecomList->FindInfo(acquirer)->DisplayName().CompareC(
       
   933                     RemoteViewName( *iViewDefinition ) ) == 0 &&
       
   934                  !VPbkFieldTypeList::IsSame( acquirer.SortOrder(), 
       
   935                     aSortOrder) )
       
   936                 {
       
   937                 User::Leave( KErrArgument );
       
   938                 }
       
   939             }
       
   940         CleanupStack::PopAndDestroy( ecomList );
       
   941         }
       
   942     }
       
   943 } // namespace VPbkCntModel
       
   944 
       
   945 // End of File