phonebookui/Phonebook/Engine/src/CPbkFieldsInfo.cpp
changeset 0 e686773b3f54
child 21 9da50d567e3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook/Engine/src/CPbkFieldsInfo.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,627 @@
+/*
+* Copyright (c) 2002 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: 
+*		Phonebook field types collection class
+*
+*/
+
+
+// INCLUDE FILES
+#include    "CPbkFieldsInfo.h"
+#include    <barsc.h>       // RResourceFile
+#include    <barsread.h>    // RResourceReader
+#include    <cntitem.h>
+#include    <cntmodel.rsg>
+
+#include    <PbkEng.rsg>
+#include    "CPbkFieldInfo.h"
+#include    "CPbkFieldInfoGroup.h"
+#include    "CPbkUidMap.h"
+#include    "TPbkContactItemFieldType.h"
+#include    "TPbkVcardFieldType.h"
+#include    "TPbkMatchPriorityLevel.h"
+#include    <MPbkGlobalSetting.h>
+#include    "CPbkCenRepSetting.h"
+
+// MODULE DATA STRUCTURES
+
+
+/// Unnamed namespace for local definitions
+namespace {
+
+// LOCAL CONSTANTS AND MACROS
+enum TPanicCode
+    {
+    EPanicIndexOutOfRange = 1,
+    EPanicResourceArrayCountsMismatch,
+    EPanicFieldInfoArrayCountMismatch,
+    EPanicResourceLinkedGroupNotFound
+    };
+
+
+// LOCAL FUNCTIONS
+
+void Panic(TPanicCode aReason)
+    {
+    _LIT(KPanicText, "CPbkFieldsInfo");
+    User::Panic(KPanicText, aReason);
+    }
+
+TInt CompareOrdering(const CPbkFieldInfo& aLeft, const CPbkFieldInfo& aRight)
+    {
+    return aLeft.CompareOrdering(aRight);
+    }
+
+/**
+ * Interface that matches a CPbkFieldInfo object against some criteria.
+ */
+class MPbkFieldInfoMatcher
+    {
+    public: // Interface
+        /**
+         * Returns true if aFieldInfo matches some criteria.
+         */
+        virtual TBool Match(const CPbkFieldInfo& aFieldInfo) const = 0;
+    };
+
+/**
+ * Interface for an operation to be performed to a field info object.
+ */
+class MPbkFieldInfoOperation
+    {
+    public:  // Interface
+        /**
+         * Performs operation for aFieldInfo.
+         */
+        virtual void ProcessL(const CPbkFieldInfo& aFieldInfo) =0;
+    };
+
+/**
+ * Implements MPbkFieldInfoMatcher to match a TPbkFieldId
+ */
+NONSHARABLE_CLASS(TMatchFieldId) : 
+        public MPbkFieldInfoMatcher
+    {
+    public:  // Interface
+		/**
+         * Constructor.
+		 * @param aFieldId contact item field id
+         */
+        inline TMatchFieldId(TPbkFieldId aFieldId) : 
+            iFieldId(aFieldId) 
+            { 
+            }
+
+    public:  // from MPbkFieldInfoMatcher
+        TBool Match(const CPbkFieldInfo& aFieldInfo) const
+            {
+            return (aFieldInfo.FieldId()==iFieldId);
+            }
+
+    private:  // data
+		/// Own: contact item field id
+        const TPbkFieldId iFieldId;
+    };
+
+/**
+ * Implements MPbkFieldInfoMatcher to match a <TPbkFieldId,TPbkFieldLocation> pair.
+ */
+NONSHARABLE_CLASS(TMatchFieldIdAndLocation) : 
+        public MPbkFieldInfoMatcher
+    {
+    public:  // Interface
+		/**
+         * Constructor.
+		 * @param aFieldId contact item field id
+		 * @param aLocation field location
+         */
+        inline TMatchFieldIdAndLocation
+                (TPbkFieldId aFieldId, TPbkFieldLocation aLocation) : 
+            iFieldId(aFieldId), iLocation(aLocation)
+            { 
+            }
+
+    public:  // from MPbkFieldInfoMatcher
+        TBool Match(const CPbkFieldInfo& aFieldInfo) const
+            {
+            return (aFieldInfo.FieldId()==iFieldId && aFieldInfo.Location()==iLocation);
+            }
+
+    private:  // data
+		/// Own: field id
+        const TPbkFieldId iFieldId;
+		/// Own: field location
+        const TPbkFieldLocation iLocation;
+    };
+
+/**
+ * Implements MPbkFieldInfoMatcher to match a CContactItemField.
+ */
+NONSHARABLE_CLASS(TMatchContactItemField) : 
+        public MPbkFieldInfoMatcher
+    {
+    public:  // Interface
+		/**
+         * Constructor.
+		 * @param aField contact item field
+		 * @param aUidMap UID map
+         */
+        inline TMatchContactItemField
+                (const CContactItemField& aField, const CPbkUidMap& aUidMap) : 
+            iFieldType(aField,aUidMap)
+            { 
+            }
+
+    public:  // from MPbkFieldInfoMatcher
+        TBool Match(const CPbkFieldInfo& aFieldInfo) const
+            {
+            return aFieldInfo.Match(iFieldType);
+            }
+
+    private:  // data
+		/// Own: field type
+        const TPbkContactItemFieldType iFieldType;
+    };
+
+/**
+ * Implements MPbkFieldInfoMatcher to match a CContactItemField with priority.
+ */
+NONSHARABLE_CLASS(TMatchContactItemFieldWithLevel) : 
+        public MPbkFieldInfoMatcher
+    {
+    public:  // Interface
+		/**
+         * Constructor.
+		 * @param aField contact item field
+		 * @param aUidMap UID map
+		 * @param aLevel match priority level
+         */
+        inline TMatchContactItemFieldWithLevel
+                (const CContactItemField& aField, 
+                const CPbkUidMap& aUidMap,
+                const TPbkMatchPriorityLevel& aLevel) : 
+            iFieldType(aField,aUidMap), iLevel(aLevel)
+            { 
+            }
+
+    public:  // from MPbkFieldInfoMatcher
+        TBool Match(const CPbkFieldInfo& aFieldInfo) const
+            {
+            return aFieldInfo.Match(iFieldType,iLevel);
+            }
+
+    private:  // data
+		/// Own: contact item field type
+        const TPbkContactItemFieldType iFieldType;
+		/// Own: match priority level
+        const TPbkMatchPriorityLevel iLevel;
+    };
+
+/**
+ * Implements MPbkFieldInfoMatcher to match a vCard property.
+ */
+NONSHARABLE_CLASS(TMatchVcard) : 
+        public MPbkFieldInfoMatcher
+    {
+    public:  // Interface
+		/**
+         * Constructor.
+		 * @param aVcardProperty
+		 * @param aUidMap UID map
+		 * @param aLevel match priority level
+         */
+        inline TMatchVcard
+                (const MPbkVcardProperty& aVcardProperty,
+                const CPbkUidMap& aUidMap,
+                const TPbkMatchPriorityLevel& aLevel) : 
+            iVcardType(aVcardProperty,aUidMap), iLevel(aLevel)
+            { 
+            }
+
+    public:  // from MPbkFieldInfoMatcher
+        TBool Match(const CPbkFieldInfo& aFieldInfo) const
+            {
+            return aFieldInfo.Match(iVcardType,iLevel);
+            }
+
+    private:  // data
+		/// Own: vCard field type
+        const TPbkVcardFieldType iVcardType;
+		/// Own: match priority level
+        const TPbkMatchPriorityLevel iLevel;
+    };
+
+/**
+ * Implements MPbkFieldInfoOperation to call CPbkFieldInfo::AddToViewDefL.
+ */
+NONSHARABLE_CLASS(TAddToViewDef) : 
+        public MPbkFieldInfoOperation
+    {
+    public:  // Interface
+		/**
+		 * Constructor.
+		 * @param aViewDef view definition to contact item
+		 */
+        inline TAddToViewDef(CContactItemViewDef& aViewDef) :
+            iViewDef(aViewDef)
+            {
+            }
+
+    public:  // From MPbkFieldInfoOperation
+        void ProcessL(const CPbkFieldInfo& aFieldInfo)
+            {
+            aFieldInfo.AddToViewDefL(iViewDef);
+            }
+
+    private:  // Data
+		/// Ref: view definition
+        CContactItemViewDef& iViewDef;
+    };
+
+/**
+ * Implements MPbkFieldInfoOperation to call CPbkFieldInfo::AddToFieldDefL.
+ */
+NONSHARABLE_CLASS(TAddToFieldDef) : 
+        public MPbkFieldInfoOperation
+    {
+    public:  // Interface
+		/**
+		 * Constructor.
+		 * @param aFieldDef field definition for contact item
+		 */
+        inline TAddToFieldDef(CContactItemFieldDef& aFieldDef) :
+            iFieldDef(aFieldDef)
+            {
+            }
+
+    public:  // From MPbkFieldInfoOperation
+        void ProcessL(const CPbkFieldInfo& aFieldInfo)
+            {
+            aFieldInfo.AddToFieldDefL(iFieldDef);
+            }
+
+    private:  // Data
+		/// Ref: field definition
+        CContactItemFieldDef& iFieldDef;
+    };
+
+/**
+ * Finds a matching field info object in an array.
+ * @param aFieldInfos   array to search.
+ * @param aMatcher      the matching predicate.
+ * @return the matching field info object or NULL if no match is found.
+ */
+CPbkFieldInfo* FindMatching
+        (const RPointerArray<CPbkFieldInfo>& aFieldInfos,
+        const MPbkFieldInfoMatcher& aMatcher)
+    {
+    const TInt count = aFieldInfos.Count();
+    for (TInt i=0; i < count; ++i)
+        {
+        const CPbkFieldInfo& fieldInfo = *aFieldInfos[i];
+        if (aMatcher.Match(fieldInfo))
+            {
+            return CONST_CAST(CPbkFieldInfo*,&fieldInfo);
+            }
+        }
+    return NULL;
+    }
+
+/**
+ * Processes matching field info objects in an array.
+ *
+ * @param aFieldInfos   array of field info objects to process.
+ * @param aMatcher      the matching predicate.
+ * @param aOperation    operation to perform to all matching field info 
+ *                      objects.
+ * @return number of field info objects processed
+ */
+void ProcessMatchingL
+        (const RPointerArray<CPbkFieldInfo>& aFieldInfos,
+        const MPbkFieldInfoMatcher& aMatcher,
+        MPbkFieldInfoOperation& aOperation)
+    {
+    const TInt count = aFieldInfos.Count();
+    for (TInt i=0; i < count; ++i)
+        {
+        const CPbkFieldInfo& fieldInfo = *aFieldInfos[i];
+        if (aMatcher.Match(fieldInfo))
+            {
+            aOperation.ProcessL(fieldInfo);
+            }
+        }
+    }
+
+/**
+ * Process all field info objects which match aFieldTypes.
+ */
+void ProcessMatchingL
+        (const RPointerArray<CPbkFieldInfo>& aFieldInfos,
+        const CPbkFieldIdArray& aFieldTypes,
+        MPbkFieldInfoOperation& aOperation)
+    {
+    const TInt count = aFieldTypes.Count();
+    for (TInt i=0; i<count; ++i)
+        {
+        TMatchFieldId fieldIdMatcher(aFieldTypes[i]);
+        ProcessMatchingL(aFieldInfos,fieldIdMatcher,aOperation);
+        }
+    }
+
+/**
+ * Reads the needed central repository max number length value
+ */
+inline TInt ReadMaxNumberLengthL()
+    {     
+    MPbkGlobalSetting* globalSetting = CPbkCenRepSetting::NewL();
+    // push to cleanupStack
+    globalSetting->PushL();
+    globalSetting->ConnectL(MPbkGlobalSetting::EPbkConfigurationCategory);
+    TInt maxLength(0);
+    TInt err = globalSetting->Get
+        (MPbkGlobalSetting::EEditorMaxNumberLength, maxLength);
+    User::LeaveIfError( err );
+    CleanupStack::PopAndDestroy( globalSetting );    
+    return maxLength;
+    }
+
+}  // namespace
+
+
+// ==================== MEMBER FUNCTIONS ====================
+
+inline CPbkFieldsInfo::CPbkFieldsInfo()
+    {
+    // CBase::operator new(TLeave) resets members
+    }
+
+CPbkFieldsInfo* CPbkFieldsInfo::NewL
+		(RResourceFile& aPbkResFile, RResourceFile& aCntModelResFile)
+    {
+    CPbkFieldsInfo* self = new(ELeave) CPbkFieldsInfo;
+    CleanupStack::PushL(self);
+    self->ConstructFromResourceL(aPbkResFile,aCntModelResFile);
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CPbkFieldsInfo::~CPbkFieldsInfo()
+    {
+    iGroups.ResetAndDestroy();
+    delete iTypeUidMap;
+    // Cannot use iEntries.ResetAndDestroy() because CPbkFieldInfo destructor 
+    // is private
+    for (TInt i=iEntries.Count()-1; i >= 0; --i)
+        {
+        delete iEntries[i];
+        }
+    iEntries.Close();
+    delete iPbkFieldInfoParams;
+    }
+
+EXPORT_C CPbkFieldInfo* CPbkFieldsInfo::Find
+		(TPbkFieldId aFieldId) const 
+    {
+    TMatchFieldId matcher(aFieldId);
+    return FindMatching(iEntries,matcher);
+    }
+
+EXPORT_C CPbkFieldInfo* CPbkFieldsInfo::Find
+		(TPbkFieldId aFieldId, TPbkFieldLocation aLocation) const 
+    {
+    TMatchFieldIdAndLocation matcher(aFieldId,aLocation);
+    return FindMatching(iEntries,matcher);
+    }
+
+EXPORT_C CPbkFieldInfo* CPbkFieldsInfo::Find
+		(const CContactItemField& aField) const
+    {
+    TMatchContactItemField matcher(aField,*iTypeUidMap);
+    return FindMatching(iEntries,matcher);
+    }
+
+CPbkFieldInfo* CPbkFieldsInfo::Match
+		(const CContactItemField& aField,
+        const TPbkMatchPriorityLevel& aMatchPriority) const
+    {
+    TMatchContactItemFieldWithLevel matcher(aField,*iTypeUidMap,aMatchPriority);
+    return FindMatching(iEntries,matcher);
+    }
+
+EXPORT_C CPbkFieldInfo* CPbkFieldsInfo::Match
+        (const MPbkVcardProperty& aVcardProperty,
+        const TPbkMatchPriorityLevel& aMatchPriority) const
+    {
+    TMatchVcard matcher(aVcardProperty, *iTypeUidMap, aMatchPriority);
+    return FindMatching(iEntries,matcher);
+    }
+
+EXPORT_C TPbkMatchPriorityLevel CPbkFieldsInfo::CreateMatchPriority() const
+    {
+    return TPbkMatchPriorityLevel(iHighestMatchPriorityLevel);
+    }
+
+EXPORT_C TInt CPbkFieldsInfo::Count() const 
+    { 
+    return iEntries.Count(); 
+    }
+
+EXPORT_C CPbkFieldInfo* CPbkFieldsInfo::operator[](TInt aIndex) const
+    {
+    __ASSERT_ALWAYS(aIndex >= 0 && aIndex < iEntries.Count(), 
+        Panic(EPanicIndexOutOfRange));
+    return CONST_CAST(CPbkFieldInfo*,iEntries[aIndex]);
+    }
+
+EXPORT_C TInt CPbkFieldsInfo::GroupCount() const
+    {
+    return iGroups.Count();
+    }
+
+EXPORT_C const CPbkFieldInfoGroup& CPbkFieldsInfo::GroupAt(TInt aIndex) const
+    {
+    return *iGroups[aIndex];
+    }
+
+EXPORT_C CContactItemViewDef* CPbkFieldsInfo::CreateContactItemViewDefLC
+        (const CPbkFieldIdArray& aFieldTypes) const
+    {
+    CContactItemViewDef* result = 
+        CContactItemViewDef::NewLC(
+            CContactItemViewDef::EIncludeFields, 
+            CContactItemViewDef::EIncludeHiddenFields);
+    TAddToViewDef viewDefAdder(*result);
+    ProcessMatchingL(iEntries, aFieldTypes, viewDefAdder);
+    return result;
+    }
+
+EXPORT_C CContactItemFieldDef* CPbkFieldsInfo::CreateContactItemFieldDefLC
+        (const CPbkFieldIdArray* aFieldTypes) const
+    {
+    CContactItemFieldDef* result = new(ELeave) CContactItemFieldDef;
+    CleanupStack::PushL(result);
+    if (aFieldTypes)
+        {
+        TAddToFieldDef fieldDefAdder(*result);
+        ProcessMatchingL(iEntries, *aFieldTypes, fieldDefAdder);
+        }
+    else
+        {
+        // No Phonebook fields specified, match all contact fields
+        result->AppendL(KUidContactFieldMatchAll);
+        }
+    return result;
+    }
+
+void CPbkFieldsInfo::AddFieldTypesFromResourceL
+        (TResourceReader& aPbkResReader, 
+        TResourceReader& aCntModelResReader,
+        RArray<const CPbkFieldInfo*>* aAddedFieldTypes)
+    {
+    // get the counts of items in the arrays
+    const TInt stdCount = aCntModelResReader.ReadInt16();
+    const TInt addCount = aPbkResReader.ReadInt16();
+    __ASSERT_ALWAYS(stdCount==addCount, 
+        Panic(EPanicResourceArrayCountsMismatch));
+
+    // Read central repository params before the loop.
+    // Otherwise there can be performance problems during device boot up.
+    // Params are read to iPbkFieldInfoParams when needed.
+    ReadFieldInfoParamsL();    
+
+    // Allocate the info array
+    TInt i;
+    for (i=0; i < stdCount; ++i)
+        {
+        // Create new field info object and initialise it from resources
+        CPbkFieldInfo* fieldInfo = CPbkFieldInfo::NewLC
+            (aCntModelResReader, aPbkResReader, *iPbkFieldInfoParams);
+        fieldInfo->UpdateTypeUidMapL(*iTypeUidMap);
+        
+        // Set the group of the field info object
+        const TPbkFieldGroupId groupId = fieldInfo->iGroupLink.iGroupId;
+        if (groupId == EPbkFieldGroupIdNone)
+            {
+            fieldInfo->iGroupLink.iGroup = NULL;
+            }
+        else
+            {
+            CPbkFieldInfoGroup* group = FindGroup(groupId);
+            __ASSERT_ALWAYS(group, Panic(EPanicResourceLinkedGroupNotFound));
+            group->AddL(*fieldInfo);
+            fieldInfo->iGroupLink.iGroup = group;
+            }
+
+        // Add field info object to the array
+        User::LeaveIfError(iEntries.Append(fieldInfo));
+        CleanupStack::Pop(fieldInfo);
+        if (aAddedFieldTypes)
+            {
+            User::LeaveIfError( aAddedFieldTypes->Append(fieldInfo) );
+            }
+        }
+
+    // Calculate type mapping signatures and maximum level of import priorities
+    const TInt allCount = iEntries.Count();
+    for (i=0; i < allCount; ++i)
+        {
+        iEntries[i]->CalculateTypeSignatures(*iTypeUidMap);
+        const TInt importPropertyCount = iEntries[i]->ImportPropertyCount();
+        if (importPropertyCount > iHighestMatchPriorityLevel)
+            {
+            iHighestMatchPriorityLevel = importPropertyCount;
+            }
+        }
+
+    // Sort the info array to specified field ordering
+    iEntries.Sort(CompareOrdering);
+    }
+
+inline CPbkFieldInfoGroup* CPbkFieldsInfo::FindGroup(TPbkFieldGroupId aGroupId)
+    {
+    const TInt count = iGroups.Count();
+    for (TInt i=0; i < count; ++i)
+        {
+        CPbkFieldInfoGroup* group = iGroups[i];
+        if (group->Id() == aGroupId)
+            {
+            return group;
+            }
+        }
+    return NULL;
+    }
+
+inline void CPbkFieldsInfo::ReadGroupsInfoL(RResourceFile& aResFile)
+    {
+    TResourceReader resReader;
+    resReader.SetBuffer(aResFile.AllocReadLC(R_PBK_FIELD_GROUPS));
+    TInt count = resReader.ReadInt16();
+    while (count-- > 0)
+        {
+        CPbkFieldInfoGroup* group = CPbkFieldInfoGroup::NewLC(resReader);
+        User::LeaveIfError(iGroups.Append(group));
+        CleanupStack::Pop(group);
+        }
+    CleanupStack::PopAndDestroy();  // R_PBK_FIELD_GROUPS
+    }
+
+void CPbkFieldsInfo::ConstructFromResourceL
+		(RResourceFile& aPbkResFile, RResourceFile& aCntModelResFile)
+    {
+    // Read contact model field information
+    TResourceReader cntModelReader;
+    cntModelReader.SetBuffer(aCntModelResFile.AllocReadLC(R_CNTUI_NEW_FIELD_DEFNS));
+    // Read additional phonebook information
+    TResourceReader pbkReader;
+	pbkReader.SetBuffer(aPbkResFile.AllocReadLC(R_PHONEBOOK_FIELD_PROPERTIES));
+
+    // Allocate type UID map
+    iTypeUidMap = new (ELeave) CPbkUidMap;
+
+    ReadGroupsInfoL(aPbkResFile);
+
+    AddFieldTypesFromResourceL(pbkReader, cntModelReader, NULL);    
+    CleanupStack::PopAndDestroy(2);  // R_PHONEBOOK_FIELD_PROPERTIES, R_CNTUI_NEW_FIELD_DEFNS
+    }
+
+void CPbkFieldsInfo::ReadFieldInfoParamsL()
+    {    
+    if (!iPbkFieldInfoParams)
+        {
+        iPbkFieldInfoParams = new (ELeave) CPbkFieldInfo::TPbkFieldInfoParams();
+        iPbkFieldInfoParams->iEditorMaxNumberLength = ReadMaxNumberLengthL();
+        }
+    }
+
+//  End of File