diff -r 000000000000 -r e686773b3f54 phonebookengines/VirtualPhonebook/VPbkCntModel/src/CFieldFactory.cpp --- /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 +#include +#include +#include +#include + +// System includes +#include +#include +#include + +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