/*
* 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: The contact manager for accessing different stores.
* Initialization: a client gives an array of store URIs (Virtual
* offers some URIs, see VPbkStoreUriLiterals.h) when creating
* a manager. The client uses store list to open all stores.
*
*/
// INCLUDES
#include "CVPbkContactManager.h"
// Virtual Phonebook
#include "CVPbkFieldType.h"
#include "CVPbkFieldTypeList.h"
#include "CVPbkContactStoreDomainList.h"
#include "CVPbkCompositeContactView.h"
#include "CVPbkCopyContactsOperation.h"
#include "CVPbkFoldingContactView.h"
#include "CVPbkContactAttributeManager.h"
#include "MVPbkContactStoreLoader.h"
#include "VPbkCompositeContactViewFactory.h"
#include <MVPbkContactStore.h>
#include <MVPbkContactStoreProperties.h>
#include <MVPbkContactLink.h>
#include <MVPbkStoreContact.h>
#include <CVPbkContactViewDefinition.h>
#include <MVPbkContactView.h>
#include <MVPbkContactOperation.h>
#include <VPbkEng.rsg>
#include <VPbkDataCaging.hrh>
#include <CVPbkContactLinkArray.h>
#include <CVPbkContactStoreUriArray.h>
#include <CVPbkContactCopier.h>
#include <MVPbkContactOperationFactory.h>
#include <MVPbkContactOperationFactory2.h>
// System includes
#include <s32buf.h>
#include <s32mem.h>
#include <barsc.h>
#include <bautils.h>
#include <barsread.h>
#include <ecom/ecom.h>
#include <RLocalizedResourceFile.h>
#ifdef _DEBUG
namespace {
enum TPanic
{
EPreCond_CreateContactViewLC,
EUnknownViewType_CreateContactViewLC,
ENo_Factory_Extension_FindL
};
void Panic( TPanic aPanic )
{
_LIT(KPanicCat, "CVPbkContactManager");
User::Panic( KPanicCat, aPanic );
}
}
#endif // _DEBUG
// --------------------------------------------------------------------------
// IsPlaceHolderCompositeView
// Returns ETrue if aViewDefinition is a composite that has no children
// --------------------------------------------------------------------------
//
TBool IsPlaceHolderCompositeView(
const CVPbkContactViewDefinition& aViewDefinition )
{
return ( aViewDefinition.Type() == EVPbkCompositeView &&
aViewDefinition.SubViewCount() == 0 );
}
/**
* A loader class that uses CVPbkContactManager for loading stores
*/
NONSHARABLE_CLASS(CVPbkContactManager::CContactStoreLoader)
: public CBase,
public MVPbkContactStoreLoader
{
public:
CContactStoreLoader( CVPbkContactManager& aContactManager );
// From base class MVPbkContactStoreLoader
MVPbkContactStoreList& ContactStoreListL() const;
void LoadContactStoreL( const TVPbkContactStoreUriPtr& aURI );
private:
CVPbkContactManager& iContactManager;
};
CVPbkContactManager::CContactStoreLoader::CContactStoreLoader(
CVPbkContactManager& aContactManager )
: iContactManager( aContactManager )
{
}
MVPbkContactStoreList&
CVPbkContactManager::CContactStoreLoader::ContactStoreListL() const
{
return iContactManager.ContactStoresL();
}
void CVPbkContactManager::CContactStoreLoader::LoadContactStoreL(
const TVPbkContactStoreUriPtr& aURI )
{
iContactManager.LoadContactStoreL( aURI );
}
// --------------------------------------------------------------------------
// CVPbkContactManager::CVPbkContactManager
// --------------------------------------------------------------------------
//
inline CVPbkContactManager::CVPbkContactManager( TSecurityInfo aSecurityInfo, RFs* aFs)
: iSecurityInfo( aSecurityInfo )
{
if (aFs)
{
iFs = *aFs;
}
}
// --------------------------------------------------------------------------
// CVPbkContactManager::~CVPbkContactManager
// --------------------------------------------------------------------------
//
CVPbkContactManager::~CVPbkContactManager()
{
delete iStoreLoader;
delete iAttributeManager;
delete iContactStoreDomains;
delete iFieldTypes;
iOwnFs.Close();
}
// --------------------------------------------------------------------------
// CVPbkContactManager::NewL
// --------------------------------------------------------------------------
//
EXPORT_C CVPbkContactManager* CVPbkContactManager::NewL(
const CVPbkContactStoreUriArray& aURIList,
RFs* aFs /*= NULL*/)
{
TSecurityInfo secInfo;
secInfo.SetToCurrentInfo();
CVPbkContactManager* self = new(ELeave) CVPbkContactManager( secInfo, aFs);
CleanupStack::PushL(self);
self->ConstructL(aURIList);
CleanupStack::Pop(self);
return self;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::NewL
// --------------------------------------------------------------------------
//
EXPORT_C CVPbkContactManager* CVPbkContactManager::NewL(
TSecurityInfo aSecurityInfo,
const CVPbkContactStoreUriArray& aURIList,
RFs* aFs /*= NULL*/)
{
CVPbkContactManager* self = new(ELeave) CVPbkContactManager( aSecurityInfo, aFs);
CleanupStack::PushL(self);
self->ConstructL(aURIList);
CleanupStack::Pop(self);
return self;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::ConstructL
// --------------------------------------------------------------------------
//
inline void CVPbkContactManager::ConstructL
(const CVPbkContactStoreUriArray& aURIList)
{
if (iFs.Handle() == KNullHandle)
{
User::LeaveIfError(iOwnFs.Connect());
iFs = iOwnFs;
}
VPbkEngUtils::RLocalizedResourceFile resFile;
resFile.OpenLC( iFs, KVPbkRomFileDrive,
KDC_RESOURCE_FILES_DIR, KVPbkDefResFileName );
HBufC8* fieldTypesBuf = resFile.AllocReadLC(R_VPBK_GLOBAL_FIELD_TYPES);
TResourceReader resReader;
resReader.SetBuffer(fieldTypesBuf);
iFieldTypes = CVPbkFieldTypeList::NewL(resFile, resReader);
CleanupStack::PopAndDestroy(2, &resFile);
iContactStoreDomains =
CVPbkContactStoreDomainList::NewL( aURIList, *iFieldTypes, iSecurityInfo );
iStoreLoader = new( ELeave ) CContactStoreLoader( *this );
}
// --------------------------------------------------------------------------
// CVPbkContactManager::FieldTypes
// --------------------------------------------------------------------------
//
EXPORT_C const MVPbkFieldTypeList& CVPbkContactManager::FieldTypes() const
{
return *iFieldTypes;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::ContactStoresL
// --------------------------------------------------------------------------
//
EXPORT_C MVPbkContactStoreList& CVPbkContactManager::ContactStoresL()
{
return *iContactStoreDomains;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::LoadContactStoreL
// --------------------------------------------------------------------------
//
EXPORT_C void CVPbkContactManager::LoadContactStoreL
(const TVPbkContactStoreUriPtr& aURI)
{
if (!iContactStoreDomains->Find(aURI))
{
CVPbkContactStoreUriArray* uriList = CVPbkContactStoreUriArray::NewLC();
uriList->AppendL(aURI);
iContactStoreDomains->LoadPluginStoreDomainsL( *uriList, *iFieldTypes,
iSecurityInfo );
CleanupStack::PopAndDestroy(); // uriList
}
}
// --------------------------------------------------------------------------
// CVPbkContactManager::ContactAttributeManagerL
// --------------------------------------------------------------------------
//
EXPORT_C MVPbkContactAttributeManager&
CVPbkContactManager::ContactAttributeManagerL()
{
if (!iAttributeManager)
{
iAttributeManager = CVPbkContactAttributeManager::NewL(*this);
}
return *iAttributeManager;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::CreateContactViewLC
// --------------------------------------------------------------------------
//
EXPORT_C MVPbkContactViewBase* CVPbkContactManager::CreateContactViewLC(
MVPbkContactViewObserver& aObserver,
const CVPbkContactViewDefinition& aViewDefinition,
const MVPbkFieldTypeList& aSortOrder) const
{
MVPbkContactViewBase* result = NULL;
switch ( aViewDefinition.Type() )
{
case EVPbkContactsView: // FALLTHROUGH
case EVPbkGroupsView:
{
// Create a leaf view from the store plug-in.
MVPbkContactStore* store = FindStore( aViewDefinition.Uri() );
if ( !store )
{
User::Leave( KErrNotFound );
}
result = store->CreateViewLC( aViewDefinition, aObserver,
aSortOrder );
break;
}
case EVPbkFoldingView:
{
// Create a folding view. Folding view can then
// be expanded to its subviews.
result = CVPbkFoldingContactView::NewLC( aObserver,
aViewDefinition, *this, aSortOrder );
break;
}
case EVPbkCompositeView:
{
result = CreateOptimizedCompositeViewLC( aObserver,
aViewDefinition, aSortOrder );
break;
}
default:
{
__ASSERT_DEBUG( EFalse, Panic ( EUnknownViewType_CreateContactViewLC ));
CleanupStack::PushL( result ); // LC semantics
break;
}
}
return result;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::RetrieveContactL
// --------------------------------------------------------------------------
//
EXPORT_C MVPbkContactOperationBase* CVPbkContactManager::RetrieveContactL(
const MVPbkContactLink& aLink,
MVPbkSingleContactOperationObserver& aObserver) const
{
MVPbkContactOperation* operation =
iContactStoreDomains->CreateContactRetrieverL( aLink, aObserver );
if (operation)
{
CleanupDeletePushL(operation);
operation->StartL();
CleanupStack::Pop(); // operation
}
return operation;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::CreateLinksLC
// --------------------------------------------------------------------------
//
EXPORT_C MVPbkContactLinkArray* CVPbkContactManager::CreateLinksLC(
const TDesC8& aPackedLinks) const
{
RDesReadStream readStream( aPackedLinks );
readStream.PushL();
CVPbkContactLinkArray* linkArray = CVPbkContactLinkArray::NewLC(
readStream, *iStoreLoader );
CleanupStack::Pop( linkArray );
CleanupStack::PopAndDestroy( &readStream );
CleanupStack::PushL( linkArray );
return linkArray;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::CreateLinksLC
// --------------------------------------------------------------------------
//
EXPORT_C MVPbkContactLinkArray* CVPbkContactManager::CreateLinksLC(
RReadStream& aStream) const
{
CVPbkContactLinkArray* linkArray = CVPbkContactLinkArray::NewLC(
aStream, *iStoreLoader );
return linkArray;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::DeleteContactsL
// --------------------------------------------------------------------------
//
EXPORT_C MVPbkContactOperationBase* CVPbkContactManager::DeleteContactsL(
const MVPbkContactLinkArray& aContactLinks,
MVPbkBatchOperationObserver& aObserver)
{
MVPbkContactOperation* operation =
iContactStoreDomains->CreateDeleteContactsOperationL(
aContactLinks, aObserver);
if (operation)
{
CleanupDeletePushL(operation);
operation->StartL();
CleanupStack::Pop(); // operation
}
return operation;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::CommitContactsL
// --------------------------------------------------------------------------
//
EXPORT_C MVPbkContactOperationBase* CVPbkContactManager::CommitContactsL(
const TArray<MVPbkStoreContact*>& aContacts,
MVPbkBatchOperationObserver& aObserver)
{
MVPbkContactOperation* operation =
iContactStoreDomains->CreateCommitContactsOperationL(
aContacts, aObserver);
if (operation)
{
CleanupDeletePushL(operation);
operation->StartL();
CleanupStack::Pop(); // operation
}
return operation;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::CopyContactsL
// --------------------------------------------------------------------------
//
EXPORT_C MVPbkContactOperationBase* CVPbkContactManager::CopyContactsL(
const MVPbkContactLinkArray& aContactLinks,
MVPbkContactStore* aTargetStore,
MVPbkBatchOperationObserver& aObserver)
{
MVPbkContactOperation* operation = CVPbkCopyContactsOperation::NewLC(
CVPbkContactCopier::EVPbkSimpleContactCopy,
*this,
aContactLinks,
aTargetStore,
NULL,
aObserver);
operation->StartL();
CleanupStack::Pop(); // operation
return operation;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::MatchPhoneNumberL
// --------------------------------------------------------------------------
//
EXPORT_C MVPbkContactOperationBase* CVPbkContactManager::MatchPhoneNumberL(
const TDesC& aPhoneNumber,
TInt aMaxMatchDigits,
MVPbkContactFindObserver& aObserver)
{
MVPbkContactOperation* operation =
iContactStoreDomains->CreateMatchPhoneNumberOperationL(
aPhoneNumber, aMaxMatchDigits, aObserver);
if (operation)
{
CleanupDeletePushL(operation);
operation->StartL();
CleanupStack::Pop(); // operation
}
return operation;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::FindL
// --------------------------------------------------------------------------
//
EXPORT_C MVPbkContactOperationBase* CVPbkContactManager::FindL(
const TDesC& aSearchString,
const MVPbkFieldTypeList& aFieldTypes,
MVPbkContactFindObserver& aObserver)
{
MVPbkContactOperation* operation =
(static_cast<MVPbkContactOperationFactory*>(iContactStoreDomains))->CreateFindOperationL(
aSearchString, aFieldTypes, aObserver);
if (operation)
{
CleanupDeletePushL(operation);
operation->StartL();
CleanupStack::Pop(); // operation
}
return operation;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::FindL
// --------------------------------------------------------------------------
//
EXPORT_C MVPbkContactOperationBase* CVPbkContactManager::FindL(
const MDesC16Array& aSearchStrings,
const MVPbkFieldTypeList& aFieldTypes,
MVPbkContactFindFromStoresObserver& aObserver,
const TCallBack& aWordParserCallBack )
{
MVPbkContactOperation* operation =
(static_cast<MVPbkContactOperationFactory*>(iContactStoreDomains))->CreateFindOperationL(
aSearchStrings, aFieldTypes, aObserver, aWordParserCallBack );
if (operation)
{
CleanupDeletePushL(operation);
operation->StartL();
CleanupStack::Pop(); // operation
}
return operation;
}
EXPORT_C MVPbkContactOperationBase* CVPbkContactManager::FindL(
const MDesC16Array& aSearchStrings,
const MVPbkFieldTypeList& aFieldTypes,
MVPbkContactFindFromStoresObserver& aObserver,
const TCallBack& aWordParserCallBack, const CDesC16ArrayFlat& aStoreEntriesArray )
{
MVPbkContactOperation* operation = NULL;
MVPbkContactOperationFactory2* factoryExtension = reinterpret_cast<MVPbkContactOperationFactory2*>
(iContactStoreDomains->ContactOperationFactoryExtension(KMVPbkContactOperationFactory2Uid) );
// Safeguard to avoid factory extension initialization. It is a programming error if
// factory extension does not exist.
__ASSERT_DEBUG(factoryExtension, Panic( ENo_Factory_Extension_FindL ) );
operation =
factoryExtension->CreateFindOperationL(
aSearchStrings, aFieldTypes, aObserver, aWordParserCallBack ,aStoreEntriesArray );
if (operation)
{
CleanupDeletePushL(operation);
operation->StartL();
CleanupStack::Pop(); // operation
}
return operation;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::CompressStoresL
// --------------------------------------------------------------------------
//
EXPORT_C MVPbkContactOperationBase* CVPbkContactManager::CompressStoresL(
MVPbkBatchOperationObserver& aObserver)
{
MVPbkContactOperation* operation =
iContactStoreDomains->CreateCompressStoresOperationL(aObserver);
if (operation)
{
CleanupDeletePushL(operation);
operation->StartL();
CleanupStack::Pop(); // operation
}
return operation;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::FsSession
// --------------------------------------------------------------------------
//
EXPORT_C RFs& CVPbkContactManager::FsSession()
{
return iFs;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::FindStore
// --------------------------------------------------------------------------
//
MVPbkContactStore* CVPbkContactManager::FindStore
( const TVPbkContactStoreUriPtr& aURI ) const
{
const TInt count = iContactStoreDomains->Count();
for (TInt i = 0; i < count; ++i)
{
MVPbkContactStore& store = iContactStoreDomains->At(i);
if (store.StoreProperties().Uri().Compare(aURI,
TVPbkContactStoreUriPtr::EContactStoreUriAllComponents) == 0)
{
return &store;
}
}
return NULL;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::CreateOptimizedCompositeViewLC
// --------------------------------------------------------------------------
//
MVPbkContactViewBase* CVPbkContactManager::CreateOptimizedCompositeViewLC(
MVPbkContactViewObserver& aObserver,
const CVPbkContactViewDefinition& aViewDefinition,
const MVPbkFieldTypeList& aSortOrder) const
{
// First the placeholder composites must be reduced from the count
// so that the actual number of subviews are known.
TInt subViewCount = aViewDefinition.SubViewCount();
TInt actualSubViewCount = subViewCount;
for ( TInt i = 0; i < subViewCount; ++i )
{
if ( IsPlaceHolderCompositeView( aViewDefinition.SubViewAt( i ) ) )
{
--actualSubViewCount;
}
}
MVPbkContactViewBase* result = NULL;
const TInt oneSubview = 1;
if ( actualSubViewCount == oneSubview )
{
// Create the one subview directly using aObserver.
// Loop must be used to ignore placeholders.
for ( TInt i = 0; i < subViewCount && !result; ++i )
{
result = CreateContactViewLC( aObserver,
aViewDefinition.SubViewAt( i ), aSortOrder );
if ( !result )
{
CleanupStack::Pop( result );
}
}
}
else
{
// many subviews
result = CreateCompositeViewLC( aObserver, aViewDefinition,
aSortOrder );
}
return result;
}
// --------------------------------------------------------------------------
// CVPbkContactManager::CreateCompositeViewLC
// --------------------------------------------------------------------------
//
MVPbkContactViewBase* CVPbkContactManager::CreateCompositeViewLC(
MVPbkContactViewObserver& aObserver,
const CVPbkContactViewDefinition& aViewDefinition,
const MVPbkFieldTypeList& aSortOrder) const
{
MVPbkContactViewBase* result = NULL;
const TInt subViewCount = aViewDefinition.SubViewCount();
const TInt noSubviews = 0;
if ( subViewCount == noSubviews )
{
// The view is used as a placeholder.
// lets not create anything there
CleanupStack::PushL( result ); // LC semantics
}
else
{
// Create a composite and its subviews
CVPbkCompositeContactView* compositeView =
VPbkCompositeContactViewFactory::CreateViewLC(
aObserver, aViewDefinition.SortPolicy(),
aSortOrder, *iFieldTypes, const_cast<RFs&>(iFs) );
compositeView->SetViewId(aViewDefinition.Id());
for ( TInt i = 0; i < subViewCount; ++i )
{
const CVPbkContactViewDefinition& subViewDef =
aViewDefinition.SubViewAt(i);
if ( aViewDefinition.SortPolicy() == EVPbkSortedContactView &&
subViewDef.SortPolicy() == EVPbkUnsortedContactView )
{
// It's not possible to use unsorted subviews.
// All subviews must be sorted so that they can be merged
User::Leave(KErrArgument);
}
MVPbkContactViewBase* subView = CreateContactViewLC(
*compositeView, subViewDef, aSortOrder );
if (subView)
{
compositeView->AddSubViewL(subView, subViewDef.Id());
if ( subView->Type() == EVPbkCompositeView )
{
// Composite creates another composite as its
// subview. The view can be safely casted because
// CVPbkCompositeContactView is VPbkEng internal
// and EVPbkCompositeView type view is always
// derived from CVPbkCompositeContactView.
static_cast<CVPbkCompositeContactView*>(
subView )->ApplyInternalCompositePolicyL();
}
}
CleanupStack::Pop(); // subView
}
result = compositeView;
}
return result;
}
// End of File