diff -r 000000000000 -r e686773b3f54 phonebookengines/VirtualPhonebook/VPbkCntModel/src/CContactStore.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookengines/VirtualPhonebook/VPbkCntModel/src/CContactStore.cpp Tue Feb 02 10:12:17 2010 +0200 @@ -0,0 +1,1584 @@ +/* +* 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: Contacts Model store contact store implementation. +* +*/ + + +// INCLUDES +#include "CContactStore.h" + +// VPbkCntModel +#include "CFieldFactory.h" +#include "CFieldTypeMap.h" +#include "CAsyncContactOperation.h" +#include "CContact.h" +#include "CContactLink.h" +#include "CContactBookmark.h" +#include "CContactView.h" +#include "CFilteredContactView.h" +#include "CFilteredGroupView.h" +#include "CGroupView.h" +#include "CContactStoreDomain.h" +#include "CFieldInfo.h" +#include "CContactRetriever.h" +#include "CDeleteContactsOperation.h" +#include "CCommitContactsOperation.h" +#include "CMatchPhoneNumberOperation.h" +#include "CFindOperation.h" +#include "CFindInTextDefOperation.h" +#include "CContactStoreInfo.h" +#include "CVPbkDiskSpaceCheck.h" +#include "CNamedRemoteViewHandle.h" +#include "CSortOrderAcquirerList.h" +#include "VoiceTagSupport.h" +#include "CContactLink.h" +#include "COwnContactLinkOperation.h" +#include + +// Virtual Phonebook +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Contacts Model +#include +#include +#include + +// System includes +#include +#include +#include +#include +#include + +// Debugging headers +#include + + +namespace VPbkCntModel { + +#ifdef _DEBUG +_LIT( KContactStorePanicCat, "VPbkCntModel_CContactStore" ); +void ContactStorePanic( TContactStorePanic aPanic ) + { + User::Panic( KContactStorePanicCat, aPanic); + } +#endif // _DEBUG + +/// Unnamed namespace for local definitions +namespace { + +// LOCAL +_LIT(KCntResFile, "cntmodel.rsc"); +_LIT(KCntExtResFile, "VPbkCntModelRes.rsc"); + +// CONSTANTS +const TInt KDefaultArrayGranularity = 4; +const TInt KDiskSpaceForDbOpening = 140 * 1024; // 140 kB space for db opening + +inline void SendEventL(MVPbkContactStoreObserver* aObserver, + void (MVPbkContactStoreObserver::*aEventFunc)(MVPbkContactStore&), + MVPbkContactStore& aStore) + { + (aObserver->*aEventFunc)(aStore); + } + +inline void SendEventL( + MVPbkContactStoreObserver* aObserver, + void (MVPbkContactStoreObserver::*aEventFunc)(MVPbkContactStore&,TVPbkContactStoreEvent), + MVPbkContactStore& aStore, + TVPbkContactStoreEvent aEvent) + { + (aObserver->*aEventFunc)(aStore, aEvent); + } + +inline void SendErrorEvent(MVPbkContactStoreObserver* aObserver, + void (MVPbkContactStoreObserver::*aEventFunc)(MVPbkContactStore&,TInt), + MVPbkContactStore& aStore, TInt aError) + { + (aObserver->*aEventFunc)(aStore, aError); + } + +void SendEventL + (RPointerArray& aObservers, + void (MVPbkContactStoreObserver::*aEventFunc)(MVPbkContactStore&), + MVPbkContactStore& aStore) + { + for (TInt i = aObservers.Count() - 1; i >= 0; --i) + { + SendEventL(aObservers[i], aEventFunc, aStore); + } + } + +void SendEventL + (RPointerArray& aObservers, + void (MVPbkContactStoreObserver::*aEventFunc)(MVPbkContactStore&,TVPbkContactStoreEvent), + MVPbkContactStore& aStore, + TVPbkContactStoreEvent aEvent) + { + for (TInt i = aObservers.Count() - 1; i >= 0; --i) + { + SendEventL(aObservers[i], aEventFunc, aStore, aEvent); + } + } + +void SendErrorEvent + (RPointerArray& aObservers, + void (MVPbkContactStoreObserver::*aEventFunc)(MVPbkContactStore&,TInt), + MVPbkContactStore& aStore, TInt aError) + { + for (TInt i = aObservers.Count() - 1; i >= 0; --i) + { + SendErrorEvent(aObservers[i], aEventFunc, aStore, aError); + } + } + +TBool UpdateSystemTemplateFieldL(CContactItem& aSystemTemplate, + const CFieldInfo& aFieldInfo ) + { + TBool updated = EFalse; + // Scan system template field set for the field + CContactItemFieldSet& fieldSet = aSystemTemplate.CardFields(); + const TInt fieldCount = fieldSet.Count(); + TInt i = 0; + for (; i < fieldCount; ++i) + { + CContactItemField& sysTemplateField = fieldSet[i]; + if (aFieldInfo.IsEqualType(sysTemplateField)) + { + // Field was found, just check the label + if (!aFieldInfo.IsEqualLabel(sysTemplateField)) + { + sysTemplateField.SetLabelL(aFieldInfo.FieldName()); + updated = ETrue; + } + break; + } + } + + if ( i == fieldCount ) + { + // Field was not found, add it + CContactItemField* field = aFieldInfo.CreateFieldL(); + CleanupStack::PushL( field ); + fieldSet.AddL( *field ); + CleanupStack::Pop( field ); + updated = ETrue; + } + + return updated; + } + +TBool UpdateSystemTemplateFieldsL(CContactItem& aSystemTemplate, const CFieldsInfo& aFieldsInfo) + { + TBool updated = EFalse; + const TInt fieldInfoCount = aFieldsInfo.Count(); + + for (TInt i = 0; i < fieldInfoCount; ++i) + { + if (UpdateSystemTemplateFieldL(aSystemTemplate, *aFieldsInfo.At(i))) + { + updated = ETrue; + } + } + return updated; + } + + +TVPbkContactStoreEvent MapDbEventToStoreEvent(TContactDbObserverEvent aEvent) + { + TVPbkContactStoreEvent result(TVPbkContactStoreEvent::ENullEvent, NULL); + + switch (aEvent.iType) + { + case EContactDbObserverEventContactAdded: + { + result.iEventType = TVPbkContactStoreEvent::EContactAdded; + break; + } + case EContactDbObserverEventContactDeleted: + case EContactDbObserverEventOwnCardDeleted: + { + result.iEventType = TVPbkContactStoreEvent::EContactDeleted; + break; + } + case EContactDbObserverEventContactChanged: + case EContactDbObserverEventSpeedDialsChanged: + case EContactDbObserverEventOwnCardChanged: + { + result.iEventType = TVPbkContactStoreEvent::EContactChanged; + break; + } + case EContactDbObserverEventGroupAdded: + { + result.iEventType = TVPbkContactStoreEvent::EGroupAdded; + break; + } + case EContactDbObserverEventGroupDeleted: + { + result.iEventType = TVPbkContactStoreEvent::EGroupDeleted; + break; + } + case EContactDbObserverEventGroupChanged: + { + result.iEventType = TVPbkContactStoreEvent::EGroupChanged; + break; + } + case EContactDbObserverEventUnknownChanges: + { + result.iEventType = TVPbkContactStoreEvent::EUnknownChanges; + break; + } + case EContactDbObserverEventBackupBeginning: + { + result.iEventType = TVPbkContactStoreEvent::EStoreBackupBeginning; + break; + } + case EContactDbObserverEventRestoreBeginning: + { + result.iEventType = TVPbkContactStoreEvent::EStoreRestoreBeginning; + break; + } + case EContactDbObserverEventBackupRestoreCompleted: + { + result.iEventType = TVPbkContactStoreEvent::EStoreBackupRestoreCompleted; + break; + } + case EContactDbObserverEventCurrentItemDeleted: // FALLTHROUGH + case EContactDbObserverEventCurrentItemChanged: // FALLTHROUGH + case EContactDbObserverEventCurrentDatabaseChanged: // FALLTHROUGH + case EContactDbObserverEventRestoreBadDatabase: // FALLTHROUGH + case EContactDbObserverEventSortOrderChanged: // FALLTHROUGH + case EContactDbObserverEventPreferredTemplateChanged: // FALLTHROUGH + case EContactDbObserverEventRecover: // FALLTHROUGH + case EContactDbObserverEventRollback: // FALLTHROUGH + case EContactDbObserverEventTablesClosed: // FALLTHROUGH + case EContactDbObserverEventTablesOpened: // FALLTHROUGH + case EContactDbObserverEventTemplateChanged: // FALLTHROUGH + case EContactDbObserverEventTemplateDeleted: // FALLTHROUGH + case EContactDbObserverEventTemplateAdded: // FALLTHROUGH + case EContactDbObserverEventNull: // FALLTHROUGH + case EContactDbObserverEventUnused: // FALLTHROUGH + default: + { + result.iEventType = TVPbkContactStoreEvent::ENullEvent; + break; + } + } + + return result; + } + +} // unnamed namespace + + + +// -------------------------------------------------------------------------- +// CContactStore::CContactStore +// -------------------------------------------------------------------------- +// +CContactStore::CContactStore( CContactStoreDomain& aStoreDomain ) : + iStoreDomain( aStoreDomain ) + { + } + +// -------------------------------------------------------------------------- +// CContactStore::~CContactStore +// -------------------------------------------------------------------------- +// +CContactStore::~CContactStore() + { + VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING + ("CContactStore::~CContactStore(0x%x)"), this); + + iNamedViewContainer.ResetAndDestroy(); + CloseSystemTemplate(iContactDb); + iObservers.Close(); + delete iStoreInfo; + delete iDbNotifier; + delete iContactDb; + delete iAsyncContactOperation; + delete iAsyncOpenOp; + delete iStoreURI; + delete iFieldFactory; + delete iFieldsInfo; + delete iProperties; + delete iDiskSpaceCheck; + FeatureManager::UnInitializeLib(); + } + +// -------------------------------------------------------------------------- +// CContactStore::NewL +// -------------------------------------------------------------------------- +// +CContactStore* CContactStore::NewL + (const TVPbkContactStoreUriPtr& aURI, + CContactStoreDomain& aStoreDomain) + { + CContactStore* self = new(ELeave) CContactStore(aStoreDomain); + CleanupStack::PushL(self); + self->ConstructL(aURI); + CleanupStack::Pop(self); + return self; + } + +// -------------------------------------------------------------------------- +// CContactStore::ConstructL +// -------------------------------------------------------------------------- +// +inline void CContactStore::ConstructL( + const TVPbkContactStoreUriPtr& aURI) + { + VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING + ("CContactStore::ConstructL(%S)"), &aURI.UriDes()); + + FeatureManager::InitializeLibL(); + iProperties = CVPbkContactStoreProperties::NewL(); + iStoreURI = CVPbkContactStoreUri::NewL(aURI); + iProperties->SetName(iStoreURI->Uri()); + + // open and read the contacts model resource file cntmodel.rsc + VPbkEngUtils::RLocalizedResourceFile resFile; + resFile.OpenLC(iStoreDomain.FsSession(), + KVPbkRomFileDrive, KDC_CONTACTS_RESOURCE_DIR, KCntResFile); + + TResourceReader reader; + reader.SetBuffer( resFile.AllocReadLC(R_CNTUI_NEW_FIELD_DEFNS) ); + // create the fields info structure from the contacts model fields + iFieldsInfo = CFieldsInfo::NewL(reader); + CleanupStack::PopAndDestroy(2); // R_CNTUI_NEW_FIELD_DEFNS buffer, resFile + + // Extend the contacts model golden template with variant fields + DoAddFieldTypesL(); + + iAsyncOpenOp = + CVPbkAsyncObjectOperation::NewL(); + iAsyncContactOperation = CAsyncContactOperation::NewL(*this); + + iStoreInfo = CContactStoreInfo::NewL(*this, iStoreDomain); + + // Get contact store location drive for disk space check + const TPtrC ptr( iStoreURI->Uri().Component + ( TVPbkContactStoreUriPtr::EContactStoreUriStoreDrive ) ); + TInt drive( EDriveA ); // c is usually the default location + User::LeaveIfError( iStoreDomain.FsSession().CharToDrive + ( ptr[0], drive) ); + iDiskSpaceCheck = VPbkEngUtils::CVPbkDiskSpaceCheck::NewL + ( iStoreDomain.FsSession(), drive ); + + VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING + ("CContactStore::ConstructL end")); + } + +// -------------------------------------------------------------------------- +// CContactStore::FieldTypeMap +// -------------------------------------------------------------------------- +// +const CFieldTypeMap& CContactStore::FieldTypeMap() const + { + return iStoreDomain.FieldTypeMap(); + } + +// -------------------------------------------------------------------------- +// CContactStore::FieldFactory +// -------------------------------------------------------------------------- +// +const CFieldFactory& CContactStore::FieldFactory() const + { + return *iFieldFactory; + } + +// -------------------------------------------------------------------------- +// CContactStore::MasterFieldTypeList +// -------------------------------------------------------------------------- +// +const MVPbkFieldTypeList& CContactStore::MasterFieldTypeList() const + { + return iStoreDomain.MasterFieldTypeList(); + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateFieldLC +// -------------------------------------------------------------------------- +// +CContactItemField* CContactStore::CreateFieldLC + (const MVPbkFieldType& aFieldType) const + { + return iFieldFactory->CreateFieldLC(aFieldType); + } + +// -------------------------------------------------------------------------- +// CContactStore::ReadContactL +// -------------------------------------------------------------------------- +// +void CContactStore::ReadContactL + (TContactItemId aContactId, MVPbkContactObserver& aObserver) + { + iAsyncContactOperation->PrepareL + (MVPbkContactObserver::EContactRead, aContactId, aObserver); + iAsyncContactOperation->Execute(); + } + +// -------------------------------------------------------------------------- +// CContactStore::LockContactL +// -------------------------------------------------------------------------- +// +void CContactStore::LockContactL + (const CContact& aContact, MVPbkContactObserver& aObserver) + { + iAsyncContactOperation->PrepareL + (MVPbkContactObserver::EContactLock, aContact, aObserver); + iAsyncContactOperation->Execute(); + } + +// -------------------------------------------------------------------------- +// CContactStore::ReadAndLockContactL +// -------------------------------------------------------------------------- +// +void CContactStore::ReadAndLockContactL + (TContactItemId aContactId, MVPbkContactObserver& aObserver) + { + iAsyncContactOperation->PrepareL + (MVPbkContactObserver::EContactReadAndLock, aContactId, aObserver); + iAsyncContactOperation->Execute(); + } + +// -------------------------------------------------------------------------- +// CContactStore::DeleteContactL +// -------------------------------------------------------------------------- +// +void CContactStore::DeleteContactL + (TContactItemId aContactId, MVPbkContactObserver& aObserver) + { + iAsyncContactOperation->PrepareL + (MVPbkContactObserver::EContactDelete, aContactId, aObserver); + iAsyncContactOperation->Execute(); + } + +// -------------------------------------------------------------------------- +// CContactStore::CommitContactL +// -------------------------------------------------------------------------- +// +void CContactStore::CommitContactL( + const CContact& aContactItem, + MVPbkContactObserver& aObserver) + { + VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING + ("CContactStore::CommitContactL(0x%x,0x%x)"), + &aContactItem, &aObserver); + + iDiskSpaceCheck->DiskSpaceCheckL(); + + // verify sync field content + VPbkUtils::VerifySyncronizationFieldL( + iStoreDomain.FsSession(), + StoreProperties().SupportedFields(), + const_cast(aContactItem)); + + iAsyncContactOperation->PrepareL + (MVPbkContactObserver::EContactCommit, aContactItem, aObserver); + iAsyncContactOperation->Execute(); + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateLinkLC +// -------------------------------------------------------------------------- +// +MVPbkContactLink* CContactStore::CreateLinkLC(TContactItemId aContactId) const + { + MVPbkContactLink* ret = NULL; + // if aContactId is KGoldenTemplateId then it is probably new contact + // which is not commited to contactdb, return null then + if ( aContactId != KGoldenTemplateId && + aContactId != KNullContactId ) + { + // Contact store constness casted away, no reason to be const + ret = CContactLink::NewLC(const_cast(*this), aContactId); + } + return ret; + } + +// -------------------------------------------------------------------------- +// CContactStore::ContactDestroyed +// -------------------------------------------------------------------------- +// +void CContactStore::ContactDestroyed(CContactItem* aContactItem, TBool aCloseContact ) + { + // Release any lock on contact. + if (aContactItem) + { + // Check that contact store is open + __ASSERT_DEBUG( iContactDb, + ContactStorePanic( EPreCond_ContactDestroyed ) ); + + // Cancel async operation if any + iAsyncContactOperation->Cancel( aContactItem ); + + if ( aCloseContact ) + { + // CloseContactL doesn't leave despite its name. + iContactDb->CloseContactL(aContactItem->Id()); + } + } + } + +// -------------------------------------------------------------------------- +// CContactStore::MatchContactStore +// -------------------------------------------------------------------------- +// +TBool CContactStore::MatchContactStore(const TDesC& aContactStoreUri) const + { + if (iStoreURI->Uri().Compare( + TVPbkContactStoreUriPtr(aContactStoreUri), + TVPbkContactStoreUriPtr::EContactStoreUriAllComponents) == 0) + { + return ETrue; + } + return EFalse; + } + +// -------------------------------------------------------------------------- +// CContactStore::MatchContactStoreDomain +// -------------------------------------------------------------------------- +// +TBool CContactStore::MatchContactStoreDomain(const TDesC& aContactStoreDomain) const + { + if (iStoreURI->Uri().Compare( + aContactStoreDomain, + TVPbkContactStoreUriPtr::EContactStoreUriStoreType) == 0) + { + return ETrue; + } + return EFalse; + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateBookmarkLC +// -------------------------------------------------------------------------- +// +MVPbkContactBookmark* CContactStore::CreateBookmarkLC( + TContactItemId aContactId) const + { + // Contact store constness casted away, no reason to be const + return CContactBookmark::NewLC( aContactId, + const_cast(*this) ); + } + +// -------------------------------------------------------------------------- +// CContactStore::StoreProperties +// -------------------------------------------------------------------------- +// +const MVPbkContactStoreProperties& CContactStore::StoreProperties() const + { + return *iProperties; + } + +// -------------------------------------------------------------------------- +// CContactStore::OpenL +// -------------------------------------------------------------------------- +// +void CContactStore::OpenL( + MVPbkContactStoreObserver& aObserver) + { + VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING + ("CContactStore::OpenL(0x%x)"), &aObserver); + + AddObserverL(aObserver); + CVPbkAsyncObjectCallback* openCallback = + VPbkEngUtils::CreateAsyncObjectCallbackLC( + *this, + &CContactStore::DoOpenL, + TBool(EFalse), + &CContactStore::OpenError, + aObserver); + iAsyncOpenOp->CallbackL(openCallback); + CleanupStack::Pop( openCallback ); + } + +// -------------------------------------------------------------------------- +// CContactStore::ReplaceL +// -------------------------------------------------------------------------- +// +void CContactStore::ReplaceL(MVPbkContactStoreObserver& aObserver) + { + VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING + ("CContactStore::ReplaceL(0x%x)"), &aObserver); + + AddObserverL(aObserver); + CVPbkAsyncObjectCallback* openCallback = + VPbkEngUtils::CreateAsyncObjectCallbackLC( + *this, + &CContactStore::DoOpenL, + TBool(ETrue), + &CContactStore::OpenError, + aObserver); + iAsyncOpenOp->CallbackL(openCallback); + CleanupStack::Pop(openCallback); + } + +// -------------------------------------------------------------------------- +// CContactStore::Close +// -------------------------------------------------------------------------- +// +void CContactStore::Close( MVPbkContactStoreObserver& aObserver) + { + VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING + ("CContactStore::Close(0x%x)"), &aObserver); + + // Cancel open callback, If not active then it does nothing. + iAsyncOpenOp->CancelCallback( &aObserver ); + // Remove the observer from the observer list. + RemoveObserver(aObserver); + if (iObservers.Count() == 0) + { + iNamedViewContainer.ResetAndDestroy(); + // Zero observers left, clean the resources. + iAsyncOpenOp->Purge(); + delete iFieldFactory; + iFieldFactory = NULL; + delete iDbNotifier; + iDbNotifier = NULL; + delete iContactDb; + iContactDb = NULL; + } + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateNewContactLC +// -------------------------------------------------------------------------- +// +MVPbkStoreContact* CContactStore::CreateNewContactLC() + { + TRAPD( err, iDiskSpaceCheck->DiskSpaceCheckL() ); + if ( err != KErrNone ) + { + CCoeEnv::Static()->HandleError( err ); + } + CContactItem* newContact = CContactCard::NewLC(); + CContact* result = CContact::NewL(*this, newContact, ETrue); + CleanupStack::Pop(newContact); + CleanupStack::PushL(result); + return result; + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateNewContactGroupLC +// -------------------------------------------------------------------------- +// +MVPbkContactGroup* CContactStore::CreateNewContactGroupLC() + { + // Check that store has been opened + __ASSERT_DEBUG( iContactDb, + ContactStorePanic( EPreCond_CreateNewContactGroupLC ) ); + + iDiskSpaceCheck->DiskSpaceCheckL(); + CContactItem* newGroup = iContactDb->CreateContactGroupLC(); + TContactItemId groupId = newGroup->Id(); + CleanupStack::PopAndDestroy(); // newGroup + + CContactItem* group = iContactDb->OpenContactLX(groupId); + CleanupStack::PushL(group); + CContact* result = CContact::NewL(*this, group); + CleanupStack::Pop(2); // group, lock + CleanupStack::PushL(result); + + return result; + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateViewLC +// -------------------------------------------------------------------------- +// +MVPbkContactView* CContactStore::CreateViewLC( + const CVPbkContactViewDefinition& aViewDefinition, + MVPbkContactViewObserver& aObserver, + const MVPbkFieldTypeList& aSortOrder ) + { + VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING + ("CContactStore::CreateViewLC(0x%x)"), &aSortOrder); + + CViewBase* result = NULL; + if (aViewDefinition.SortPolicy() == EVPbkUnsortedContactView) + { + // Contact model doesn't have a view that is not sorted. + User::Leave( KErrArgument ); + } + else if (aViewDefinition.Type() == EVPbkContactsView) + { + if ( !aViewDefinition.FieldTypeFilter() && !aViewDefinition.ContactSelector() ) + { + // View without filtering + result = CContactView::NewLC( aViewDefinition, aObserver, + *this, aSortOrder ); + } + else + { + // A filtered view + result = CFilteredContactView::NewLC( aViewDefinition, + aObserver, *this, aSortOrder, iStoreDomain.FsSession() ); + } + } + else // aViewDefinition.Type() == EVPbkGroupsView + { + if ( !aViewDefinition.FieldTypeFilter() && + !aViewDefinition.FlagIsOn( EVPbkExcludeEmptyGroups ) ) + { + // View without filtering + result = CGroupView::NewLC( aViewDefinition, aObserver, *this, + aSortOrder ); + } + else + { + // A filtered view + result = CFilteredGroupView::NewLC( aViewDefinition, + aObserver, *this, aSortOrder, iStoreDomain.FsSession() ); + } + } + + return result; + } + +// -------------------------------------------------------------------------- +// CContactStore::ContactGroupsLC +// -------------------------------------------------------------------------- +// +MVPbkContactLinkArray* CContactStore::ContactGroupsLC() const + { + // Check that store has been opened + __ASSERT_DEBUG( iContactDb, + ContactStorePanic( EPreCond_ContactGroupsLC ) ); + + CVPbkContactLinkArray* result = CVPbkContactLinkArray::NewLC(); + + CContactIdArray* groups = iContactDb->GetGroupIdListL(); + if (groups) + { + CleanupStack::PushL(groups); + const TInt count = groups->Count(); + for (TInt i = 0; i < count; ++i) + { + MVPbkContactLink* link = CreateLinkLC((*groups)[i]); + result->AppendL(link); + CleanupStack::Pop(); // link + } + CleanupStack::PopAndDestroy(); // groups + } + + return result; + } + +// -------------------------------------------------------------------------- +// CContactStore::StoreInfo +// -------------------------------------------------------------------------- +// +const MVPbkContactStoreInfo& CContactStore::StoreInfo() const + { + return *iStoreInfo; + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateLinkFromInternalsLC +// -------------------------------------------------------------------------- +// +MVPbkContactLink* CContactStore::CreateLinkFromInternalsLC( + RReadStream& aStream) const + { + // Contact store constness casted away, no reason to be const + return CContactLink::NewLC(const_cast(*this), aStream); + } + + +// -------------------------------------------------------------------------- +// CContactStore::ContactStoreExtension +// -------------------------------------------------------------------------- +// +TAny* CContactStore::ContactStoreExtension( TUid aExtensionUid ) + { + if( aExtensionUid == KMVPbkContactStoreExtension2Uid ) + { + return static_cast( this ); + } + + return NULL; + } + + +// -------------------------------------------------------------------------- +// CContactStore::OwnContactLinkL +// -------------------------------------------------------------------------- +// +MVPbkContactOperationBase* CContactStore::OwnContactLinkL( + MVPbkSingleContactLinkOperationObserver& aObserver) const + { + __ASSERT_DEBUG( iContactDb, + ContactStorePanic( EPreCond_OwnContactLinkL ) ); + + MVPbkContactLink* ownContactLink = NULL; + TContactItemId ownCardId = iContactDb->OwnCardId(); + + if ( ownCardId != KNullContactId ) + { + ownContactLink = CContactLink::NewLC( + const_cast(*this), + ownCardId ); + } + + // if ownCard is KNullContactId, than return ownContactLink with NULL, async + MVPbkContactOperationBase* result = new (ELeave) COwnContactLinkOperation( + ownContactLink, + aObserver ); + + if ( ownCardId != KNullContactId ) + { + CleanupStack::Pop(); //contact link + } + + return result; + } + +// -------------------------------------------------------------------------- +// CContactStore::SetOwnContactL +// -------------------------------------------------------------------------- +// +void CContactStore::SetAsOwnL( + const CContact& aContactItem, + MVPbkContactObserver& aObserver ) + { + iAsyncContactOperation->PrepareL + (MVPbkContactObserver::EContactSetOwn, aContactItem, aObserver); + iAsyncContactOperation->Execute(); + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateContactRetrieverL +// -------------------------------------------------------------------------- +// +MVPbkContactOperation* CContactStore::CreateContactRetrieverL( + const MVPbkContactLink& aLink, + MVPbkSingleContactOperationObserver& aObserver) + { + // test if aLink is in fact a instance of this class + CContactRetriever* operation = NULL; + if (CContactLink::Matches(StoreProperties().Uri(), aLink)) + { + if ( IsOpened() ) + { + operation = CContactRetriever::NewLC(aLink, *this, aObserver); + CleanupStack::Pop(); + } + else + { + VPBK_DEBUG_PRINT( VPBK_DEBUG_STRING( + "VPbkCntModel: ContactStore not opened" ) ); + User::Leave( KErrArgument ); + } + } + + return operation; + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateDeleteContactsOperationL +// -------------------------------------------------------------------------- +// +MVPbkContactOperation* CContactStore::CreateDeleteContactsOperationL( + const MVPbkContactLinkArray& aContactLinks, + MVPbkBatchOperationObserver& aObserver) + { + CVPbkContactLinkArray* links = CVPbkContactLinkArray::NewLC(); + + const TInt linkCount = aContactLinks.Count(); + for (TInt i = 0; i < linkCount; ++i) + { + const MVPbkContactLink& link = aContactLinks.At(i); + if (CContactLink::Matches(StoreProperties().Uri(), link)) + { + MVPbkContactLink* newLink = link.CloneLC(); + links->AppendL(newLink); + CleanupStack::Pop(); // newLink + } + } + + MVPbkContactOperation* operation = NULL; + if (links->Count() > 0) + { + __ASSERT_DEBUG( IsOpened(), + VPbkError::Panic( VPbkError::EAccessOfUnopenedStore ) ); + if ( IsOpened() ) + { + operation = CDeleteContactsOperation::NewL(*this, *links, aObserver, + iStoreDomain.SharedDataClient(), + *iDiskSpaceCheck ); + } + } + CleanupStack::PopAndDestroy(); // links + + return operation; + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateCommitContactsOperationL +// -------------------------------------------------------------------------- +// +MVPbkContactOperation* CContactStore::CreateCommitContactsOperationL( + const TArray& aContacts, + MVPbkBatchOperationObserver& aObserver) + { + CArrayPtrFlat* contacts = + new(ELeave) CArrayPtrFlat(KDefaultArrayGranularity); + CleanupStack::PushL(contacts); + + const TInt contactCount = aContacts.Count(); + for (TInt i = 0; i < contactCount; ++i) + { + MVPbkStoreContact* contact = aContacts[i]; + if (&contact->ParentStore() == this) + { + contacts->AppendL(static_cast(contact)); + + // Validate syncronization field content + VPbkUtils::VerifySyncronizationFieldL( + iStoreDomain.FsSession(), + StoreProperties().SupportedFields(), + *(aContacts[i])); + } + } + + MVPbkContactOperation* operation = NULL; + if (contacts->Count() > 0) + { + __ASSERT_DEBUG( IsOpened(), + VPbkError::Panic( VPbkError::EAccessOfUnopenedStore ) ); + if ( IsOpened() ) + { + operation = CCommitContactsOperation::NewL(*this, contacts->Array(), aObserver); + } + } + CleanupStack::PopAndDestroy(); // contacts + + return operation; + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateMatchPhoneNumberOperationL +// -------------------------------------------------------------------------- +// +MVPbkContactOperation* CContactStore::CreateMatchPhoneNumberOperationL( + const TDesC& aPhoneNumber, + TInt aMaxMatchDigits, + MVPbkContactFindObserver& aObserver) + { + MVPbkContactOperation* operation = NULL; + if ( IsOpened() ) + { + operation = CMatchPhoneNumberOperation::NewL( + *this, aPhoneNumber, aMaxMatchDigits, aObserver); + } + return operation; + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateFindOperationL +// -------------------------------------------------------------------------- +// +MVPbkContactOperation* CContactStore::CreateFindOperationL( + const TDesC& aSearchString, + const MVPbkFieldTypeList& aFieldTypes, + MVPbkContactFindObserver& aObserver) + { + MVPbkContactOperation* operation = NULL; + if ( IsOpened() ) + { + operation = CFindOperation::NewL( + *this, aSearchString, aFieldTypes, aObserver); + } + return operation; + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateFindOperationL +// -------------------------------------------------------------------------- +// +MVPbkContactOperation* CContactStore::CreateFindOperationL( + const MDesC16Array& aSearchStrings, + const MVPbkFieldTypeList& aFieldTypes, + MVPbkContactFindFromStoresObserver& aObserver, + const TCallBack& aWordParserCallBack ) + { + MVPbkContactOperation* operation = NULL; + if ( IsOpened() ) + { + operation = CFindInTextDefOperation::NewL( *this, aSearchStrings, + aFieldTypes, aObserver, aWordParserCallBack ); + } + return operation; + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateCompressStoresOperationL +// -------------------------------------------------------------------------- +// +MVPbkContactOperation* CContactStore::CreateCompressStoresOperationL( + MVPbkBatchOperationObserver& /*aObserver*/) + { + // Contacts model handles compress by itself nowadays + return NULL; + } + +// -------------------------------------------------------------------------- +// CContactStore::AddObserverL +// -------------------------------------------------------------------------- +// +void CContactStore::AddObserverL(MVPbkContactStoreObserver& aObserver) + { + // adds aObserver to list of observers if it isnt there already, thus + // avoids clients registering multiple times + if (iObservers.Find(&aObserver) == KErrNotFound) + { + iObservers.AppendL( &aObserver ); + } + } + +// -------------------------------------------------------------------------- +// CContactStore::RemoveObserver +// -------------------------------------------------------------------------- +// +void CContactStore::RemoveObserver(MVPbkContactStoreObserver& aObserver) + { + const TInt pos = iObservers.Find(&aObserver); + if (pos != KErrNotFound) + { + iObservers.Remove(pos); + } + } + +// -------------------------------------------------------------------------- +// CContactStore::IsOpened +// -------------------------------------------------------------------------- +// +TBool CContactStore::IsOpened() const + { + if ( iContactDb ) + { + return ETrue; + } + else + { + return EFalse; + } + } + +// -------------------------------------------------------------------------- +// CContactStore::HandleDatabaseEventL +// -------------------------------------------------------------------------- +// +void CContactStore::HandleDatabaseEventL(TContactDbObserverEvent aEvent) + { + // Note: prints Symbian event and contact id + VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING + ("VPbkCntModel:CContactStore(0x%x)::HandleDatabaseEventL %d, cntId=%d"), + this, aEvent.iType, aEvent.iContactId ); + + TVPbkContactStoreEvent mappedEvent = MapDbEventToStoreEvent(aEvent); + + if (aEvent.iContactId != KNullContactId) + { + mappedEvent.iContactLink = CreateLinkLC(aEvent.iContactId); + } + + if (mappedEvent.iEventType != TVPbkContactStoreEvent::ENullEvent) + { + SendEventL(iObservers, &MVPbkContactStoreObserver::HandleStoreEventL, + *this, mappedEvent); + } + + // Backup handling. Send unavailable event when backup/restore begins + // and ready event when it completes. + switch( mappedEvent.iEventType ) + { + case TVPbkContactStoreEvent::EStoreRestoreBeginning: // FALLTHROUGH + case TVPbkContactStoreEvent::EStoreBackupBeginning: + { + SendErrorEvent( iObservers, + &MVPbkContactStoreObserver::StoreUnavailable, *this, + KErrAccessDenied ); + break; + } + case TVPbkContactStoreEvent::EStoreBackupRestoreCompleted: + { + SendEventL( iObservers, &MVPbkContactStoreObserver::StoreReady, + *this ); + break; + } + default: + { + // Do nothing + break; + } + } + + if ( mappedEvent.iContactLink ) + { + CleanupStack::PopAndDestroy(); // mappedEvent.iContactLink; + } + } + +// -------------------------------------------------------------------------- +// CContactStore::DoOpenL +// -------------------------------------------------------------------------- +// +void CContactStore::DoOpenL(MVPbkContactStoreObserver& aObserver, TBool aReplace) + { + VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING + ("CContactStore::DoOpenL(0x%x)"), &aObserver); + + if (!iContactDb) + { + CContactDatabase* db = NULL; + if (aReplace) + { + db = CContactDatabase::ReplaceL(StoreProperties().Name().UriDes()); + } + else + { + db = OpenInternalL(); + } + CleanupStack::PushL(db); + + // opens the Symbian Contacts model golden template + TBool updated = EFalse; + iSysTemplate = db->OpenContactL(db->TemplateId()); + // set contact model template label texts according to localisation + // must be done in order for contact field labels to be correct after language change + if (UpdateSystemTemplateFieldsL(*iSysTemplate, *iFieldsInfo)) + { + db->CommitContactL(*iSysTemplate); + updated = ETrue; + } + CloseSystemTemplate(db); + + // reopen the contact database if the golden template has been changed + if(updated) + { + CleanupStack::PopAndDestroy(db); + db = NULL; + // db already exists so we just reopen it + db = OpenInternalL(); + CleanupStack::PushL(db); + } + // read the system template and create the field factory accordingly + iSysTemplate = db->ReadContactL(db->TemplateId()); + iFieldFactory = CFieldFactory::NewL(iStoreDomain.FieldTypeMap(), + iSysTemplate, MasterFieldTypeList(), iStoreDomain.FsSession() ); + iSysTemplate = NULL; + + // set supported fields for this store + iProperties->SetSupportedFields(*iFieldFactory); + SetStaticPropertiesL(); + + iDbNotifier = CContactChangeNotifier::NewL(*db, this); + CleanupStack::Pop(db); + iContactDb = db; + + // Activate remote views so that contacts server will build + // the view as soon as possible when system boots. + // This is trapped because it's not wanted to block + // the store opening if the view building failed. + TRAP_IGNORE( DoActivateRemoteViewsL() ); + + // Send event to all observers. This means that multiple pending open requests + // are all signalled as complete here and we can cancel all other open operations. + SendEventL(iObservers, &MVPbkContactStoreObserver::StoreReady, *this); + iAsyncOpenOp->Purge(); + } + else + { + // In case the contact database is already open, we come here + SendEventL(&aObserver, &MVPbkContactStoreObserver::StoreReady, *this); + } + } + +// -------------------------------------------------------------------------- +// CContactStore::OpenError +// -------------------------------------------------------------------------- +// +void CContactStore::OpenError(MVPbkContactStoreObserver& aObserver, + TInt aError) + { + VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING + ("VPbkCntModel: CContactStore::OpenError(%d,0x%x)"), aError, &aObserver); + + SendErrorEvent(iObservers, &MVPbkContactStoreObserver::StoreUnavailable, + *this, aError); + } + +// -------------------------------------------------------------------------- +// CContactStore::SetStaticPropertiesL +// -------------------------------------------------------------------------- +// +inline void CContactStore::SetStaticPropertiesL() + { + iProperties->SetBooleanProperty + (CVPbkContactStoreProperties::EPropertyFieldLabelSupported, ETrue); + iProperties->SetBooleanProperty + (CVPbkContactStoreProperties::EPropertyDefaultsSupported, ETrue); + iProperties->SetBooleanProperty + (CVPbkContactStoreProperties::EPropertyVoiceTagsSupported, + VoiceTagSupported() ); + iProperties->SetBooleanProperty + (CVPbkContactStoreProperties::EPropertySpeedDialsSupported, ETrue); + iProperties->SetBooleanProperty + (CVPbkContactStoreProperties::EPropertyContactGroupsSupported, ETrue); + iProperties->SetBooleanProperty + (CVPbkContactStoreProperties::EPropertyOwnContactSupported, ETrue); + // Contacts Model store is never remote store but always in device memory + // or memory card. + iProperties->SetBooleanProperty( + CVPbkContactStoreProperties::EPropertyLocal, ETrue ); + // The store is always persistent because contacts are saved in data base. + iProperties->SetBooleanProperty( + CVPbkContactStoreProperties::EPropertyPersistent, ETrue ); + + // For setting removable property we need the drive letter from the URI + TDriveUnit driveUnit( iStoreURI->Uri().Component( + TVPbkContactStoreUriPtr::EContactStoreUriStoreDrive ) ); + // Then the removable information can be received from TDriveInfo + TVolumeInfo volInfo; + User::LeaveIfError( iStoreDomain.FsSession().Volume( + volInfo, driveUnit ) ); + if ( volInfo.iDrive.iDriveAtt & KDriveAttRemovable ) + { + iProperties->SetBooleanProperty( + CVPbkContactStoreProperties::EPropertyRemovable, ETrue ); + } + } + +// -------------------------------------------------------------------------- +// CContactStore::DoAddFieldTypesL +// -------------------------------------------------------------------------- +// +void CContactStore::DoAddFieldTypesL() + { + CVPbkLocalVariationManager* localVariation = + CVPbkLocalVariationManager::NewL(); + CleanupStack::PushL(localVariation); + + // open the golden template extension resource file + VPbkEngUtils::RLocalizedResourceFile resFile; + resFile.OpenLC( iStoreDomain.FsSession(), + KVPbkRomFileDrive, KDC_RESOURCE_FILES_DIR, KCntExtResFile ); + + // Nick name field + if ( localVariation->LocallyVariatedFeatureEnabled( + EVPbkLVAddNickNameField ) ) + { + TResourceReader reader; + reader.SetBuffer( + resFile.AllocReadLC( R_CNTUI_ADD_NICK_NAME_FIELD_DEFNS) ); + iFieldsInfo->AppendFieldsL( reader ); + // R_CNTUI_ADD_NICK_NAME_FIELD_DEFNS buffer + CleanupStack::PopAndDestroy(); + } + + // Video telephony fields + if ( localVariation->LocallyVariatedFeatureEnabled( + EVPbkLVAddVideoTelephonyFields) ) + { + TResourceReader reader; + reader.SetBuffer( + resFile.AllocReadLC( R_CNTUI_ADD_VIDEO_TELEPHONY_FIELD_DEFNS) ); + iFieldsInfo->AppendFieldsL( reader ); + // R_CNTUI_ADD_VIDEO_TELEPHONY_FIELD_DEFNS buffer + CleanupStack::PopAndDestroy(); + } + + // VOIP fields + if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVVOIP ) ) + { + TResourceReader reader; + reader.SetBuffer( resFile.AllocReadLC( R_CNTUI_ADD_VOIP_FIELD_DEFNS) ); + iFieldsInfo->AppendFieldsL( reader ); + CleanupStack::PopAndDestroy(); // R_CNTUI_ADD_VOIP_FIELD_DEFNS buffer + } + + // PTT/POC field + if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVPOC ) ) + { + TResourceReader reader; + reader.SetBuffer( resFile.AllocReadLC( R_CNTUI_ADD_POC_FIELD_DEF ) ); + iFieldsInfo->AppendFieldsL( reader ); + CleanupStack::PopAndDestroy(); // R_CNTUI_ADD_POC_FIELD_DEF buffer + } + + // Share View field + if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVShareView ) ) + { + TResourceReader reader; + reader.SetBuffer( + resFile.AllocReadLC( R_CNTUI_ADD_SHARE_VIEW_FIELD_DEF ) ); + iFieldsInfo->AppendFieldsL( reader ); + // R_CNTUI_ADD_SHARE_VIEW_FIELD_DEF buffer + CleanupStack::PopAndDestroy(); + } + + + // OLD VOIP fields for compatibility + if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVVOIP ) ) + { + TResourceReader reader; + reader.SetBuffer( resFile.AllocReadLC( + R_CNTUI_ADD_OLD_VOIP_FIELD_DEFNS ) ); + iFieldsInfo->AppendFieldsL( reader ); + // R_CNTUI_ADD_OLD_VOIP_FIELD_DEFNS buffer + CleanupStack::PopAndDestroy(); + } + + + // OLD PTT/POC field for compatibility + if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVPOC ) ) + { + TResourceReader reader; + reader.SetBuffer( + resFile.AllocReadLC( R_CNTUI_ADD_OLD_POC_FIELD_DEF ) ); + iFieldsInfo->AppendFieldsL( reader ); + CleanupStack::PopAndDestroy(); // R_CNTUI_ADD_OLD_POC_FIELD_DEF buffer + } + + + // OLD Share View field for compatibility + if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVShareView ) ) + { + TResourceReader reader; + reader.SetBuffer( + resFile.AllocReadLC( R_CNTUI_ADD_OLD_SHARE_VIEW_FIELD_DEF ) ); + iFieldsInfo->AppendFieldsL( reader ); + // R_CNTUI_ADD_OLD_SHARE_VIEW_FIELD_DEF buffer + CleanupStack::PopAndDestroy(); + } + + // Generic SIP field + if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVAddSIPFields ) ) + { + TResourceReader reader; + reader.SetBuffer( resFile.AllocReadLC( R_CNTUI_ADD_SIP_FIELD_DEF ) ); + iFieldsInfo->AppendFieldsL( reader ); + CleanupStack::PopAndDestroy(); // R_CNTUI_ADD_SIP_FIELD_DEF buffer + } + + // COD fields + if ( FeatureManager::FeatureSupported( KFeatureIdCallImagetext ) ) + { + TResourceReader reader; + reader.SetBuffer( resFile.AllocReadLC( R_CNTUI_ADD_COD_FIELD_DEFNS ) ); + iFieldsInfo->AppendFieldsL( reader ); + CleanupStack::PopAndDestroy(); // R_CNTUI_ADD_COD_FIELD_DEFNS buffer + } + + // MDO fields + if ( localVariation->LocallyVariatedFeatureEnabled( EVPbkLVAddMDOFields ) ) + { + TResourceReader reader; + reader.SetBuffer( + resFile.AllocReadLC( R_CNTUI_ADD_PREFIX_SUFFIX_FIELD_DEFNS ) ); + iFieldsInfo->AppendFieldsL( reader ); + // R_CNTUI_ADD_PREFIX_SUFFIX_FIELD_DEFNS buffer + CleanupStack::PopAndDestroy(); + } + + // MegaOperator fields + if ( localVariation->LocallyVariatedFeatureEnabled( + EVPbkLVMegaOperatorFields ) ) + { + TResourceReader reader; + reader.SetBuffer( + resFile.AllocReadLC( R_CNTUI_ADD_MEGAOP_FIELD_DEFNS ) ); + iFieldsInfo->AppendFieldsL( reader ); + CleanupStack::PopAndDestroy(); // R_CNTUI_ADD_MEGAOP_FIELD_DEFNS buffer + } + + CleanupStack::PopAndDestroy(2); // resFile, localVariation + } + +// -------------------------------------------------------------------------- +// CContactStore::CloseSystemTemplate +// -------------------------------------------------------------------------- +// +void CContactStore::CloseSystemTemplate(CContactDatabase* aContactDb) + { + if(iSysTemplate && aContactDb) + { + // according to contacts model documentation closecontactL + // cannot leave, so this is safe. + aContactDb->CloseContactL(iSysTemplate->Id()); + delete iSysTemplate; + iSysTemplate = NULL; + } + } + +// -------------------------------------------------------------------------- +// CContactStore::OpenL +// -------------------------------------------------------------------------- +// +CContactDatabase* CContactStore::OpenInternalL() + { + TBool creating = EFalse; + + CContactDatabase* db = NULL; + + TPtrC dbName( StoreProperties().Name().UriDes() ); + TRAPD( err, db = CContactDatabase::OpenL(dbName) ); + + if ( KErrNotFound == err ) + { + // Database not found --> Creating it + creating = ETrue; + TRAP( err, db = CContactDatabase::CreateL(dbName) ); + } + + RSharedDataClient* sharedDataClient = iStoreDomain.SharedDataClient(); + if ( KErrDiskFull == err && sharedDataClient ) + { + // Try to release space for contact db opening + sharedDataClient->RequestFreeDiskSpaceLC(KDiskSpaceForDbOpening); + if (creating) + { + // Databse was not found --> Creating it + db = CContactDatabase::CreateL(dbName); + } + else + { + // Opening database + db = CContactDatabase::OpenL(dbName); + } + CleanupStack::PopAndDestroy(); // RequestFreeDiskSpaceLC + } + else + { + User::LeaveIfError(err); + } + return db; + } + +// -------------------------------------------------------------------------- +// CContactStore::DoActivateRemoteViewsL +// -------------------------------------------------------------------------- +// +void CContactStore::DoActivateRemoteViewsL() + { + // create the parameter object + CVPbkSortOrderAcquirer::TSortOrderAcquirerParam param( + MasterFieldTypeList() ); + // load ecom plugins to acquire the sort orders from the presentation + // layer + CSortOrderAcquirerList* ecomList = CSortOrderAcquirerList::NewLC(param); + + const TInt count = ecomList->Count(); + for ( TInt i = 0; i < count; ++i ) + { + CVPbkSortOrderAcquirer& acquirer = ecomList->At( i ); + if ( acquirer.ApplySortOrderToStoreL( iStoreURI->Uri() ) ) + { + RContactViewSortOrder cntSortOrder = CreateSortOrderL( + acquirer.SortOrder() ); + CleanupClosePushL(cntSortOrder); + // Info is always found because acquirer is from same + // CSortOrderAcquirerList instance. + const CImplementationInformation* info = + ecomList->FindInfo(acquirer); + TContactViewPreferences viewPrefs = ConvertViewPrefsL( + info->OpaqueData()); + + CNamedRemoteViewHandle* handle = CNamedRemoteViewHandle::NewLC(); + // create remote view + handle->CreateRemoteViewL( info->DisplayName(), *iContactDb, + cntSortOrder, viewPrefs ); + // append handle to container + iNamedViewContainer.AppendL( handle ); + CleanupStack::Pop( handle ); + CleanupStack::PopAndDestroy(); // cntSortOrder + } + } + CleanupStack::PopAndDestroy( ecomList ); + } + +// -------------------------------------------------------------------------- +// CContactStore::CreateSortOrderL +// -------------------------------------------------------------------------- +// +RContactViewSortOrder CContactStore::CreateSortOrderL( + const MVPbkFieldTypeList& aSortOrder) const + { + RContactViewSortOrder sortOrder; + CleanupClosePushL(sortOrder); + + const TInt count = aSortOrder.FieldTypeCount(); + for ( TInt i = 0; i < count; ++i ) + { + const MVPbkFieldType& fieldType = aSortOrder.FieldTypeAt(i); + // Ignores all field types that are not supported by this store + const CContactItemField* field = iFieldFactory->FindField( + fieldType); + if (field) + { + sortOrder.AppendL(field->ContentType().FieldType(0)); + } + } + CleanupStack::Pop(); // sortOrder + return sortOrder; + } + +// -------------------------------------------------------------------------- +// CContactStore::ConvertViewPrefsL +// -------------------------------------------------------------------------- +// +TContactViewPreferences CContactStore::ConvertViewPrefsL(const TDesC8& aData) + { + // convert character to TContactViewPreferences + TLex8 lexer(aData); + TUint32 output; + User::LeaveIfError(lexer.Val(output, EDecimal)); + + TContactViewPreferences prefs = static_cast( + output); + return prefs; + } + +// -------------------------------------------------------------------------- +// CContactStore::ContactStoreDomainFsSession +// -------------------------------------------------------------------------- +// +RFs& CContactStore::ContactStoreDomainFsSession() + { + return iStoreDomain.FsSession(); + } + +} /// namespace VPbkCntModel + +// End of File