phonebookui/Phonebook2/CommandsExtension/src/CPbk2MergeContactsCmd.cpp
changeset 0 e686773b3f54
child 3 04ab22b956c2
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Phonebook 2 merge contacts command.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 
       
    21 //Phonebook2
       
    22 #include "CPbk2MergeContactsCmd.h"
       
    23 #include "CPbk2MergeResolver.h"
       
    24 #include <MPbk2CommandObserver.h>
       
    25 #include <MPbk2ContactUiControl.h>
       
    26 #include <MPbk2ApplicationServices.h>
       
    27 #include <MPbk2AppUi.h>
       
    28 #include <MPbk2DialogEliminator.h>
       
    29 #include <MPbk2ContactLinkIterator.h>
       
    30 #include <CPbk2FetchDlg.h>
       
    31 #include <CPbk2ContactViewBuilder.h>
       
    32 #include <CVPbkFilteredContactView.h>
       
    33 #include <CPbk2ApplicationServices.h>
       
    34 #include <CPbk2PresentationContact.h>
       
    35 #include <CPbk2FieldPropertyArray.h>
       
    36 #include <MPbk2ContactViewSupplier.h>
       
    37 #include <CPbk2StoreConfiguration.h>
       
    38 #include <CPbk2StorePropertyArray.h>
       
    39 #include <CPbk2StoreProperty.h>
       
    40 #include <Pbk2StoreProperty.hrh>
       
    41 #include <Pbk2ProcessDecoratorFactory.h>
       
    42 
       
    43 #include <CPbk2MergeConflictsDlg.h>
       
    44 #include <CPbk2MergePhotoConflictDlg.h>
       
    45 
       
    46 #include <pbk2uicontrols.rsg> 
       
    47 #include <pbk2cmdextres.rsg>
       
    48 #include <pbk2commonui.rsg>
       
    49 //Virtual Phonebook
       
    50 #include <MVPbkContactLink.h>
       
    51 #include <MVPbkContactViewBase.h>
       
    52 #include <CVPbkContactStoreUriArray.h>
       
    53 #include <MVPbkContactStore.h>
       
    54 #include <MVPbkContactStoreProperties.h>
       
    55 #include <MVPbkContactOperationBase.h>
       
    56 #include <CVPbkContactManager.h>
       
    57 #include <MVPbkStoreContact.h>
       
    58 #include <MVPbkContactFieldBinaryData.h>
       
    59 #include <MVPbkContactFieldTextData.h>
       
    60 #include <vpbkeng.rsg>
       
    61 #include <MVPbkContactGroup.h>
       
    62 
       
    63 //System
       
    64 #include <aknnotewrappers.h>
       
    65 #include <StringLoader.h>
       
    66 //#include <aknnavide.h>
       
    67 #include <akntitle.h>
       
    68 #include <imageconversion.h>
       
    69 
       
    70 // Debugging headers
       
    71 #include <Pbk2Debug.h>
       
    72 #include <Pbk2Profile.h>
       
    73 
       
    74 /// Unnamed namespace for local definitions
       
    75 namespace {
       
    76 
       
    77 const TInt KFirstContact = 0;
       
    78 const TInt KSecondContact = 1;
       
    79 
       
    80 _LIT( KLocalStore, "cntdb://c:contacts.cdb" );
       
    81 
       
    82 enum TPbk2PanicCodes
       
    83         {
       
    84         EPbk2CommandObserverMissing,
       
    85         EPbk2WronglyActivated,
       
    86         EPbk2DuplicateCallToExecuteLD,
       
    87         EPbk2ViewsAlreadyCreated,
       
    88         EPbk2WrongTypeOfData,
       
    89 		EPbk2PhotoConflictError
       
    90         };
       
    91     
       
    92     void Panic(TPbk2PanicCodes aReason)
       
    93         {
       
    94         _LIT( KPanicText, "CPbk2_Merge_Contacts" );
       
    95         User::Panic(KPanicText,aReason);
       
    96         }
       
    97 
       
    98 } /// namespace
       
    99 
       
   100 
       
   101 // --------------------------------------------------------------------------
       
   102 // CPbk2MergeContactsCmd::CPbk2MergeContactsCmd
       
   103 // --------------------------------------------------------------------------
       
   104 //
       
   105 CPbk2MergeContactsCmd::CPbk2MergeContactsCmd(
       
   106     MPbk2ContactUiControl& aUiControl ) :
       
   107         CActive( EPriorityStandard ),
       
   108         iNextPhase( EPhaseNone ),
       
   109         iUiControl( &aUiControl )
       
   110     {
       
   111     CActiveScheduler::Add( this );
       
   112     }
       
   113 
       
   114 // --------------------------------------------------------------------------
       
   115 // CPbk2MergeContactsCmd::~CPbk2MergeContactsCmd
       
   116 // --------------------------------------------------------------------------
       
   117 //
       
   118 CPbk2MergeContactsCmd::~CPbk2MergeContactsCmd()
       
   119     {
       
   120     PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   121         ("CPbk2NlxMergeContactsCmd(%x)::~CPbk2MergeContactsCmd()"), 
       
   122         this);
       
   123     
       
   124     Cancel();
       
   125     
       
   126     if ( iUiControl )
       
   127         {
       
   128         iUiControl->RegisterCommand( NULL );
       
   129         }
       
   130 
       
   131     CleanAfterFetching();
       
   132     delete iRetrieveOperation;
       
   133     delete iDeleteOperation;
       
   134     delete iCommitOperation;
       
   135 	delete iDeleteMergedOperation;
       
   136     Release( iAppServices );
       
   137     delete iContactFirst;
       
   138     delete iContactSecond;
       
   139     delete iMergedContactLink;
       
   140     delete iStoreContactFirst;
       
   141     delete iStoreContactSecond;
       
   142     delete iMergedContact;
       
   143     delete iMergeResolver;
       
   144     delete iBitmapFirst;
       
   145     delete iBitmapSecond;
       
   146     delete iImgDecoder;
       
   147     delete iWaitDecorator;
       
   148     if( iGroupsToAdd )
       
   149         {
       
   150         iGroupsToAdd->ResetAndDestroy();
       
   151         delete iGroupsToAdd;
       
   152         }
       
   153     if ( iContactToCommit )
       
   154         {
       
   155         iContactToCommit->Reset();
       
   156         delete iContactToCommit;
       
   157         }
       
   158     if ( iContactsToDelete )
       
   159         {
       
   160         iContactsToDelete->Reset();
       
   161         delete iContactsToDelete;
       
   162         }
       
   163     if( iGroupLinksFirst )
       
   164         {
       
   165         iGroupLinksFirst->ResetAndDestroy();
       
   166         delete iGroupLinksFirst;
       
   167         }
       
   168     if( iGroupLinksSecond )
       
   169         {
       
   170         iGroupLinksSecond->ResetAndDestroy();
       
   171         delete iGroupLinksSecond;
       
   172         }
       
   173     TRAP_IGNORE( SetTitlePaneL( EFalse ) );
       
   174     }
       
   175 
       
   176 // --------------------------------------------------------------------------
       
   177 // CPbk2MergeContactsCmd::NewL
       
   178 // --------------------------------------------------------------------------
       
   179 //
       
   180 CPbk2MergeContactsCmd* CPbk2MergeContactsCmd::NewL(
       
   181     MPbk2ContactUiControl& aUiControl )
       
   182     {
       
   183     CPbk2MergeContactsCmd* self = 
       
   184         new ( ELeave ) CPbk2MergeContactsCmd( aUiControl );
       
   185     CleanupStack::PushL( self );
       
   186     self->ConstructL();
       
   187     CleanupStack::Pop( self );
       
   188     return self;
       
   189     }
       
   190 
       
   191 // --------------------------------------------------------------------------
       
   192 // CPbk2MergeContactsCmd::ConstructL
       
   193 // --------------------------------------------------------------------------
       
   194 //
       
   195 void CPbk2MergeContactsCmd::ConstructL()
       
   196     {    
       
   197     if( iUiControl )
       
   198         {
       
   199         iUiControl->RegisterCommand( this );
       
   200         }    
       
   201     
       
   202     iContactManager = &Phonebook2::Pbk2AppUi()->ApplicationServices().ContactManager();
       
   203     iAppServices = CPbk2ApplicationServices::InstanceL();
       
   204     iPhotoConflictIndex = KErrNotFound;
       
   205     iDataFirst.Set( KNullDesC8() );
       
   206     iDataSecond.Set( KNullDesC8() );
       
   207     }
       
   208     
       
   209 // --------------------------------------------------------------------------
       
   210 // CPbk2MergeContactsCmd::ExecuteLD
       
   211 // --------------------------------------------------------------------------
       
   212 //
       
   213 void CPbk2MergeContactsCmd::ExecuteLD()
       
   214     {
       
   215     __ASSERT_ALWAYS( iCommandObserver, Panic( EPbk2CommandObserverMissing ));	    
       
   216     __ASSERT_ALWAYS( !IsActive(), Panic( EPbk2WronglyActivated ));	
       
   217     __ASSERT_ALWAYS( iNextPhase == EPhaseNone, Panic( EPbk2DuplicateCallToExecuteLD ));
       
   218     
       
   219     if( iUiControl )
       
   220         {
       
   221         // Blank UI control to avoid flicker
       
   222         iUiControl->SetBlank( ETrue );
       
   223         }
       
   224     StartNext( EPhaseGetSelection );
       
   225     }
       
   226     
       
   227 // --------------------------------------------------------------------------
       
   228 // CPbk2MergeContactsCmd::ResetUiControl
       
   229 // --------------------------------------------------------------------------
       
   230 //
       
   231 void CPbk2MergeContactsCmd::ResetUiControl( 
       
   232     MPbk2ContactUiControl& aUiControl )
       
   233     {
       
   234     if ( iUiControl == &aUiControl )
       
   235         {
       
   236         iUiControl = NULL;
       
   237         }
       
   238     }
       
   239     
       
   240 // --------------------------------------------------------------------------
       
   241 // CPbk2MergeContactsCmd::AddObserver
       
   242 // --------------------------------------------------------------------------
       
   243 //
       
   244 void CPbk2MergeContactsCmd::AddObserver( 
       
   245     MPbk2CommandObserver& aObserver )
       
   246     {
       
   247     iCommandObserver = &aObserver;
       
   248     }        
       
   249 
       
   250 // --------------------------------------------------------------------------
       
   251 // CPbk2MergeContactsCmd::AutomaticMergeL
       
   252 // --------------------------------------------------------------------------
       
   253 //
       
   254 void CPbk2MergeContactsCmd::AutomaticMergeL()
       
   255     {
       
   256     if(iStoreContactFirst && iStoreContactSecond)
       
   257         {
       
   258         iMergeResolver = CPbk2MergeResolver::NewL(
       
   259                 CPbk2PresentationContact::NewL( *iStoreContactFirst, iAppServices->FieldProperties() ), 
       
   260                 CPbk2PresentationContact::NewL( *iStoreContactSecond, iAppServices->FieldProperties() ) );
       
   261         iMergeResolver->MergeL();
       
   262         StartNext(EPhaseResolveConflicts);
       
   263         }
       
   264     else
       
   265         {
       
   266         Finish(KErrArgument);
       
   267         }
       
   268     }
       
   269 
       
   270 // --------------------------------------------------------------------------
       
   271 // CPbk2MergeContactsCmd::AddGroupsL
       
   272 // --------------------------------------------------------------------------
       
   273 //
       
   274 void CPbk2MergeContactsCmd::AddGroupsL()
       
   275     {
       
   276     TInt countGroups = iGroupsToAdd->Count();
       
   277     if(countGroups)
       
   278         {
       
   279         MVPbkStoreContact *group = iGroupsToAdd->At(countGroups - 1);
       
   280         group->LockL(*this);
       
   281         }
       
   282     else
       
   283         {
       
   284         DeleteSourceContactsL();
       
   285         }
       
   286     }
       
   287 
       
   288 // --------------------------------------------------------------------------
       
   289 // CPbk2MergeContactsCmd::RunL
       
   290 // --------------------------------------------------------------------------
       
   291 //
       
   292 void CPbk2MergeContactsCmd::RunL()
       
   293     {
       
   294     if( !iUiControl )
       
   295         {
       
   296         //UiControl reseted, so cancel all processing
       
   297         iNextPhase = EPhaseFinish ;
       
   298         }
       
   299 
       
   300     switch( iNextPhase )
       
   301     	{
       
   302     	case EPhaseGetSelection:
       
   303     	    {
       
   304     	    GetContactsFromUiFetchL();    	    
       
   305     	    }
       
   306     	    break;
       
   307     	case EPhaseGetStoreContacts:
       
   308             {
       
   309             GetStoreContactsL();
       
   310             }   
       
   311             break;
       
   312     	case EPhaseMerge:
       
   313     	    {
       
   314             AutomaticMergeL();
       
   315     	    }
       
   316             break;
       
   317     	case EPhaseResolveConflicts:
       
   318             {
       
   319             ResolveConflictsL();
       
   320             }
       
   321             break;
       
   322         case EPhaseResolvePhotoConflict:
       
   323             {
       
   324             ResolvePhotoConflictL();
       
   325             }
       
   326             break;
       
   327     	case EPhaseCreateMergedContact:
       
   328         	{
       
   329         	iWaitDecorator = Pbk2ProcessDecoratorFactory::CreateWaitNoteDecoratorL
       
   330                                    ( R_QTN_MERGE_CONTACTS_WAIT_NOTE, EFalse );
       
   331         	iWaitDecorator->SetObserver( *this );
       
   332             iWaitDecorator->ProcessStartedL( 0 );
       
   333             FinalizeMergeL();
       
   334         	}
       
   335     		break;
       
   336     	case EPhaseGetGroups:
       
   337             {
       
   338             GetGroupsL();
       
   339             }
       
   340             break;
       
   341     	case EPhaseAddGroups:
       
   342             {
       
   343             AddGroupsL();
       
   344             }
       
   345             break;
       
   346     	case EPhaseFinish:
       
   347             {
       
   348             if ( iWaitDecorator )
       
   349                 {
       
   350                 // Decorator calls ProcessDismissed
       
   351                 iWaitDecorator->ProcessStopped();
       
   352                 }
       
   353             else
       
   354                 {
       
   355                 // In case Decorator wasn't initialized we invoke
       
   356                 // ProcessDismissed to finish merge command execution
       
   357                 ProcessDismissed( KErrNone );
       
   358                 }
       
   359             }
       
   360             break;
       
   361             
       
   362     	default:
       
   363     		Panic( EPbk2WronglyActivated );
       
   364     		break;
       
   365     	}
       
   366     }    
       
   367 
       
   368 // --------------------------------------------------------------------------
       
   369 // CPbk2MergeContactsCmd::RunError
       
   370 // --------------------------------------------------------------------------
       
   371 //
       
   372 TInt CPbk2MergeContactsCmd::RunError(TInt aError)
       
   373 	{
       
   374 	Finish( aError );
       
   375     return KErrNone;
       
   376 	}
       
   377     
       
   378 // --------------------------------------------------------------------------
       
   379 // CPbk2MergeContactsCmd::FinalizeMergeL
       
   380 // --------------------------------------------------------------------------
       
   381 //
       
   382 void CPbk2MergeContactsCmd::FinalizeMergeL()
       
   383     {
       
   384     if( !iMergeResolver ||  
       
   385             ( !iMergeResolver->CountMerged() && !iMergeResolver->CountConflicts() ) )
       
   386         {
       
   387         Finish( KErrNone );
       
   388         return;
       
   389         }
       
   390     
       
   391     MVPbkContactStore& store = iStoreContactFirst->ParentStore();
       
   392     iMergedContact = store.CreateNewContactLC();
       
   393     CleanupStack::Pop();
       
   394     
       
   395     TInt mergedFieldsCount = iMergeResolver->CountMerged();
       
   396     // add merged fields
       
   397     for ( TInt i = 0; i < mergedFieldsCount; i++ )
       
   398         {
       
   399         MVPbkStoreContactField& field = iMergeResolver->GetMergedAt( i );
       
   400         AddFieldToMergedContactL( field );
       
   401         }
       
   402     
       
   403     TInt conflictCount = iMergeResolver->CountConflicts();
       
   404     // add conflicted fields
       
   405     for ( TInt i = 0; i < conflictCount; i++ )
       
   406         {
       
   407         MPbk2MergeConflict& conflict = iMergeResolver->GetConflictAt( i );
       
   408         
       
   409         RPointerArray<MVPbkStoreContactField> fields;
       
   410         conflict.GetChosenFieldsL( fields );
       
   411         
       
   412         TInt newFields = fields.Count();
       
   413         /// if newFields == 0 not resolved conflict exist
       
   414         
       
   415         for ( TInt j = 0; j < newFields; j++ )
       
   416             {
       
   417             MVPbkStoreContactField* field = fields[ j ];
       
   418             AddFieldToMergedContactL( *field );
       
   419             }
       
   420         fields.Close();
       
   421         }
       
   422     
       
   423     iContactToCommit = new ( ELeave ) CArrayPtrFlat<MVPbkStoreContact>( 1 );
       
   424     iContactToCommit->AppendL( iMergedContact );
       
   425     iCommitOperation = iContactManager->CommitContactsL( iContactToCommit->Array(), *this );
       
   426     }
       
   427 
       
   428 // --------------------------------------------------------------------------
       
   429 // CPbk2MergeContactsCmd::ShowContactsMergedNoteL
       
   430 // --------------------------------------------------------------------------
       
   431 //
       
   432 void CPbk2MergeContactsCmd::ShowContactsMergedNoteL()
       
   433     {
       
   434     HBufC* firstContactString = ContactAsStringLC( iStoreContactFirst );
       
   435     HBufC* secondContactString = ContactAsStringLC( iStoreContactSecond );
       
   436     HBufC* mergedContactString = ContactAsStringLC( iMergedContact );
       
   437     HBufC* unnamed = StringLoader::LoadLC( R_QTN_PHOB_UNNAMED );
       
   438     CDesCArrayFlat* strings = new(ELeave) CDesCArrayFlat( 3 );
       
   439     CleanupStack::PushL( strings );
       
   440     
       
   441     HBufC* prompt = NULL;
       
   442     if ( (firstContactString->Length() > 0 || secondContactString->Length() > 0)
       
   443             && mergedContactString->Length() > 0 )
       
   444         {
       
   445         if ( 0 != firstContactString->Length() )
       
   446             {
       
   447             strings->AppendL( *firstContactString );
       
   448             }
       
   449         else
       
   450             {
       
   451             strings->AppendL( *unnamed );
       
   452             }
       
   453         if ( 0 != secondContactString->Length() )
       
   454             {
       
   455             strings->AppendL( *secondContactString );
       
   456             }
       
   457         else
       
   458             {
       
   459             strings->AppendL( *unnamed );
       
   460             }
       
   461         strings->AppendL( *mergedContactString );
       
   462 
       
   463         prompt = StringLoader::LoadLC( R_QTN_PHOB_NOTE_CONTACTS_WERE_MERGED, *strings );
       
   464         }
       
   465     else
       
   466         {
       
   467         strings->AppendL( *unnamed );
       
   468         prompt = StringLoader::LoadLC( R_QTN_PHOB_NOTE_UNNAMED_CONTACTS_WERE_MERGED , *strings );
       
   469         }
       
   470 
       
   471     CAknNoteDialog* dlg = new( ELeave ) CAknNoteDialog( CAknNoteDialog::ENoTone );
       
   472     dlg->PrepareLC( R_PBK2_MERGE_CONTACTS_CONFIRMATION_NOTE );
       
   473     dlg->SetTextL( *prompt );
       
   474     dlg->RunLD();
       
   475     CleanupStack::PopAndDestroy( prompt );
       
   476     CleanupStack::PopAndDestroy( strings );
       
   477     CleanupStack::PopAndDestroy( unnamed );
       
   478     CleanupStack::PopAndDestroy( mergedContactString );
       
   479     CleanupStack::PopAndDestroy( secondContactString );
       
   480     CleanupStack::PopAndDestroy( firstContactString );
       
   481     }
       
   482 
       
   483 // --------------------------------------------------------------------------
       
   484 // CPbk2MergeContactsCmd::ContactAsStringLC
       
   485 // --------------------------------------------------------------------------
       
   486 //
       
   487 HBufC* CPbk2MergeContactsCmd::ContactAsStringLC( MVPbkStoreContact* aStoreContact )
       
   488     {
       
   489     _LIT(KResultFormat, "%S %S");
       
   490     TPtrC firstName( KNullDesC() );
       
   491     TPtrC lastName( KNullDesC() );
       
   492 	
       
   493     MVPbkStoreContactFieldCollection& fields = aStoreContact->Fields();
       
   494     for ( TInt i(0); i < fields.FieldCount(); ++i )
       
   495         {
       
   496         MVPbkStoreContactField& field = fields.FieldAt( i );
       
   497         if ( field.BestMatchingFieldType()->FieldTypeResId() == R_VPBK_FIELD_TYPE_FIRSTNAME )
       
   498             {
       
   499             MVPbkContactFieldData& data = field.FieldData();
       
   500             __ASSERT_DEBUG( data.DataType() == EVPbkFieldStorageTypeText, Panic( EPbk2WrongTypeOfData ) );
       
   501             MVPbkContactFieldTextData& textData = MVPbkContactFieldTextData::Cast( data );
       
   502             firstName.Set( textData.Text() );
       
   503             }
       
   504         else if ( field.BestMatchingFieldType()->FieldTypeResId() == R_VPBK_FIELD_TYPE_LASTNAME )
       
   505             {
       
   506             MVPbkContactFieldData& data = field.FieldData();
       
   507             __ASSERT_DEBUG( data.DataType() == EVPbkFieldStorageTypeText, Panic( EPbk2WrongTypeOfData ) );
       
   508             MVPbkContactFieldTextData& textData = MVPbkContactFieldTextData::Cast( data );
       
   509             lastName.Set( textData.Text() );        
       
   510             }
       
   511         }
       
   512     
       
   513     HBufC* result = NULL;
       
   514     if ( firstName.Length() > 0 && lastName.Length() > 0 )
       
   515         {
       
   516         result = HBufC::NewLC( firstName.Length() + lastName.Length() + KResultFormat().Length() );
       
   517         TPtr resAsDes = result->Des();
       
   518         resAsDes.Format( KResultFormat, &firstName, &lastName );
       
   519         }
       
   520     else if ( firstName.Length() > 0 )
       
   521         {
       
   522         result = firstName.AllocLC(); 
       
   523         }    
       
   524     else
       
   525         {
       
   526         result = lastName.AllocLC();
       
   527         }
       
   528     return result;
       
   529     }
       
   530 
       
   531 // --------------------------------------------------------------------------
       
   532 // CPbk2MergeContactsCmd::DoCancel
       
   533 // --------------------------------------------------------------------------
       
   534 //
       
   535 void CPbk2MergeContactsCmd::DoCancel()
       
   536     {
       
   537     }
       
   538 
       
   539 // --------------------------------------------------------------------------
       
   540 // CPbk2MergeContactsCmd::NotifyObservers
       
   541 // --------------------------------------------------------------------------
       
   542 //
       
   543 void CPbk2MergeContactsCmd::NotifyObservers()
       
   544     {
       
   545     if ( iCommandObserver )
       
   546         {
       
   547         iCommandObserver->CommandFinished( *this );
       
   548         }
       
   549     
       
   550     if ( iUiControl )
       
   551         {
       
   552         iUiControl->SetBlank( EFalse );
       
   553         iUiControl->UpdateAfterCommandExecution();
       
   554         }
       
   555     }
       
   556 
       
   557 // --------------------------------------------------------------------------
       
   558 // CPbk2MergeContactsCmd::AcceptFetchSelectionL
       
   559 // --------------------------------------------------------------------------
       
   560 //
       
   561 MPbk2FetchDlgObserver::TPbk2FetchAcceptSelection CPbk2MergeContactsCmd::AcceptFetchSelectionL(
       
   562     TInt /*aNumMarkedEntries*/,
       
   563     MVPbkContactLink& /*aLastSelection*/ )
       
   564     {
       
   565     return MPbk2FetchDlgObserver::EFetchYes;
       
   566     }
       
   567 
       
   568 // --------------------------------------------------------------------------
       
   569 // CPbk2MergeContactsCmd::FetchCompletedL
       
   570 // --------------------------------------------------------------------------
       
   571 //
       
   572 void CPbk2MergeContactsCmd::FetchCompletedL(
       
   573     MVPbkContactLinkArray* aMarkedEntries )
       
   574     {   
       
   575     if ( aMarkedEntries )
       
   576         {
       
   577         TInt count = aMarkedEntries->Count();
       
   578         if ( count == 2 )
       
   579             {
       
   580             iContactFirst = aMarkedEntries->At( KFirstContact ).CloneLC();
       
   581             CleanupStack::Pop();
       
   582             iContactSecond = aMarkedEntries->At( KSecondContact ).CloneLC();
       
   583             CleanupStack::Pop();
       
   584             StartNext( EPhaseGetStoreContacts );
       
   585             }
       
   586         else
       
   587             {
       
   588             // Show a note
       
   589             HBufC* prompt = NULL;
       
   590             prompt = StringLoader::LoadLC( R_QTN_PHOB_NOTE_SELECT_2_TO_MERGE );
       
   591             CAknNoteDialog* dlg = new( ELeave ) CAknNoteDialog( CAknNoteDialog::ENoTone );
       
   592             dlg->PrepareLC( R_PBK2_MERGE_CONTACTS_ERROR_NOTE );
       
   593             dlg->SetTextL( *prompt );
       
   594             dlg->RunLD();
       
   595             CleanupStack::PopAndDestroy( prompt ); 
       
   596             }
       
   597         }
       
   598     }
       
   599 
       
   600 // --------------------------------------------------------------------------
       
   601 // CPbk2MergeContactsCmd::FetchCanceled
       
   602 // --------------------------------------------------------------------------
       
   603 //
       
   604 void CPbk2MergeContactsCmd::FetchCanceled()
       
   605     {
       
   606     Finish( KErrCancel );
       
   607     }
       
   608 
       
   609 // --------------------------------------------------------------------------
       
   610 // CPbk2MergeContactsCmd::FetchAborted
       
   611 // --------------------------------------------------------------------------
       
   612 //
       
   613 void CPbk2MergeContactsCmd::FetchAborted()
       
   614     {
       
   615     Finish( KErrCancel );
       
   616     }
       
   617 
       
   618 // --------------------------------------------------------------------------
       
   619 // CPbk2MergeContactsCmd::FetchOkToExit
       
   620 // --------------------------------------------------------------------------
       
   621 //
       
   622 TBool CPbk2MergeContactsCmd::FetchOkToExit()
       
   623     {
       
   624     if ( iNextPhase == EPhaseFinish )
       
   625         {
       
   626         return ETrue;
       
   627         }
       
   628     
       
   629     if ( iContactFirst && iContactSecond )
       
   630         {
       
   631         return ETrue;
       
   632         }
       
   633     else
       
   634         {
       
   635         return EFalse;
       
   636         }
       
   637     }
       
   638 
       
   639 // --------------------------------------------------------------------------
       
   640 // CPbk2MergeContactsCmd::GetContactsFromUiFetchL
       
   641 // --------------------------------------------------------------------------
       
   642 //
       
   643 void CPbk2MergeContactsCmd::GetContactsFromUiFetchL()
       
   644     {
       
   645     __ASSERT_DEBUG( !iAllContactsView, Panic( EPbk2ViewsAlreadyCreated ));
       
   646     CPbk2FetchDlg::TParams params;
       
   647     params.iResId = R_PBK2_MULTIPLE_ENTRY_FETCH_NO_GROUPS_DLG;
       
   648     params.iCbaId = R_PBK2_SOFTKEYS_MERGE_BACK_MARK;
       
   649     params.iNaviPaneId = R_PBK2_MERGE_CONTACTS_FETCH_NAVILABEL;
       
   650     
       
   651     CPbk2StorePropertyArray& storeProperties =
       
   652         Phonebook2::Pbk2AppUi()->ApplicationServices().StoreProperties();
       
   653     
       
   654     // Fetch dlg uses this view instead of AllNameslistView if it is not suitable
       
   655     iStoreUris = Phonebook2::Pbk2AppUi()->
       
   656         ApplicationServices().StoreConfiguration().CurrentConfigurationL();
       
   657     
       
   658     TBool createNewView = EFalse;
       
   659     for ( TInt i = iStoreUris->Count()-1; i >= 0; --i )
       
   660         {
       
   661         const CPbk2StoreProperty* storeProperty = 
       
   662             storeProperties.FindProperty( ( *iStoreUris )[i] );
       
   663         
       
   664         if ( storeProperty != NULL && storeProperty->StoreUri().UriDes().Compare( KLocalStore ) )
       
   665             {
       
   666             iStoreUris->Remove( (*iStoreUris)[i] );
       
   667             createNewView = ETrue;
       
   668             }
       
   669         }    
       
   670     
       
   671     if ( createNewView )
       
   672         {
       
   673         iAllContactsView = CVPbkFilteredContactView::NewL
       
   674             ( *Phonebook2::Pbk2AppUi()->ApplicationServices().ViewSupplier().
       
   675               AllContactsViewL(), *this, *this, iContactManager->FieldTypes() );
       
   676         
       
   677         params.iNamesListView = iAllContactsView;
       
   678         iObservedView = iAllContactsView;
       
   679         }
       
   680     else{
       
   681         params.iNamesListView =
       
   682             Phonebook2::Pbk2AppUi()->ApplicationServices().ViewSupplier().AllContactsViewL();
       
   683         iObservedView =
       
   684             Phonebook2::Pbk2AppUi()->ApplicationServices().ViewSupplier().AllContactsViewL();
       
   685         }    
       
   686 
       
   687     iObservedView->AddObserverL( *this );
       
   688         
       
   689     params.iGroupsListView = NULL;
       
   690     params.iFlags = CPbk2FetchDlg::EFetchMultiple;
       
   691     params.iExitCallback = this;
       
   692     
       
   693     CPbk2FetchDlg* dlg = CPbk2FetchDlg::NewL( params, *this );
       
   694     iFetchDlgEliminator = dlg;
       
   695     iFetchDlgEliminator->ResetWhenDestroyed( &iFetchDlgEliminator );
       
   696     
       
   697     SetTitlePaneL( ETrue );
       
   698     dlg->ExecuteLD(); // Completion is signalled with a callback.
       
   699     }
       
   700 
       
   701 // --------------------------------------------------------------------------
       
   702 // CPbk2MergeContactsCmd::IsFromReadOnlyStore
       
   703 // --------------------------------------------------------------------------
       
   704 //
       
   705 TBool CPbk2MergeContactsCmd::IsFromReadOnlyStore
       
   706         ( const MVPbkContactLink& aContactLink ) const
       
   707     {
       
   708     TBool ret = EFalse;
       
   709 
       
   710     const MVPbkContactStore& store = aContactLink.ContactStore();
       
   711     if ( store.StoreProperties().ReadOnly() )
       
   712         {
       
   713         ret = ETrue;
       
   714         }
       
   715 
       
   716     return ret;
       
   717     }
       
   718 
       
   719 // --------------------------------------------------------------------------
       
   720 // CPbk2MergeContactsCmd::CleanAfterFetching
       
   721 // insure the fetch dlg is deleted and destroy resources used by it 
       
   722 // --------------------------------------------------------------------------
       
   723 //
       
   724 void CPbk2MergeContactsCmd::CleanAfterFetching()
       
   725     {
       
   726     if ( iFetchDlgEliminator )
       
   727         {
       
   728         iFetchDlgEliminator->ForceExit();
       
   729         }
       
   730     if ( iObservedView )
       
   731         {
       
   732         iObservedView->RemoveObserver( *this );
       
   733         }
       
   734     delete iAllContactsView;
       
   735     iAllContactsView = NULL;   
       
   736     delete iStoreUris;
       
   737     iStoreUris = NULL;
       
   738     }
       
   739 
       
   740 // ---------------------------------------------------------------------------
       
   741 // CPbk2MergeContactsCmd::Finish
       
   742 // ---------------------------------------------------------------------------
       
   743 //
       
   744 void CPbk2MergeContactsCmd::Finish( TInt aReason )
       
   745 	{
       
   746 	if ( aReason != KErrNone && aReason != KErrCancel )
       
   747 	    {
       
   748 	    CCoeEnv::Static()->HandleError( aReason );
       
   749 	    }
       
   750 	
       
   751 	if( iNextPhase != EPhaseFinish )
       
   752 		{
       
   753     	StartNext( EPhaseFinish );
       
   754 		}
       
   755 	}
       
   756 
       
   757 // ---------------------------------------------------------------------------
       
   758 // CPbk2MergeContactsCmd::StartNext
       
   759 // ---------------------------------------------------------------------------
       
   760 //
       
   761 void CPbk2MergeContactsCmd::StartNext( TPhase aPhase )
       
   762     {
       
   763     __ASSERT_DEBUG( !IsActive(), Panic( EPbk2WronglyActivated ));    
       
   764     iNextPhase = aPhase;    
       
   765     TRequestStatus* status = &iStatus;
       
   766     User::RequestComplete(status, KErrNone);
       
   767     SetActive();
       
   768     }
       
   769 
       
   770 // ---------------------------------------------------------------------------
       
   771 // CPbk2MergeContactsCmd::StartNext
       
   772 // ---------------------------------------------------------------------------
       
   773 //
       
   774 void CPbk2MergeContactsCmd::StartNext()
       
   775     {
       
   776     __ASSERT_DEBUG( !IsActive(), Panic( EPbk2WronglyActivated ));    
       
   777     TRequestStatus* status = &iStatus;
       
   778     User::RequestComplete(status, KErrNone);
       
   779     SetActive();
       
   780     }
       
   781 
       
   782 // --------------------------------------------------------------------------
       
   783 // CPbk2MergeContactsCmd::RetrieveContactL
       
   784 // --------------------------------------------------------------------------
       
   785 //
       
   786 void CPbk2MergeContactsCmd::RetrieveContactL(
       
   787         const MVPbkContactLink& aContactLink )
       
   788     {
       
   789     // Retrieve the actual store contact from the given link
       
   790     iRetrieveOperation = iAppServices->
       
   791         ContactManager().RetrieveContactL( aContactLink, *this );
       
   792     }
       
   793 
       
   794 ////////////////////////////// CALLBACKS /////////////////////////////////////
       
   795 
       
   796 // --------------------------------------------------------------------------
       
   797 // CPbk2MergeContactsCmd::VPbkSingleContactOperationComplete
       
   798 // --------------------------------------------------------------------------
       
   799 //
       
   800 void CPbk2MergeContactsCmd::VPbkSingleContactOperationComplete(
       
   801         MVPbkContactOperationBase& aOperation,
       
   802         MVPbkStoreContact* aContact )
       
   803     {
       
   804     if ( &aOperation == iRetrieveOperation )
       
   805         {
       
   806         delete iRetrieveOperation;
       
   807         iRetrieveOperation = NULL;
       
   808 
       
   809         if( !iStoreContactFirst )
       
   810             {
       
   811             iStoreContactFirst = aContact;
       
   812             TRAP_IGNORE( RetrieveContactL( *iContactSecond ) ); 
       
   813             }
       
   814         else if( !iStoreContactSecond )
       
   815             {
       
   816             iStoreContactSecond = aContact;
       
   817             StartNext();
       
   818             }
       
   819         else if( iNextPhase == EPhaseGetGroups 
       
   820                  && aContact->Group()
       
   821                  && iGroupLinksFirst 
       
   822                  && iGroupLinksSecond
       
   823                  && iGroupsToAdd )
       
   824             {
       
   825             TBool sameGroup = EFalse;
       
   826             for( TInt idx = 0; idx < iGroupsToAdd->Count(); idx++ )
       
   827                 {
       
   828                 if( aContact->IsSame( *iGroupsToAdd->At( idx ) ) )
       
   829                     {
       
   830                     sameGroup = ETrue;
       
   831                     break;
       
   832                     }
       
   833                 }
       
   834             TInt error = KErrNone;
       
   835             if( !sameGroup )
       
   836                 {
       
   837                 TRAP( error, iGroupsToAdd->AppendL( aContact ); );
       
   838                 if ( error != KErrNone )
       
   839                     {
       
   840                     delete aContact;
       
   841                     DeleteMergedContact();
       
   842                     return;
       
   843                     }
       
   844                 }
       
   845             else
       
   846                 {
       
   847                 delete aContact;
       
   848                 }
       
   849             
       
   850             TInt countFirst = iGroupLinksFirst->Count();
       
   851             TInt countSecond = iGroupLinksSecond->Count();
       
   852             
       
   853             if( countFirst )
       
   854                 {
       
   855                 delete &( iGroupLinksFirst->At( countFirst - 1 ) );
       
   856                 iGroupLinksFirst->Remove( countFirst - 1 );
       
   857                 }
       
   858             else if( countSecond )
       
   859                 {
       
   860                 delete &( iGroupLinksSecond->At( countSecond - 1 ) );
       
   861                 iGroupLinksSecond->Remove( countSecond - 1 );
       
   862                 }
       
   863             
       
   864             countFirst = iGroupLinksFirst->Count();
       
   865             countSecond = iGroupLinksSecond->Count();
       
   866             
       
   867             if( countFirst )
       
   868                 {
       
   869                 TRAP( error, RetrieveContactL( iGroupLinksFirst->At( countFirst - 1 ) ); );
       
   870                 }
       
   871             else if( countSecond )
       
   872                 {
       
   873                 TRAP( error, RetrieveContactL( iGroupLinksSecond->At( countSecond - 1 ) ); );
       
   874                 }
       
   875             else
       
   876                 {
       
   877                 StartNext( EPhaseAddGroups );
       
   878                 }
       
   879             if ( error != KErrNone )
       
   880                 {
       
   881                 delete aContact;
       
   882                 DeleteMergedContact();
       
   883                 }
       
   884             }
       
   885         else
       
   886             {
       
   887             delete aContact;
       
   888             DeleteMergedContact();
       
   889             }
       
   890         }
       
   891     }
       
   892 
       
   893 // --------------------------------------------------------------------------
       
   894 // CPbk2MergeContactsCmd::VPbkSingleContactOperationFailed
       
   895 // --------------------------------------------------------------------------
       
   896 //
       
   897 void CPbk2MergeContactsCmd::VPbkSingleContactOperationFailed(
       
   898         MVPbkContactOperationBase& aOperation,
       
   899         TInt aError )
       
   900     {
       
   901     if ( &aOperation == iRetrieveOperation )
       
   902         {
       
   903         delete iRetrieveOperation;
       
   904         iRetrieveOperation = NULL;
       
   905         
       
   906         Finish( aError );
       
   907         }
       
   908     }
       
   909 
       
   910 // --------------------------------------------------------------------------
       
   911 // CPbk2MergeContactsCmd::ContactOperationCompleted
       
   912 // --------------------------------------------------------------------------
       
   913 //
       
   914 void CPbk2MergeContactsCmd::ContactOperationCompleted(
       
   915         TContactOpResult aResult )
       
   916     {
       
   917     if( aResult.iOpCode == MVPbkContactObserver::EContactLock )
       
   918         {
       
   919         TInt countGroups = iGroupsToAdd->Count();
       
   920         if( countGroups )
       
   921             {
       
   922             MVPbkStoreContact* group = iGroupsToAdd->At( countGroups - 1 );
       
   923             TRAPD( error, 
       
   924                 group->Group()->AddContactL( *iMergedContactLink );
       
   925                 group->CommitL( *this );
       
   926             );
       
   927             if ( error != KErrNone )
       
   928                 {
       
   929                 DeleteMergedContact();
       
   930                 }
       
   931             }
       
   932         }
       
   933     else if( aResult.iOpCode == MVPbkContactObserver::EContactCommit) 
       
   934         {
       
   935         TInt countGroups = iGroupsToAdd->Count();
       
   936         if( countGroups )
       
   937             {
       
   938             MVPbkStoreContact* group = iGroupsToAdd->At( countGroups - 1 );
       
   939             delete group;
       
   940             iGroupsToAdd->Delete( countGroups - 1 );
       
   941             }
       
   942         countGroups = iGroupsToAdd->Count();
       
   943         if( countGroups )
       
   944             {
       
   945             MVPbkStoreContact* group = iGroupsToAdd->At( countGroups - 1 );
       
   946             TRAPD( error, 
       
   947                 group->LockL( *this );
       
   948             );
       
   949            if ( error != KErrNone )
       
   950                {
       
   951                DeleteMergedContact();
       
   952                }
       
   953             }
       
   954         else
       
   955             {
       
   956             TRAPD( error, 
       
   957                 DeleteSourceContactsL();
       
   958             );
       
   959            if ( error != KErrNone )
       
   960                {
       
   961                DeleteMergedContact();
       
   962                }
       
   963             }
       
   964         }
       
   965     delete aResult.iStoreContact;
       
   966     }
       
   967 
       
   968 // --------------------------------------------------------------------------
       
   969 // CPbk2MergeContactsCmd::ContactOperationFailed
       
   970 // --------------------------------------------------------------------------
       
   971 //
       
   972 void CPbk2MergeContactsCmd::ContactOperationFailed(
       
   973         TContactOp /*aOpCode*/, TInt /*aErrorCode*/, TBool /*aErrorNotified*/ )
       
   974     {
       
   975     DeleteMergedContact();
       
   976     }
       
   977 
       
   978 // --------------------------------------------------------------------------
       
   979 // CPbk2MergeContactsCmd::ProcessDismissed
       
   980 // --------------------------------------------------------------------------
       
   981 //
       
   982 void CPbk2MergeContactsCmd::ProcessDismissed
       
   983         ( TInt /*aCancelCode*/ )
       
   984     {
       
   985     if( iMergedContact )
       
   986         {
       
   987         TRAP_IGNORE( ShowContactsMergedNoteL() );
       
   988         }
       
   989     NotifyObservers();
       
   990     }
       
   991 
       
   992 // --------------------------------------------------------------------------
       
   993 // CPbk2MergeContactsCmd::ContactViewReady
       
   994 // --------------------------------------------------------------------------
       
   995 //
       
   996 void CPbk2MergeContactsCmd::ContactViewReady
       
   997         ( MVPbkContactViewBase& /*aView*/ )
       
   998     {
       
   999     // Do nothing
       
  1000     }
       
  1001 
       
  1002 // --------------------------------------------------------------------------
       
  1003 // CPbk2MergeContactsCmd::ContactViewUnavailable
       
  1004 // --------------------------------------------------------------------------
       
  1005 //
       
  1006 void CPbk2MergeContactsCmd::ContactViewUnavailable
       
  1007         ( MVPbkContactViewBase& /*aView*/ )
       
  1008     {
       
  1009     // Do nothing
       
  1010     }
       
  1011 
       
  1012 // --------------------------------------------------------------------------
       
  1013 // CPbk2MergeContactsCmd::ContactAddedToView
       
  1014 // --------------------------------------------------------------------------
       
  1015 //
       
  1016 void CPbk2MergeContactsCmd::ContactAddedToView
       
  1017         ( MVPbkContactViewBase& /*aView*/, TInt /*aIndex*/,
       
  1018           const MVPbkContactLink& aContactLink )
       
  1019     {
       
  1020     if ( iMergedContact && iNextPhase == EPhaseCreateMergedContact )
       
  1021         {
       
  1022         TRAPD( error,
       
  1023             if( !iMergedContactLink  )
       
  1024                 {
       
  1025                 iMergedContactLink = iMergedContact->CreateLinkLC();
       
  1026                 if ( iMergedContactLink )
       
  1027                     {
       
  1028                     CleanupStack::Pop();
       
  1029                     }
       
  1030                 else
       
  1031                     {
       
  1032                     User::Leave( KErrGeneral );
       
  1033                     }
       
  1034                 }
       
  1035             if ( iMergedContactLink && iMergedContactLink->IsSame( aContactLink ) )
       
  1036                 {
       
  1037                 StartNext( EPhaseGetGroups );
       
  1038                 }
       
  1039         );
       
  1040         if ( error != KErrNone )
       
  1041             {
       
  1042             Finish( error );
       
  1043             }
       
  1044         }
       
  1045     }
       
  1046 
       
  1047 // --------------------------------------------------------------------------
       
  1048 // CPbk2MergeContactsCmd::ContactRemovedFromView
       
  1049 // --------------------------------------------------------------------------
       
  1050 //
       
  1051 void CPbk2MergeContactsCmd::ContactRemovedFromView
       
  1052         ( MVPbkContactViewBase& /*aView*/, TInt /*aIndex*/,
       
  1053           const MVPbkContactLink& /*aContactLink*/ )
       
  1054     {
       
  1055     // Do nothing
       
  1056     }
       
  1057 
       
  1058 // --------------------------------------------------------------------------
       
  1059 // CPbk2MergeContactsCmd::ContactViewError
       
  1060 // --------------------------------------------------------------------------
       
  1061 //
       
  1062 void CPbk2MergeContactsCmd::ContactViewError
       
  1063         ( MVPbkContactViewBase& /*aView*/, TInt /*aError*/,
       
  1064           TBool /*aErrorNotified*/ )
       
  1065     {
       
  1066     // Do nothing
       
  1067     }
       
  1068 
       
  1069 // --------------------------------------------------------------------------
       
  1070 // CPbk2MergeContactsCmd::OkToExitL
       
  1071 // --------------------------------------------------------------------------
       
  1072 //
       
  1073 TBool CPbk2MergeContactsCmd::OkToExitL( TInt /*aCommandId*/ )
       
  1074     {
       
  1075     return ETrue;
       
  1076     }
       
  1077 
       
  1078 // --------------------------------------------------------------------------
       
  1079 // CPbk2MergeContactsCmd::IsContactIncluded
       
  1080 // --------------------------------------------------------------------------
       
  1081 //
       
  1082 TBool CPbk2MergeContactsCmd::IsContactIncluded
       
  1083         ( const MVPbkBaseContact& aContact )
       
  1084     {
       
  1085     for ( TInt i = iStoreUris->Count()-1; i >= 0; --i )
       
  1086         {
       
  1087         if ( aContact.MatchContactStore((*iStoreUris)[i].UriDes()) )
       
  1088             {
       
  1089             return ETrue;
       
  1090             }
       
  1091         }  
       
  1092     return EFalse;
       
  1093     }
       
  1094 
       
  1095 // --------------------------------------------------------------------------
       
  1096 // CPbk2MergeContactsCmd::StepComplete
       
  1097 // --------------------------------------------------------------------------
       
  1098 //
       
  1099 void CPbk2MergeContactsCmd::StepComplete( MVPbkContactOperationBase& /*aOperation*/, TInt /*aStepSize*/ )
       
  1100     {
       
  1101     
       
  1102     }
       
  1103 
       
  1104 // --------------------------------------------------------------------------
       
  1105 // CPbk2MergeContactsCmd::StepFailed
       
  1106 // --------------------------------------------------------------------------
       
  1107 //
       
  1108 TBool CPbk2MergeContactsCmd::StepFailed( MVPbkContactOperationBase& aOperation, 
       
  1109                                          TInt /*aStepSize*/, TInt aError )
       
  1110     {
       
  1111     if ( &aOperation == iCommitOperation )
       
  1112         {
       
  1113         delete iCommitOperation;
       
  1114         iCommitOperation = NULL;
       
  1115         iContactToCommit->Reset();
       
  1116         delete iContactToCommit;
       
  1117         iContactToCommit = NULL;
       
  1118         Finish( aError );
       
  1119         }
       
  1120     else if ( &aOperation == iDeleteOperation )
       
  1121         {
       
  1122         delete iDeleteOperation;
       
  1123         iDeleteOperation = NULL;
       
  1124         // Merged contact must be deleted
       
  1125         DeleteMergedContact();
       
  1126         }
       
  1127     else if ( &aOperation == iDeleteMergedOperation )
       
  1128         {
       
  1129         delete iDeleteMergedOperation;
       
  1130         iDeleteMergedOperation = NULL;
       
  1131         Finish( aError );
       
  1132         }
       
  1133     return EFalse;
       
  1134     }
       
  1135 
       
  1136 // --------------------------------------------------------------------------
       
  1137 // CPbk2MergeContactsCmd::perationComplete
       
  1138 // --------------------------------------------------------------------------
       
  1139 //
       
  1140 void CPbk2MergeContactsCmd::OperationComplete( MVPbkContactOperationBase& aOperation )
       
  1141     {
       
  1142     if ( &aOperation == iCommitOperation )
       
  1143         {
       
  1144         delete iCommitOperation;
       
  1145         iCommitOperation = NULL;
       
  1146         iContactToCommit->Reset();
       
  1147         delete iContactToCommit;
       
  1148         iContactToCommit = NULL;
       
  1149         }
       
  1150     else if ( &aOperation == iDeleteOperation )
       
  1151         {
       
  1152         delete iDeleteOperation;
       
  1153         iDeleteOperation = NULL;
       
  1154         Finish( KErrNone );
       
  1155         }
       
  1156     else if ( &aOperation == iDeleteMergedOperation )
       
  1157         {
       
  1158         delete iDeleteMergedOperation;
       
  1159         iDeleteMergedOperation = NULL;
       
  1160         delete iMergedContact;
       
  1161         iMergedContact = NULL;
       
  1162         Finish( KErrInUse );
       
  1163         }
       
  1164     }
       
  1165 
       
  1166 
       
  1167 // --------------------------------------------------------------------------
       
  1168 // CPbk2MergeContactsCmd::SetTitlePaneL
       
  1169 // --------------------------------------------------------------------------
       
  1170 //
       
  1171 void CPbk2MergeContactsCmd::SetTitlePaneL( TBool aCustom )
       
  1172     {
       
  1173     CEikStatusPane* statusPane = iAvkonAppUi->StatusPane();
       
  1174     if ( statusPane && statusPane->PaneCapabilities( TUid::Uid( EEikStatusPaneUidTitle ) ).IsPresent() )
       
  1175         {
       
  1176         CAknTitlePane* titlePane = static_cast<CAknTitlePane*>
       
  1177             ( statusPane->ControlL ( TUid::Uid( EEikStatusPaneUidTitle ) ) );
       
  1178         
       
  1179         if ( aCustom )
       
  1180             {
       
  1181             HBufC* title = StringLoader::LoadLC( R_QTN_PHOB_TITLE_MERGE_CONTACTS );
       
  1182             titlePane->SetTextL( *title );
       
  1183             CleanupStack::PopAndDestroy( title );  
       
  1184             }
       
  1185         else
       
  1186             {
       
  1187             titlePane->SetTextToDefaultL();
       
  1188             }
       
  1189         }
       
  1190     }
       
  1191 
       
  1192 // --------------------------------------------------------------------------
       
  1193 // CPbk2MergeContactsCmd::CheckPhotoConflictL
       
  1194 // --------------------------------------------------------------------------
       
  1195 //
       
  1196 void CPbk2MergeContactsCmd::CheckPhotoConflictL()
       
  1197     {
       
  1198     iImageTypeConflictsCount = 0;
       
  1199     iPhotoConflictIndex = KErrNotFound;
       
  1200     TInt conflictsCount = iMergeResolver->CountConflicts();
       
  1201     for ( TInt i = 0; i < conflictsCount; i++ )
       
  1202         {
       
  1203         MPbk2MergeConflict& conflict = iMergeResolver->GetConflictAt( i );
       
  1204         TInt type = conflict.GetConflictType();
       
  1205         if ( type == EPbk2ConflictTypeImage )
       
  1206             {
       
  1207             iImageTypeConflictsCount++;
       
  1208             CPbk2MergeConflict& conflict =
       
  1209                 ( CPbk2MergeConflict& ) iMergeResolver->GetConflictAt( i );
       
  1210             const MVPbkStoreContactField* firstField;
       
  1211             const MVPbkStoreContactField* secondField;
       
  1212             conflict.GetFieldsL( firstField, secondField );
       
  1213             
       
  1214             const MVPbkFieldType* fieldType = firstField->BestMatchingFieldType();
       
  1215             TArray<TVPbkFieldVersitProperty> versitPropArr = fieldType->VersitProperties();
       
  1216             TInt count = versitPropArr.Count();
       
  1217         
       
  1218             for( TInt idx = 0; idx < count; idx++ )
       
  1219                 {
       
  1220                 TVPbkFieldVersitProperty versitProp = versitPropArr[idx];
       
  1221                 if( versitProp.Name() == EVPbkVersitNamePHOTO )
       
  1222                     {
       
  1223                     if ( firstField->FieldData().DataType() == EVPbkFieldStorageTypeBinary && 
       
  1224                             secondField->FieldData().DataType() == EVPbkFieldStorageTypeBinary )
       
  1225                         {
       
  1226                         iDataFirst.Set( MVPbkContactFieldBinaryData::Cast
       
  1227                             ( firstField->FieldData() ).BinaryData() );
       
  1228                         iDataSecond.Set( MVPbkContactFieldBinaryData::Cast
       
  1229                             ( secondField->FieldData() ).BinaryData() );
       
  1230                         
       
  1231                         iPhotoConflictIndex = i;
       
  1232                         break;
       
  1233                         }
       
  1234                     }
       
  1235                 }
       
  1236             }
       
  1237         }
       
  1238     }
       
  1239 
       
  1240 // --------------------------------------------------------------------------
       
  1241 // CPbk2MergeContactsCmd::ResolveAllPhotoConflicts
       
  1242 // --------------------------------------------------------------------------
       
  1243 //
       
  1244 void CPbk2MergeContactsCmd::ResolveAllPhotoConflicts( 
       
  1245         EPbk2ConflictedNumber aConflictResolutionNumber )
       
  1246     {
       
  1247     TInt conflictsCount = iMergeResolver->CountConflicts();
       
  1248     for ( TInt i = 0; i < conflictsCount; i++ )
       
  1249         {
       
  1250         MPbk2MergeConflict& conflict = iMergeResolver->GetConflictAt( i );
       
  1251         if ( conflict.GetConflictType() == EPbk2ConflictTypeImage )
       
  1252             {
       
  1253             conflict.ResolveConflict( aConflictResolutionNumber );
       
  1254             }
       
  1255         }
       
  1256     }
       
  1257 
       
  1258 // --------------------------------------------------------------------------
       
  1259 // CPbk2MergeContactsCmd::ResolvePhotoConflictL
       
  1260 // --------------------------------------------------------------------------
       
  1261 //
       
  1262 void CPbk2MergeContactsCmd::ResolvePhotoConflictL()
       
  1263     {
       
  1264     if ( iStatus != KErrNone || iPhotoConflictIndex == KErrNotFound )
       
  1265         {
       
  1266         StartNext( EPhaseCreateMergedContact );
       
  1267         return;
       
  1268         }
       
  1269     
       
  1270     if ( iDataFirst.Length() == 0 || iDataSecond.Length() == 0 )
       
  1271         {
       
  1272         StartNext( EPhaseFinish );
       
  1273         return;
       
  1274         }
       
  1275     
       
  1276     if ( !iBitmapFirst )
       
  1277         {
       
  1278         InitBitmapL( iBitmapFirst, iDataFirst );
       
  1279         return;
       
  1280         }
       
  1281     if ( !iBitmapSecond )
       
  1282         {
       
  1283         InitBitmapL( iBitmapSecond, iDataSecond  );
       
  1284         return;
       
  1285         }
       
  1286     
       
  1287     delete iImgDecoder;
       
  1288     iImgDecoder = NULL;
       
  1289     TInt result = EPbk2ConflictedFirst;
       
  1290     
       
  1291     CPbk2MergePhotoConflictDlg* dlg = 
       
  1292         CPbk2MergePhotoConflictDlg::NewL( iBitmapFirst, iBitmapSecond, &result );
       
  1293     if ( !dlg->ExecuteLD( R_PBK2_MERGE_CONTACTS_PHOTO_CONFLICT_RESOLUTION_DLG ) )
       
  1294         {
       
  1295         // dlg returns 0 if canceled
       
  1296         Finish( KErrNone );
       
  1297         }
       
  1298     else
       
  1299         {
       
  1300         ResolveAllPhotoConflicts( (EPbk2ConflictedNumber) result );
       
  1301         StartNext( EPhaseCreateMergedContact );
       
  1302         }
       
  1303     delete iBitmapFirst;
       
  1304     iBitmapFirst = NULL;
       
  1305     delete iBitmapSecond;
       
  1306     iBitmapSecond = NULL;
       
  1307     }
       
  1308 
       
  1309 // --------------------------------------------------------------------------
       
  1310 // CPbk2MergeContactsCmd::InitBitmapL
       
  1311 // --------------------------------------------------------------------------
       
  1312 //
       
  1313 void CPbk2MergeContactsCmd::InitBitmapL( CFbsBitmap*& aBitmap, TDesC8& aData )
       
  1314     {
       
  1315     delete iImgDecoder;
       
  1316     iImgDecoder = NULL;
       
  1317     iImgDecoder = CImageDecoder::DataNewL
       
  1318         ( iContactManager->FsSession(), aData, CImageDecoder::EOptionAlwaysThread );
       
  1319     
       
  1320     TFrameInfo info = iImgDecoder->FrameInfo();
       
  1321     aBitmap = new ( ELeave ) CFbsBitmap;
       
  1322     User::LeaveIfError( aBitmap->Create
       
  1323         ( info.iOverallSizeInPixels, info.iFrameDisplayMode ));
       
  1324     
       
  1325     iImgDecoder->Convert( &iStatus, *aBitmap );
       
  1326     SetActive();
       
  1327     }
       
  1328 
       
  1329 // --------------------------------------------------------------------------
       
  1330 // CPbk2MergeContactsCmd::AddFieldToMergedContactL
       
  1331 // --------------------------------------------------------------------------
       
  1332 //
       
  1333 void CPbk2MergeContactsCmd::AddFieldToMergedContactL( MVPbkStoreContactField& field )
       
  1334     {
       
  1335     const MVPbkFieldType* type = field.BestMatchingFieldType();
       
  1336     if ( type )
       
  1337         {
       
  1338         MVPbkStoreContactField* newField = iMergedContact->CreateFieldLC( *type );
       
  1339         newField->SetFieldLabelL( field.FieldLabel() );
       
  1340         newField->FieldData().CopyL( field.FieldData() );
       
  1341         iMergedContact->AddFieldL( newField );
       
  1342         CleanupStack::Pop( newField );
       
  1343         }
       
  1344     }
       
  1345 
       
  1346 // --------------------------------------------------------------------------
       
  1347 // CPbk2MergeContactsCmd::DoResolveConflictsL
       
  1348 // --------------------------------------------------------------------------
       
  1349 //
       
  1350 void CPbk2MergeContactsCmd::ResolveConflictsL()
       
  1351     {
       
  1352     CheckPhotoConflictL();
       
  1353     
       
  1354     TBool isPhotoConflict = iPhotoConflictIndex != KErrNotFound;
       
  1355     TInt normalConflicts = 0;
       
  1356     if( iMergeResolver )
       
  1357         {
       
  1358         normalConflicts = iMergeResolver->CountConflicts() - iImageTypeConflictsCount;
       
  1359         }
       
  1360     
       
  1361     if( normalConflicts )
       
  1362         {
       
  1363         // resolve conflicts
       
  1364         CPbk2MergeConflictsDlg* dlg = CPbk2MergeConflictsDlg::NewL( iMergeResolver, isPhotoConflict );
       
  1365         if ( !dlg->ExecuteLD( R_PBK2_MERGE_CONTACTS_CONFLICT_RESOLUTION_DLG ) )
       
  1366             {
       
  1367             // dlg returns 0 if canceled
       
  1368             Finish( KErrCancel );
       
  1369             }
       
  1370         else
       
  1371             {
       
  1372             StartNext( EPhaseResolvePhotoConflict );
       
  1373             }
       
  1374         }
       
  1375     else
       
  1376         {
       
  1377         StartNext( EPhaseResolvePhotoConflict );
       
  1378         }
       
  1379     }
       
  1380 
       
  1381 // --------------------------------------------------------------------------
       
  1382 // CPbk2MergeContactsCmd::GetStoreContactsL
       
  1383 // --------------------------------------------------------------------------
       
  1384 //
       
  1385 void CPbk2MergeContactsCmd::GetStoreContactsL()
       
  1386     {
       
  1387     if( iContactFirst && iContactSecond )
       
  1388         {
       
  1389         if( !iStoreContactFirst )
       
  1390             {
       
  1391             RetrieveContactL( *iContactFirst );
       
  1392             }
       
  1393         else if( iStoreContactSecond )
       
  1394             {
       
  1395             StartNext( EPhaseMerge );
       
  1396             }
       
  1397         else
       
  1398             {
       
  1399             Finish( KErrArgument );
       
  1400             }
       
  1401         }
       
  1402     else
       
  1403         {
       
  1404         Finish( KErrArgument );
       
  1405         }
       
  1406     }
       
  1407 
       
  1408 // --------------------------------------------------------------------------
       
  1409 // CPbk2MergeContactsCmd::DeleteSourceContactsL
       
  1410 // --------------------------------------------------------------------------
       
  1411 //
       
  1412 void CPbk2MergeContactsCmd::DeleteSourceContactsL()
       
  1413     {
       
  1414     User::LeaveIfNull( iContactFirst );
       
  1415     User::LeaveIfNull( iContactSecond );
       
  1416     if( iContactsToDelete )
       
  1417         {
       
  1418         delete iContactsToDelete;
       
  1419         iContactsToDelete = NULL;
       
  1420         }
       
  1421     iContactsToDelete = CVPbkContactLinkArray::NewL();
       
  1422     iContactsToDelete->AppendL( iContactSecond );
       
  1423     iContactsToDelete->AppendL( iContactFirst );
       
  1424     if( iDeleteOperation )
       
  1425         {
       
  1426         delete iDeleteOperation;
       
  1427         iDeleteOperation = NULL;
       
  1428         }
       
  1429     iDeleteOperation = iContactManager->DeleteContactsL( *iContactsToDelete, *this );
       
  1430     }
       
  1431 
       
  1432 // --------------------------------------------------------------------------
       
  1433 // CPbk2MergeContactsCmd::DeleteMergedContact
       
  1434 // --------------------------------------------------------------------------
       
  1435 //
       
  1436 void CPbk2MergeContactsCmd::DeleteMergedContact()
       
  1437     {
       
  1438     TRAPD( error, 
       
  1439             DeleteMergedContactL();
       
  1440     );
       
  1441     if( error != KErrNone )
       
  1442         {
       
  1443         Finish( KErrGeneral );
       
  1444         }
       
  1445     }
       
  1446 
       
  1447 // --------------------------------------------------------------------------
       
  1448 // CPbk2MergeContactsCmd::DeleteMergedContactL
       
  1449 // --------------------------------------------------------------------------
       
  1450 //
       
  1451 void CPbk2MergeContactsCmd::DeleteMergedContactL()
       
  1452     {
       
  1453     if ( iContactsToDelete )
       
  1454         {
       
  1455         iContactsToDelete->Reset();
       
  1456         }
       
  1457     else
       
  1458         {
       
  1459         iContactsToDelete = CVPbkContactLinkArray::NewL();
       
  1460         }
       
  1461     
       
  1462     if ( iMergedContact )
       
  1463         {
       
  1464         if( !iMergedContactLink  )
       
  1465             {
       
  1466             MVPbkContactLink* iMergedContactLink = iMergedContact->CreateLinkLC();
       
  1467             if ( iMergedContactLink )
       
  1468                 {
       
  1469                 CleanupStack::Pop();
       
  1470                 }
       
  1471             else
       
  1472                 {
       
  1473                 User::Leave( KErrGeneral );
       
  1474                 }
       
  1475             }
       
  1476         iContactsToDelete->AppendL( iMergedContactLink );
       
  1477         iDeleteMergedOperation = iContactManager->DeleteContactsL( *iContactsToDelete, *this );
       
  1478         }
       
  1479     else
       
  1480         {
       
  1481         User::Leave( KErrGeneral );
       
  1482         }
       
  1483     }
       
  1484 
       
  1485 // --------------------------------------------------------------------------
       
  1486 // CPbk2MergeContactsCmd::GetGroupsL
       
  1487 // --------------------------------------------------------------------------
       
  1488 //
       
  1489 void CPbk2MergeContactsCmd::GetGroupsL()
       
  1490     {
       
  1491     if( iStoreContactFirst && iStoreContactFirst && iMergedContact )
       
  1492         {
       
  1493         if( !iGroupsToAdd )
       
  1494             {
       
  1495             iGroupsToAdd = new ( ELeave ) CArrayPtrFlat<MVPbkStoreContact>( 1 );
       
  1496             }
       
  1497         iGroupLinksFirst = static_cast<CVPbkContactLinkArray*>( iStoreContactFirst->GroupsJoinedLC() );
       
  1498         CleanupStack::Pop(); 
       
  1499         iGroupLinksSecond = static_cast<CVPbkContactLinkArray*>( iStoreContactSecond->GroupsJoinedLC() );
       
  1500         CleanupStack::Pop(); 
       
  1501         
       
  1502         TInt countFirst = iGroupLinksFirst->Count();
       
  1503         TInt countSecond = iGroupLinksSecond->Count();
       
  1504         
       
  1505         if( countFirst )
       
  1506             {
       
  1507             RetrieveContactL( iGroupLinksFirst->At( countFirst - 1 ) );
       
  1508             }
       
  1509         else if( countSecond )
       
  1510             {
       
  1511             RetrieveContactL( iGroupLinksSecond->At( countSecond - 1 ) );
       
  1512             }
       
  1513         else
       
  1514             {
       
  1515             DeleteSourceContactsL();
       
  1516             }
       
  1517         }
       
  1518     else
       
  1519         {
       
  1520         DeleteMergedContactL();
       
  1521         }
       
  1522     }
       
  1523 //  End of File