--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook2/CommandsExtension/src/CPbk2MergeContactsCmd.cpp Wed Sep 01 12:29:52 2010 +0100
@@ -0,0 +1,1505 @@
+/*
+* Copyright (c) 2009 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: Phonebook 2 merge contacts command.
+*
+*/
+
+
+// INCLUDE FILES
+
+//Phonebook2
+#include "CPbk2MergeContactsCmd.h"
+#include "CPbk2MergeResolver.h"
+#include <MPbk2CommandObserver.h>
+#include <MPbk2ContactUiControl.h>
+#include <MPbk2ApplicationServices.h>
+#include <MPbk2AppUi.h>
+#include <MPbk2DialogEliminator.h>
+#include <MPbk2ContactLinkIterator.h>
+#include <CPbk2FetchDlg.h>
+#include <CPbk2ContactViewBuilder.h>
+#include <CVPbkFilteredContactView.h>
+#include <CPbk2ApplicationServices.h>
+#include <CPbk2PresentationContact.h>
+#include <CPbk2FieldPropertyArray.h>
+#include <MPbk2ContactViewSupplier.h>
+#include <CPbk2StoreConfiguration.h>
+#include <CPbk2StorePropertyArray.h>
+#include <CPbk2StoreProperty.h>
+#include <Pbk2StoreProperty.hrh>
+#include <Pbk2ProcessDecoratorFactory.h>
+#include <MPbk2ContactNameFormatter.h>
+
+#include <CPbk2MergeConflictsDlg.h>
+#include <CPbk2MergePhotoConflictDlg.h>
+
+#include <Pbk2UIControls.rsg>
+#include <Pbk2CmdExtRes.rsg>
+#include <Pbk2CommonUi.rsg>
+//Virtual Phonebook
+#include <MVPbkContactLink.h>
+#include <MVPbkContactViewBase.h>
+#include <CVPbkContactStoreUriArray.h>
+#include <MVPbkContactStore.h>
+#include <MVPbkContactStoreProperties.h>
+#include <MVPbkContactOperationBase.h>
+#include <CVPbkContactManager.h>
+#include <MVPbkStoreContact.h>
+#include <MVPbkContactFieldBinaryData.h>
+#include <MVPbkContactFieldTextData.h>
+#include <VPbkEng.rsg>
+#include <MVPbkContactGroup.h>
+
+//System
+#include <aknnotewrappers.h>
+#include <StringLoader.h>
+//#include <aknnavide.h>
+#include <akntitle.h>
+#include <imageconversion.h>
+
+// Debugging headers
+#include <Pbk2Debug.h>
+#include <Pbk2Profile.h>
+
+/// Unnamed namespace for local definitions
+namespace {
+
+const TInt KFirstContact = 0;
+const TInt KSecondContact = 1;
+const TInt KAmountToMerge = 2;
+const TInt KDeletionDelay = 1000000; // 1s
+
+_LIT( KLocalStore, "cntdb://c:contacts.cdb" );
+
+enum TPbk2PanicCodes
+ {
+ EPbk2CommandObserverMissing,
+ EPbk2WronglyActivated,
+ EPbk2DuplicateCallToExecuteLD,
+ EPbk2ViewsAlreadyCreated,
+ EPbk2WrongTypeOfData,
+ EPbk2PhotoConflictError
+ };
+
+ void Panic(TPbk2PanicCodes aReason)
+ {
+ _LIT( KPanicText, "CPbk2_Merge_Contacts" );
+ User::Panic(KPanicText,aReason);
+ }
+
+} /// namespace
+
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::CPbk2MergeContactsCmd
+// --------------------------------------------------------------------------
+//
+CPbk2MergeContactsCmd::CPbk2MergeContactsCmd(
+ MPbk2ContactUiControl& aUiControl ) :
+ CActive( EPriorityStandard ),
+ iNextPhase( EPhaseNone ),
+ iUiControl( &aUiControl )
+ {
+ CActiveScheduler::Add( this );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::~CPbk2MergeContactsCmd
+// --------------------------------------------------------------------------
+//
+CPbk2MergeContactsCmd::~CPbk2MergeContactsCmd()
+ {
+ PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
+ ("CPbk2NlxMergeContactsCmd(%x)::~CPbk2MergeContactsCmd()"),
+ this);
+
+ Cancel();
+
+ if ( iUiControl )
+ {
+ iUiControl->RegisterCommand( NULL );
+ }
+
+ CleanAfterFetching();
+ iTimer.Cancel();
+ iTimer.Close();
+ delete iFirstContactString;
+ delete iSecondContactString;
+ delete iMergedContactString;
+ delete iRetrieveOperation;
+ delete iDeleteOperation;
+ delete iCommitOperation;
+ delete iDeleteMergedOperation;
+ Release( iAppServices );
+ delete iContactFirst;
+ delete iContactSecond;
+ delete iMergedContactLink;
+ delete iStoreContactFirst;
+ delete iStoreContactSecond;
+ delete iMergedContact;
+ delete iMergeResolver;
+ delete iWaitDecorator;
+ if( iGroupsToAdd )
+ {
+ iGroupsToAdd->ResetAndDestroy();
+ delete iGroupsToAdd;
+ }
+ if ( iContactToCommit )
+ {
+ iContactToCommit->Reset();
+ delete iContactToCommit;
+ }
+ if ( iContactsToDelete )
+ {
+ iContactsToDelete->Reset();
+ delete iContactsToDelete;
+ }
+ if( iGroupLinksFirst )
+ {
+ iGroupLinksFirst->ResetAndDestroy();
+ delete iGroupLinksFirst;
+ }
+ if( iGroupLinksSecond )
+ {
+ iGroupLinksSecond->ResetAndDestroy();
+ delete iGroupLinksSecond;
+ }
+ TRAP_IGNORE( SetTitlePaneL( EFalse ) );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::NewL
+// --------------------------------------------------------------------------
+//
+CPbk2MergeContactsCmd* CPbk2MergeContactsCmd::NewL(
+ MPbk2ContactUiControl& aUiControl )
+ {
+ CPbk2MergeContactsCmd* self =
+ new ( ELeave ) CPbk2MergeContactsCmd( aUiControl );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ConstructL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ConstructL()
+ {
+ if( iUiControl )
+ {
+ iUiControl->RegisterCommand( this );
+ }
+
+ iContactManager = &Phonebook2::Pbk2AppUi()->ApplicationServices().ContactManager();
+ iAppServices = CPbk2ApplicationServices::InstanceL();
+ iPhotoConflictIndex = KErrNotFound;
+ User::LeaveIfError( iTimer.CreateLocal() );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ExecuteLD
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ExecuteLD()
+ {
+ __ASSERT_ALWAYS( iCommandObserver, Panic( EPbk2CommandObserverMissing ));
+ __ASSERT_ALWAYS( !IsActive(), Panic( EPbk2WronglyActivated ));
+ __ASSERT_ALWAYS( iNextPhase == EPhaseNone, Panic( EPbk2DuplicateCallToExecuteLD ));
+
+ if( iUiControl )
+ {
+ // Blank UI control to avoid flicker
+ iUiControl->SetBlank( ETrue );
+ }
+ StartNext( EPhaseGetSelection );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ResetUiControl
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ResetUiControl(
+ MPbk2ContactUiControl& aUiControl )
+ {
+ if ( iUiControl == &aUiControl )
+ {
+ iUiControl = NULL;
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::AddObserver
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::AddObserver(
+ MPbk2CommandObserver& aObserver )
+ {
+ iCommandObserver = &aObserver;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::AutomaticMergeL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::AutomaticMergeL()
+ {
+ if(iStoreContactFirst && iStoreContactSecond)
+ {
+ iMergeResolver = CPbk2MergeResolver::NewL(
+ CPbk2PresentationContact::NewL( *iStoreContactFirst, iAppServices->FieldProperties() ),
+ CPbk2PresentationContact::NewL( *iStoreContactSecond, iAppServices->FieldProperties() ) );
+ iMergeResolver->MergeL();
+ StartNext(EPhaseResolveConflicts);
+ }
+ else
+ {
+ Finish(KErrArgument);
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::AddGroupsL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::AddGroupsL()
+ {
+ TInt countGroups = iGroupsToAdd->Count();
+ if(countGroups)
+ {
+ MVPbkStoreContact *group = iGroupsToAdd->At(countGroups - 1);
+ group->LockL(*this);
+ }
+ else
+ {
+ DeleteSourceContactsL();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::RunL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::RunL()
+ {
+ if( !iUiControl )
+ {
+ //UiControl reseted, so cancel all processing
+ iNextPhase = EPhaseFinish ;
+ }
+
+ switch( iNextPhase )
+ {
+ case EPhaseGetSelection:
+ {
+ GetContactsFromUiFetchL();
+ }
+ break;
+ case EPhaseGetStoreContacts:
+ {
+ GetStoreContacts();
+ }
+ break;
+ case EPhaseMerge:
+ {
+ AutomaticMergeL();
+ }
+ break;
+ case EPhaseResolveConflicts:
+ {
+ ResolveConflictsL();
+ }
+ break;
+ case EPhaseResolvePhotoConflict:
+ {
+ ResolvePhotoConflictL();
+ }
+ break;
+ case EPhaseCreateMergedContact:
+ {
+ iWaitDecorator = Pbk2ProcessDecoratorFactory::CreateWaitNoteDecoratorL
+ ( R_QTN_MERGE_CONTACTS_WAIT_NOTE, EFalse );
+ iWaitDecorator->SetObserver( *this );
+ iWaitDecorator->ProcessStartedL( 0 );
+ FinalizeMergeL();
+ }
+ break;
+ case EPhaseGetGroups:
+ {
+ GetGroupsL();
+ }
+ break;
+ case EPhaseAddGroups:
+ {
+ AddGroupsL();
+ }
+ break;
+ case EPhaseFinish:
+ {
+ if ( iWaitDecorator )
+ {
+ // Decorator calls ProcessDismissed
+ iWaitDecorator->ProcessStopped();
+ }
+ else
+ {
+ // In case Decorator wasn't initialized we invoke
+ // ProcessDismissed to finish merge command execution
+ ProcessDismissed( KErrNone );
+ }
+ }
+ break;
+
+ default:
+ Panic( EPbk2WronglyActivated );
+ break;
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::RunError
+// --------------------------------------------------------------------------
+//
+TInt CPbk2MergeContactsCmd::RunError(TInt aError)
+ {
+ Finish( aError );
+ return KErrNone;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::FinalizeMergeL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::FinalizeMergeL()
+ {
+ if( !iMergeResolver ||
+ ( !iMergeResolver->CountMerged() && !iMergeResolver->CountConflicts() ) )
+ {
+ Finish( KErrNone );
+ return;
+ }
+
+ MVPbkContactStore& store = iStoreContactFirst->ParentStore();
+ iMergedContact = store.CreateNewContactLC();
+ CleanupStack::Pop();
+
+ // the conflict thumbnail data's field, used for comparing
+ MVPbkStoreContactField* thumbnailPicField = NULL;
+
+ TInt conflictCount = iMergeResolver->CountConflicts();
+ // add conflicted fields
+ for ( TInt i = 0; i < conflictCount; i++ )
+ {
+ MPbk2MergeConflict& conflict = iMergeResolver->GetConflictAt( i );
+
+ RPointerArray<MVPbkStoreContactField> fields;
+ conflict.GetChosenFieldsL( fields );
+
+ TInt newFields = fields.Count();
+ /// if newFields == 0 not resolved conflict exist
+
+ for ( TInt j = 0; j < newFields; j++ )
+ {
+ MVPbkStoreContactField* field = fields[ j ];
+ const MVPbkFieldType* fieldType = field->BestMatchingFieldType();
+
+ // assign value to thumnailPicField with the field's value
+ if ( fieldType->FieldTypeResId() == R_VPBK_FIELD_TYPE_THUMBNAILPIC )
+ {
+ thumbnailPicField = field;
+ }
+ AddFieldToMergedContactL( *field );
+ }
+ fields.Close();
+ }
+
+ TInt mergedFieldsCount = iMergeResolver->CountMerged();
+
+ // add merged fields
+ for ( TInt i = 0; i < mergedFieldsCount; i++ )
+ {
+ MVPbkStoreContactField& field = iMergeResolver->GetMergedAt( i );
+ const MVPbkFieldType* fieldType = field.BestMatchingFieldType();
+
+ // avoid merging filePath when the two field unmatched to a contact
+ if ( fieldType->FieldTypeResId() == R_VPBK_FIELD_TYPE_CALLEROBJIMG && thumbnailPicField )
+ {
+ if ( !thumbnailPicField->ParentContact().IsSame( field.ParentContact() ) )
+ {
+ continue;
+ }
+ }
+ AddFieldToMergedContactL( field );
+ }
+
+ iContactToCommit = new ( ELeave ) CArrayPtrFlat<MVPbkStoreContact>( 1 );
+ iContactToCommit->AppendL( iMergedContact );
+ iCommitOperation = iContactManager->CommitContactsL( iContactToCommit->Array(), *this );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ShowContactsMergedNoteL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ShowContactsMergedNoteL()
+ {
+ HBufC* unnamed = StringLoader::LoadLC( R_QTN_PHOB_UNNAMED );
+ CDesCArrayFlat* strings = new(ELeave) CDesCArrayFlat( 3 );
+ CleanupStack::PushL( strings );
+
+ HBufC* prompt = NULL;
+
+ if ( ( iFirstContactString->Compare( *unnamed ) || iSecondContactString->Compare( *unnamed ) )
+ && iMergedContactString->Compare( *unnamed ) )
+ {
+ strings->AppendL( *iFirstContactString );
+ strings->AppendL( *iSecondContactString );
+ strings->AppendL( *iMergedContactString );
+
+ prompt = StringLoader::LoadLC( R_QTN_PHOB_NOTE_CONTACTS_WERE_MERGED, *strings );
+ }
+ else
+ {
+ strings->AppendL( *unnamed );
+ prompt = StringLoader::LoadLC( R_QTN_PHOB_NOTE_UNNAMED_CONTACTS_WERE_MERGED , *strings );
+ }
+
+ CAknQueryDialog* dlg = CAknQueryDialog::NewL();
+ dlg->ExecuteLD( R_PBK2_MERGE_CONTACTS_CONFIRMATION_NOTE, *prompt );
+
+ CleanupStack::PopAndDestroy( prompt );
+ CleanupStack::PopAndDestroy( strings );
+ CleanupStack::PopAndDestroy( unnamed );
+
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ContactAsStringLC
+// --------------------------------------------------------------------------
+//
+HBufC* CPbk2MergeContactsCmd::ContactAsStringL( MVPbkStoreContact* aStoreContact )
+ {
+ MVPbkStoreContactFieldCollection& fields = aStoreContact->Fields();
+ HBufC* result = NULL;
+ const TInt KDefaultListFormatting =
+ MPbk2ContactNameFormatter::EDisableCompanyNameSeparator;
+ result = Phonebook2::Pbk2AppUi()->
+ ApplicationServices().NameFormatter().GetContactTitleL( fields, KDefaultListFormatting );
+ if( !result )
+ {
+ result = StringLoader::LoadLC( R_QTN_PHOB_UNNAMED );
+ CleanupStack::Pop( result );
+ }
+ return result;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::DoCancel
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::DoCancel()
+ {
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::NotifyObservers
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::NotifyObservers()
+ {
+ if ( iCommandObserver )
+ {
+ iCommandObserver->CommandFinished( *this );
+ }
+
+ if ( iUiControl )
+ {
+ iUiControl->SetBlank( EFalse );
+ iUiControl->UpdateAfterCommandExecution();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::AcceptFetchSelectionL
+// --------------------------------------------------------------------------
+//
+MPbk2FetchDlgObserver::TPbk2FetchAcceptSelection CPbk2MergeContactsCmd::AcceptFetchSelectionL(
+ TInt /*aNumMarkedEntries*/,
+ MVPbkContactLink& /*aLastSelection*/ )
+ {
+ return MPbk2FetchDlgObserver::EFetchYes;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::FetchCompletedL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::FetchCompletedL(
+ MVPbkContactLinkArray* aMarkedEntries )
+ {
+ if ( aMarkedEntries )
+ {
+ TInt count = aMarkedEntries->Count();
+ if ( count == 2 )
+ {
+ iContactFirst = aMarkedEntries->At( KFirstContact ).CloneLC();
+ CleanupStack::Pop();
+ iContactSecond = aMarkedEntries->At( KSecondContact ).CloneLC();
+ CleanupStack::Pop();
+ StartNext( EPhaseGetStoreContacts );
+ }
+ else
+ {
+ // Show a note
+ HBufC* prompt = NULL;
+ prompt = StringLoader::LoadLC( R_QTN_PHOB_NOTE_SELECT_2_TO_MERGE );
+ CAknQueryDialog* dlg = CAknQueryDialog::NewL();
+ dlg->ExecuteLD( R_PBK2_MERGE_CONTACTS_ERROR_NOTE, *prompt );
+ CleanupStack::PopAndDestroy( prompt );
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::FetchCanceled
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::FetchCanceled()
+ {
+ Finish( KErrCancel );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::FetchAborted
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::FetchAborted()
+ {
+ Finish( KErrCancel );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::FetchOkToExit
+// --------------------------------------------------------------------------
+//
+TBool CPbk2MergeContactsCmd::FetchOkToExit()
+ {
+ if ( iNextPhase == EPhaseFinish )
+ {
+ return ETrue;
+ }
+
+ if ( iContactFirst && iContactSecond )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::GetContactsFromUiFetchL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::GetContactsFromUiFetchL()
+ {
+ __ASSERT_DEBUG( !iAllContactsView, Panic( EPbk2ViewsAlreadyCreated ));
+ CPbk2FetchDlg::TParams params;
+ params.iResId = R_PBK2_MULTIPLE_ENTRY_FETCH_NO_GROUPS_DLG;
+ params.iCbaId = R_PBK2_SOFTKEYS_MERGE_BACK_MARK;
+ params.iNaviPaneId = R_PBK2_MERGE_CONTACTS_FETCH_NAVILABEL;
+ params.iMinSelection = KAmountToMerge;
+
+ CPbk2StorePropertyArray& storeProperties =
+ Phonebook2::Pbk2AppUi()->ApplicationServices().StoreProperties();
+
+ // Fetch dlg uses this view instead of AllNameslistView if it is not suitable
+ iStoreUris = Phonebook2::Pbk2AppUi()->
+ ApplicationServices().StoreConfiguration().CurrentConfigurationL();
+
+ TBool createNewView = EFalse;
+ for ( TInt i = iStoreUris->Count()-1; i >= 0; --i )
+ {
+ const CPbk2StoreProperty* storeProperty =
+ storeProperties.FindProperty( ( *iStoreUris )[i] );
+
+ if ( storeProperty != NULL && storeProperty->StoreUri().UriDes().Compare( KLocalStore ) )
+ {
+ iStoreUris->Remove( (*iStoreUris)[i] );
+ createNewView = ETrue;
+ }
+ }
+
+ if ( createNewView )
+ {
+ iAllContactsView = CVPbkFilteredContactView::NewL
+ ( *Phonebook2::Pbk2AppUi()->ApplicationServices().ViewSupplier().
+ AllContactsViewL(), *this, *this, iContactManager->FieldTypes() );
+
+ params.iNamesListView = iAllContactsView;
+ iObservedView = iAllContactsView;
+ }
+ else{
+ params.iNamesListView =
+ Phonebook2::Pbk2AppUi()->ApplicationServices().ViewSupplier().AllContactsViewL();
+ iObservedView =
+ Phonebook2::Pbk2AppUi()->ApplicationServices().ViewSupplier().AllContactsViewL();
+ }
+
+ iObservedView->AddObserverL( *this );
+
+ params.iGroupsListView = NULL;
+ params.iFlags = CPbk2FetchDlg::EFetchMultiple;
+ params.iExitCallback = this;
+
+ CPbk2FetchDlg* dlg = CPbk2FetchDlg::NewL( params, *this );
+ iFetchDlgEliminator = dlg;
+ iFetchDlgEliminator->ResetWhenDestroyed( &iFetchDlgEliminator );
+
+ SetTitlePaneL( ETrue );
+ dlg->ExecuteLD(); // Completion is signalled with a callback.
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::IsFromReadOnlyStore
+// --------------------------------------------------------------------------
+//
+TBool CPbk2MergeContactsCmd::IsFromReadOnlyStore
+ ( const MVPbkContactLink& aContactLink ) const
+ {
+ TBool ret = EFalse;
+
+ const MVPbkContactStore& store = aContactLink.ContactStore();
+ if ( store.StoreProperties().ReadOnly() )
+ {
+ ret = ETrue;
+ }
+
+ return ret;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::CleanAfterFetching
+// insure the fetch dlg is deleted and destroy resources used by it
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::CleanAfterFetching()
+ {
+ if ( iFetchDlgEliminator )
+ {
+ iFetchDlgEliminator->ForceExit();
+ }
+ if ( iObservedView )
+ {
+ iObservedView->RemoveObserver( *this );
+ }
+ delete iAllContactsView;
+ iAllContactsView = NULL;
+ delete iStoreUris;
+ iStoreUris = NULL;
+ }
+
+// ---------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::Finish
+// ---------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::Finish( TInt aReason )
+ {
+ if ( aReason != KErrNone && aReason != KErrCancel )
+ {
+ CCoeEnv::Static()->HandleError( aReason );
+ }
+
+ if( iNextPhase != EPhaseFinish )
+ {
+ StartNext( EPhaseFinish );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::StartNext
+// ---------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::StartNext( TPhase aPhase )
+ {
+ __ASSERT_DEBUG( !IsActive(), Panic( EPbk2WronglyActivated ));
+
+ iNextPhase = aPhase;
+
+ if ( iNextPhase == EPhaseGetGroups )
+ {
+ iTimer.After( iStatus, KDeletionDelay );
+ }
+ else
+ {
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete( status, KErrNone );
+ }
+ SetActive();
+ }
+
+// ---------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::StartNext
+// ---------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::StartNext()
+ {
+ __ASSERT_DEBUG( !IsActive(), Panic( EPbk2WronglyActivated ));
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ SetActive();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::RetrieveContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::RetrieveContact(
+ const MVPbkContactLink& aContactLink )
+ {
+ // Retrieve the actual store contact from the given link
+ TRAPD( error,
+ iRetrieveOperation = iAppServices->
+ ContactManager().RetrieveContactL( aContactLink, *this );
+ );
+ if( error != KErrNone )
+ {
+ Finish( error );
+ }
+ }
+
+////////////////////////////// CALLBACKS /////////////////////////////////////
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::VPbkSingleContactOperationComplete
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::VPbkSingleContactOperationComplete(
+ MVPbkContactOperationBase& aOperation,
+ MVPbkStoreContact* aContact )
+ {
+ if ( &aOperation == iRetrieveOperation )
+ {
+ delete iRetrieveOperation;
+ iRetrieveOperation = NULL;
+
+ if( !iStoreContactFirst )
+ {
+ iStoreContactFirst = aContact;
+ TRAPD( error, iStoreContactFirst->LockL( *this ) );
+ if( error != KErrNone )
+ {
+ Finish( error );
+ }
+ }
+ else if( !iStoreContactSecond )
+ {
+ iStoreContactSecond = aContact;
+ TRAPD( error, iStoreContactSecond->LockL( *this ) );
+ if( error != KErrNone )
+ {
+ Finish( error );
+ }
+ }
+ else if( iNextPhase == EPhaseGetGroups
+ && aContact->Group()
+ && iGroupLinksFirst
+ && iGroupLinksSecond
+ && iGroupsToAdd )
+ {
+ TBool sameGroup = EFalse;
+ for( TInt idx = 0; idx < iGroupsToAdd->Count(); idx++ )
+ {
+ if( aContact->IsSame( *iGroupsToAdd->At( idx ) ) )
+ {
+ sameGroup = ETrue;
+ break;
+ }
+ }
+ TInt error = KErrNone;
+ if( !sameGroup )
+ {
+ TRAP( error, iGroupsToAdd->AppendL( aContact ); );
+ if ( error != KErrNone )
+ {
+ delete aContact;
+ DeleteMergedContact();
+ return;
+ }
+ }
+ else
+ {
+ delete aContact;
+ }
+
+ TInt countFirst = iGroupLinksFirst->Count();
+ TInt countSecond = iGroupLinksSecond->Count();
+
+ if( countFirst )
+ {
+ delete &( iGroupLinksFirst->At( countFirst - 1 ) );
+ iGroupLinksFirst->Remove( countFirst - 1 );
+ }
+ else if( countSecond )
+ {
+ delete &( iGroupLinksSecond->At( countSecond - 1 ) );
+ iGroupLinksSecond->Remove( countSecond - 1 );
+ }
+
+ countFirst = iGroupLinksFirst->Count();
+ countSecond = iGroupLinksSecond->Count();
+
+ if( countFirst )
+ {
+ RetrieveContact( iGroupLinksFirst->At( countFirst - 1 ) );
+ }
+ else if( countSecond )
+ {
+ RetrieveContact( iGroupLinksSecond->At( countSecond - 1 ) );
+ }
+ else
+ {
+ StartNext( EPhaseAddGroups );
+ }
+ if ( error != KErrNone )
+ {
+ delete aContact;
+ DeleteMergedContact();
+ }
+ }
+ else
+ {
+ delete aContact;
+ DeleteMergedContact();
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::VPbkSingleContactOperationFailed
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::VPbkSingleContactOperationFailed(
+ MVPbkContactOperationBase& aOperation,
+ TInt aError )
+ {
+ if ( &aOperation == iRetrieveOperation )
+ {
+ delete iRetrieveOperation;
+ iRetrieveOperation = NULL;
+
+ Finish( aError );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ContactOperationCompleted
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ContactOperationCompleted(
+ TContactOpResult aResult )
+ {
+ if( aResult.iOpCode == MVPbkContactObserver::EContactLock
+ && iNextPhase == EPhaseGetStoreContacts && !iStoreContactSecond )
+ {
+ RetrieveContact( *iContactSecond );
+ }
+ else if( aResult.iOpCode == MVPbkContactObserver::EContactLock
+ && iNextPhase == EPhaseGetStoreContacts )
+ {
+ StartNext( EPhaseMerge );
+ }
+ else if( aResult.iOpCode == MVPbkContactObserver::EContactLock )
+ {
+ TInt countGroups = iGroupsToAdd->Count();
+ if( countGroups )
+ {
+ MVPbkStoreContact* group = iGroupsToAdd->At( countGroups - 1 );
+ TRAPD( error,
+ group->Group()->AddContactL( *iMergedContactLink );
+ group->CommitL( *this );
+ );
+ if ( error != KErrNone )
+ {
+ DeleteMergedContact();
+ }
+ }
+ }
+ else if( aResult.iOpCode == MVPbkContactObserver::EContactCommit)
+ {
+ TInt countGroups = iGroupsToAdd->Count();
+ if( countGroups )
+ {
+ MVPbkStoreContact* group = iGroupsToAdd->At( countGroups - 1 );
+ delete group;
+ iGroupsToAdd->Delete( countGroups - 1 );
+ }
+ countGroups = iGroupsToAdd->Count();
+ if( countGroups )
+ {
+ MVPbkStoreContact* group = iGroupsToAdd->At( countGroups - 1 );
+ TRAPD( error,
+ group->LockL( *this );
+ );
+ if ( error != KErrNone )
+ {
+ DeleteMergedContact();
+ }
+ }
+ else
+ {
+ TRAPD( error,
+ DeleteSourceContactsL();
+ );
+ if ( error != KErrNone )
+ {
+ DeleteMergedContact();
+ }
+ }
+ }
+ delete aResult.iStoreContact;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ContactOperationFailed
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ContactOperationFailed(
+ TContactOp aOpCode, TInt aErrorCode, TBool /*aErrorNotified*/ )
+ {
+ if( aOpCode == MVPbkContactObserver::EContactLock && iNextPhase == EPhaseGetStoreContacts )
+ {
+ Finish( aErrorCode );
+ }
+ else
+ {
+ DeleteMergedContact();
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ProcessDismissed
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ProcessDismissed
+ ( TInt /*aCancelCode*/ )
+ {
+ if( iMergedContact )
+ {
+ TRAP_IGNORE( ShowContactsMergedNoteL() );
+ }
+ NotifyObservers();
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ContactViewReady
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ContactViewReady
+ ( MVPbkContactViewBase& /*aView*/ )
+ {
+ // Do nothing
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ContactViewUnavailable
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ContactViewUnavailable
+ ( MVPbkContactViewBase& /*aView*/ )
+ {
+ // Do nothing
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ContactAddedToView
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ContactAddedToView
+ ( MVPbkContactViewBase& /*aView*/, TInt /*aIndex*/,
+ const MVPbkContactLink& aContactLink )
+ {
+ if ( iMergedContact && iNextPhase == EPhaseCreateMergedContact )
+ {
+ TRAPD( error,
+ if( !iMergedContactLink )
+ {
+ iMergedContactLink = iMergedContact->CreateLinkLC();
+ if ( iMergedContactLink )
+ {
+ CleanupStack::Pop();
+ }
+ else
+ {
+ User::Leave( KErrGeneral );
+ }
+ }
+ if ( iMergedContactLink && iMergedContactLink->IsSame( aContactLink ) )
+ {
+ StartNext( EPhaseGetGroups );
+ }
+ );
+ if ( error != KErrNone )
+ {
+ Finish( error );
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ContactRemovedFromView
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ContactRemovedFromView
+ ( MVPbkContactViewBase& /*aView*/, TInt /*aIndex*/,
+ const MVPbkContactLink& /*aContactLink*/ )
+ {
+ // Do nothing
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ContactViewError
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ContactViewError
+ ( MVPbkContactViewBase& /*aView*/, TInt /*aError*/,
+ TBool /*aErrorNotified*/ )
+ {
+ // Do nothing
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::OkToExitL
+// --------------------------------------------------------------------------
+//
+TBool CPbk2MergeContactsCmd::OkToExitL( TInt /*aCommandId*/ )
+ {
+ return ETrue;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::IsContactIncluded
+// --------------------------------------------------------------------------
+//
+TBool CPbk2MergeContactsCmd::IsContactIncluded
+ ( const MVPbkBaseContact& aContact )
+ {
+ for ( TInt i = iStoreUris->Count()-1; i >= 0; --i )
+ {
+ if ( aContact.MatchContactStore((*iStoreUris)[i].UriDes()) )
+ {
+ return ETrue;
+ }
+ }
+ return EFalse;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::StepComplete
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::StepComplete( MVPbkContactOperationBase& /*aOperation*/, TInt /*aStepSize*/ )
+ {
+
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::StepFailed
+// --------------------------------------------------------------------------
+//
+TBool CPbk2MergeContactsCmd::StepFailed( MVPbkContactOperationBase& aOperation,
+ TInt /*aStepSize*/, TInt aError )
+ {
+ if ( &aOperation == iCommitOperation )
+ {
+ delete iCommitOperation;
+ iCommitOperation = NULL;
+ iContactToCommit->Reset();
+ delete iContactToCommit;
+ iContactToCommit = NULL;
+ Finish( aError );
+ }
+ else if ( &aOperation == iDeleteOperation )
+ {
+ delete iDeleteOperation;
+ iDeleteOperation = NULL;
+ // Merged contact must be deleted
+ DeleteMergedContact();
+ }
+ else if ( &aOperation == iDeleteMergedOperation )
+ {
+ delete iDeleteMergedOperation;
+ iDeleteMergedOperation = NULL;
+ Finish( aError );
+ }
+ return EFalse;
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::perationComplete
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::OperationComplete( MVPbkContactOperationBase& aOperation )
+ {
+ if ( &aOperation == iCommitOperation )
+ {
+ delete iCommitOperation;
+ iCommitOperation = NULL;
+ iContactToCommit->Reset();
+ delete iContactToCommit;
+ iContactToCommit = NULL;
+ }
+ else if ( &aOperation == iDeleteOperation )
+ {
+ delete iDeleteOperation;
+ iDeleteOperation = NULL;
+ Finish( KErrNone );
+ }
+ else if ( &aOperation == iDeleteMergedOperation )
+ {
+ delete iDeleteMergedOperation;
+ iDeleteMergedOperation = NULL;
+ delete iMergedContact;
+ iMergedContact = NULL;
+ Finish( KErrInUse );
+ }
+ }
+
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::SetTitlePaneL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::SetTitlePaneL( TBool aCustom )
+ {
+ if ( iAvkonAppUi )
+ {
+ CEikStatusPane* statusPane = iAvkonAppUi->StatusPane();
+ if ( statusPane && statusPane->PaneCapabilities( TUid::Uid( EEikStatusPaneUidTitle ) ).IsPresent() )
+ {
+ CAknTitlePane* titlePane = static_cast<CAknTitlePane*>
+ ( statusPane->ControlL ( TUid::Uid( EEikStatusPaneUidTitle ) ) );
+
+ if ( aCustom )
+ {
+ HBufC* title = StringLoader::LoadLC( R_QTN_PHOB_TITLE_MERGE_CONTACTS );
+ titlePane->SetTextL( *title );
+ CleanupStack::PopAndDestroy( title );
+ }
+ else
+ {
+ titlePane->SetTextToDefaultL();
+ }
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::CheckPhotoConflictL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::CheckPhotoConflictL()
+ {
+ iImageTypeConflictsCount = 0;
+ iPhotoConflictIndex = KErrNotFound;
+ TInt conflictsCount = iMergeResolver->CountConflicts();
+ for ( TInt i = 0; i < conflictsCount; i++ )
+ {
+ MPbk2MergeConflict& conflict = iMergeResolver->GetConflictAt( i );
+ TInt type = conflict.GetConflictType();
+ if ( type == EPbk2ConflictTypeImage )
+ {
+ iImageTypeConflictsCount++;
+ CPbk2MergeConflict& conflict =
+ ( CPbk2MergeConflict& ) iMergeResolver->GetConflictAt( i );
+ const MVPbkStoreContactField* firstField;
+ const MVPbkStoreContactField* secondField;
+ conflict.GetFieldsL( firstField, secondField );
+
+ const MVPbkFieldType* fieldType = firstField->BestMatchingFieldType();
+ if ( fieldType )
+ {
+ TArray<TVPbkFieldVersitProperty> versitPropArr = fieldType->VersitProperties();
+ TInt count = versitPropArr.Count();
+
+ for( TInt idx = 0; idx < count; idx++ )
+ {
+ TVPbkFieldVersitProperty versitProp = versitPropArr[idx];
+ if( versitProp.Name() == EVPbkVersitNamePHOTO )
+ {
+ if ( firstField->FieldData().DataType() == EVPbkFieldStorageTypeBinary &&
+ secondField->FieldData().DataType() == EVPbkFieldStorageTypeBinary )
+ {
+ iPhotoConflictIndex = i;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ResolveAllPhotoConflicts
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ResolveAllPhotoConflicts(
+ EPbk2ConflictedNumber aConflictResolutionNumber )
+ {
+ TInt conflictsCount = iMergeResolver->CountConflicts();
+ for ( TInt i = 0; i < conflictsCount; i++ )
+ {
+ MPbk2MergeConflict& conflict = iMergeResolver->GetConflictAt( i );
+ if ( conflict.GetConflictType() == EPbk2ConflictTypeImage )
+ {
+ conflict.ResolveConflict( aConflictResolutionNumber );
+ }
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::ResolvePhotoConflictL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ResolvePhotoConflictL()
+ {
+ if ( iStatus != KErrNone || iPhotoConflictIndex == KErrNotFound )
+ {
+ StartNext( EPhaseCreateMergedContact );
+ return;
+ }
+
+ TInt result = EPbk2ConflictedFirst;
+
+ CPbk2MergePhotoConflictDlg* dlg =
+ CPbk2MergePhotoConflictDlg::NewL( iStoreContactFirst, iStoreContactSecond, &result );
+ if ( !dlg->ExecuteLD( R_PBK2_MERGE_CONTACTS_PHOTO_CONFLICT_RESOLUTION_DLG ) )
+ {
+ // dlg returns 0 if canceled
+ Finish( KErrNone );
+ }
+ else
+ {
+ ResolveAllPhotoConflicts( (EPbk2ConflictedNumber) result );
+ StartNext( EPhaseCreateMergedContact );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::AddFieldToMergedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::AddFieldToMergedContactL( MVPbkStoreContactField& field )
+ {
+ const MVPbkFieldType* type = field.BestMatchingFieldType();
+ if ( type )
+ {
+ MVPbkStoreContactField* newField = iMergedContact->CreateFieldLC( *type );
+ newField->SetFieldLabelL( field.FieldLabel() );
+ newField->FieldData().CopyL( field.FieldData() );
+ iMergedContact->AddFieldL( newField );
+ CleanupStack::Pop( newField );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::DoResolveConflictsL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::ResolveConflictsL()
+ {
+ CheckPhotoConflictL();
+
+ TBool isPhotoConflict = iPhotoConflictIndex != KErrNotFound;
+ TInt normalConflicts = 0;
+ if( iMergeResolver )
+ {
+ normalConflicts = iMergeResolver->CountConflicts() - iImageTypeConflictsCount;
+ }
+
+ if( normalConflicts )
+ {
+ // resolve conflicts
+ CPbk2MergeConflictsDlg* dlg = CPbk2MergeConflictsDlg::NewL( iMergeResolver, isPhotoConflict );
+ if ( !dlg->ExecuteLD( R_PBK2_MERGE_CONTACTS_CONFLICT_RESOLUTION_DLG ) )
+ {
+ // dlg returns 0 if canceled
+ Finish( KErrCancel );
+ }
+ else
+ {
+ StartNext( EPhaseResolvePhotoConflict );
+ }
+ }
+ else
+ {
+ StartNext( EPhaseResolvePhotoConflict );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::GetStoreContactsL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::GetStoreContacts()
+ {
+ if( iContactFirst && iContactSecond )
+ {
+ if( !iStoreContactFirst )
+ {
+ RetrieveContact( *iContactFirst );
+ }
+ else
+ {
+ Finish( KErrArgument );
+ }
+ }
+ else
+ {
+ Finish( KErrArgument );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::DeleteSourceContactsL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::DeleteSourceContactsL()
+ {
+ User::LeaveIfNull( iContactFirst );
+ User::LeaveIfNull( iContactSecond );
+
+ iFirstContactString = ContactAsStringL( iStoreContactFirst );
+ iSecondContactString = ContactAsStringL( iStoreContactSecond );
+ iMergedContactString = ContactAsStringL( iMergedContact );
+
+ delete iStoreContactFirst;
+ iStoreContactFirst = NULL;
+
+ delete iStoreContactSecond;
+ iStoreContactSecond = NULL;
+
+ if( iContactsToDelete )
+ {
+ delete iContactsToDelete;
+ iContactsToDelete = NULL;
+ }
+ iContactsToDelete = CVPbkContactLinkArray::NewL();
+ iContactsToDelete->AppendL( iContactSecond );
+ iContactsToDelete->AppendL( iContactFirst );
+ if( iDeleteOperation )
+ {
+ delete iDeleteOperation;
+ iDeleteOperation = NULL;
+ }
+ iDeleteOperation = iContactManager->DeleteContactsL( *iContactsToDelete, *this );
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::DeleteMergedContact
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::DeleteMergedContact()
+ {
+ TRAPD( error,
+ DeleteMergedContactL();
+ );
+ if( error != KErrNone )
+ {
+ Finish( KErrGeneral );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::DeleteMergedContactL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::DeleteMergedContactL()
+ {
+ if ( iContactsToDelete )
+ {
+ iContactsToDelete->Reset();
+ }
+ else
+ {
+ iContactsToDelete = CVPbkContactLinkArray::NewL();
+ }
+
+ if ( iMergedContact )
+ {
+ if( !iMergedContactLink )
+ {
+ MVPbkContactLink* iMergedContactLink = iMergedContact->CreateLinkLC();
+ if ( iMergedContactLink )
+ {
+ CleanupStack::Pop();
+ }
+ else
+ {
+ User::Leave( KErrGeneral );
+ }
+ }
+ iContactsToDelete->AppendL( iMergedContactLink );
+ iDeleteMergedOperation = iContactManager->DeleteContactsL( *iContactsToDelete, *this );
+ }
+ else
+ {
+ User::Leave( KErrGeneral );
+ }
+ }
+
+// --------------------------------------------------------------------------
+// CPbk2MergeContactsCmd::GetGroupsL
+// --------------------------------------------------------------------------
+//
+void CPbk2MergeContactsCmd::GetGroupsL()
+ {
+ if( iStoreContactFirst && iStoreContactFirst && iMergedContact )
+ {
+ if( !iGroupsToAdd )
+ {
+ iGroupsToAdd = new ( ELeave ) CArrayPtrFlat<MVPbkStoreContact>( 1 );
+ }
+ iGroupLinksFirst = static_cast<CVPbkContactLinkArray*>( iStoreContactFirst->GroupsJoinedLC() );
+ CleanupStack::Pop();
+ iGroupLinksSecond = static_cast<CVPbkContactLinkArray*>( iStoreContactSecond->GroupsJoinedLC() );
+ CleanupStack::Pop();
+
+ TInt countFirst = iGroupLinksFirst->Count();
+ TInt countSecond = iGroupLinksSecond->Count();
+
+ if( countFirst )
+ {
+ RetrieveContact( iGroupLinksFirst->At( countFirst - 1 ) );
+ }
+ else if( countSecond )
+ {
+ RetrieveContact( iGroupLinksSecond->At( countSecond - 1 ) );
+ }
+ else
+ {
+ DeleteSourceContactsL();
+ }
+ }
+ else
+ {
+ DeleteMergedContactL();
+ }
+ }
+// End of File