phonebookui/Phonebook2/Presentation/src/CPbk2ContactMerge.cpp
changeset 0 e686773b3f54
child 21 9da50d567e3c
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2006-2007 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:  A class for combining data of two contacts
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include <CPbk2ContactMerge.h>
       
    21 
       
    22 // From Phonebook2
       
    23 #include "Pbk2PresentationUtils.h"
       
    24 #include <MPbk2ContactNameFormatter.h>
       
    25 #include <MPbk2FieldPropertyArray.h>
       
    26 #include <MPbk2FieldProperty.h>
       
    27 #include <RPbk2LocalizedResourceFile.h>
       
    28 #include <Pbk2Presentation.rsg>
       
    29 #include <Pbk2DataCaging.hrh>
       
    30 
       
    31 
       
    32 // From Virtual Phonebook
       
    33 #include <MVPbkFieldType.h>
       
    34 #include <CVPbkContactManager.h>
       
    35 #include <MVPbkStoreContactFieldCollection.h>
       
    36 #include <MVPbkStoreContact.h>
       
    37 #include <MVPbkContactFieldTextData.h>
       
    38 #include <MVPbkContactFieldBinaryData.h>
       
    39 #include <MVPbkContactFieldDateTimeData.h>
       
    40 #include <CVPbkContactFieldIterator.h>
       
    41 #include <MVPbkContactStore.h>
       
    42 #include <MVPbkContactStoreProperties.h>
       
    43 #include <TVPbkFieldVersitProperty.h>
       
    44 #include <CVPbkFieldTypeSelector.h>
       
    45 
       
    46 // From System
       
    47 #include <barsread.h>
       
    48 
       
    49 // ======== MEMBER FUNCTIONS ========
       
    50 
       
    51 // ---------------------------------------------------------------------------
       
    52 // CPbk2ContactMerge::CPbk2ContactMerge
       
    53 // ---------------------------------------------------------------------------
       
    54 //
       
    55 CPbk2ContactMerge::CPbk2ContactMerge( 
       
    56         CVPbkContactManager& aContactManager, 
       
    57         MPbk2ContactNameFormatter& aNameFormatter,
       
    58         const MPbk2FieldPropertyArray& aFieldProperties )
       
    59         :   iContactManager( aContactManager ),
       
    60             iNameFormatter( aNameFormatter ),
       
    61             iFieldProperties( aFieldProperties )
       
    62     {
       
    63     }
       
    64 
       
    65 // ---------------------------------------------------------------------------
       
    66 // CPbk2ContactMerge::~CPbk2ContactMerge
       
    67 // ---------------------------------------------------------------------------
       
    68 //
       
    69 CPbk2ContactMerge::~CPbk2ContactMerge()
       
    70     {
       
    71     delete iEMailSelector;
       
    72     delete iNumberSelector;
       
    73     }
       
    74     
       
    75 // ---------------------------------------------------------------------------
       
    76 // CPbk2ContactMerge::NewL
       
    77 // ---------------------------------------------------------------------------
       
    78 //
       
    79 EXPORT_C CPbk2ContactMerge* CPbk2ContactMerge::NewL(
       
    80         CVPbkContactManager& aContactManager, 
       
    81         MPbk2ContactNameFormatter& aNameFormatter,
       
    82         const MPbk2FieldPropertyArray& aFieldProperties )
       
    83     {
       
    84     CPbk2ContactMerge* self = new( ELeave ) CPbk2ContactMerge( 
       
    85         aContactManager, aNameFormatter, aFieldProperties );
       
    86     CleanupStack::PushL( self );
       
    87     self->ConstructL();
       
    88     CleanupStack::Pop( self );
       
    89     return self;
       
    90     }
       
    91 
       
    92 // ---------------------------------------------------------------------------
       
    93 // CPbk2ContactMerge::ConstructL
       
    94 // ---------------------------------------------------------------------------
       
    95 //
       
    96 void CPbk2ContactMerge::ConstructL()
       
    97     {
       
    98     RPbk2LocalizedResourceFile resFile( &iContactManager.FsSession() );
       
    99     resFile.OpenLC( KPbk2RomFileDrive,
       
   100         KDC_RESOURCE_FILES_DIR,
       
   101         Pbk2PresentationUtils::PresentationResourceFile() );
       
   102     
       
   103     TResourceReader reader;
       
   104     reader.SetBuffer( resFile.AllocReadLC( R_PBK2_EMAIL_SELECTOR ) );
       
   105     
       
   106     iEMailSelector = CVPbkFieldTypeSelector::NewL(
       
   107         reader,
       
   108         iContactManager.FieldTypes() );
       
   109     CleanupStack::PopAndDestroy(); // reader
       
   110     
       
   111     reader.SetBuffer( resFile.AllocReadLC( R_PBK2_NUMBER_SELECTOR ) );
       
   112     iNumberSelector  = CVPbkFieldTypeSelector::NewL(
       
   113         reader,
       
   114         iContactManager.FieldTypes() );
       
   115     CleanupStack::PopAndDestroy(2); // reader, resFile
       
   116     }
       
   117     
       
   118 
       
   119 // ---------------------------------------------------------------------------
       
   120 // CPbk2ContactMerge::MergeDataL
       
   121 // ---------------------------------------------------------------------------
       
   122 //
       
   123 EXPORT_C TBool CPbk2ContactMerge::MergeDataL( 
       
   124         const MVPbkBaseContact& aContactFrom, MVPbkStoreContact& aContactTo )
       
   125     {
       
   126     TInt srcTitleFieldCount = 0;
       
   127     TInt copiedFieldCount = 0;
       
   128     const MVPbkBaseContactFieldCollection& srcFields = aContactFrom.Fields();
       
   129     const TInt srcFieldCount = srcFields.FieldCount();
       
   130     const MVPbkFieldTypeList& targetTypes = 
       
   131         aContactTo.ParentStore().StoreProperties().SupportedFields();
       
   132     for ( TInt i = 0; i < srcFieldCount; ++i )
       
   133         {
       
   134         const MVPbkBaseContactField& srcField = srcFields.FieldAt( i );
       
   135         const MVPbkFieldType* type = srcField.BestMatchingFieldType();
       
   136         // Title fields are not merged
       
   137         TBool titleField = iNameFormatter.IsTitleFieldType( *type );
       
   138         if ( titleField )
       
   139             {
       
   140             ++srcTitleFieldCount;
       
   141             }
       
   142         else if ( type && targetTypes.ContainsSame( *type ) )
       
   143             {            
       
   144             CVPbkBaseContactFieldTypeIterator* iter = 
       
   145                     CVPbkBaseContactFieldTypeIterator::NewLC( *type, 
       
   146                         aContactTo.Fields() );
       
   147             TInt maxNumOfFields = aContactTo.MaxNumberOfFieldL( *type );
       
   148             TInt curFieldCount = 0;
       
   149             while ( iter->HasNext() )
       
   150                 {
       
   151                 iter->Next();
       
   152                 ++curFieldCount;
       
   153                 }
       
   154             CleanupStack::PopAndDestroy( iter );
       
   155             
       
   156             // Check field multiplicity
       
   157             const MPbk2FieldProperty* prop = 
       
   158                 iFieldProperties.FindProperty( *type );
       
   159             if ( prop && prop->Multiplicity() == EPbk2FieldMultiplicityOne )
       
   160                 {
       
   161                 // If UI specification limits the number of certain type
       
   162                 // of field to one then check if the target contact
       
   163                 // already contains that type of field
       
   164                 if ( curFieldCount == 0 )
       
   165                     {
       
   166                     CopyFieldDataL( srcField, aContactTo );
       
   167                     ++copiedFieldCount;
       
   168                     }
       
   169                 }
       
   170             else if ( ( maxNumOfFields == KVPbkStoreContactUnlimitedNumber ||
       
   171                       curFieldCount < aContactTo.MaxNumberOfFieldL( *type )) &&
       
   172                       !FindMatch( srcField, aContactTo ))
       
   173                 {
       
   174                 // Field can be copied from source to destination. This is 
       
   175                 // because target field count is not limited or target contact
       
   176                 // field limit is not exceeded.
       
   177                 CopyFieldDataL( srcField, aContactTo );
       
   178                 ++copiedFieldCount;
       
   179                 }
       
   180             }
       
   181         }
       
   182     // Return ETrue if all data fields from source contact were copied to target
       
   183     return ( srcTitleFieldCount + copiedFieldCount ) == srcFieldCount;
       
   184     }
       
   185 
       
   186 // ---------------------------------------------------------------------------
       
   187 // CPbk2ContactMerge::CopyFieldDataL
       
   188 // ---------------------------------------------------------------------------
       
   189 //
       
   190 void CPbk2ContactMerge::CopyFieldDataL( const MVPbkBaseContactField& aField, 
       
   191         MVPbkStoreContact& aContactTo )
       
   192     {
       
   193     // Field has always a non NULL field type when this function is called
       
   194     MVPbkStoreContactField* field = aContactTo.CreateFieldLC(
       
   195         *aField.BestMatchingFieldType() );
       
   196     field->FieldData().CopyL( aField.FieldData() );
       
   197     aContactTo.AddFieldL( field );
       
   198     CleanupStack::Pop(); // field
       
   199     }
       
   200 
       
   201 // ---------------------------------------------------------------------------
       
   202 // CPbk2ContactMerge::FindMatch
       
   203 // ---------------------------------------------------------------------------
       
   204 //    
       
   205 TBool CPbk2ContactMerge::FindMatch( const MVPbkBaseContactField& aField, 
       
   206         MVPbkStoreContact& aContactTo )
       
   207     {
       
   208     TBool result = EFalse;
       
   209     
       
   210     MVPbkStoreContactFieldCollection& fields = aContactTo.Fields();
       
   211     const TInt count = fields.FieldCount();
       
   212     // Check if any of the email fields contains a same email address
       
   213     if ( iEMailSelector->IsFieldIncluded( aField ) )
       
   214         {
       
   215         for ( TInt i = 0 ; i < count && !result; ++i )
       
   216             {
       
   217             MVPbkStoreContactField& field = fields.FieldAt( i );
       
   218             if ( iEMailSelector->IsFieldIncluded( field ) )
       
   219                 {
       
   220                 result = CompareData( aField.FieldData(), 
       
   221                     field.FieldData() );
       
   222                 }
       
   223             }    
       
   224         }
       
   225     // Check if any of the number fields contains a same number
       
   226     else if ( iNumberSelector->IsFieldIncluded( aField ) )
       
   227         {
       
   228         for ( TInt i = 0 ; i < count && !result; ++i )
       
   229             {
       
   230             MVPbkStoreContactField& field = fields.FieldAt( i );
       
   231             if ( iNumberSelector->IsFieldIncluded( field ) )
       
   232                 {
       
   233                 result = CompareData( aField.FieldData(), 
       
   234                     field.FieldData() );
       
   235                 }
       
   236             }    
       
   237         }
       
   238     // Check if there is a same type of field and if found, compare the data
       
   239     else
       
   240         {
       
   241         const MVPbkFieldType* type = aField.BestMatchingFieldType();
       
   242         if ( type )
       
   243             {
       
   244             // If iterator creation fails we cannot make comparison and 
       
   245             // the result is false.
       
   246             TRAP_IGNORE(
       
   247                 {
       
   248                 CVPbkBaseContactFieldTypeIterator* iter = 
       
   249                     CVPbkBaseContactFieldTypeIterator::NewLC( *type, fields );
       
   250                 while ( iter->HasNext() && !result )
       
   251                     {
       
   252                     const MVPbkBaseContactField* field = iter->Next();
       
   253                     result = CompareData( aField.FieldData(), field->FieldData() );
       
   254                     }
       
   255                 CleanupStack::PopAndDestroy( iter );                
       
   256                 });
       
   257             }
       
   258         }
       
   259          
       
   260     return result;
       
   261     }
       
   262 
       
   263 // ---------------------------------------------------------------------------
       
   264 // CPbk2ContactMerge::CompareTextData
       
   265 // ---------------------------------------------------------------------------
       
   266 //        
       
   267 TBool CPbk2ContactMerge::CompareData( const MVPbkContactFieldData& aData1,
       
   268         const MVPbkContactFieldData& aData2 )
       
   269     {
       
   270     TBool result = EFalse;
       
   271     TVPbkFieldStorageType dataType = aData1.DataType();
       
   272     if ( dataType == aData2.DataType() )
       
   273         {
       
   274         if ( dataType == EVPbkFieldStorageTypeText )
       
   275             {
       
   276             result = CompareTextData( 
       
   277                 MVPbkContactFieldTextData::Cast( aData1 ),
       
   278                 MVPbkContactFieldTextData::Cast( aData2 ) );
       
   279             }
       
   280         else if ( dataType == EVPbkFieldStorageTypeBinary )
       
   281             {
       
   282             result = CompareBinaryData( 
       
   283                 MVPbkContactFieldBinaryData::Cast( aData1 ),
       
   284                 MVPbkContactFieldBinaryData::Cast( aData2 ) );
       
   285             }
       
   286         else if ( dataType == EVPbkFieldStorageTypeDateTime )
       
   287             {
       
   288             result = CompareDateTimeData( 
       
   289                 MVPbkContactFieldDateTimeData::Cast( aData1 ),
       
   290                 MVPbkContactFieldDateTimeData::Cast( aData2 ) );
       
   291             }
       
   292         }
       
   293     return result;
       
   294     }
       
   295     
       
   296 // ---------------------------------------------------------------------------
       
   297 // CPbk2ContactMerge::CompareTextData
       
   298 // ---------------------------------------------------------------------------
       
   299 //        
       
   300 TBool CPbk2ContactMerge::CompareTextData( 
       
   301         const MVPbkContactFieldTextData& aData1, 
       
   302         const MVPbkContactFieldTextData& aData2)
       
   303     {
       
   304     return aData1.Text().CompareF( aData2.Text() ) == 0;
       
   305     }
       
   306 
       
   307 // ---------------------------------------------------------------------------
       
   308 // CPbk2ContactMerge::CompareBinaryData
       
   309 // ---------------------------------------------------------------------------
       
   310 //            
       
   311 TBool CPbk2ContactMerge::CompareBinaryData( 
       
   312         const MVPbkContactFieldBinaryData& aData1, 
       
   313         const MVPbkContactFieldBinaryData& aData2 )
       
   314     {
       
   315     return aData1.BinaryData().Compare( aData2.BinaryData() ) == 0;
       
   316     }
       
   317     
       
   318 // ---------------------------------------------------------------------------
       
   319 // CPbk2ContactMerge::CompareDateTimeData
       
   320 // ---------------------------------------------------------------------------
       
   321 //            
       
   322 TBool CPbk2ContactMerge::CompareDateTimeData( 
       
   323         const MVPbkContactFieldDateTimeData& aData1, 
       
   324         const MVPbkContactFieldDateTimeData& aData2 )
       
   325     {
       
   326     return aData1.DateTime() == aData2.DateTime();
       
   327     }