--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/VirtualPhonebook/VPbkSimStore/src/CContactView.cpp Wed Sep 01 12:29:52 2010 +0100
@@ -0,0 +1,944 @@
+/*
+* Copyright (c) 2002-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Virtual phonebook view implementation
+*
+*/
+
+
+#include "CContactView.h"
+
+// VPbkSimStore
+#include "CFieldTypeMappings.h"
+#include "CContactStore.h"
+#include "CViewContact.h"
+#include "CRemoteStore.h"
+#include "CRemoteView.h"
+#include "CContactLink.h"
+#include "VPbkSimStoreError.h"
+#include "CSupportedFieldTypes.h"
+#include "CFindView.h"
+#include "RemoteViewPreferences.h"
+#include "CSortOrderAcquirerList.h"
+
+// VPbkEngUtils
+#include <CVPbkAsyncOperation.h>
+#include <CVPbkAsyncCallback.h>
+
+// VPbkEng
+#include <CVPbkSortOrder.h>
+#include <CVPbkContactViewDefinition.h>
+#include <CVPbkFieldTypeSelector.h>
+#include <CVPbkFieldTypeRefsList.h>
+#include <MVPbkContactViewObserver.h>
+#include <MVPbkFieldType.h>
+#include <MVPbkContactStoreProperties.h>
+#include <VPbkSendEventUtility.h>
+#include <VPbkError.h>
+
+// VPbkSimStoreImpl
+#include <CVPbkSimFieldTypeFilter.h>
+#include <CVPbkSimContactView.h>
+#include <RVPbkStreamedIntArray.h>
+#include <MVPbkSimContact.h>
+
+
+namespace VPbkSimStore {
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// --------------------------------------------------------------------------
+// ConvertSortOrderL
+// Converts VPbk sort order to native sort order
+// --------------------------------------------------------------------------
+//
+void ConvertSortOrderL( const MVPbkFieldTypeList& aSource,
+ RVPbkSimFieldTypeArray& aTarget, CFieldTypeMappings& aMappings )
+ {
+ TInt typeCount = aSource.FieldTypeCount();
+ for ( TInt i = 0; i < typeCount; ++i )
+ {
+ const MVPbkFieldType& vpbkType = aSource.FieldTypeAt( i );
+ TVPbkSimCntFieldType simType =
+ aMappings.Match( vpbkType );
+ if ( simType != EVPbkSimUnknownType )
+ {
+ aTarget.AppendL( simType );
+ }
+ }
+ __ASSERT_DEBUG( aTarget.Count() > 0,
+ VPbkSimStore::Panic( VPbkSimStore::EZeroSortOrder ) );
+ }
+
+// --------------------------------------------------------------------------
+// ConvertSortOrderL
+// Converts VPbk sort order to native sort order
+// --------------------------------------------------------------------------
+//
+void ConvertSortOrderL( const RVPbkSimFieldTypeArray& aSource,
+ CVPbkFieldTypeRefsList& aTarget, CFieldTypeMappings& aMappings )
+ {
+ TInt typeCount = aSource.Count();
+ for ( TInt i = 0; i < typeCount; ++i )
+ {
+ const MVPbkFieldType* vpbkType = aMappings.Match( aSource[i] );
+ if ( vpbkType )
+ {
+ aTarget.AppendL( *vpbkType );
+ }
+ }
+ __ASSERT_DEBUG( aTarget.FieldTypeCount() > 0,
+ VPbkSimStore::Panic( VPbkSimStore::EZeroSortOrder ) );
+ }
+
+// --------------------------------------------------------------------------
+// ConvertFieldTypeFilter
+// Converts VPbk field type filter to native filter
+// --------------------------------------------------------------------------
+//
+void ConvertFieldTypeFilter( CVPbkFieldTypeSelector& aSource,
+ CVPbkSimFieldTypeFilter& aTarget,
+ const MVPbkFieldTypeList& aFieldTypeList,
+ CFieldTypeMappings& aMappings )
+ {
+ TInt typeCount = aFieldTypeList.FieldTypeCount();
+ for ( TInt i = 0; i < typeCount; ++i )
+ {
+ const MVPbkFieldType& fieldType =
+ aFieldTypeList.FieldTypeAt( i );
+
+ if ( aSource.IsFieldTypeIncluded( fieldType ) )
+ {
+ // Match was found, now find out the which
+ // SIM field type maps to the match
+ TVPbkSimCntFieldType simType = EVPbkSimUnknownType;
+
+ const TVPbkFieldVersitProperty* versitProperty =
+ aSource.MatchingVersitProperty( fieldType );
+ if ( versitProperty )
+ {
+ simType = aMappings.Match( *versitProperty );
+ }
+ else
+ {
+ TVPbkNonVersitFieldType nonVersitType =
+ aSource.MatchingNonVersitType( fieldType );
+
+ if ( nonVersitType != EVPbkNonVersitTypeNone )
+ {
+ simType = aMappings.Match( nonVersitType );
+ }
+ }
+
+ // Construct a filter based on the SIM field type
+ TUint16 filteringFlag =
+ aTarget.FilteringFlagForSimFieldType( simType );
+ aTarget.AppendFilteringFlag( filteringFlag );
+
+ // Add also additional number to the filtering
+ // if main number is included
+ if ( filteringFlag &
+ CVPbkSimFieldTypeFilter::ESimFilterCriteriaGsmNumber )
+ {
+ aTarget.AppendFilteringFlag(
+ CVPbkSimFieldTypeFilter::ESimFilterCriteriaAdditionalNumber );
+ }
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// ConvertSortPolicy
+// Convert between EVPbkSortedSimView and EVPbkUnsortedContactView
+// --------------------------------------------------------------------------
+//
+TVPbkSimViewConstructionPolicy ConvertSortPolicy(
+ TVPbkContactViewSortPolicy aVPbkSortPolicy )
+ {
+ TVPbkSimViewConstructionPolicy sortPolicy = EVPbkSortedSimView;
+ if ( aVPbkSortPolicy == EVPbkUnsortedContactView )
+ {
+ sortPolicy = EVPbkUnsortedSimView;
+ }
+ return sortPolicy;
+ }
+
+// --------------------------------------------------------------------------
+// FindFieldTypeIndex
+// --------------------------------------------------------------------------
+//
+TInt FindFieldTypeIndex( const MVPbkFieldTypeList& aTypeList,
+ const MVPbkFieldType& aType )
+ {
+ TInt result = KErrNotFound;
+ const TInt count = aTypeList.FieldTypeCount();
+ for ( TInt i = 0; i < count && result == KErrNotFound; ++i )
+ {
+ if ( aTypeList.FieldTypeAt(i).IsSame( aType ) )
+ {
+ result = i;
+ }
+ }
+ return result;
+ }
+
+// ============================ MEMBER FUNCTIONS ============================
+
+// --------------------------------------------------------------------------
+// CContactView::CContactView
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// --------------------------------------------------------------------------
+//
+inline CContactView::CContactView(CContactStore& aParentStore) :
+ iParentStore(aParentStore),
+ iViewState( ENotReady )
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::~CContactView
+// --------------------------------------------------------------------------
+//
+CContactView::~CContactView()
+ {
+ delete iViewDefinition;
+ delete iObserverOp;
+ delete iFilterObsOp;
+ delete iCurrentContact;
+ delete iSortOrder;
+ if ( iNativeView )
+ {
+ iNativeView->Close( *this );
+ delete iNativeView;
+ }
+ iObservers.Close();
+ iFilteringObservers.Close();
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::NewLC
+// Two-phased constructor.
+// --------------------------------------------------------------------------
+//
+CContactView* CContactView::NewLC(MVPbkContactViewObserver& aObserver,
+ CContactStore& aParentStore,
+ const MVPbkFieldTypeList& aSortOrder,
+ const CVPbkContactViewDefinition& aViewDefinition)
+ {
+ CContactView* self = new(ELeave) CContactView(aParentStore);
+ CleanupStack::PushL(self);
+ self->ConstructL(aSortOrder, aViewDefinition);
+ self->AddObserverL(aObserver);
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::ConstructL
+// Symbian 2nd phase constructor can leave.
+// --------------------------------------------------------------------------
+//
+void CContactView::ConstructL( const MVPbkFieldTypeList& aSortOrder,
+ const CVPbkContactViewDefinition& aViewDefinition )
+ {
+ // Copy the sort order
+ iSortOrder = CVPbkSortOrder::NewL( aSortOrder );
+
+ // Create current view contact
+ iCurrentContact = CViewContact::NewL( *this, *iSortOrder );
+
+ iViewDefinition = CVPbkContactViewDefinition::NewL( aViewDefinition );
+
+ // Convert VPbk sort order to sim sort order
+ RVPbkSimFieldTypeArray sortOrder;
+ CleanupClosePushL( sortOrder );
+ ConvertSortOrderL( aSortOrder, sortOrder,
+ iParentStore.FieldTypeMappings() );
+
+ CVPbkSimFieldTypeFilter* filter = new ( ELeave ) CVPbkSimFieldTypeFilter;
+ CVPbkFieldTypeSelector* selector = iViewDefinition->FieldTypeFilter();
+ if ( selector )
+ {
+ // First construct filter for supported SIM fields
+ ConvertFieldTypeFilter( *selector, *filter,
+ iParentStore.MasterFieldTypeList(),
+ iParentStore.FieldTypeMappings() );
+ }
+
+ // Sorted or SIM index ordered view.
+ TVPbkSimViewConstructionPolicy sortPolicy = ConvertSortPolicy(
+ iViewDefinition->SortPolicy() );
+
+ if ( RemoteViewDefinition( *iViewDefinition ) )
+ {
+ // Create a remote view from remote store
+ iNativeView = iParentStore.NativeStore().CreateViewL( sortOrder,
+ sortPolicy, RemoteViewName( *iViewDefinition ), filter );
+ }
+ else
+ {
+ // Create a local view
+ CVPbkSimContactView* view = CVPbkSimContactView::NewLC( sortOrder,
+ sortPolicy, iParentStore.NativeStore(),
+ RemoteViewName( *iViewDefinition ), filter );
+ CleanupStack::Pop( view );
+ iNativeView = view;
+ }
+
+ iNativeView->OpenL( *this );
+ CleanupStack::PopAndDestroy(); // sortOrder
+
+ iObserverOp =
+ CVPbkAsyncObjectOperation<MVPbkContactViewObserver>::NewL();
+ iFilterObsOp =
+ CVPbkAsyncObjectOperation<MFilteredViewSupportObserver>::NewL();
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::ParentObject
+// --------------------------------------------------------------------------
+//
+MVPbkObjectHierarchy& CContactView::ParentObject() const
+ {
+ return iParentStore;
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::Type
+// --------------------------------------------------------------------------
+//
+TVPbkContactViewType CContactView::Type() const
+ {
+ return EVPbkContactsView;
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::ChangeSortOrderL
+// --------------------------------------------------------------------------
+//
+void CContactView::ChangeSortOrderL( const MVPbkFieldTypeList& aSortOrder )
+ {
+ // Check that S60 shared view sort order is not changed illegally.
+ LeaveIfIncorrectSortOrderL( aSortOrder );
+
+ // Create a new sort order
+ CVPbkSortOrder* sortOrder = CVPbkSortOrder::NewL( aSortOrder );
+ CleanupStack::PushL( sortOrder );
+
+ // Change remote view sort order
+ RVPbkSimFieldTypeArray nativeOrder;
+ CleanupClosePushL( nativeOrder );
+ ConvertSortOrderL( *sortOrder, nativeOrder,
+ iParentStore.FieldTypeMappings() );
+ iNativeView->ChangeSortOrderL( nativeOrder );
+ CleanupStack::PopAndDestroy( &nativeOrder );
+
+ // Swap
+ delete iSortOrder;
+ iSortOrder = sortOrder;
+ CleanupStack::Pop( sortOrder );
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::SortOrder
+// --------------------------------------------------------------------------
+//
+const MVPbkFieldTypeList& CContactView::SortOrder() const
+ {
+ return *iSortOrder;
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::RefreshL
+// --------------------------------------------------------------------------
+//
+void CContactView::RefreshL()
+ {
+ // Rebuild view
+ RVPbkSimFieldTypeArray sortOrder;
+ CleanupClosePushL( sortOrder );
+ ConvertSortOrderL( *iSortOrder, sortOrder,
+ iParentStore.FieldTypeMappings() );
+ iNativeView->ChangeSortOrderL( sortOrder );
+ CleanupStack::PopAndDestroy(); // sortOrder
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::ContactCountL
+// --------------------------------------------------------------------------
+//
+TInt CContactView::ContactCountL() const
+ {
+ TInt res = 0;
+ if ( State() == EReady )
+ {
+ res = iNativeView->CountL();
+ }
+ return res;
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::ContactAtL
+// --------------------------------------------------------------------------
+//
+const MVPbkViewContact& CContactView::ContactAtL( TInt aIndex ) const
+ {
+ __ASSERT_ALWAYS( aIndex >= KErrNotFound,
+ VPbkError::Panic( VPbkError::EInvalidContactIndex ) );
+
+ if( aIndex == KErrNotFound)
+ {
+ User::Leave( KErrNotFound );
+ }
+ else if ( aIndex >= iNativeView->CountL() )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ iCurrentContact->SetSimContactL( iNativeView->ContactAtL( aIndex ) );
+ return *iCurrentContact;
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::CreateLinkLC
+// --------------------------------------------------------------------------
+//
+MVPbkContactLink* CContactView::CreateLinkLC( TInt aIndex ) const
+ {
+ __ASSERT_ALWAYS( aIndex >= 0,
+ VPbkError::Panic(VPbkError::EInvalidContactIndex) );
+ if ( aIndex >= iNativeView->CountL() )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ TInt simIndex = MapViewIndexToSimIndexL( aIndex );
+ return CContactLink::NewLC( iParentStore, simIndex );
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::IndexOfLinkL
+// --------------------------------------------------------------------------
+//
+TInt CContactView::IndexOfLinkL( const MVPbkContactLink& aContactLink ) const
+ {
+ if ( &aContactLink.ContactStore() == &iParentStore )
+ {
+ TInt simIndex =
+ static_cast<const CContactLink&>( aContactLink ).SimIndex();
+ return iNativeView->MapSimIndexToViewIndexL( simIndex );
+ }
+ return KErrNotFound;
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::AddObserverL
+// --------------------------------------------------------------------------
+//
+void CContactView::AddObserverL( MVPbkContactViewObserver& aObserver )
+ {
+ CVPbkAsyncObjectCallback<MVPbkContactViewObserver>* callback =
+ VPbkEngUtils::CreateAsyncObjectCallbackLC(
+ *this,
+ &CContactView::DoAddObserverL,
+ &CContactView::AddObserverError,
+ aObserver);
+
+ iObserverOp->CallbackL( callback );
+ CleanupStack::Pop( callback );
+
+ /// Insert to first position because event are send in reverse order.
+ /// Last inserted gets notifcation last.
+ if ( iObservers.Find( &aObserver ) == KErrNotFound )
+ {
+ iObservers.InsertL( &aObserver, 0 );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::RemoveObserver
+// --------------------------------------------------------------------------
+//
+void CContactView::RemoveObserver( MVPbkContactViewObserver& aObserver )
+ {
+ iObserverOp->CancelCallback( &aObserver );
+ TInt pos = iObservers.Find( &aObserver );
+ if ( pos != KErrNotFound )
+ {
+ iObservers.Remove( pos );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::MatchContactStore
+// --------------------------------------------------------------------------
+//
+TBool CContactView::MatchContactStore(const TDesC& aContactStoreUri) const
+ {
+ return iParentStore.MatchContactStore(aContactStoreUri);
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::MatchContactStoreDomain
+// --------------------------------------------------------------------------
+//
+TBool CContactView::MatchContactStoreDomain(
+ const TDesC& aContactStoreDomain) const
+ {
+ return iParentStore.MatchContactStoreDomain(aContactStoreDomain);
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::CreateBookmarkLC
+// --------------------------------------------------------------------------
+//
+MVPbkContactBookmark* CContactView::CreateBookmarkLC(TInt aIndex) const
+ {
+ __ASSERT_ALWAYS( aIndex >= 0,
+ VPbkError::Panic( VPbkError::EInvalidContactIndex ) );
+
+ TInt simIndex = MapViewIndexToSimIndexL( aIndex );
+ // This store implements bookmark as a link
+ return CContactLink::NewLC( iParentStore, simIndex );
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::IndexOfBookmarkL
+// --------------------------------------------------------------------------
+//
+TInt CContactView::IndexOfBookmarkL(
+ const MVPbkContactBookmark& aContactBookmark) const
+ {
+ // Bookmark is implemented as a link in this store
+ const CContactLink* link =
+ dynamic_cast<const CContactLink*>( &aContactBookmark );
+ if ( link && ( &link->ContactStore() == &iParentStore ) )
+ {
+ return iNativeView->MapSimIndexToViewIndexL( link->SimIndex() );
+ }
+ return KErrNotFound;
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::AddFilteringObserverL
+// --------------------------------------------------------------------------
+//
+void CContactView::AddFilteringObserverL(
+ MFilteredViewSupportObserver& aObserver )
+ {
+ // Add observer in the callback to ensure that observer will get the
+ // event asynchrnously all times.
+ CVPbkAsyncObjectCallback<MFilteredViewSupportObserver>* callback =
+ VPbkEngUtils::CreateAsyncObjectCallbackLC(
+ *this,
+ &CContactView::DoAddFilteringObserverL,
+ &CContactView::DoAddFilteringObserverError,
+ aObserver);
+
+ iFilterObsOp->CallbackL( callback );
+ CleanupStack::Pop( callback );
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::RemoveFilteringObserver
+// --------------------------------------------------------------------------
+//
+void CContactView::RemoveFilteringObserver(
+ MFilteredViewSupportObserver& aObserver )
+ {
+ iFilterObsOp->CancelCallback( &aObserver );
+ const TInt index( iFilteringObservers.Find( &aObserver ) );
+ if ( index != KErrNotFound )
+ {
+ iFilteringObservers.Remove( index );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::IsNativeMatchingRequestActive
+// --------------------------------------------------------------------------
+//
+TBool CContactView::IsNativeMatchingRequestActive()
+ {
+ return EFalse;
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::ViewFiltering
+// --------------------------------------------------------------------------
+//
+MVPbkContactViewFiltering* CContactView::ViewFiltering()
+ {
+ return this;
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::CreateFilteredViewLC
+// --------------------------------------------------------------------------
+//
+MVPbkContactViewBase* CContactView::CreateFilteredViewLC(
+ MVPbkContactViewObserver& aObserver,
+ const MDesCArray& aFindWords,
+ const MVPbkContactBookmarkCollection* aAlwaysIncludedContacts )
+ {
+ CFindView* findView = CFindView::NewLC( aFindWords, *this, aObserver,
+ aAlwaysIncludedContacts, Store().ContactStoreDomainFsSession() );
+ findView->ActivateContactMatchL();
+ return findView;
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::UpdateFilterL
+// --------------------------------------------------------------------------
+//
+void CContactView::UpdateFilterL(
+ const MDesCArray& /*aFindWords*/,
+ const MVPbkContactBookmarkCollection* /*aAlwaysIncludedContacts*/ )
+ {
+ // This view itself is not a filtered view.
+ User::Leave( KErrNotSupported );
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::ViewReady
+// --------------------------------------------------------------------------
+//
+void CContactView::ViewReady( MVPbkSimCntView& aView )
+ {
+ // Due to fact that native view can be a remote view the sort order
+ // must be up to date with the actual view in server side.
+ TInt inspectionResult = KErrNone;
+ TRAPD( res, inspectionResult = InspectSortOrderL() );
+ if ( res == KErrNone )
+ {
+ res = inspectionResult;
+ }
+
+ if ( res == KErrNone )
+ {
+ iViewState = EReady;
+ iCurrentContact->SetSortOrder( *iSortOrder );
+ SendViewStateEvent();
+ }
+ else
+ {
+ ViewError( aView, res );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::ViewError
+// --------------------------------------------------------------------------
+//
+void CContactView::ViewError( MVPbkSimCntView& /*aView*/, TInt aError )
+ {
+ iViewState = ENotAvailable;
+ SendViewErrorEvent( aError );
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::ViewNotAvailable
+// --------------------------------------------------------------------------
+//
+void CContactView::ViewNotAvailable( MVPbkSimCntView& /*aView*/ )
+ {
+ iViewState = ENotAvailable;
+ SendViewStateEvent();
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::ViewContactEvent
+// --------------------------------------------------------------------------
+//
+void CContactView::ViewContactEvent( TEvent aEvent, TInt aIndex,
+ TInt aSimIndex )
+ {
+ CContactLink* link = NULL;
+ TRAPD( result,
+ {
+ link = CContactLink::NewLC( iParentStore, aSimIndex );
+ CleanupStack::Pop( link );
+ });
+ if ( result != KErrNone )
+ {
+ ViewError( *iNativeView, result );
+ return;
+ }
+
+ switch ( aEvent )
+ {
+ case EContactAdded:
+ {
+ // First to external observers of this view
+ VPbkEng::SendViewEventToObservers( *this, aIndex, *link,
+ iObservers,
+ &MVPbkContactViewObserver::ContactAddedToView,
+ &MVPbkContactViewObserver::ContactViewError );
+ // Then to internal filtering observers
+ VPbkEng::SendViewEventToObservers( *this, aIndex, *link,
+ iFilteringObservers,
+ &MVPbkContactViewObserver::ContactAddedToView,
+ &MVPbkContactViewObserver::ContactViewError );
+ break;
+ }
+ case EContactDeleted:
+ {
+ // First to external observers of this view
+ VPbkEng::SendViewEventToObservers( *this, aIndex, *link,
+ iObservers,
+ &MVPbkContactViewObserver::ContactRemovedFromView,
+ &MVPbkContactViewObserver::ContactViewError );
+ // Then to internal filtering observers
+ VPbkEng::SendViewEventToObservers( *this, aIndex, *link,
+ iFilteringObservers,
+ &MVPbkContactViewObserver::ContactRemovedFromView,
+ &MVPbkContactViewObserver::ContactViewError );
+ break;
+ }
+ default:
+ {
+ __ASSERT_DEBUG( EFalse,
+ VPbkSimStore::Panic( VPbkSimStore::EUnknownSimViewEvent ) );
+ SendViewErrorEvent( KErrUnknown );
+ break;
+ }
+ }
+
+ delete link;
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::InspectSortOrderL
+// --------------------------------------------------------------------------
+//
+TInt CContactView::InspectSortOrderL()
+ {
+ // Get sort order from SIM view
+ const RVPbkSimFieldTypeArray& nativeOrder = iNativeView->SortOrderL();
+ CVPbkFieldTypeRefsList* fieldTypes = CVPbkFieldTypeRefsList::NewL();
+ CleanupStack::PushL( fieldTypes );
+ // Convert to VPbk format
+ ConvertSortOrderL( nativeOrder, *fieldTypes,
+ iParentStore.FieldTypeMappings() );
+
+ // Check that all native field types are found from iSortOrder that
+ // came from client. Types must be also in same order in nativeOrder
+ // as in iSortOrder but there can be types in iSortOrder that are not
+ // supported by nativeOrder.
+ TInt result = KErrNone;
+ TInt typeIndex = KErrNotFound;
+ const TInt nativeCount = fieldTypes->FieldTypeCount();
+ for ( TInt i = 0; i < nativeCount && result == KErrNone; ++i )
+ {
+ TInt index = FindFieldTypeIndex( *iSortOrder,
+ fieldTypes->FieldTypeAt(i) );
+ // Check the order of native order type against iSortOrder type
+ if ( index <= typeIndex )
+ {
+ // If this is the case then client has tried to create a
+ result = KErrArgument;
+ }
+ typeIndex = index;
+ }
+
+ CleanupStack::PopAndDestroy( fieldTypes );
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::MapViewIndexToSimIndexL
+// --------------------------------------------------------------------------
+//
+TInt CContactView::MapViewIndexToSimIndexL( TInt aViewIndex ) const
+ {
+ MVPbkSimContact& cnt = iNativeView->ContactAtL( aViewIndex );
+ return cnt.SimIndex();
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::DoAddObserverL
+// --------------------------------------------------------------------------
+//
+void CContactView::DoAddObserverL(MVPbkContactViewObserver& aObserver)
+ {
+ if ( iViewState == EReady )
+ {
+ // If this view is ready and there was no error,
+ // tell it to the observer
+ aObserver.ContactViewReady( *this );
+ }
+ else if ( iViewState == ENotAvailable )
+ {
+ // AddObserverL must always make a callback according VPbk API
+ // documentation. If iViewState is ENotReady then the call back
+ // will be caused by CRemoteView::OpenL
+ aObserver.ContactViewUnavailable( *this );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::AddObserverError
+// --------------------------------------------------------------------------
+//
+void CContactView::AddObserverError( MVPbkContactViewObserver& aObserver,
+ TInt aError )
+ {
+ aObserver.ContactViewError(*this, aError, EFalse);
+ }
+
+// --------------------------------------------------------------------------
+// CViewBase::DoAddFilteringObserverL
+// --------------------------------------------------------------------------
+//
+void CContactView::DoAddFilteringObserverL(
+ MFilteredViewSupportObserver& aObserver )
+ {
+ /// Insert to first position because event are send in reverse order.
+ /// Last inserted gets notifcation last.
+ iFilteringObservers.InsertL( &aObserver, 0 );
+
+ if ( iViewState == EReady )
+ {
+ // If this view is ready and there was no error,
+ // tell it to the observer
+ aObserver.ContactViewReadyForFiltering( *this );
+ aObserver.ContactViewReady( *this );
+ }
+ else if ( iViewState == ENotAvailable )
+ {
+ // If iViewState is ENotReady then the call back
+ // will be caused by CRemoteView::OpenL
+ aObserver.ContactViewUnavailableForFiltering( *this );
+ aObserver.ContactViewUnavailable( *this );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::DoAddFilteringObserverError
+// --------------------------------------------------------------------------
+//
+void CContactView::DoAddFilteringObserverError(
+ MFilteredViewSupportObserver& aObserver, TInt aError )
+ {
+ aObserver.ContactViewError(*this, aError, EFalse);
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::PurgeObserverCallbacks
+// --------------------------------------------------------------------------
+//
+void CContactView::PurgeObserverCallbacks()
+ {
+ // Cancel all async observer callbacks
+ iObserverOp->Purge();
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::SendViewStateEvent
+// --------------------------------------------------------------------------
+//
+void CContactView::SendViewStateEvent()
+ {
+ if ( iViewState != ENotReady )
+ {
+ // Cancel async operation to avoid double message sending
+ // to observer in DoAddObserverL
+ PurgeObserverCallbacks();
+
+ void (MVPbkContactViewObserver::*obsNotifyFunc)(
+ MVPbkContactViewBase&) =
+ &MVPbkContactViewObserver::ContactViewReady;
+ void (MFilteredViewSupportObserver::*filtObsNotifyFunc)(
+ MParentViewForFiltering&) =
+ &MFilteredViewSupportObserver::ContactViewReadyForFiltering;
+
+ if ( iViewState == ENotAvailable )
+ {
+ obsNotifyFunc = &MVPbkContactViewObserver::ContactViewUnavailable;
+ filtObsNotifyFunc =
+ &MFilteredViewSupportObserver::ContactViewUnavailableForFiltering;
+ }
+
+ // Due to filtered view stack it must be ensured that internal
+ // filtered views know first about changes because CRefineViews
+ // have pointers to contacts that must not be invalidated.
+ // On the other hand the events to external observers must come
+ // first from lowest view in the view stack.
+ // See MVPbkContactViewFiltering interface.
+ VPbkEng::SendViewEventToObservers( *this, iFilteringObservers,
+ filtObsNotifyFunc, &MVPbkContactViewObserver::ContactViewError );
+ VPbkEng::SendViewEventToObservers( *this, iObservers,
+ obsNotifyFunc, &MVPbkContactViewObserver::ContactViewError );
+ VPbkEng::SendViewEventToObservers( *this, iFilteringObservers,
+ obsNotifyFunc, &MVPbkContactViewObserver::ContactViewError );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::SendViewStateEvent
+// --------------------------------------------------------------------------
+//
+void CContactView::SendViewErrorEvent( TInt aError )
+ {
+ // Cancel async operation to avoid double message sending
+ // to observer in DoAddObserverL
+ PurgeObserverCallbacks();
+
+ /// Then report the failure to client so that in handle it.
+ TBool errorIsNotified = EFalse;
+ VPbkEng::SendEventToObservers( *this, aError, errorIsNotified,
+ iObservers, &MVPbkContactViewObserver::ContactViewError );
+ VPbkEng::SendEventToObservers( *this, aError, errorIsNotified,
+ iFilteringObservers, &MVPbkContactViewObserver::ContactViewError );
+ }
+
+// --------------------------------------------------------------------------
+// CContactView::LeaveIfIncorrectSortOrderL
+// --------------------------------------------------------------------------
+//
+void CContactView::LeaveIfIncorrectSortOrderL(
+ const MVPbkFieldTypeList& aSortOrder )
+ {
+ if ( RemoteViewDefinition( *iViewDefinition ) )
+ {
+ // Get allowed sort orders via ECOM
+ CVPbkSortOrderAcquirer::TSortOrderAcquirerParam param(
+ iParentStore.MasterFieldTypeList() );
+ CSortOrderAcquirerList* ecomList =
+ CSortOrderAcquirerList::NewLC(param);
+
+ const TInt count = ecomList->Count();
+ for ( TInt i = 0; i < count; ++i )
+ {
+ CVPbkSortOrderAcquirer& acquirer = ecomList->At( i );
+ // Sort order is incorrect if
+ // 1) acquirer is for this store
+ // 2) this is a shared view and acquirer is for the
+ // same named view.
+ // 3) aSortOrder is not same as acquirer's sort order.
+ if ( acquirer.ApplySortOrderToStoreL(
+ iParentStore.StoreProperties().Uri() ) &&
+ ecomList->FindInfo(acquirer)->DisplayName().CompareC(
+ RemoteViewName( *iViewDefinition ) ) == 0 &&
+ !VPbkFieldTypeList::IsSame( acquirer.SortOrder(),
+ aSortOrder) )
+ {
+ User::Leave( KErrArgument );
+ }
+ }
+ CleanupStack::PopAndDestroy( ecomList );
+ }
+ }
+} // namespace VPbkSimStore
+
+// End of File