phonebookui/Phonebook/Engine/src/CPbkSortOrderManager.cpp
changeset 0 e686773b3f54
child 68 9da50d567e3c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/phonebookui/Phonebook/Engine/src/CPbkSortOrderManager.cpp	Tue Feb 02 10:12:17 2010 +0200
@@ -0,0 +1,395 @@
+/*
+* 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 contact Sort order manager.
+*
+*/
+
+
+// INCLUDE FILES
+#include "CPbkSortOrderManager.h"
+#include <featmgr.h>
+#include <bldvariant.hrh>
+#include <CPbkContactEngine.h>
+#include <StringLoader.h>
+#include <PbkEng.rsg>
+#include <barsread.h>    // TResourceReader
+#include <PbkGlobalSettingFactory.h>
+#include <MPbkGlobalSetting.h>
+#include "PbkUID.h"
+#include <PbkEngUtils.h>
+#include "PbkEng.hrh"
+/// Unnamed namespace for local definitions
+namespace {
+
+// CONSTANTS
+
+// Name order setting value for First Name Last Name
+// This value comes from phonebook specification (see
+// qtn_phob_name_order) and it's opposite compared to
+// TPbkNameOrder that is used in CenRep.
+_LIT(KPbkFirstLastNameEnabled, "0");
+// Value when name separator is used
+_LIT(KPbkNameSeparatorUsed, "1");
+// Dec value for space character
+const TInt KPbkSpaceDecValue = 32;
+
+// Separator string length is set to 4.
+// Separator should be only one character long,
+// but sometimes localized string or cenrep initial value
+// may contain additional space characters at the end of string.
+const TInt KPbkSeparatorMaxLength = 4;
+
+#ifdef _DEBUG
+// CONSTANTS
+enum TPanicCode
+    {
+    EPanicPreCond_SetNameDisplayOrderL = 1
+    };
+
+// LOCAL FUNCTIONS
+void Panic(TPanicCode aReason)
+    {
+    _LIT(KPanicText, "CPbkSortOrderManager");
+    User::Panic(KPanicText, aReason);
+    }
+#endif // _DEBUG
+
+// Conversion function is used because old functions
+// SetNameSeparatorL() and NameSeparator() are supported.
+// In old format 0 means that space character is used and in
+// new format 23 stands for space character
+inline TChar ConvertSeparatorCharacterToOld(TChar aFrom)
+    {
+    // Convert space value to 0 value.
+    return (TUint(aFrom)==KPbkSpaceDecValue)? TChar(0) : aFrom;
+    }
+
+inline TChar ConvertSeparatorCharacterToNew(TChar aFrom)
+    {
+    // Convert 0 value to space value.
+    return TUint(aFrom)==0? TChar(KPbkSpaceDecValue) : aFrom;
+    }
+
+} // namespace
+
+// ==================== MEMBER FUNCTIONS ====================
+
+inline CPbkSortOrderManager::CPbkSortOrderManager(RFs& aFs, TBool aSettingsVisible):
+                                        iFs(aFs), iSettingsVisible(aSettingsVisible)
+    {
+    }
+
+inline void CPbkSortOrderManager::ConstructL()
+    {
+    iPersistentSetting = PbkGlobalSettingFactory::CreatePersistentSettingL();
+    iPersistentSetting->ConnectL(MPbkGlobalSetting::EGeneralSettingCategory);
+
+    // construct name sort order
+    RContactViewSortOrder sortOrder =
+        DoCreateSortOrderL(PersistentNameDisplayOrderL(), iSettingsVisible);
+    iSortOrder = sortOrder;
+    iNameSeparator =
+        ConvertSeparatorCharacterToOld(PersistentNameSeparatorCharL());
+    iPersistentSetting->RegisterObserverL(this);
+    }
+
+inline void CPbkSortOrderManager::SetPersistentNameDisplayOrderL
+        (CPbkContactEngine::TPbkNameOrder aNameOrder)
+    {
+    __ASSERT_DEBUG(
+            aNameOrder == CPbkContactEngine::EPbkNameOrderLastNameFirstName ||
+            aNameOrder == CPbkContactEngine::EPbkNameOrderFirstNameLastName,
+            Panic(EPanicPreCond_SetNameDisplayOrderL));
+
+    User::LeaveIfError(iPersistentSetting->Set(
+        MPbkGlobalSetting::ENameOrdering, TInt(aNameOrder)));
+    }
+
+inline void CPbkSortOrderManager::
+        SetPersistentNameSeparatorCharL(TChar aNameSeparatorChar)
+    {
+    // 1 character is appended.
+    TBuf<1> string;
+    string.Append(aNameSeparatorChar);
+    User::LeaveIfError(iPersistentSetting->Set(
+        MPbkGlobalSetting::ENameSeparatorChar, string));
+    }
+
+
+CPbkSortOrderManager* CPbkSortOrderManager::NewL(RFs& aFs, TBool aSettingsVisible)
+    {
+    CPbkSortOrderManager* self = new(ELeave) CPbkSortOrderManager(aFs, aSettingsVisible);
+    CleanupStack::PushL(self);
+    self->ConstructL();
+    CleanupStack::Pop(self);
+    return self;
+    }
+
+CPbkSortOrderManager::~CPbkSortOrderManager()
+    {
+    if (iPersistentSetting)
+        {
+        iPersistentSetting->Close();
+        delete iPersistentSetting;
+        }
+    iSortOrder.Close();
+    delete iNameOrderSetting;
+    delete iNameSeparatorUsed;
+    delete iInitialNameSeparatorChar;
+    }
+
+const RContactViewSortOrder& CPbkSortOrderManager::SortOrder() const
+    {
+    return iSortOrder;
+    }
+
+void CPbkSortOrderManager::SetNameDisplayOrderL
+        (CPbkContactEngine::TPbkNameOrder aNameOrder)
+    {
+    // create new view sort order from aNameOrder
+    RContactViewSortOrder newSortOrder = DoCreateSortOrderL(aNameOrder,
+                                                            iSettingsVisible);
+    CleanupClosePushL(newSortOrder);
+
+    if (iContactView)
+        {
+        //retrieve the contact view sort order
+        RContactViewSortOrder oldViewSortOrder;
+        CleanupClosePushL(oldViewSortOrder);
+        iContactView->GetSortOrderL(oldViewSortOrder);
+
+        // try to change the contact view sort order
+        iContactView->ChangeSortOrderL(newSortOrder);
+        // Try to change the persistent key for name ordering
+        TRAPD(err,SetPersistentNameDisplayOrderL(aNameOrder));
+        if (err)
+            {
+            // error occurred, restore view sort order
+            iContactView->ChangeSortOrderL(oldViewSortOrder);
+            CleanupStack::Pop(); // oldViewSortOrder
+            }
+        else
+            {
+            CleanupStack::PopAndDestroy(); // oldViewSortOrder
+            iSortOrder.Close();
+            iSortOrder = newSortOrder;
+            CleanupStack::Pop(); // newSortOrder
+            }
+        }
+    else
+        {
+        CleanupStack::PopAndDestroy(); // newSortOrder
+        }
+    }
+
+CPbkContactEngine::TPbkNameOrder CPbkSortOrderManager::NameDisplayOrder() const
+    {
+    // return current name display order
+    for (TInt i = 0; i < iSortOrder.Count(); ++i)
+        {
+        if (iSortOrder[i] == KUidContactFieldFamilyName)
+            {
+            return CPbkContactEngine::EPbkNameOrderLastNameFirstName;
+            }
+        else if (iSortOrder[i] == KUidContactFieldGivenName)
+            {
+            return CPbkContactEngine::EPbkNameOrderFirstNameLastName;
+            }
+        }
+    return CPbkContactEngine::EPbkNameOrderLastNameFirstName;
+    }
+
+void CPbkSortOrderManager::SetContactView
+        (CContactNamedRemoteView& aContactView)
+    {
+    iContactView = &aContactView;
+    }
+
+void CPbkSortOrderManager::SettingChangedL(MPbkGlobalSetting::
+                                                    TPbkGlobalSetting aKey)
+    {
+    if (aKey == MPbkGlobalSetting::ENameOrdering ||
+        aKey == MPbkGlobalSetting::ENameSeparatorChar)
+        {
+        // Update sortorder and name separator char
+        RContactViewSortOrder sortOrder =
+                            DoCreateSortOrderL(PersistentNameDisplayOrderL(),
+                                               iSettingsVisible);
+        iSortOrder.Close();
+        iSortOrder = sortOrder;
+
+        iNameSeparator =
+            ConvertSeparatorCharacterToOld(PersistentNameSeparatorCharL());
+        }
+    }
+
+void CPbkSortOrderManager::SetNameSeparatorL(TChar aNameSeparator)
+    {
+    // 0 is converted to space character
+    SetPersistentNameSeparatorCharL(
+        ConvertSeparatorCharacterToNew(aNameSeparator));
+    iNameSeparator = aNameSeparator;
+    }
+
+TChar CPbkSortOrderManager::NameSeparator() const
+    {
+    return iNameSeparator;
+    }
+
+RContactViewSortOrder CPbkSortOrderManager::DoCreateSortOrderL
+        (CPbkContactEngine::TPbkNameOrder aNameOrder,
+         TBool aSettingVisible)
+    {
+    RContactViewSortOrder sortOrder;
+    CleanupClosePushL(sortOrder);
+    // engine creation will assign it to the views
+	
+	sortOrder.AppendL(TUid::Uid(KUidContactFieldTopContactValue));
+	
+    if (FeatureManager::FeatureSupported(KFeatureIdChinese) &&
+        !aSettingVisible)
+        {
+        // Chinese sort ordering
+        sortOrder.AppendL(KUidContactFieldFamilyName);
+        sortOrder.AppendL(KUidContactFieldGivenName);
+        sortOrder.AppendL(KUidContactFieldCompanyName);
+        }
+    else if (FeatureManager::FeatureSupported(KFeatureIdJapanese))
+        {
+        // japanese sort ordering
+        if (aNameOrder == CPbkContactEngine::EPbkNameOrderLastNameFirstName)
+            {
+            sortOrder.AppendL(KUidContactFieldFamilyNamePronunciation);
+            sortOrder.AppendL(KUidContactFieldGivenNamePronunciation);
+            sortOrder.AppendL(KUidContactFieldFamilyName);
+            sortOrder.AppendL(KUidContactFieldGivenName);
+            }
+        else
+            {
+            sortOrder.AppendL(KUidContactFieldGivenNamePronunciation);
+            sortOrder.AppendL(KUidContactFieldFamilyNamePronunciation);
+            sortOrder.AppendL(KUidContactFieldGivenName);
+            sortOrder.AppendL(KUidContactFieldFamilyName);
+            }
+        sortOrder.AppendL(KUidContactFieldCompanyName);
+        }
+    else
+        {
+        // default sort ordering
+        if (aNameOrder == CPbkContactEngine::EPbkNameOrderLastNameFirstName)
+            {
+            sortOrder.AppendL(KUidContactFieldFamilyName);
+            sortOrder.AppendL(KUidContactFieldGivenName);
+            }
+        else
+            {
+            sortOrder.AppendL(KUidContactFieldGivenName);
+            sortOrder.AppendL(KUidContactFieldFamilyName);
+            }
+        sortOrder.AppendL(KUidContactFieldCompanyName);
+        }
+    sortOrder.AppendL(KUidContactFieldTemplateLabel);
+
+    CleanupStack::Pop(); // sortOrder
+    return sortOrder;
+    }
+
+CPbkContactEngine::TPbkNameOrder
+    CPbkSortOrderManager::PersistentNameDisplayOrderL()
+    {
+    TInt nameOrder = KErrNotFound;
+    User::LeaveIfError(
+        iPersistentSetting->Get(MPbkGlobalSetting::ENameOrdering, nameOrder));
+    CPbkContactEngine::TPbkNameOrder pbkNameOrder =
+        static_cast<CPbkContactEngine::TPbkNameOrder>(nameOrder);
+
+    // Read phonebook contact name presentation order configuration
+    // if order not defined.
+    if (pbkNameOrder == CPbkContactEngine::EPbkNameOrderNotDefined)
+        {
+        RResourceFile pbkResFile;
+        // Calls CleanupClosePushL for pbkResFile.
+        PbkEngUtils::FindAndOpenDefaultResourceFileLC(iFs, pbkResFile);
+        TResourceReader reader;
+
+        if(!iNameOrderSetting)
+            {
+            // Value 0 is first name last name and value 1 is last name first name
+            reader.SetBuffer(pbkResFile.AllocReadLC(R_PBK_NAME_ORDER));
+            iNameOrderSetting = reader.ReadHBufCL();
+            CleanupStack::PopAndDestroy();  // R_PBK_NAME_ORDER
+            }
+
+        if (!iNameOrderSetting->Compare(KPbkFirstLastNameEnabled))
+            {
+            // Compare return 0 if setting order value in loaded resource is "0"
+            // then first name last name order is used.
+            pbkNameOrder = CPbkContactEngine::EPbkNameOrderFirstNameLastName;
+            }
+        else
+            {
+            pbkNameOrder = CPbkContactEngine::EPbkNameOrderLastNameFirstName;
+            }
+        CleanupStack::PopAndDestroy(1); // pbkResFile
+        }
+    return pbkNameOrder;
+    }
+
+TChar CPbkSortOrderManager::PersistentNameSeparatorCharL()
+    {
+    TBuf<KPbkSeparatorMaxLength> string;
+    string.SetLength(0);
+    User::LeaveIfError(iPersistentSetting->Get(
+        MPbkGlobalSetting::ENameSeparatorChar, string));
+    // NULL string is for undefined
+    if (!string.Length() || string[0] == 0)
+        {
+        RResourceFile pbkResFile;
+        // Calls CleanupClosePushL for pbkResFile.
+        PbkEngUtils::FindAndOpenDefaultResourceFileLC(iFs, pbkResFile);
+        TResourceReader reader;
+
+        if(!iNameSeparatorUsed)
+            {
+            reader.SetBuffer(pbkResFile.AllocReadLC(R_PBK_NAME_SEPARATOR_USED));
+            iNameSeparatorUsed = reader.ReadHBufCL();
+            CleanupStack::PopAndDestroy();  // R_PBK_NAME_SEPARATOR_USED
+            }
+        if(!iNameSeparatorUsed->Compare(KPbkNameSeparatorUsed))
+            {
+            // Separator is used, use initial value
+            if(!iInitialNameSeparatorChar)
+                {
+                reader.SetBuffer(pbkResFile.AllocReadLC(R_PBK_NAME_SEPARATOR_CHAR));
+                iInitialNameSeparatorChar = reader.ReadHBufCL();
+                CleanupStack::PopAndDestroy();  // R_PBK_NAME_SEPARATOR_CHAR
+                }
+            string.SetLength(0);
+            string.Append(*iInitialNameSeparatorChar);
+            }
+        else if (string.Length()<KPbkSeparatorMaxLength)
+            {
+            // Space is used if separator character is not defined by default.
+            TChar space(KPbkSpaceDecValue);
+            string.SetLength(0);
+            string.Append(space);
+            }
+        CleanupStack::PopAndDestroy(1); // pbkResFile
+        }
+
+    return TChar(string[0]);
+    }
+
+// End of File