phonebookui/Phonebook2/CommandsExtension/src/CPbk2MergeResolver.cpp
changeset 0 e686773b3f54
child 6 e8e3147d53eb
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 resolver.
       
    15  *
       
    16  */
       
    17 
       
    18 // INCLUDE FILES
       
    19 
       
    20 //Phonebook2
       
    21 #include "CPbk2MergeResolver.h"
       
    22 #include <CPbk2PresentationContact.h>
       
    23 #include <CPbk2PresentationContactFieldCollection.h>
       
    24 #include <CPbk2PresentationContactField.h>
       
    25 #include <MPbk2FieldProperty.h>
       
    26 
       
    27 //Virtual Phonebook
       
    28 #include <MVPbkStoreContact.h>
       
    29 #include <MVPbkStoreContactFieldCollection.h>
       
    30 #include <MVPbkContactFieldTextData.h>
       
    31 #include <MVPbkContactFieldDateTimeData.h>
       
    32 #include <MVPbkContactFieldUriData.h>
       
    33 #include <MVPbkContactFieldBinaryData.h>
       
    34 
       
    35 // Debugging headers
       
    36 #include <Pbk2Debug.h>
       
    37 #include <Pbk2Profile.h>
       
    38 
       
    39 /// Unnamed namespace for local definitions
       
    40 namespace 
       
    41     {
       
    42     enum TPbk2PanicCodes
       
    43         {
       
    44         EPbk2WrongArgument,
       
    45         EPbk2FieldTypeNotExists
       
    46         };
       
    47     
       
    48     void Panic(TPbk2PanicCodes aReason)
       
    49         {
       
    50         _LIT( KPanicText, "CPbk2_Merge_Resolver" );
       
    51         User::Panic(KPanicText,aReason);
       
    52         }
       
    53     
       
    54 #ifdef _DEBUG
       
    55     #define DEBUG_PRINT_FIELD( field ) PrintFieldL( field );
       
    56     const TInt KEndLine = '\0';
       
    57 #else
       
    58     #define DEBUG_PRINT_FIELD( field ) 
       
    59 #endif
       
    60     
       
    61     } /// namespace
       
    62 
       
    63 
       
    64 
       
    65 // --------------------------------------------------------------------------
       
    66 // CPbk2MergeResolver::CPbk2MergeResolver
       
    67 // --------------------------------------------------------------------------
       
    68 //
       
    69 CPbk2MergeResolver::CPbk2MergeResolver(
       
    70         CPbk2PresentationContact* aFirstContact, 
       
    71         CPbk2PresentationContact* aSecondContact )
       
    72     :iFirstContact( aFirstContact ), 
       
    73      iSecondContact( aSecondContact )
       
    74     {
       
    75     }
       
    76 
       
    77 // --------------------------------------------------------------------------
       
    78 // CPbk2MergeResolver::~CPbk2MergeResolver
       
    79 // --------------------------------------------------------------------------
       
    80 //
       
    81 CPbk2MergeResolver::~CPbk2MergeResolver()
       
    82     {
       
    83     iConflicts.ResetAndDestroy();
       
    84     iMerged.Close();
       
    85     delete iFirstContact;
       
    86     delete iSecondContact;
       
    87     }
       
    88 
       
    89 // --------------------------------------------------------------------------
       
    90 // CPbk2MergeResolver::NewL
       
    91 // --------------------------------------------------------------------------
       
    92 //
       
    93 CPbk2MergeResolver* CPbk2MergeResolver::NewL( 
       
    94         CPbk2PresentationContact* aFirstContact, 
       
    95         CPbk2PresentationContact* aSecondContact )
       
    96     {
       
    97     CPbk2MergeResolver* self = 
       
    98         new ( ELeave ) CPbk2MergeResolver( aFirstContact, aSecondContact );
       
    99     return self;
       
   100     }
       
   101 
       
   102 // --------------------------------------------------------------------------
       
   103 // CPbk2MergeResolver::MergeL
       
   104 // --------------------------------------------------------------------------
       
   105 //
       
   106 void CPbk2MergeResolver::MergeL()
       
   107     {
       
   108     iConflicts.ResetAndDestroy();
       
   109     iMerged.Close();
       
   110     
       
   111     CPbk2PresentationContactFieldCollection & firstCollection = iFirstContact->PresentationFields();
       
   112     CPbk2PresentationContactFieldCollection & secondCollection = iSecondContact->PresentationFields();
       
   113     
       
   114     RArray<TInt> duplicatesInFirst;
       
   115     CleanupClosePushL(duplicatesInFirst);
       
   116     RArray<TInt> duplicatesInSecond;
       
   117     CleanupClosePushL(duplicatesInSecond);
       
   118     
       
   119     TInt countFirst = firstCollection.FieldCount();
       
   120     TInt countSecond = secondCollection.FieldCount();
       
   121     TBool addressesMerged = EFalse;
       
   122     
       
   123     for( TInt idxFirst = 0; idxFirst < countFirst; idxFirst++)
       
   124         {
       
   125         const MVPbkStoreContactField& fieldFirst = firstCollection.FieldAt( idxFirst );
       
   126        
       
   127         for( TInt idxSecond = 0; idxSecond < countSecond; idxSecond++)
       
   128             {
       
   129             const MVPbkStoreContactField& fieldSecond = secondCollection.FieldAt( idxSecond );
       
   130             
       
   131             if( AddressField( fieldFirst ) )
       
   132                 {
       
   133                 if( !addressesMerged )
       
   134                     {
       
   135                     MergeAddressesL();
       
   136                     addressesMerged = ETrue;
       
   137                     }
       
   138                 continue;
       
   139                 }
       
   140             
       
   141             if( AddressField( fieldSecond ) )
       
   142                 {
       
   143                 continue;
       
   144                 }
       
   145                 
       
   146             
       
   147             TBool sameTypes = AreFieldsTypeSame( fieldFirst, fieldSecond );
       
   148             TBool sameValues = EqualsValues( fieldFirst, fieldSecond );
       
   149             
       
   150             PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   151                 ("CPbk2MergeResolver::MergeL - Fields:") );
       
   152             DEBUG_PRINT_FIELD( fieldFirst )
       
   153             DEBUG_PRINT_FIELD( fieldSecond )
       
   154             PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   155                 ("CPbk2MergeResolver::MergeL - Fields are the same:%d"), sameTypes);
       
   156             PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   157                 ("CPbk2MergeResolver::MergeL - Fields have the same values:%d"), sameValues);
       
   158             
       
   159             if( sameTypes )
       
   160                 {
       
   161                 if( IsTopContactField( fieldFirst ) )
       
   162                     {
       
   163                     if( CompareTopConactFields( fieldFirst, fieldSecond ) <= 0 )
       
   164                         {
       
   165                         duplicatesInSecond.AppendL( idxSecond );
       
   166                         }
       
   167                     else
       
   168                         {
       
   169                         duplicatesInFirst.AppendL( idxFirst );
       
   170                         }
       
   171                     }
       
   172                 else
       
   173                     {
       
   174                     if( !sameValues && FieldMultiplicity( fieldFirst ) == EPbk2FieldMultiplicityOne  )
       
   175                         {
       
   176                         AddConflictL( fieldFirst, fieldSecond );
       
   177                         }
       
   178                     if( sameValues )
       
   179                         {
       
   180                         duplicatesInSecond.AppendL( idxSecond );
       
   181                         }
       
   182                     }
       
   183                 }
       
   184             }
       
   185         }
       
   186     
       
   187     if( !addressesMerged )
       
   188         {
       
   189         MergeAddressesL();
       
   190         }
       
   191     
       
   192     CompleteMergeArrL( duplicatesInFirst, duplicatesInSecond );
       
   193     
       
   194     CleanupStack::PopAndDestroy( &duplicatesInSecond );
       
   195     CleanupStack::PopAndDestroy( &duplicatesInFirst );
       
   196     }
       
   197 
       
   198 // --------------------------------------------------------------------------
       
   199 // CPbk2MergeResolver::MergeAddressesL
       
   200 // --------------------------------------------------------------------------
       
   201 //
       
   202 void CPbk2MergeResolver::MergeAddressesL()
       
   203     {
       
   204     for (TInt groupId = EPbk2FieldGroupIdPostalAddress; groupId
       
   205             <= EPbk2FieldGroupIdCompanyAddress; groupId++)
       
   206         {
       
   207         ECompareAddress compareAddresses = CompareAddresses(
       
   208                 ( TPbk2FieldGroupId) groupId );
       
   209         switch ( compareAddresses )
       
   210             {
       
   211             case ECASame:
       
   212                 CopyAddressToMergedL( *iFirstContact, 
       
   213                         ( TPbk2FieldGroupId) groupId );
       
   214                 break;
       
   215             case ECAFirstIncludesSecond:
       
   216                 CopyAddressToMergedL( *iFirstContact,
       
   217                         ( TPbk2FieldGroupId) groupId );
       
   218                 break;
       
   219             case ECASecondIncludesFirst:
       
   220                 CopyAddressToMergedL( *iSecondContact,
       
   221                         ( TPbk2FieldGroupId) groupId );
       
   222                 break;
       
   223             case ECADifferent:
       
   224                 AddAddressConflictL( (TPbk2FieldGroupId) groupId );
       
   225                 break;
       
   226             case ECAUndefined:
       
   227                 // Both addresses don't exist
       
   228                 break;
       
   229             default:
       
   230                 Panic( EPbk2WrongArgument );
       
   231             }
       
   232         }
       
   233     }
       
   234 
       
   235 // --------------------------------------------------------------------------
       
   236 // CPbk2MergeResolver::CompleteMergeArrL
       
   237 // --------------------------------------------------------------------------
       
   238 //
       
   239 void CPbk2MergeResolver::CompleteMergeArrL( 
       
   240         RArray<TInt>& aDuplicatesInFirst, 
       
   241         RArray<TInt>& aDuplicatesInSecond )
       
   242     {
       
   243     CPbk2PresentationContactFieldCollection & firstCollection = iFirstContact->PresentationFields();
       
   244     CPbk2PresentationContactFieldCollection & secondCollection = iSecondContact->PresentationFields();
       
   245         
       
   246     TInt countFirst = firstCollection.FieldCount();
       
   247     TInt countSecond = secondCollection.FieldCount();
       
   248 
       
   249     for( TInt idxFirst = 0; idxFirst < countFirst; idxFirst++)
       
   250         {
       
   251         const MVPbkStoreContactField& fieldFirst = firstCollection.FieldAt( idxFirst );
       
   252         if( FindConflictByFieldL( fieldFirst ) == KErrNotFound &&
       
   253             aDuplicatesInFirst.Find( idxFirst ) == KErrNotFound  &&
       
   254             !AddressField( fieldFirst ) )
       
   255             {
       
   256             iMerged.AppendL( &fieldFirst );
       
   257             
       
   258             PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   259                 ("CPbk2MergeResolver::MergeL - Field added to merged(first contact):"));
       
   260             DEBUG_PRINT_FIELD( fieldFirst )
       
   261             }
       
   262         }
       
   263     
       
   264     for( TInt idxSecond = 0; idxSecond < countSecond; idxSecond++)
       
   265         {
       
   266         const MVPbkStoreContactField& fieldSecond = secondCollection.FieldAt( idxSecond );
       
   267         if( FindConflictByFieldL( fieldSecond ) == KErrNotFound && 
       
   268             aDuplicatesInSecond.Find( idxSecond ) == KErrNotFound  && 
       
   269             !AddressField( fieldSecond ) )
       
   270             {
       
   271             iMerged.AppendL( &fieldSecond );
       
   272             
       
   273             PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   274                 ("CPbk2MergeResolver::MergeL - Field added to merged(second contact):"));
       
   275             DEBUG_PRINT_FIELD( fieldSecond )
       
   276             }
       
   277         }
       
   278     }
       
   279 
       
   280 // --------------------------------------------------------------------------
       
   281 // CPbk2MergeResolver::IsTopContactField
       
   282 // --------------------------------------------------------------------------
       
   283 //
       
   284 TBool CPbk2MergeResolver::IsTopContactField( 
       
   285         const MVPbkStoreContactField& aField )
       
   286     {
       
   287     const MVPbkFieldType* fieldType = aField.BestMatchingFieldType();
       
   288     __ASSERT_ALWAYS( fieldType, Panic( EPbk2FieldTypeNotExists ) );
       
   289     TArray<TVPbkFieldVersitProperty> versitProp = fieldType->VersitProperties();
       
   290     
       
   291     TBool topContact = EFalse;
       
   292     
       
   293     for( TInt idx = 0; idx < versitProp.Count() && !topContact; idx++ )
       
   294         {
       
   295         TVPbkFieldVersitProperty versitPropFirst = versitProp[idx];
       
   296         if( versitPropFirst.Name() == EVPbkVersitNameTopContact )
       
   297             {
       
   298             topContact = ETrue;
       
   299             }
       
   300         }
       
   301     
       
   302     return topContact;
       
   303     }
       
   304 
       
   305 // --------------------------------------------------------------------------
       
   306 // CPbk2MergeResolver::CompareTopConactFields
       
   307 // --------------------------------------------------------------------------
       
   308 //
       
   309 TInt CPbk2MergeResolver::CompareTopConactFields(
       
   310         const MVPbkStoreContactField& aFieldFirst,
       
   311         const MVPbkStoreContactField& aFieldSecond )
       
   312     {
       
   313     const MVPbkContactFieldData& dataFirst = aFieldFirst.FieldData();
       
   314     TVPbkFieldStorageType storageTypeFirst = dataFirst.DataType();
       
   315     
       
   316     const MVPbkContactFieldData& dataSecond = aFieldSecond.FieldData();
       
   317     TVPbkFieldStorageType storageTypeSecond = dataSecond.DataType();
       
   318         
       
   319     TInt ret = KErrGeneral;
       
   320     
       
   321     if( storageTypeFirst != storageTypeSecond ||
       
   322         storageTypeFirst != EVPbkFieldStorageTypeText )
       
   323         {
       
   324         return ret;
       
   325         }
       
   326     
       
   327     TInt valueFirst;
       
   328     TInt valueSecond;
       
   329     TInt errorCode;
       
   330     TLex lex( MVPbkContactFieldTextData::Cast( dataFirst ).Text() );
       
   331     errorCode = lex.Val( valueFirst );
       
   332     
       
   333     if( errorCode == KErrNone )
       
   334         {
       
   335         TLex lex( MVPbkContactFieldTextData::Cast( dataSecond ).Text() );
       
   336         errorCode = lex.Val( valueSecond );
       
   337         }
       
   338     
       
   339     if( errorCode == KErrNone )
       
   340         {
       
   341         if( valueFirst > valueSecond )
       
   342             {
       
   343             ret = 1;
       
   344             }
       
   345         else if( valueFirst < valueSecond )
       
   346             {
       
   347             ret = -1;
       
   348             }
       
   349         else
       
   350             {
       
   351             ret = 0;
       
   352             }
       
   353         }
       
   354     
       
   355     return ret;
       
   356     }
       
   357 
       
   358 // --------------------------------------------------------------------------
       
   359 // CPbk2MergeResolver::CountConflicts
       
   360 // --------------------------------------------------------------------------
       
   361 //
       
   362 TInt CPbk2MergeResolver::CountConflicts()
       
   363     {
       
   364     return iConflicts.Count();
       
   365     }
       
   366 
       
   367 // --------------------------------------------------------------------------
       
   368 // CPbk2MergeResolver::GetConflictAt
       
   369 // --------------------------------------------------------------------------
       
   370 //
       
   371 MPbk2MergeConflict& CPbk2MergeResolver::GetConflictAt( TInt aConflict )
       
   372     {
       
   373     __ASSERT_ALWAYS( aConflict >= 0 && aConflict < CountConflicts(), Panic( EPbk2WrongArgument ) );
       
   374     
       
   375     return *iConflicts[aConflict];
       
   376     }
       
   377 
       
   378 // --------------------------------------------------------------------------
       
   379 // CPbk2MergeResolver::CountMerged
       
   380 // --------------------------------------------------------------------------
       
   381 //
       
   382 TInt CPbk2MergeResolver::CountMerged()
       
   383     {
       
   384     return iMerged.Count();
       
   385     }
       
   386 
       
   387 // --------------------------------------------------------------------------
       
   388 // CPbk2MergeResolver::GetMergedAtL
       
   389 // --------------------------------------------------------------------------
       
   390 //
       
   391 MVPbkStoreContactField& CPbk2MergeResolver::GetMergedAt( TInt aMarged )
       
   392     {
       
   393     __ASSERT_ALWAYS( aMarged >= 0 && aMarged < CountMerged(), Panic( EPbk2WrongArgument ) );
       
   394     
       
   395     return *iMerged[aMarged];
       
   396     }
       
   397 
       
   398 // --------------------------------------------------------------------------
       
   399 // CPbk2MergeResolver::CompareAddresses
       
   400 // --------------------------------------------------------------------------
       
   401 //
       
   402 CPbk2MergeResolver::ECompareAddress CPbk2MergeResolver::CompareAddresses( 
       
   403         TPbk2FieldGroupId aGroupId )
       
   404     {
       
   405     ECompareAddress retCompare = ECAUndefined;
       
   406     
       
   407     TInt countEquals = 0;
       
   408     
       
   409     CPbk2PresentationContactFieldCollection& firstCollection = iFirstContact->PresentationFields();
       
   410     CPbk2PresentationContactFieldCollection& secondCollection = iSecondContact->PresentationFields();
       
   411     
       
   412     TInt countFirst = firstCollection.FieldCount();
       
   413     TInt countSecond = secondCollection.FieldCount();
       
   414     
       
   415     TInt countAddressFieldsFirst = 0;
       
   416     TInt countAddressFieldsSecond = 0;
       
   417     
       
   418     for( TInt idxFirst = 0; idxFirst < countFirst && retCompare != ECADifferent; idxFirst++)
       
   419         {
       
   420         const CPbk2PresentationContactField& fieldFirst = firstCollection.At( idxFirst );
       
   421         const MPbk2FieldProperty& propFirst = fieldFirst.FieldProperty();
       
   422         
       
   423         if( !AddressField( fieldFirst ) || propFirst.GroupId() != aGroupId )
       
   424             {
       
   425             continue;
       
   426             }
       
   427         
       
   428         countAddressFieldsFirst++;
       
   429         
       
   430         for( TInt idxSecond = 0; idxSecond < countSecond; idxSecond++)
       
   431             {
       
   432             const CPbk2PresentationContactField& fieldSecond = secondCollection.At( idxSecond );
       
   433             const MPbk2FieldProperty& propSecond = fieldSecond.FieldProperty();
       
   434             
       
   435             if( !AddressField( fieldSecond ) || propSecond.GroupId() != aGroupId )
       
   436                 {
       
   437                 continue;
       
   438                 }
       
   439             
       
   440             if( countAddressFieldsFirst == 1 )
       
   441                 {
       
   442                 countAddressFieldsSecond++;  
       
   443                 }
       
   444             
       
   445             if( !AreAddressesSubTypeSame( fieldFirst, fieldSecond ) )
       
   446                 {
       
   447                 continue;
       
   448                 }
       
   449             
       
   450             if( EqualsValues( fieldFirst, fieldSecond ) )
       
   451                 {
       
   452                 countEquals++;
       
   453                 }
       
   454             else
       
   455                 {
       
   456                 return ECADifferent;
       
   457                 }
       
   458             }
       
   459         }
       
   460     
       
   461     if( countAddressFieldsFirst == 0 )
       
   462         {
       
   463         for( TInt idxSecond = 0; idxSecond < countSecond; idxSecond++)
       
   464             {
       
   465             const CPbk2PresentationContactField& fieldSecond = secondCollection.At( idxSecond );
       
   466             const MPbk2FieldProperty& propSecond = fieldSecond.FieldProperty();
       
   467             
       
   468             if( AddressField( fieldSecond ) && propSecond.GroupId() == aGroupId )
       
   469                 {
       
   470                 countAddressFieldsSecond++; 
       
   471                 }
       
   472             }
       
   473         }
       
   474 
       
   475     return DoCompareAddresses( countEquals, countAddressFieldsFirst, countAddressFieldsSecond );
       
   476     }
       
   477 
       
   478 // --------------------------------------------------------------------------
       
   479 // CPbk2MergeResolver::CompareAddresses
       
   480 // --------------------------------------------------------------------------
       
   481 //
       
   482 CPbk2MergeResolver::ECompareAddress CPbk2MergeResolver::DoCompareAddresses( 
       
   483         TInt aCountEquals, 
       
   484         TInt aCountAddressFieldsFirst,
       
   485         TInt aCountAddressFieldsSecond )
       
   486     {
       
   487     ECompareAddress retCompare = ECAUndefined;
       
   488     
       
   489     if( aCountAddressFieldsFirst == 0 && aCountAddressFieldsSecond != 0 )
       
   490         {
       
   491         retCompare = ECASecondIncludesFirst;
       
   492         }
       
   493     else if( aCountAddressFieldsFirst != 0 && aCountAddressFieldsSecond == 0 )
       
   494         {
       
   495         retCompare = ECAFirstIncludesSecond;
       
   496         }
       
   497     else if( aCountAddressFieldsFirst != 0 && aCountAddressFieldsSecond != 0 )
       
   498         {
       
   499         if( aCountEquals == aCountAddressFieldsFirst && aCountEquals == aCountAddressFieldsSecond )
       
   500             {
       
   501             retCompare = ECASame;
       
   502             }
       
   503         else if( aCountEquals == aCountAddressFieldsFirst )
       
   504             {
       
   505             retCompare = ECASecondIncludesFirst;
       
   506             }
       
   507         else if( aCountEquals == aCountAddressFieldsSecond )
       
   508             {
       
   509             retCompare = ECAFirstIncludesSecond;
       
   510             }
       
   511         else
       
   512             {
       
   513             retCompare = ECADifferent;
       
   514             }
       
   515         }
       
   516     
       
   517     return retCompare;
       
   518     }
       
   519 
       
   520 // --------------------------------------------------------------------------
       
   521 // CPbk2MergeResolver::AddressField
       
   522 // --------------------------------------------------------------------------
       
   523 //
       
   524 TBool CPbk2MergeResolver::AddressField( const MVPbkStoreContactField& aField )
       
   525     {
       
   526     const MVPbkFieldType* fieldType = aField.BestMatchingFieldType();
       
   527     __ASSERT_ALWAYS( fieldType, Panic( EPbk2FieldTypeNotExists ) );
       
   528     TArray<TVPbkFieldVersitProperty> versitProp = fieldType->VersitProperties();
       
   529     
       
   530     TBool address = EFalse;
       
   531     
       
   532     for( TInt idx = 0; idx < versitProp.Count() && !address; idx++ )
       
   533         {
       
   534         TVPbkFieldVersitProperty versitPropFirst = versitProp[idx];
       
   535         if( versitPropFirst.Name() == EVPbkVersitNameADR ||
       
   536             versitPropFirst.Name() == EVPbkVersitNameGEO )
       
   537             {
       
   538             address = ETrue;
       
   539             }
       
   540         }
       
   541     
       
   542     return address;
       
   543     }
       
   544 
       
   545 // --------------------------------------------------------------------------
       
   546 // CPbk2MergeResolver::FieldMultiplicity
       
   547 // --------------------------------------------------------------------------
       
   548 //
       
   549 TPbk2FieldMultiplicity CPbk2MergeResolver::FieldMultiplicity( const MVPbkStoreContactField& aField )
       
   550     {
       
   551     const CPbk2PresentationContactField& presentationField = 
       
   552             static_cast<const CPbk2PresentationContactField&>( aField );
       
   553     
       
   554     return presentationField.FieldProperty().Multiplicity();
       
   555     }
       
   556 
       
   557 // --------------------------------------------------------------------------
       
   558 // CPbk2MergeResolver::EqualsValues
       
   559 // --------------------------------------------------------------------------
       
   560 //
       
   561 TBool CPbk2MergeResolver::EqualsValues( 
       
   562         const MVPbkStoreContactField& aFieldFirst,
       
   563         const MVPbkStoreContactField& aFieldSecond )
       
   564     {
       
   565     const MVPbkContactFieldData& dataFirst = aFieldFirst.FieldData();
       
   566     TVPbkFieldStorageType storageTypeFirst = dataFirst.DataType();
       
   567     
       
   568     const MVPbkContactFieldData& dataSecond = aFieldSecond.FieldData();
       
   569     TVPbkFieldStorageType storageTypeSecond = dataSecond.DataType();
       
   570         
       
   571     if( storageTypeFirst != storageTypeSecond )
       
   572         {
       
   573         return EFalse;
       
   574         }
       
   575     
       
   576     TBool sameValues = EFalse;
       
   577     
       
   578     switch( storageTypeFirst )
       
   579         {
       
   580         case EVPbkFieldStorageTypeText:
       
   581             {
       
   582             if( MVPbkContactFieldTextData::Cast( dataFirst ).Text() == 
       
   583                 MVPbkContactFieldTextData::Cast( dataSecond ).Text() )
       
   584                 {
       
   585                 sameValues = ETrue;
       
   586                 }
       
   587             }
       
   588             break;
       
   589         case EVPbkFieldStorageTypeDateTime:
       
   590             {
       
   591             if( MVPbkContactFieldDateTimeData::Cast( dataFirst ).DateTime() == 
       
   592                 MVPbkContactFieldDateTimeData::Cast( dataSecond ).DateTime() )
       
   593                 {
       
   594                 sameValues = ETrue;
       
   595                 }
       
   596             }
       
   597             break;
       
   598         case EVPbkFieldStorageTypeUri:
       
   599             {
       
   600             if( MVPbkContactFieldUriData::Cast( dataFirst ).Text() == 
       
   601                 MVPbkContactFieldUriData::Cast( dataSecond ).Text() )
       
   602                 {
       
   603                 sameValues = ETrue;
       
   604                 }
       
   605             }
       
   606             break;
       
   607         case EVPbkFieldStorageTypeBinary:
       
   608             {
       
   609             const MVPbkContactFieldBinaryData& binaryFirst = 
       
   610                     MVPbkContactFieldBinaryData::Cast( dataFirst );
       
   611             const MVPbkContactFieldBinaryData& binarySecond = 
       
   612                     MVPbkContactFieldBinaryData::Cast( dataSecond );
       
   613             if( binaryFirst.BinaryData() == binarySecond.BinaryData() )
       
   614                 {
       
   615                 sameValues = ETrue;
       
   616                 }
       
   617             break;
       
   618             }
       
   619         // Ignore other field types
       
   620         }
       
   621     
       
   622     return sameValues;
       
   623     }
       
   624 
       
   625 // --------------------------------------------------------------------------
       
   626 // CPbk2MergeResolver::AreAddressesSubTypeSame
       
   627 // --------------------------------------------------------------------------
       
   628 //
       
   629 TBool CPbk2MergeResolver::AreAddressesSubTypeSame( 
       
   630         const MVPbkStoreContactField& aFieldFirst,
       
   631         const MVPbkStoreContactField& aFieldSecond )
       
   632     {
       
   633     const MVPbkFieldType* fieldTypeFirst = aFieldFirst.BestMatchingFieldType();
       
   634     __ASSERT_ALWAYS( fieldTypeFirst, Panic( EPbk2FieldTypeNotExists ) );
       
   635     
       
   636     const MVPbkFieldType* fieldTypeSecond = aFieldSecond.BestMatchingFieldType();
       
   637     __ASSERT_ALWAYS( fieldTypeSecond, Panic( EPbk2FieldTypeNotExists ) );
       
   638     
       
   639     TArray<TVPbkFieldVersitProperty> versitPropArrFirst = fieldTypeFirst->VersitProperties();
       
   640     TArray<TVPbkFieldVersitProperty> versitPropArrSecond = fieldTypeSecond->VersitProperties();
       
   641     
       
   642     TInt countFirst = versitPropArrFirst.Count();
       
   643     TInt countSecond = versitPropArrSecond.Count();
       
   644 
       
   645     TBool retCompare = EFalse;
       
   646     
       
   647     for( TInt idxFirst = 0; idxFirst < countFirst && !retCompare; idxFirst++ )
       
   648         {
       
   649         TVPbkFieldVersitProperty versitPropFirst = versitPropArrFirst[idxFirst];
       
   650         for( TInt idxSecond = 0; idxSecond < countSecond; idxSecond++ )
       
   651             {
       
   652             TVPbkFieldVersitProperty versitPropSecond = versitPropArrSecond[idxSecond];
       
   653             if( versitPropFirst.SubField() == versitPropSecond.SubField() )
       
   654                 {
       
   655                 retCompare = ETrue;
       
   656                 break;
       
   657                 }
       
   658             }
       
   659         }
       
   660     
       
   661     return retCompare;
       
   662     }
       
   663 
       
   664 // --------------------------------------------------------------------------
       
   665 // CPbk2MergeResolver::AreFieldsTypeSame
       
   666 // --------------------------------------------------------------------------
       
   667 //
       
   668 TBool CPbk2MergeResolver::AreFieldsTypeSame( 
       
   669         const MVPbkStoreContactField& aFieldFirst,
       
   670         const MVPbkStoreContactField& aFieldSecond )
       
   671     {
       
   672     const MVPbkFieldType* fieldTypeFirst = aFieldFirst.BestMatchingFieldType();
       
   673     __ASSERT_ALWAYS( fieldTypeFirst, Panic( EPbk2FieldTypeNotExists ) );
       
   674     
       
   675     const MVPbkFieldType* fieldTypeSecond = aFieldSecond.BestMatchingFieldType();
       
   676     __ASSERT_ALWAYS( fieldTypeSecond, Panic( EPbk2FieldTypeNotExists ) );
       
   677     
       
   678     return fieldTypeFirst->IsSame( *fieldTypeSecond );
       
   679     }
       
   680 
       
   681 // --------------------------------------------------------------------------
       
   682 // CPbk2MergeResolver::AddConflictL
       
   683 // --------------------------------------------------------------------------
       
   684 //
       
   685 void CPbk2MergeResolver::AddConflictL( 
       
   686         const MVPbkStoreContactField& aFieldFirst,
       
   687         const MVPbkStoreContactField& aFieldSecond )
       
   688     {
       
   689     CPbk2MergeConflict* conflictNew = CPbk2MergeConflict::NewL();
       
   690     CleanupStack::PushL( conflictNew );
       
   691     conflictNew->AddFields( aFieldFirst, aFieldSecond );
       
   692     iConflicts.AppendL( conflictNew );
       
   693     CleanupStack::Pop( conflictNew );
       
   694     
       
   695     PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING( "CPbk2MergeResolver::AddConflictL - Conflict created" ) );
       
   696     }
       
   697 
       
   698 // --------------------------------------------------------------------------
       
   699 // CPbk2MergeResolver::AddAddressConflictL
       
   700 // --------------------------------------------------------------------------
       
   701 //
       
   702 void CPbk2MergeResolver::AddAddressConflictL( TPbk2FieldGroupId aGroupId )
       
   703     {
       
   704     CPbk2MergeConflictAddress* conflictNew = CPbk2MergeConflictAddress::NewL();
       
   705     CleanupStack::PushL( conflictNew );
       
   706     conflictNew->AddAddress( *iFirstContact, *iSecondContact, aGroupId );
       
   707     iConflicts.AppendL( conflictNew );
       
   708     CleanupStack::Pop( conflictNew );
       
   709     
       
   710     PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING( "CPbk2MergeResolver::AddAddressConflictL - Conflict created" ) );
       
   711     }
       
   712 
       
   713 // --------------------------------------------------------------------------
       
   714 // CPbk2MergeResolver::FindConflictByFieldL
       
   715 // --------------------------------------------------------------------------
       
   716 //
       
   717 TInt CPbk2MergeResolver::FindConflictByFieldL( const MVPbkStoreContactField& aField )
       
   718     {
       
   719     TInt countConflicts = iConflicts.Count();
       
   720     for( TInt idx = 0; idx < countConflicts; idx++ )
       
   721         {
       
   722         if( iConflicts[idx] && 
       
   723             ( iConflicts[idx]->GetConflictType() == EPbk2ConflictTypeNormal || 
       
   724               iConflicts[idx]->GetConflictType() == EPbk2ConflictTypeImage ) )
       
   725             {
       
   726             CPbk2MergeConflict* conflict = static_cast<CPbk2MergeConflict*>( iConflicts[idx] );
       
   727             if( conflict )
       
   728                 {
       
   729                 const MVPbkStoreContactField* fieldFirst = NULL;
       
   730                 const MVPbkStoreContactField* fieldSecond = NULL;
       
   731                 conflict->GetFieldsL( fieldFirst, fieldSecond );
       
   732                 if( fieldFirst == &aField || fieldSecond == &aField )
       
   733                     {
       
   734                     return idx;
       
   735                     }
       
   736                 }
       
   737             }
       
   738         }
       
   739     return KErrNotFound;
       
   740     }
       
   741 
       
   742 // --------------------------------------------------------------------------
       
   743 // CPbk2MergeResolver::CopyAddressToMergedL
       
   744 // --------------------------------------------------------------------------
       
   745 //
       
   746 void CPbk2MergeResolver::CopyAddressToMergedL( 
       
   747         const CPbk2PresentationContact& aContact, 
       
   748         TPbk2FieldGroupId aAddressGroup )
       
   749     {
       
   750     PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   751         ("CPbk2MergeResolver::CopyAddressToMergedL - Add address(group id:%d) to merged. Fields:"), 
       
   752         aAddressGroup);
       
   753     CPbk2PresentationContactFieldCollection& fields = aContact.PresentationFields();
       
   754     for( TInt idx = 0; idx < fields.FieldCount(); idx++ )
       
   755         {
       
   756         CPbk2PresentationContactField& field = fields.At( idx );
       
   757         const MPbk2FieldProperty& property = field.FieldProperty();
       
   758         if( property.GroupId() == aAddressGroup )
       
   759             {
       
   760             DEBUG_PRINT_FIELD( field )
       
   761             iMerged.AppendL( &field );
       
   762             }
       
   763         }
       
   764     }
       
   765 
       
   766 #ifdef _DEBUG
       
   767 // --------------------------------------------------------------------------
       
   768 // CPbk2MergeResolver::PrintFieldL
       
   769 // --------------------------------------------------------------------------
       
   770 //
       
   771 void CPbk2MergeResolver::PrintFieldL( const MVPbkStoreContactField& aField )
       
   772     {
       
   773     const MVPbkContactFieldData& data = aField.FieldData();
       
   774     TVPbkFieldStorageType storageType = data.DataType();
       
   775     
       
   776     RBuf lebel;
       
   777     CleanupClosePushL( lebel );
       
   778     RBuf value;
       
   779     CleanupClosePushL( value );
       
   780     
       
   781     lebel.CreateL( aField.FieldLabel().Length() + 1 );
       
   782     lebel = aField.FieldLabel();
       
   783     lebel.SetLength( aField.FieldLabel().Length() + 1 );
       
   784     lebel[aField.FieldLabel().Length()] = KEndLine;
       
   785     
       
   786     switch( storageType )
       
   787         {
       
   788         case EVPbkFieldStorageTypeText:
       
   789             {
       
   790             value.CreateL( MVPbkContactFieldTextData::Cast( data ).Text().Length() + 1 );
       
   791             value = MVPbkContactFieldTextData::Cast( data ).Text();
       
   792             value.SetLength( MVPbkContactFieldTextData::Cast( data ).Text().Length() + 1 );
       
   793             value[MVPbkContactFieldTextData::Cast( data ).Text().Length()] = KEndLine;
       
   794             PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   795                 ( "CPbk2MergeResolver: Field Info: %s:%s "), lebel.Ptr(), value.Ptr() );
       
   796             }
       
   797             break;
       
   798         case EVPbkFieldStorageTypeDateTime:
       
   799             {
       
   800             PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   801                 ( "CPbk2MergeResolver: Field Info: %s"), lebel.Ptr() );
       
   802             }
       
   803             break;
       
   804         case EVPbkFieldStorageTypeUri:
       
   805             {
       
   806             value.CreateL( MVPbkContactFieldUriData::Cast( data ).Text().Length() + 1 );
       
   807             value = MVPbkContactFieldUriData::Cast( data ).Text();
       
   808             value.SetLength( MVPbkContactFieldUriData::Cast( data ).Text().Length() + 1 );
       
   809             value[MVPbkContactFieldUriData::Cast( data ).Text().Length()] = KEndLine;
       
   810             PBK2_DEBUG_PRINT(PBK2_DEBUG_STRING
       
   811                 ( "CPbk2MergeResolver: Field Info: %s:%s "), lebel.Ptr(), value.Ptr() );
       
   812             }
       
   813             break;
       
   814         }
       
   815     CleanupStack::PopAndDestroy( &value );
       
   816     CleanupStack::PopAndDestroy( &lebel );
       
   817     }
       
   818 #endif