diff -r 5b6f26637ad3 -r f4a778e096c2 phonebookui/Phonebook2/CommonUI/src/CPbk2ContactRelocator.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/phonebookui/Phonebook2/CommonUI/src/CPbk2ContactRelocator.cpp Wed Sep 01 12:29:52 2010 +0100 @@ -0,0 +1,1035 @@ +/* +* 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 relocator. +* +*/ + + + +// INCLUDE FILES +#include + +// Phonebook 2 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Virtual Phonebook +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// System includes +#include +#include +#include + +/// Unnamed namespace for local definitions +namespace { + +// LOCAL CONSTANTS AND MACROS + +const TInt KFirstElement = 0; +const TInt KOneContact = 1; +const TInt KDefaultTitleFormat = MPbk2ContactNameFormatter::EUseSeparator; + +#ifdef _DEBUG + +// Definition for many contacts relocation +const TInt KLinkArrayRelocationMinCount = 2; + +enum TPanicCode + { + EPanicPreCond_ContactsSaved, + EPanicLogic_AskConfirmationL, + EPanicPreCond_RelocateContactL, + EPanicPreCond_RelocateContactsL, + EPanicPreCond_RelocateAndLockContactL, + EPanicPreCond_PrepareToRelocateContactL, + EPanicPreCond_DeleteSourceContact, + EPanicPreCond_VerifyRelocationQueryType + }; + +void Panic( TInt aReason ) + { + _LIT( KPanicText, "CPbk2ContactRelocator" ); + User::Panic( KPanicText, aReason ); + } + +#endif // _DEBUG + +/** + * Fetches contact's store name, which can be use in relocation queries. + * If store name cannot be fetched from global store properties, then + * contact's store property is returned. + * + * @param aContact Reference to contact. + * @param aStoreProperties Reference to store properties. + * @return Pointer to store name. Ownership is not transferred + */ +const TDesC* StoreName( + const MVPbkStoreContact* aContact, + CPbk2StorePropertyArray& aStoreProperties ) + { + const TDesC* storeName = NULL; + if ( aContact ) + { + // Fetch store name + TVPbkContactStoreUriPtr uri = + aContact->ParentStore().StoreProperties().Uri(); + const CPbk2StoreProperty* storeProperty = + aStoreProperties.FindProperty( uri ); + + if (storeProperty) + { + storeName = &storeProperty->StoreName(); + } + else + { + storeName = &uri.UriDes(); + } + } + return storeName; + } + +} // namespace + + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::CPbk2ContactRelocator +// -------------------------------------------------------------------------- +// +CPbk2ContactRelocator::CPbk2ContactRelocator() : + CActive( CActive::EPriorityStandard ) + { + CActiveScheduler::Add( this ); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::~CPbk2ContactRelocator +// -------------------------------------------------------------------------- +// +CPbk2ContactRelocator::~CPbk2ContactRelocator() + { + Cancel(); + delete iSourceContact; + delete iSourceContacts; + delete iRelocatedContact; + delete iContactRetriever; + delete iSavedContactsRetriever; + delete iContactCopier; + delete iCopyPolicyManager; + delete iQueryDialog; + + if ( iTargetStore ) + { + iTargetStore->Close( *this ); + } + + if ( iDestroyedPtr ) + { + *iDestroyedPtr = ETrue; + } + Release( iAppServices ); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::NewL +// -------------------------------------------------------------------------- +// +EXPORT_C CPbk2ContactRelocator* CPbk2ContactRelocator::NewL() + { + CPbk2ContactRelocator* self = + new ( ELeave ) CPbk2ContactRelocator(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::ConstructL +// -------------------------------------------------------------------------- +// +inline void CPbk2ContactRelocator::ConstructL() + { + iAppServices = CPbk2ApplicationServices::InstanceL(); + iRelocationPolicy = ReadRelocationPolicyL(); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::RelocateContactL +// -------------------------------------------------------------------------- +// +EXPORT_C TBool CPbk2ContactRelocator::RelocateContactL( + MVPbkStoreContact* aContact, + MPbk2ContactRelocatorObserver& aObserver, + Pbk2ContactRelocator::TPbk2ContactRelocationQueryPolicy aQueryPolicy, + TUint32 aFlags ) + { + __ASSERT_DEBUG( aContact, Panic( EPanicPreCond_RelocateContactL ) ); + + // Adjust policy + if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemoryAndLock ) + { + iRelocationPolicy = Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemory; + } + else if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock ) + { + iRelocationPolicy = Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory; + } + + return PrepareToRelocateContactL( aContact, NULL, aObserver, + aQueryPolicy, aFlags ); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::RelocateAndLockContactL +// -------------------------------------------------------------------------- +// +EXPORT_C TBool CPbk2ContactRelocator::RelocateAndLockContactL( + MVPbkStoreContact* aContact, + MPbk2ContactRelocatorObserver& aObserver, + Pbk2ContactRelocator::TPbk2ContactRelocationQueryPolicy aQueryPolicy, + TUint32 aFlags ) + { + __ASSERT_DEBUG( aContact, Panic( EPanicPreCond_RelocateAndLockContactL ) ); + + // Adjust policy + if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemory ) + { + iRelocationPolicy = Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemoryAndLock; + } + else if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory ) + { + iRelocationPolicy = Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock; + } + + return PrepareToRelocateContactL( aContact, NULL, aObserver, + aQueryPolicy, aFlags ); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::RelocateContactsL +// -------------------------------------------------------------------------- +// +EXPORT_C TBool CPbk2ContactRelocator::RelocateContactsL( + CVPbkContactLinkArray* aContacts, + MPbk2ContactRelocatorObserver& aObserver, + Pbk2ContactRelocator::TPbk2ContactRelocationQueryPolicy aQueryPolicy ) + { + __ASSERT_DEBUG( aContacts, Panic(EPanicPreCond_RelocateContactsL ) ); + + return PrepareToRelocateContactL( NULL, aContacts, aObserver, + aQueryPolicy, EPbk2RelocatorExistingContact ); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::IsPhoneMemoryContact +// -------------------------------------------------------------------------- +// +EXPORT_C TBool CPbk2ContactRelocator::IsPhoneMemoryContact( + const MVPbkStoreContact& aContact) const + { + TBool ret = EFalse; + + TVPbkContactStoreUriPtr uri = + aContact.ParentStore().StoreProperties().Uri(); + + TVPbkContactStoreUriPtr phoneMemoryUri + ( VPbkContactStoreUris::DefaultCntDbUri() ); + + if (uri.Compare( phoneMemoryUri, + TVPbkContactStoreUriPtr::EContactStoreUriStoreType ) == 0) + { + ret = ETrue; + } + + return ret; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::IsPhoneMemoryInConfigurationL +// -------------------------------------------------------------------------- +// +EXPORT_C TBool CPbk2ContactRelocator::IsPhoneMemoryInConfigurationL() const + { + TBool ret = EFalse; + + // Get current configuration + CPbk2StoreConfiguration& storeConfig = iAppServices->StoreConfiguration(); + + CVPbkContactStoreUriArray* uriArray = storeConfig.CurrentConfigurationL(); + + // Check is phone memory included + ret = uriArray->IsIncluded( VPbkContactStoreUris::DefaultCntDbUri() ); + delete uriArray; + + return ret; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::RunL +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::RunL() + { + // This methods gets called only when the relocation was cancelled or + // otherwise stopped at the very beginning. The observer is needed to + // be called back asynchronously, so the active object is set running. + if ( iSourceContact ) + { + MVPbkStoreContact* sourceContact = iSourceContact; + iSourceContact = NULL; + iObserver->ContactRelocationFailed( iErrorCode, sourceContact ); + } + else if ( iSourceContacts ) + { + CVPbkContactLinkArray* sourceContacts = iSourceContacts; + iSourceContacts = NULL; + iObserver->ContactsRelocationFailed( iErrorCode, sourceContacts ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::DoCancel +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::DoCancel() + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::RunError +// -------------------------------------------------------------------------- +// +TInt CPbk2ContactRelocator::RunError( TInt /*aError*/ ) + { + // No leaving code in RunL + return KErrNone; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::StoreReady +// Phone memory store was succesfully opened. +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::StoreReady + ( MVPbkContactStore& /*aContactStore*/ ) + { + iTargetStoreOpen = ETrue; + // Safe to ignore error + TRAPD( err, DoRelocateContactL() ); + if ( err == KErrDiskFull ) + { + IssueRequest(); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::IssueRequest +// Inform failure asynchronously +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::IssueRequest() + { + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrNone ); + SetActive(); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::StoreUnavailable +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::StoreUnavailable + ( MVPbkContactStore& /*aContactStore*/, TInt aReason ) + { + // Problem in opening phone memory store + iObserver->ContactRelocationFailed( aReason, iSourceContact ); + iSourceContact = NULL; // ownership was given away + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::HandleStoreEventL +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::HandleStoreEventL + ( MVPbkContactStore& /*aContactStore*/, + TVPbkContactStoreEvent /*aStoreEvent*/ ) + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::FieldAddedToContact +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::FieldAddedToContact + ( MVPbkContactOperationBase& /*aOperation*/ ) + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::FieldAddingFailed +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::FieldAddingFailed + ( MVPbkContactOperationBase& /*aOperation*/, TInt /*aError*/ ) + { + // Do nothing + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::ContactsSaved +// Contact was succesfully saved to phone memory +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::ContactsSaved + ( MVPbkContactOperationBase& /*aOperation*/, + MVPbkContactLinkArray* aResults ) + { + // There should be only one link in the results array + __ASSERT_DEBUG( aResults && aResults->Count() == KOneContact, + Panic( EPanicPreCond_ContactsSaved ) ); + + TRAPD( err, + { + CleanupDeletePushL( aResults ); + + // Next, retrieve the saved contact + RetrieveSavedContactL( aResults->At( KFirstElement ) ); + CleanupStack::PopAndDestroy(); // aResults + }); + + if ( err != KErrNone ) + { + iObserver->ContactRelocationFailed( err, iSourceContact ); + iSourceContact = NULL; // ownership was given away + } + + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::ContactsSavingFailed +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::ContactsSavingFailed + ( MVPbkContactOperationBase& /*aOperation*/, TInt aError ) + { + // Contact was not succesfully saved to phone memory + iObserver->ContactRelocationFailed( aError, iSourceContact ); + iSourceContact = NULL; // ownership was given away + + // Move to next request, if any. Safe to ignore error. + TRAP_IGNORE( DoRelocateContactL() ); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::VPbkSingleContactOperationComplete +// Contact was succesfully retrieved from a link. +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::VPbkSingleContactOperationComplete + ( MVPbkContactOperationBase& aOperation, + MVPbkStoreContact* aContact ) + { + if ( &aOperation == iSavedContactsRetriever ) + { + // Destroy the last relocated contact + delete iRelocatedContact; + iRelocatedContact = NULL; + // Assign a new relocated contact + iRelocatedContact = aContact; + if ( ( iActivePolicy == Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemoryAndLock ) || + ( iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock ) ) + { + // Lock the contact + TRAPD( err, iRelocatedContact->LockL( *this ) ); + if ( err != KErrNone ) + { + iObserver->ContactRelocationFailed( err, iSourceContact ); + iSourceContact = NULL; // ownership was given away + + // Move to next request, if any. Safe to ignore error. + TRAP_IGNORE( DoRelocateContactL() ); + } + } + else if ( iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory ) + { + DeleteSourceContact(); + } + else // EPbk2CopyContactToPhoneMemory + { + DoHandleContactRelocated(); + TRAP_IGNORE( DoRelocateContactL() ); + FinalizeIfReady(); + } + } + else if ( &aOperation == iContactRetriever ) + { + // One contact from given link array was retrieved, now it has + // to be stored and then relocated + iSourceContact = aContact; + DoRelocateContactL(); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::VPbkSingleContactOperationFailed +// Contact was not succesfully retrieved from a link. +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::VPbkSingleContactOperationFailed + ( MVPbkContactOperationBase& /*aOperation*/, TInt aError ) + { + if ( aError != KErrDiskFull ) + { + iObserver->ContactRelocationFailed( aError, iSourceContact ); + iSourceContact = NULL; // ownership was given away + + // Move to next request, if any + TRAP_IGNORE( DoRelocateContactL() ); + } + else + { + IssueRequest(); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::ContactOperationCompleted +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::ContactOperationCompleted + ( TContactOpResult aResult ) + { + if ( aResult.iOpCode == MVPbkContactObserver::EContactLock ) + { + if ( iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock ) + { + // One step to -> delete the original contact + DeleteSourceContact(); + } + else + { + // Relocation is done with current contact + DoHandleContactRelocated(); + // Continue if there are still contacts to relocate + TRAP_IGNORE( DoRelocateContactL() ); + FinalizeIfReady(); + } + } + else if ( aResult.iOpCode == MVPbkContactObserver::EContactDelete ) + { + // The original contact was succesfully deleted. + // Notify has already been called, so move to next request, if any. + // In practise: + DoHandleContactRelocated(); + TRAP_IGNORE( DoRelocateContactL() ); + FinalizeIfReady(); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::ContactOperationFailed +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::ContactOperationFailed + ( TContactOp /*aOpCode*/, TInt aErrorCode, + TBool /*aErrorNotified*/ ) + { + // Request of the deletion of the original contact + // was not succesfully completed + // Give ownership of the failed contact to the observer + iObserver->ContactRelocationFailed( aErrorCode, iSourceContact ); + iSourceContact = NULL; + + // Move to next request, if any + TRAP_IGNORE( DoRelocateContactL() ); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::ReadRelocationPolicyL +// -------------------------------------------------------------------------- +// +Pbk2ContactRelocator::TPbk2ContactRelocationPolicy + CPbk2ContactRelocator::ReadRelocationPolicyL() + { + // Default to copy option + Pbk2ContactRelocator::TPbk2ContactRelocationPolicy ret = Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemory; + TInt result = 0; + + // Get real setting from central repository + CRepository* repository = CRepository::NewL + ( TUid::Uid( KCRUidPhonebookInternalConfig ) ); + CleanupStack::PushL( repository ); + TInt err = repository->Get( KPhonebookContactRelocationPolicy, result ); + if ( err == KErrNone ) + { + ret = Pbk2ContactRelocator::TPbk2ContactRelocationPolicy( result ); + } + + CleanupStack::PopAndDestroy( repository ); + return ret; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::OpenTargetStoreL +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::OpenTargetStoreL() + { + if ( !iTargetStore ) + { + const TVPbkContactStoreUriPtr phoneMemoryUri = + VPbkContactStoreUris::DefaultCntDbUri(); + CVPbkContactManager& contactManager = + iAppServices->ContactManager(); + contactManager.LoadContactStoreL( phoneMemoryUri ); + + MVPbkContactStoreList& storeList = contactManager.ContactStoresL(); + + iTargetStore = storeList.Find( phoneMemoryUri ); + User::LeaveIfNull( iTargetStore ); + iTargetStore->OpenL( *this ); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::DoRelocateContactL +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::DoRelocateContactL() + { + // No previous multirelocate request exists, + // cleanup the previous request + if ( iSourceContacts && iSourceContacts->Count() < KOneContact ) + { + // All contacts were sent to relocation, its important + // to clean the array and set it NULL + delete iSourceContacts; + iSourceContacts = NULL; + } + + if ( iSourceContact ) + { + // Start the copy operation + CopyContactL( *iSourceContact ); + } + else if ( iSourceContacts ) + { + // Since we can not use batch copy operation (it does not give + // copied contact links back) we have to retrieve all the contacts + // and relocate them one by one + if ( iSourceContacts->Count() >= KOneContact ) + { + // Take the first contact link of the array + MVPbkContactLink* contactLink = + iSourceContacts->At( KFirstElement ).CloneLC(); + // Then remove it from the array + iSourceContacts->Delete( KFirstElement ); + + // Then retrieve it + delete iContactRetriever; + iContactRetriever = NULL; + iContactRetriever = + iAppServices->ContactManager(). + RetrieveContactL( *contactLink, *this ); + CleanupStack::PopAndDestroy(); // contactLink + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::InitCopyPolicyL +// -------------------------------------------------------------------------- +// +inline void CPbk2ContactRelocator::InitCopyPolicyL() + { + if (!iCopyPolicy) + { + // There is no copy policy manager if we are in this method + // so creating a new one is always ok + delete iCopyPolicyManager; + iCopyPolicyManager = NULL; + iCopyPolicyManager = CVPbkContactCopyPolicyManager::NewL(); + iCopyPolicy = iCopyPolicyManager->GetPolicyL + ( iAppServices->ContactManager(), + VPbkContactStoreUris::DefaultCntDbUri()); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::DoHandleContactRelocated +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::DoHandleContactRelocated() + { + if ( iRelocatedContact ) + { + MVPbkStoreContact* relocatedContact = iRelocatedContact; + iRelocatedContact = NULL; + // Give ownership of the relocated contact to client. + TRAPD( res, iObserver->ContactRelocatedL( relocatedContact ) ); + if ( res != KErrNone ) + { + MVPbkStoreContact* sourceContact = iSourceContact; + iSourceContact = NULL; + // Give source contact as documented in observer. Client + // takes the ownership + iObserver->ContactRelocationFailed( res, sourceContact ); + } + + delete iSourceContact; + iSourceContact = NULL; + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::DeleteSourceContact +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::DeleteSourceContact() + { + // Source contact is deleted only if policy is MOVE + __ASSERT_DEBUG( iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory || + iActivePolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock, + Panic( EPanicPreCond_DeleteSourceContact ) ); + + // Delete original contact + if ( iSourceContact ) + { + TRAPD( err, iSourceContact->DeleteL( *this ) ); + if ( err != KErrNone ) + { + MVPbkStoreContact* sourceContact = iSourceContact; + iSourceContact = NULL; + // Give source contact as documented in observer. Client + // takes the ownership + iObserver->ContactRelocationFailed( err, sourceContact ); + if ( !iSourceContacts ) + { + // If no more contacts to relocate then complete the relocation + iObserver->RelocationProcessComplete(); + } + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::AskConfirmationL +// -------------------------------------------------------------------------- +// +TBool CPbk2ContactRelocator::AskConfirmationL( + MVPbkStoreContact* aContact, + CVPbkContactLinkArray* aContacts, + TPbk2RelocationQueryType aRelocationQueryType ) + { + TBool ret = ETrue; + + HBufC* prompt = NULL; + HBufC* nameBuffer = NULL; + const TDesC* storeName = + StoreName( aContact, + iAppServices->StoreProperties() ); + + if ( aContact ) + { + nameBuffer = + iAppServices->NameFormatter(). + GetContactTitleL( aContact->Fields(), KDefaultTitleFormat ); + + CleanupStack::PushL( nameBuffer ); + } + + switch( aRelocationQueryType ) + { + case EPbk2NoRelocationQuery: + //don't show the following queries anymore + case EPbk2CopyOneToStoreQuery: + case EPbk2MoveOneToStoreQuery: + case EPbk2CopyOneToPhoneQuery: + case EPbk2MoveOneToPhoneQuery: + case EPbk2CopyManyToStoreQuery: + case EPbk2MoveManyToStoreQuery: + { + // Do nothing + } + break; + default: + { + __ASSERT_DEBUG( EFalse, + Panic( EPanicLogic_AskConfirmationL ) ); + break; + } + } + + if ( prompt ) + { + CleanupStack::PushL( prompt ); + delete iQueryDialog; + iQueryDialog = NULL; + iQueryDialog = CAknQueryDialog::NewL(); + iQueryDialog->SetPromptL( *prompt ); + + CleanupStack::PopAndDestroy( prompt ); + + ret = iQueryDialog->ExecuteLD( R_PBK2_COMMONUI_CONFIRMATION_QUERY ); + iQueryDialog = NULL; + } + + if ( aContact ) + { + CleanupStack::PopAndDestroy(); // nameBuffer + } + return ret; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::RetrieveSavedContactL +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::RetrieveSavedContactL + ( const MVPbkContactLink& aLink ) + { + delete iSavedContactsRetriever; + iSavedContactsRetriever = NULL; + iSavedContactsRetriever = + iAppServices->ContactManager(). + RetrieveContactL( aLink, *this ); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::VerifyPolicy +// -------------------------------------------------------------------------- +// +inline void CPbk2ContactRelocator::VerifyPolicy( + MVPbkStoreContact* aContact, TUint32 aFlags ) + { + // Reset policy + iActivePolicy = iRelocationPolicy; + + // Read-only contacts can not be moved so + // adjust active policy if necessary. New contacts are also not moved. + if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory || + iRelocationPolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock ) + { + if ( aContact ) + { + if (aContact->ParentStore().StoreProperties().ReadOnly() || + aFlags & EPbk2RelocatorNewContact ) + { + iActivePolicy = Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemory; + if ( iRelocationPolicy == Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock ) + { + iActivePolicy = Pbk2ContactRelocator::EPbk2CopyContactToPhoneMemoryAndLock; + } + } + } + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::PrepareToRelocateContactL +// -------------------------------------------------------------------------- +// +TBool CPbk2ContactRelocator::PrepareToRelocateContactL( + MVPbkStoreContact* aContact, + CVPbkContactLinkArray* aContacts, + MPbk2ContactRelocatorObserver& aObserver, + Pbk2ContactRelocator::TPbk2ContactRelocationQueryPolicy aQueryPolicy, + TUint32 aFlags ) + { + __ASSERT_DEBUG( !iSourceContact && !iSourceContacts, + Panic( EPanicPreCond_PrepareToRelocateContactL ) ); + + iObserver = &aObserver; + + TBool result = EFalse; + + // If this is deleted when confirmation note returns do not access + // any member data. + TBool thisDestroyed = EFalse; + iDestroyedPtr = &thisDestroyed; + TPbk2DestructionIndicator indicator + ( &thisDestroyed, iDestroyedPtr ); + + + if ( aContact || aContacts ) + { + VerifyPolicy( aContact, aFlags ); + TPbk2RelocationQueryType relocationQueryType = + SelectRelocationQueryType( aContact, aContacts, aQueryPolicy ); + + // Take ownership + iSourceContact = aContact; + iSourceContacts = aContacts; + + result = AskConfirmationL( aContact, aContacts, relocationQueryType ); + } + else + { + iErrorCode = KErrArgument; + } + + if ( !thisDestroyed ) + { + if ( !result ) + { + iErrorCode = KErrCancel; + } + + if ( iErrorCode != KErrNone ) + { + IssueRequest(); + } + else + { + if ( !iTargetStoreOpen ) + { + OpenTargetStoreL(); + } + else + { + DoRelocateContactL(); + } + } + } + + return result; + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::CopyContactL +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::CopyContactL( MVPbkStoreContact& aContact ) + { + // Init copy policy + InitCopyPolicyL(); + + delete iContactCopier; + iContactCopier = NULL; + iContactCopier = iCopyPolicy->CopyContactL + ( aContact, *iTargetStore, *this ); + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::FinalizeIfReady +// -------------------------------------------------------------------------- +// +void CPbk2ContactRelocator::FinalizeIfReady() + { + // If there are no more contacts waiting to be relocated in this + // request, signal process complete + if ( !iSourceContacts ) + { + iObserver->RelocationProcessComplete(); + } + } + +// -------------------------------------------------------------------------- +// CPbk2ContactRelocator::SelectRelocationQueryType +// -------------------------------------------------------------------------- +// +CPbk2ContactRelocator::TPbk2RelocationQueryType + CPbk2ContactRelocator::SelectRelocationQueryType( + MVPbkStoreContact* aContact, + CVPbkContactLinkArray* aContacts, + Pbk2ContactRelocator::TPbk2ContactRelocationQueryPolicy + aQueryPolicy ) + { + TPbk2RelocationQueryType relocationQueryType(EPbk2NoRelocationQuery); + TBool moveRelocation(EFalse); + + if ( Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemory == iActivePolicy || + Pbk2ContactRelocator::EPbk2MoveContactToPhoneMemoryAndLock == iActivePolicy ) + { + moveRelocation = ETrue; + } + + switch (aQueryPolicy) + { + case Pbk2ContactRelocator::EPbk2DisplayNoQueries: + { + relocationQueryType = EPbk2NoRelocationQuery; + } + break; + + case Pbk2ContactRelocator::EPbk2DisplayBasicQuery: + { + relocationQueryType = EPbk2CopyOneToStoreQuery; + if ( moveRelocation ) + { + relocationQueryType = EPbk2MoveOneToStoreQuery; + } + } + break; + + case Pbk2ContactRelocator::EPbk2DisplayStoreDoesNotSupportQuery: + { + relocationQueryType = EPbk2CopyOneToPhoneQuery; + if ( moveRelocation ) + { + relocationQueryType = EPbk2MoveOneToPhoneQuery; + } + } + break; + + default: + { + __ASSERT_DEBUG( EFalse, + Panic( EPanicPreCond_VerifyRelocationQueryType ) ); + break; + } + } + + if ( !aContact && aContacts && + aQueryPolicy != Pbk2ContactRelocator::EPbk2DisplayNoQueries ) + { + // Relocation is going to be done for many contacts + // and query policy is defined. + __ASSERT_DEBUG( aContacts->Count() >= KLinkArrayRelocationMinCount, + Panic( EPanicPreCond_VerifyRelocationQueryType ) ); + + relocationQueryType = EPbk2CopyManyToStoreQuery; + if ( moveRelocation ) + { + relocationQueryType = EPbk2MoveManyToStoreQuery; + } + } + return relocationQueryType; + } + +// End of File