phonebookengines/VirtualPhonebook/VPbkCntModel/src/CFieldFactory.cpp
changeset 0 e686773b3f54
child 68 9da50d567e3c
equal deleted inserted replaced
-1:000000000000 0:e686773b3f54
       
     1 /*
       
     2 * Copyright (c) 2004-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:  The virtual phonebook field factory
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDES
       
    20 
       
    21 // From VirtualPhonebook
       
    22 #include "CFieldFactory.h"
       
    23 #include "CFieldTypeMap.h"
       
    24 #include "CFieldInfo.h"
       
    25 #include <TVPbkFieldVersitProperty.h>
       
    26 #include <MVPbkFieldType.h>
       
    27 #include <RLocalizedResourceFile.h>
       
    28 #include <VPbkDataCaging.hrh>
       
    29 #include <VPbkCntModelRes.rsg>
       
    30 
       
    31 // System includes
       
    32 #include <cntdef.hrh>
       
    33 #include <cntitem.h>
       
    34 #include <barsread.h>
       
    35 
       
    36 namespace {
       
    37 
       
    38 // CONSTANTS
       
    39 _LIT(KCntExtResFile, "VPbkCntModelRes.rsc");
       
    40 }
       
    41 
       
    42 namespace VPbkCntModel {
       
    43     
       
    44 TBool ContainsField( CFieldsInfo& aFieldsInfo, 
       
    45         const CContactItemField& aField )
       
    46     {
       
    47     const TInt count = aFieldsInfo.Count();
       
    48     for ( TInt i = 0; i < count; ++i )
       
    49         {
       
    50         if ( aFieldsInfo[i]->IsEqualType( aField ) )
       
    51             {
       
    52             return ETrue;
       
    53             }
       
    54         }
       
    55     return EFalse;
       
    56     }    
       
    57     
       
    58 /**
       
    59  * Maps a Versit type to a Contact Model field.
       
    60  */
       
    61 NONSHARABLE_CLASS(CFieldFactory::TFieldAndTypeTuple)
       
    62     {
       
    63     public:
       
    64         TFieldAndTypeTuple(const MVPbkFieldType& aFieldType, 
       
    65                           const CContactItemField& aNativeField);
       
    66     public:
       
    67         const MVPbkFieldType& iFieldType;
       
    68         const CContactItemField& iNativeField;
       
    69     };
       
    70 
       
    71 CFieldFactory::TFieldAndTypeTuple::TFieldAndTypeTuple
       
    72         (const MVPbkFieldType& aFieldType, 
       
    73          const CContactItemField& aNativeField) :
       
    74     iFieldType(aFieldType),
       
    75     iNativeField(aNativeField)
       
    76     {
       
    77     }
       
    78 
       
    79 // CFieldFactory implementation
       
    80 CFieldFactory::CFieldFactory()
       
    81     {
       
    82     }
       
    83 
       
    84 inline void CFieldFactory::ConstructL(
       
    85         const CFieldTypeMap& aFieldTypeMap, 
       
    86         const CContactItem& aSystemTemplate,
       
    87         const MVPbkFieldTypeList& aMasterFieldTypeList,
       
    88         RFs& aFs )
       
    89     {
       
    90     // open the golden template extension resource file
       
    91     // for filtering some fields that are not allowed to create.
       
    92     VPbkEngUtils::RLocalizedResourceFile resFile;
       
    93     resFile.OpenLC(aFs, KVPbkRomFileDrive, KDC_RESOURCE_FILES_DIR, 
       
    94         KCntExtResFile );
       
    95     
       
    96     // Create fields infos that are not allowed to create from the factory
       
    97     TResourceReader reader;
       
    98     reader.SetBuffer( resFile.AllocReadLC( R_CNTUI_NON_CREATABLE_FIELD_DEFNS ));
       
    99     CFieldsInfo* fieldsInfo = CFieldsInfo::NewL( reader );
       
   100     CleanupStack::PopAndDestroy(); // reader buffer
       
   101     CleanupStack::PushL( fieldsInfo );
       
   102     
       
   103     const CContactItemFieldSet& fieldSet = aSystemTemplate.CardFields();
       
   104     const TInt fieldCount = fieldSet.Count();
       
   105 
       
   106     for (TInt i = 0; i < fieldCount; ++i)
       
   107         {
       
   108         const CContactItemField& nativeField = fieldSet[i];
       
   109         
       
   110         if ( !ContainsField( *fieldsInfo, nativeField ) )
       
   111             {
       
   112             DoInsertMappingTupleL(aMasterFieldTypeList, 
       
   113                     aFieldTypeMap, nativeField);
       
   114             }
       
   115         }
       
   116     CleanupStack::PopAndDestroy( fieldsInfo );
       
   117     iMaxMatchPriority = aMasterFieldTypeList.MaxMatchPriority();
       
   118 
       
   119     // add field and type mappings that are not in the system template
       
   120     reader.SetBuffer( resFile.AllocReadLC( 
       
   121             R_CNTUI_NON_SYSTEM_TEMPLATE_FIELD_DEFNS ));
       
   122     CFieldsInfo* nonSystemTemplatefieldsInfo = CFieldsInfo::NewL( reader );
       
   123     CleanupStack::PopAndDestroy(2); // reader buffer, resFile
       
   124     CleanupStack::PushL( nonSystemTemplatefieldsInfo );
       
   125 
       
   126     for (TInt j = 0; j < nonSystemTemplatefieldsInfo->Count() ; ++j )
       
   127         {
       
   128         const CFieldInfo* fieldInfo = (*nonSystemTemplatefieldsInfo)[j];
       
   129         CContactItemField* field = fieldInfo->CreateFieldL();
       
   130         CleanupStack::PushL(field);
       
   131 
       
   132         DoInsertMappingTupleL(aMasterFieldTypeList, 
       
   133                 aFieldTypeMap, *field);
       
   134         // append field to array of non system template fields        
       
   135         iNonSystemTemplateFields.AppendL(field);
       
   136         CleanupStack::Pop(field);
       
   137         }
       
   138     CleanupStack::PopAndDestroy( nonSystemTemplatefieldsInfo );
       
   139     }
       
   140 
       
   141 CFieldFactory* CFieldFactory::NewL(
       
   142         const CFieldTypeMap& aFieldTypeMap, 
       
   143         CContactItem* aSystemTemplate, 
       
   144         const MVPbkFieldTypeList& aMasterFieldTypeList,
       
   145         RFs& aFs )
       
   146     {
       
   147     CFieldFactory* self = new(ELeave) CFieldFactory;
       
   148     CleanupStack::PushL(self);
       
   149     self->ConstructL(aFieldTypeMap, *aSystemTemplate, aMasterFieldTypeList, 
       
   150         aFs );
       
   151     CleanupStack::Pop(self);
       
   152     // Take ownership after all initialisation that can leave is done
       
   153     self->iSystemTemplate = aSystemTemplate;
       
   154     return self;
       
   155     }
       
   156 
       
   157 CFieldFactory::~CFieldFactory()
       
   158     {
       
   159     iFieldAndTypeMapping.Close();
       
   160     iNonSystemTemplateFields.ResetAndDestroy();
       
   161     delete iSystemTemplate;
       
   162     }
       
   163 
       
   164 CContactItemField* CFieldFactory::CreateFieldLC
       
   165         (const MVPbkFieldType& aFieldType) const
       
   166     {
       
   167     CContactItemField* result = NULL;
       
   168     const CContactItemField* field = FindField(aFieldType);
       
   169     if (field)
       
   170         {
       
   171         result = CContactItemField::NewLC(*field);
       
   172         }
       
   173     return result;
       
   174     }
       
   175 
       
   176 const CContactItemField* CFieldFactory::FindField(const MVPbkFieldType& aFieldType) const
       
   177     {
       
   178     const CContactItemField* contactItemField = NULL;
       
   179 
       
   180     const TInt count = iFieldAndTypeMapping.Count();
       
   181     for (TInt i = 0; i < count; ++i)
       
   182         {
       
   183         if (iFieldAndTypeMapping[i].iFieldType.IsSame(aFieldType))
       
   184             {
       
   185             contactItemField = &iFieldAndTypeMapping[i].iNativeField;
       
   186             break;
       
   187             }
       
   188         }
       
   189 
       
   190     return contactItemField;
       
   191     }
       
   192 
       
   193 TInt CFieldFactory::FieldTypeCount() const
       
   194     {
       
   195     return iFieldAndTypeMapping.Count();
       
   196     }
       
   197 
       
   198 const MVPbkFieldType& CFieldFactory::FieldTypeAt(TInt aIndex) const
       
   199     {
       
   200     return iFieldAndTypeMapping[aIndex].iFieldType;
       
   201     }
       
   202 
       
   203 TBool CFieldFactory::ContainsSame(const MVPbkFieldType& aFieldType) const
       
   204     {
       
   205     TBool result = EFalse;
       
   206     const TInt count = iFieldAndTypeMapping.Count();
       
   207     for (TInt i = 0; i < count; ++i)
       
   208         {
       
   209         if (iFieldAndTypeMapping[i].iFieldType.IsSame(aFieldType))
       
   210             {
       
   211             result = ETrue;
       
   212             break;
       
   213             }
       
   214         }
       
   215     return result;
       
   216     }
       
   217 
       
   218 TInt CFieldFactory::MaxMatchPriority() const
       
   219     {
       
   220     return iMaxMatchPriority;
       
   221     }
       
   222 
       
   223 const MVPbkFieldType* CFieldFactory::FindMatch(
       
   224         const TVPbkFieldVersitProperty& aMatchProperty,
       
   225         TInt aMatchPriority) const
       
   226     {
       
   227     const MVPbkFieldType* result = NULL;
       
   228 
       
   229     const TInt count = iFieldAndTypeMapping.Count();
       
   230     for (TInt i = 0; i < count; ++i)
       
   231         {
       
   232         if (iFieldAndTypeMapping[i].iFieldType.Matches(aMatchProperty, aMatchPriority))
       
   233             {
       
   234             result = &iFieldAndTypeMapping[i].iFieldType;
       
   235             break;
       
   236             }
       
   237         }
       
   238     return result;
       
   239     }
       
   240 
       
   241 const MVPbkFieldType* CFieldFactory::FindMatch
       
   242     (TVPbkNonVersitFieldType aNonVersitType) const
       
   243     {
       
   244     const MVPbkFieldType* result = NULL;
       
   245 
       
   246     const TInt count = iFieldAndTypeMapping.Count();
       
   247     for (TInt i = 0; i < count; ++i)
       
   248         {
       
   249         if (iFieldAndTypeMapping[i].iFieldType.NonVersitType() == aNonVersitType)
       
   250             {
       
   251             result = &iFieldAndTypeMapping[i].iFieldType;
       
   252             }
       
   253         }
       
   254     return result;
       
   255     }
       
   256 
       
   257 const MVPbkFieldType* CFieldFactory::Find(
       
   258         TInt aFieldTypeResId) const
       
   259     {
       
   260     const MVPbkFieldType* result = NULL;
       
   261 
       
   262     const TInt count = iFieldAndTypeMapping.Count();
       
   263     for (TInt i = 0; i < count; ++i)
       
   264         {
       
   265         if (iFieldAndTypeMapping[i].iFieldType.FieldTypeResId() == aFieldTypeResId)
       
   266             {
       
   267             result = &iFieldAndTypeMapping[i].iFieldType;
       
   268             break;
       
   269             }
       
   270         }
       
   271     return result;
       
   272     }
       
   273 
       
   274 void CFieldFactory::InsertInMasterFieldTypeOrderL( TFieldAndTypeTuple& aMapping,
       
   275         const MVPbkFieldTypeList& aMasterFieldTypeList )
       
   276     {
       
   277     // Insert field type mapping in the order defined in master field type
       
   278     // list.
       
   279     TInt newTypeIndex = IndexOfTypeInMasterList( aMapping.iFieldType, 
       
   280         aMasterFieldTypeList );
       
   281     const TInt count = iFieldAndTypeMapping.Count();
       
   282     TBool mappingInserted = EFalse;
       
   283     for ( TInt i = 0; i < count && !mappingInserted; ++i )
       
   284         {
       
   285         TInt curTypeIndex = IndexOfTypeInMasterList
       
   286             ( iFieldAndTypeMapping[i].iFieldType, aMasterFieldTypeList );
       
   287         if ( newTypeIndex < curTypeIndex )
       
   288             {
       
   289             iFieldAndTypeMapping.InsertL( aMapping, i );
       
   290             mappingInserted = ETrue;
       
   291             }
       
   292         }
       
   293     
       
   294     if ( !mappingInserted )
       
   295         {
       
   296         iFieldAndTypeMapping.AppendL( aMapping );
       
   297         }
       
   298     }
       
   299 
       
   300 TInt CFieldFactory::IndexOfTypeInMasterList( const MVPbkFieldType& aType,
       
   301         const MVPbkFieldTypeList& aMasterFieldTypeList )
       
   302     {
       
   303     const TInt count = aMasterFieldTypeList.FieldTypeCount();
       
   304     TInt result = KErrNotFound;
       
   305     for ( TInt i = 0; i < count && ( result == KErrNotFound ); ++i )
       
   306         {
       
   307         if ( aMasterFieldTypeList.FieldTypeAt( i ).IsSame( aType ) )
       
   308             {
       
   309             result =  i;
       
   310             }
       
   311         }
       
   312     return result;
       
   313     }
       
   314 
       
   315 void CFieldFactory::DoInsertMappingTupleL(
       
   316         const MVPbkFieldTypeList& aMasterFieldTypeList,
       
   317         const CFieldTypeMap& aFieldTypeMap,
       
   318         const CContactItemField& aField)
       
   319     {
       
   320     const TInt maxMatchPriority = aMasterFieldTypeList.MaxMatchPriority();
       
   321     for (TInt matchPriority = 0; matchPriority <= maxMatchPriority; 
       
   322             ++matchPriority)
       
   323         {
       
   324         // retrieves the VPbk field type for this contact model field
       
   325         const MVPbkFieldType* genericType = aFieldTypeMap.GenericFieldType(
       
   326             aField, matchPriority);
       
   327         if (genericType)
       
   328             {
       
   329             // Field mappings must be in the correct order because this
       
   330             // class is also the supported field types of the store.
       
   331             // Field types are inserted into same order as in the master
       
   332             // field type list. This way FindMatch works correctly.
       
   333             TFieldAndTypeTuple fieldAndTypeTuple(*genericType, aField);
       
   334             InsertInMasterFieldTypeOrderL( fieldAndTypeTuple, 
       
   335                     aMasterFieldTypeList );
       
   336             break;
       
   337             }
       
   338         }
       
   339     }
       
   340 
       
   341 }  // namespace VPbkCntModel
       
   342 
       
   343 // end of file