phonebookengines/VirtualPhonebook/VPbkCntModel/src/CFieldFactory.cpp
changeset 0 e686773b3f54
child 68 9da50d567e3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookengines/VirtualPhonebook/VPbkCntModel/src/CFieldFactory.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,343 @@
+/*
+* Copyright (c) 2004-2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  The virtual phonebook field factory
+*
+*/
+
+
+// INCLUDES
+
+// From VirtualPhonebook
+#include "CFieldFactory.h"
+#include "CFieldTypeMap.h"
+#include "CFieldInfo.h"
+#include <TVPbkFieldVersitProperty.h>
+#include <MVPbkFieldType.h>
+#include <RLocalizedResourceFile.h>
+#include <VPbkDataCaging.hrh>
+#include <VPbkCntModelRes.rsg>
+
+// System includes
+#include <cntdef.hrh>
+#include <cntitem.h>
+#include <barsread.h>
+
+namespace {
+
+// CONSTANTS
+_LIT(KCntExtResFile, "VPbkCntModelRes.rsc");
+}
+
+namespace VPbkCntModel {
+    
+TBool ContainsField( CFieldsInfo& aFieldsInfo, 
+        const CContactItemField& aField )
+    {
+    const TInt count = aFieldsInfo.Count();
+    for ( TInt i = 0; i < count; ++i )
+        {
+        if ( aFieldsInfo[i]->IsEqualType( aField ) )
+            {
+            return ETrue;
+            }
+        }
+    return EFalse;
+    }    
+    
+/**
+ * Maps a Versit type to a Contact Model field.
+ */
+NONSHARABLE_CLASS(CFieldFactory::TFieldAndTypeTuple)
+    {
+    public:
+        TFieldAndTypeTuple(const MVPbkFieldType& aFieldType, 
+                          const CContactItemField& aNativeField);
+    public:
+        const MVPbkFieldType& iFieldType;
+        const CContactItemField& iNativeField;
+    };
+
+CFieldFactory::TFieldAndTypeTuple::TFieldAndTypeTuple
+        (const MVPbkFieldType& aFieldType, 
+         const CContactItemField& aNativeField) :
+    iFieldType(aFieldType),
+    iNativeField(aNativeField)
+    {
+    }
+
+// CFieldFactory implementation
+CFieldFactory::CFieldFactory()
+    {
+    }
+
+inline void CFieldFactory::ConstructL(
+        const CFieldTypeMap& aFieldTypeMap, 
+        const CContactItem& aSystemTemplate,
+        const MVPbkFieldTypeList& aMasterFieldTypeList,
+        RFs& aFs )
+    {
+    // open the golden template extension resource file
+    // for filtering some fields that are not allowed to create.
+    VPbkEngUtils::RLocalizedResourceFile resFile;
+    resFile.OpenLC(aFs, KVPbkRomFileDrive, KDC_RESOURCE_FILES_DIR, 
+        KCntExtResFile );
+    
+    // Create fields infos that are not allowed to create from the factory
+    TResourceReader reader;
+    reader.SetBuffer( resFile.AllocReadLC( R_CNTUI_NON_CREATABLE_FIELD_DEFNS ));
+    CFieldsInfo* fieldsInfo = CFieldsInfo::NewL( reader );
+    CleanupStack::PopAndDestroy(); // reader buffer
+    CleanupStack::PushL( fieldsInfo );
+    
+    const CContactItemFieldSet& fieldSet = aSystemTemplate.CardFields();
+    const TInt fieldCount = fieldSet.Count();
+
+    for (TInt i = 0; i < fieldCount; ++i)
+        {
+        const CContactItemField& nativeField = fieldSet[i];
+        
+        if ( !ContainsField( *fieldsInfo, nativeField ) )
+            {
+            DoInsertMappingTupleL(aMasterFieldTypeList, 
+                    aFieldTypeMap, nativeField);
+            }
+        }
+    CleanupStack::PopAndDestroy( fieldsInfo );
+    iMaxMatchPriority = aMasterFieldTypeList.MaxMatchPriority();
+
+    // add field and type mappings that are not in the system template
+    reader.SetBuffer( resFile.AllocReadLC( 
+            R_CNTUI_NON_SYSTEM_TEMPLATE_FIELD_DEFNS ));
+    CFieldsInfo* nonSystemTemplatefieldsInfo = CFieldsInfo::NewL( reader );
+    CleanupStack::PopAndDestroy(2); // reader buffer, resFile
+    CleanupStack::PushL( nonSystemTemplatefieldsInfo );
+
+    for (TInt j = 0; j < nonSystemTemplatefieldsInfo->Count() ; ++j )
+        {
+        const CFieldInfo* fieldInfo = (*nonSystemTemplatefieldsInfo)[j];
+        CContactItemField* field = fieldInfo->CreateFieldL();
+        CleanupStack::PushL(field);
+
+        DoInsertMappingTupleL(aMasterFieldTypeList, 
+                aFieldTypeMap, *field);
+        // append field to array of non system template fields        
+        iNonSystemTemplateFields.AppendL(field);
+        CleanupStack::Pop(field);
+        }
+    CleanupStack::PopAndDestroy( nonSystemTemplatefieldsInfo );
+    }
+
+CFieldFactory* CFieldFactory::NewL(
+        const CFieldTypeMap& aFieldTypeMap, 
+        CContactItem* aSystemTemplate, 
+        const MVPbkFieldTypeList& aMasterFieldTypeList,
+        RFs& aFs )
+    {
+    CFieldFactory* self = new(ELeave) CFieldFactory;
+    CleanupStack::PushL(self);
+    self->ConstructL(aFieldTypeMap, *aSystemTemplate, aMasterFieldTypeList, 
+        aFs );
+    CleanupStack::Pop(self);
+    // Take ownership after all initialisation that can leave is done
+    self->iSystemTemplate = aSystemTemplate;
+    return self;
+    }
+
+CFieldFactory::~CFieldFactory()
+    {
+    iFieldAndTypeMapping.Close();
+    iNonSystemTemplateFields.ResetAndDestroy();
+    delete iSystemTemplate;
+    }
+
+CContactItemField* CFieldFactory::CreateFieldLC
+        (const MVPbkFieldType& aFieldType) const
+    {
+    CContactItemField* result = NULL;
+    const CContactItemField* field = FindField(aFieldType);
+    if (field)
+        {
+        result = CContactItemField::NewLC(*field);
+        }
+    return result;
+    }
+
+const CContactItemField* CFieldFactory::FindField(const MVPbkFieldType& aFieldType) const
+    {
+    const CContactItemField* contactItemField = NULL;
+
+    const TInt count = iFieldAndTypeMapping.Count();
+    for (TInt i = 0; i < count; ++i)
+        {
+        if (iFieldAndTypeMapping[i].iFieldType.IsSame(aFieldType))
+            {
+            contactItemField = &iFieldAndTypeMapping[i].iNativeField;
+            break;
+            }
+        }
+
+    return contactItemField;
+    }
+
+TInt CFieldFactory::FieldTypeCount() const
+    {
+    return iFieldAndTypeMapping.Count();
+    }
+
+const MVPbkFieldType& CFieldFactory::FieldTypeAt(TInt aIndex) const
+    {
+    return iFieldAndTypeMapping[aIndex].iFieldType;
+    }
+
+TBool CFieldFactory::ContainsSame(const MVPbkFieldType& aFieldType) const
+    {
+    TBool result = EFalse;
+    const TInt count = iFieldAndTypeMapping.Count();
+    for (TInt i = 0; i < count; ++i)
+        {
+        if (iFieldAndTypeMapping[i].iFieldType.IsSame(aFieldType))
+            {
+            result = ETrue;
+            break;
+            }
+        }
+    return result;
+    }
+
+TInt CFieldFactory::MaxMatchPriority() const
+    {
+    return iMaxMatchPriority;
+    }
+
+const MVPbkFieldType* CFieldFactory::FindMatch(
+        const TVPbkFieldVersitProperty& aMatchProperty,
+        TInt aMatchPriority) const
+    {
+    const MVPbkFieldType* result = NULL;
+
+    const TInt count = iFieldAndTypeMapping.Count();
+    for (TInt i = 0; i < count; ++i)
+        {
+        if (iFieldAndTypeMapping[i].iFieldType.Matches(aMatchProperty, aMatchPriority))
+            {
+            result = &iFieldAndTypeMapping[i].iFieldType;
+            break;
+            }
+        }
+    return result;
+    }
+
+const MVPbkFieldType* CFieldFactory::FindMatch
+    (TVPbkNonVersitFieldType aNonVersitType) const
+    {
+    const MVPbkFieldType* result = NULL;
+
+    const TInt count = iFieldAndTypeMapping.Count();
+    for (TInt i = 0; i < count; ++i)
+        {
+        if (iFieldAndTypeMapping[i].iFieldType.NonVersitType() == aNonVersitType)
+            {
+            result = &iFieldAndTypeMapping[i].iFieldType;
+            }
+        }
+    return result;
+    }
+
+const MVPbkFieldType* CFieldFactory::Find(
+        TInt aFieldTypeResId) const
+    {
+    const MVPbkFieldType* result = NULL;
+
+    const TInt count = iFieldAndTypeMapping.Count();
+    for (TInt i = 0; i < count; ++i)
+        {
+        if (iFieldAndTypeMapping[i].iFieldType.FieldTypeResId() == aFieldTypeResId)
+            {
+            result = &iFieldAndTypeMapping[i].iFieldType;
+            break;
+            }
+        }
+    return result;
+    }
+
+void CFieldFactory::InsertInMasterFieldTypeOrderL( TFieldAndTypeTuple& aMapping,
+        const MVPbkFieldTypeList& aMasterFieldTypeList )
+    {
+    // Insert field type mapping in the order defined in master field type
+    // list.
+    TInt newTypeIndex = IndexOfTypeInMasterList( aMapping.iFieldType, 
+        aMasterFieldTypeList );
+    const TInt count = iFieldAndTypeMapping.Count();
+    TBool mappingInserted = EFalse;
+    for ( TInt i = 0; i < count && !mappingInserted; ++i )
+        {
+        TInt curTypeIndex = IndexOfTypeInMasterList
+            ( iFieldAndTypeMapping[i].iFieldType, aMasterFieldTypeList );
+        if ( newTypeIndex < curTypeIndex )
+            {
+            iFieldAndTypeMapping.InsertL( aMapping, i );
+            mappingInserted = ETrue;
+            }
+        }
+    
+    if ( !mappingInserted )
+        {
+        iFieldAndTypeMapping.AppendL( aMapping );
+        }
+    }
+
+TInt CFieldFactory::IndexOfTypeInMasterList( const MVPbkFieldType& aType,
+        const MVPbkFieldTypeList& aMasterFieldTypeList )
+    {
+    const TInt count = aMasterFieldTypeList.FieldTypeCount();
+    TInt result = KErrNotFound;
+    for ( TInt i = 0; i < count && ( result == KErrNotFound ); ++i )
+        {
+        if ( aMasterFieldTypeList.FieldTypeAt( i ).IsSame( aType ) )
+            {
+            result =  i;
+            }
+        }
+    return result;
+    }
+
+void CFieldFactory::DoInsertMappingTupleL(
+        const MVPbkFieldTypeList& aMasterFieldTypeList,
+        const CFieldTypeMap& aFieldTypeMap,
+        const CContactItemField& aField)
+    {
+    const TInt maxMatchPriority = aMasterFieldTypeList.MaxMatchPriority();
+    for (TInt matchPriority = 0; matchPriority <= maxMatchPriority; 
+            ++matchPriority)
+        {
+        // retrieves the VPbk field type for this contact model field
+        const MVPbkFieldType* genericType = aFieldTypeMap.GenericFieldType(
+            aField, matchPriority);
+        if (genericType)
+            {
+            // Field mappings must be in the correct order because this
+            // class is also the supported field types of the store.
+            // Field types are inserted into same order as in the master
+            // field type list. This way FindMatch works correctly.
+            TFieldAndTypeTuple fieldAndTypeTuple(*genericType, aField);
+            InsertInMasterFieldTypeOrderL( fieldAndTypeTuple, 
+                    aMasterFieldTypeList );
+            break;
+            }
+        }
+    }
+
+}  // namespace VPbkCntModel
+
+// end of file