/*
* 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 <VPbkCntModelRes.rsg>
// Virtual Phonebook
#include <VPbkError.h>
#include <MVPbkContactStoreObserver.h>
#include <TVPbkContactStoreUriPtr.h>
#include <CVPbkContactStoreUri.h>
#include <CVPbkAsyncOperation.h>
#include <RLocalizedResourceFile.h>
#include <CVPbkAsyncCallback.h>
#include <CVPbkContactViewDefinition.h>
#include <VPbkContactView.hrh>
#include <CVPbkContactStoreProperties.h>
#include <CVPbkLocalVariationManager.h>
#include <CVPbkFieldTypeSelector.h>
#include <VPbkUtils.h>
#include <TVPbkContactStoreUriPtr.h>
#include <VPbkDataCaging.hrh>
#include <VPbkContactStoreUris.h>
#include <MVPbkSingleContactLinkOperationObserver.h>
// Contacts Model
#include <cntdb.h>
#include <cntitem.h>
#include <cntmodel.rsg>
// System includes
#include <barsc.h>
#include <barsread.h>
#include <featmgr.h>
#include <shareddataclient.h>
#include <coemain.h>
// Debugging headers
#include <VPbkDebug.h>
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<MVPbkContactStoreObserver>& aObservers,
void (MVPbkContactStoreObserver::*aEventFunc)(MVPbkContactStore&),
MVPbkContactStore& aStore)
{
for (TInt i = aObservers.Count() - 1; i >= 0; --i)
{
SendEventL(aObservers[i], aEventFunc, aStore);
}
}
void SendEventL
(RPointerArray<MVPbkContactStoreObserver>& 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<MVPbkContactStoreObserver>& 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
// --------------------------------------------------------------------------
// CContactStoreOpenOperation
// --------------------------------------------------------------------------
//
class CContactStoreOpenOperation : public CActive
{
public: // construction & destruction
/**
* Open native contact database operation. Started automatically.
*
* @param aStore Store that will receive events when operation is complete
* @param aReplace replace contact database (instead of open)
*/
CContactStoreOpenOperation( CContactStore& aStore, TBool aReplace );
~CContactStoreOpenOperation();
private: // From CActive
void DoCancel();
void RunL();
TInt RunError( TInt aError );
private: // data types
/// Operation states
enum TStates
{
// Operation: Replace default store
// Next states: [EStateDone]
EStateReplaceStore,
// Operation: Open default store
// Next states: [EStateStoreOpened]
EStateOpenStore,
// Result: State when store has been opened (success or failure)
// Next states: [EStateStoreOpenedAfterError, EStateDone]
EStateStoreOpened,
// Result: State after second attempt to open store (first have failed).
// Next states: [EStateDone]
EStateStoreOpenedAfterError,
// Result: DB has been opened successfully. Report it to store.
// Next states: -
EStateDone,
};
private: // implementation
/**
* Move to next state asynchronously
*/
void IssueRequest( TStates aNextState, TInt aError = KErrNone );
/**
* Handle state EStateStoreOpened
*/
void HandleStoreOpenedL( TInt aError );
private: // data
/// Active state
TStates iState;
/// Ref: Contact store
CContactStore& iStore;
/// Own: Native contact database
CContactDatabase* iDb;
/// Own: Native contact database open operation
CContactOpenOperation* iOperation;
};
// --------------------------------------------------------------------------
// CContactStoreOpenOperation::~CContactStoreOpenOperation
// --------------------------------------------------------------------------
//
CContactStoreOpenOperation::~CContactStoreOpenOperation()
{
Cancel();
delete iDb;
delete iOperation;
}
// --------------------------------------------------------------------------
// CContactStoreOpenOperation::DoCancel
// --------------------------------------------------------------------------
//
void CContactStoreOpenOperation::DoCancel()
{
delete iOperation;
iOperation = NULL;
}
// --------------------------------------------------------------------------
// CContactStoreOpenOperation::RunL
// --------------------------------------------------------------------------
//
void CContactStoreOpenOperation::RunL()
{
switch( iState )
{
case EStateReplaceStore:
{
iDb = CContactDatabase::ReplaceL(
iStore.StoreProperties().Name().UriDes() );
IssueRequest( EStateDone );
break;
}
case EStateOpenStore:
{
iOperation = CContactDatabase::Open(
iStore.StoreProperties().Name().UriDes(), iStatus );
SetActive();
iState = EStateStoreOpened;
break;
}
case EStateStoreOpened:
{
HandleStoreOpenedL( iStatus.Int() );
break;
}
case EStateStoreOpenedAfterError:
{
User::LeaveIfError( iStatus.Int() ); // report errors immediately
iDb = iOperation->TakeDatabase();
IssueRequest( EStateDone );
break;
}
case EStateDone:
{
CContactDatabase* db = iDb;
iDb = NULL; // give ownership
CContactStore& store = iStore;
TRAPD( err, store.StoreOpenedL( db ) );
// NOTE! Don't touch members after this call.
// This instance could be deleted
if( err )
{
store.StoreOpenFailed( err );
}
break;
}
default:
{
// unknown state
__ASSERT_DEBUG( EFalse,
ContactStorePanic( EPreCond_OpenOperationState ) );
iStore.StoreOpenFailed( KErrUnknown );
}
}
}
// --------------------------------------------------------------------------
// CContactStoreOpenOperation::RunError
// --------------------------------------------------------------------------
//
TInt CContactStoreOpenOperation::RunError( TInt aError )
{
iStore.StoreOpenFailed( aError );
return KErrNone;
}
// --------------------------------------------------------------------------
// CContactStoreOpenOperation::CContactStoreOpenOperation
// --------------------------------------------------------------------------
//
CContactStoreOpenOperation::CContactStoreOpenOperation(
CContactStore& aStore, TBool aReplace ) :
CActive( EPriorityLow ),
iStore( aStore )
{
CActiveScheduler::Add( this );
IssueRequest( aReplace ? EStateReplaceStore : EStateOpenStore ); // start working
}
// --------------------------------------------------------------------------
// CContactStoreOpenOperation::IssueRequest
// --------------------------------------------------------------------------
//
void CContactStoreOpenOperation::IssueRequest( TStates aNextState, TInt aError )
{
if( !IsActive() )
{
TRequestStatus* status = &iStatus;
User::RequestComplete( status, aError );
SetActive();
iState = aNextState;
}
}
// --------------------------------------------------------------------------
// CContactStoreOpenOperation::HandleStoreOpenedL
// --------------------------------------------------------------------------
//
void CContactStoreOpenOperation::HandleStoreOpenedL( TInt aError )
{
if( aError == KErrNone )
{
// Store opened succesfully
iDb = iOperation->TakeDatabase();
IssueRequest( EStateDone );
}
else // some error happened
{
delete iOperation;
iOperation = NULL;
const TDesC& dbName = iStore.StoreProperties().Name().UriDes();
TInt creating = EFalse;
if( aError == KErrNotFound )
{
// Database not found --> Creating it
creating = ETrue;
TRAP( aError, iDb = CContactDatabase::CreateL( dbName ) );
}
if ( KErrDiskFull == aError )
{
// Try to release space for contact db opening
if( iStore.RequestFreeDiskSpaceLC( KDiskSpaceForDbOpening ) )
{
aError = KErrNone;
if( creating )
{
// Databse was not found --> Creating it
iDb = CContactDatabase::CreateL( dbName );
}
else
{
// Opening database
iOperation = CContactDatabase::Open( dbName, iStatus );
SetActive();
iState = EStateStoreOpenedAfterError;
}
CleanupStack::PopAndDestroy(); // RequestFreeDiskSpaceLC
}
}
// leave on unhandled error
User::LeaveIfError( aError );
if( iDb )
{
IssueRequest( EStateDone );
}
}
}
// --------------------------------------------------------------------------
// 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;
delete iOpenOperation;
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<MVPbkContactStoreObserver>::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<CContact&>(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<CContactStore&>(*this), aContactId);
}
return ret;
}
// --------------------------------------------------------------------------
// CContactStore::ContactDestroyed
// --------------------------------------------------------------------------
//
void CContactStore::ContactDestroyed(CContactItem* aContactItem, TBool aCloseContact )
{
// Release any lock on contact.
if (aContactItem)
{
// Cancel async operation if any
iAsyncContactOperation->Cancel( aContactItem );
//iContactDb may be already null if store configuration changed by
//removing the current store from store configuartion
if ( aCloseContact && iContactDb)
{
// 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<CContactStore&>(*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<MVPbkContactStoreObserver>* 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<MVPbkContactStoreObserver>* 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;
// Set iGroupsFetched to false.
// Make sure iGroupIds is updated again after store is opened again.
iStoreInfo->ResetGroupsFetched();
}
}
// --------------------------------------------------------------------------
// CContactStore::CreateNewContactLC
// --------------------------------------------------------------------------
//
MVPbkStoreContact* CContactStore::CreateNewContactLC()
{
TRAPD( err, iDiskSpaceCheck->DiskSpaceCheckL() );
if ( err != KErrNone )
{
CCoeEnv::Static()->HandleError( err );
User::Leave(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<CContactStore&>(*this), aStream);
}
// --------------------------------------------------------------------------
// CContactStore::ContactStoreExtension
// --------------------------------------------------------------------------
//
TAny* CContactStore::ContactStoreExtension( TUid aExtensionUid )
{
if( aExtensionUid == KMVPbkContactStoreExtension2Uid )
{
return static_cast<MVPbkContactStore2*>( 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<CContactStore&>(*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::StoreOpenedL
// --------------------------------------------------------------------------
//
void CContactStore::StoreOpenedL( CContactDatabase* aDB )
{
VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
("VPbkCntModel: CContactStore::StoreOpenedL"));
CleanupStack::PushL( aDB );
delete iOpenOperation;
iOpenOperation = NULL;
if( !iGoldenTemplateUpdated )
{
iSysTemplate = aDB->OpenContactL(aDB->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 ) )
{
aDB->CommitContactL( *iSysTemplate );
iGoldenTemplateUpdated = ETrue;
}
CloseSystemTemplate( aDB );
// reopen the contact database if the golden template has been changed
if( iGoldenTemplateUpdated )
{
// template updated -> reopen store
CleanupStack::PopAndDestroy( aDB );
iOpenOperation = new(ELeave) CContactStoreOpenOperation( *this, EFalse );
return;
}
}
// read the system template and create the field factory accordingly
iSysTemplate = aDB->ReadContactL(aDB->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(*aDB, this);
CleanupStack::Pop(aDB);
iContactDb = aDB;
// 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();
}
// --------------------------------------------------------------------------
// CContactStore::StoreOpenFailed
// --------------------------------------------------------------------------
//
void CContactStore::StoreOpenFailed( TInt aError )
{
VPBK_DEBUG_PRINT(VPBK_DEBUG_STRING
("VPbkCntModel: CContactStore::StoreOpenFailed(%d)"), aError);
delete iOpenOperation;
iOpenOperation = NULL;
SendErrorEvent(iObservers, &MVPbkContactStoreObserver::StoreUnavailable,
*this, aError );
}
// --------------------------------------------------------------------------
// CContactStore::RequestFreeDiskSpaceLC
// --------------------------------------------------------------------------
//
TBool CContactStore::RequestFreeDiskSpaceLC( TInt aSpace )
{
RSharedDataClient* sharedDataClient = iStoreDomain.SharedDataClient();
if( sharedDataClient )
{
// Try to release space for contact db opening
sharedDataClient->RequestFreeDiskSpaceLC( aSpace );
return ETrue;
}
return EFalse;
}
// --------------------------------------------------------------------------
// 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<MVPbkStoreContact*>& aContacts,
MVPbkBatchOperationObserver& aObserver)
{
CArrayPtrFlat<CContact>* contacts =
new(ELeave) CArrayPtrFlat<CContact>(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<CContact*>(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)
{
// start opening store if it's not already pending
if( !iOpenOperation )
{
iOpenOperation = new(ELeave) CContactStoreOpenOperation( *this, EFalse );
}
}
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<TContactViewPreferences>(
output);
return prefs;
}
// --------------------------------------------------------------------------
// CContactStore::ContactStoreDomainFsSession
// --------------------------------------------------------------------------
//
RFs& CContactStore::ContactStoreDomainFsSession()
{
return iStoreDomain.FsSession();
}
} /// namespace VPbkCntModel
// End of File