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