sysstatemgmt/syslangutil/ssmlangselcmd/src/ssmlangselcmd.cpp
changeset 0 4e1aa6a622a0
child 13 cef4ff1e6c4f
child 60 ccb4f6b3db21
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sysstatemgmt/syslangutil/ssmlangselcmd/src/ssmlangselcmd.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,507 @@
+/*
+* Copyright (c) 2009 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:
+* Implementation of CSsmLangSelCmd class.
+*
+*/
+
+#include "ssmlangselcmd.h"
+#include "ssmmapperutility.h"
+#include "ssmalternativelanguages.h"
+#include "ssmlanguageloader.h"
+#include "syslangutilprivatecrkeys.h"
+#include "trace.h"
+
+#include <syslangutil.h>
+#include <CommonEngineDomainCRKeys.h>
+#include <centralrepository.h>
+
+
+/** Default granularity for list of installed languages. */
+const TInt KLanguageListGranularity( 4 );
+
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::NewL
+// ---------------------------------------------------------------------------
+//
+CSsmLangSelCmd* CSsmLangSelCmd::NewL()
+	{
+    FUNC_LOG;
+    CSsmLangSelCmd* self = new ( ELeave ) CSsmLangSelCmd();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+	return self;	
+	}
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::~CSsmLangSelCmd
+// ---------------------------------------------------------------------------
+//
+CSsmLangSelCmd::~CSsmLangSelCmd()
+    {
+    FUNC_LOG;
+    delete iLangList;
+    delete iMapperUtility;
+    }
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::RunL
+//
+// ---------------------------------------------------------------------------
+//
+void CSsmLangSelCmd::RunL()
+    {
+    FUNC_LOG;
+    TInt errorCode = iStatus.Int();
+    
+    ERROR( errorCode, "CSsmLangSelCmd::RunL with error" );
+
+    if ( iState == EQueryListSize )
+        {
+        if ( errorCode == KErrNone )
+            {
+            TRAP( errorCode, FetchLanguageListL() );
+            ERROR( errorCode, "Failed to fetch language list" );
+            }
+        else
+            {
+            TryNextList();
+            }
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::DoCancel
+//
+// ---------------------------------------------------------------------------
+//
+void CSsmLangSelCmd::DoCancel()
+    {
+    FUNC_LOG;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::Initialize
+// ---------------------------------------------------------------------------
+//
+TInt CSsmLangSelCmd::Initialize( CSsmCustomCommandEnv* aCmdEnv )
+    {
+    FUNC_LOG;
+
+    iEnv = aCmdEnv;
+    TRAPD( errorCode, InitializeL() );
+    return errorCode;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::Execute
+// ---------------------------------------------------------------------------
+//
+void CSsmLangSelCmd::Execute(
+    const TDesC8& /*aParams*/,
+    TRequestStatus& aRequest )
+    {
+    FUNC_LOG;
+    
+    ASSERT_TRACE( !iClientStatus );
+    ASSERT_TRACE( !IsActive() );
+    ASSERT_TRACE( iEnv );
+
+    aRequest = KRequestPending;
+    iClientStatus = &aRequest;
+    
+
+    RFs* fsSession = &( const_cast<RFs&>( iEnv->Rfs() ) );
+    TInt errorCode = SysLangUtil::GetDefaultLanguage( iDefaultLanguage,
+                                                      fsSession );
+    ERROR( errorCode, "Failed to get default language" );
+
+    TInt lastSelectedLang = GetLastSelectedLang();
+    // Revert to automatic selection if fetching last used language
+    // fails, last used language is not valid (and obviously when last
+    // selection is automatic).
+    if ( lastSelectedLang == 0 )
+        {
+        PrepareNextList();
+        }
+    else if ( IsValid( lastSelectedLang ) )
+        {
+        UseLanguage( lastSelectedLang );
+        }
+    else
+        {
+        UseLanguage( iDefaultLanguage );
+        }    
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::ExecuteCancel
+// ---------------------------------------------------------------------------
+//
+void CSsmLangSelCmd::ExecuteCancel()
+    {
+    FUNC_LOG;
+
+    Cancel();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::Close
+// ---------------------------------------------------------------------------
+//
+void CSsmLangSelCmd::Close()
+    {
+    FUNC_LOG;
+    delete iValidLanguages;
+    iValidLanguages = NULL;
+    
+    iAdaptation.Close();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::Release
+// ---------------------------------------------------------------------------
+//
+void CSsmLangSelCmd::Release()
+    {
+    FUNC_LOG;
+
+	delete this;
+    }
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::CSsmLangSelCmd
+// ---------------------------------------------------------------------------
+//
+
+CSsmLangSelCmd::CSsmLangSelCmd()
+  : CActive( EPriorityNormal )
+    {
+    FUNC_LOG;
+
+    CActiveScheduler::Add( this );
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CSsmLangSelCmd::ConstructL()
+    {
+    iMapperUtility = CSsmMapperUtility::NewL();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::InitializeL
+// ---------------------------------------------------------------------------
+//
+void CSsmLangSelCmd::InitializeL()
+    {
+
+    FUNC_LOG;
+    ASSERT_TRACE( iEnv );
+    
+    iValidLanguages = new ( ELeave ) CArrayFixFlat<TInt>( 
+                                                    KLanguageListGranularity );
+    RFs* fsSession = &( const_cast<RFs&>( iEnv->Rfs() ) );
+    TInt errorCode = SysLangUtil::GetInstalledLanguages( iValidLanguages,
+                                                         fsSession );
+    
+    ERROR( errorCode, "Failed to get installed languages" );
+    User::LeaveIfError( errorCode );
+    
+    errorCode = iAdaptation.Connect();
+    ERROR( errorCode, "Failed to connect to RSsmMiscAdaptation" );
+    User::LeaveIfError( errorCode );
+    }
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::GetLastSelectedLang
+//
+// ---------------------------------------------------------------------------
+//
+TInt CSsmLangSelCmd::GetLastSelectedLang()
+    {
+    FUNC_LOG;
+
+    TInt value( 0 );
+    TInt errorCode = iMapperUtility->CrValue( KCRUidCommonEngineKeys, 
+                                              KGSDisplayTxtLang,
+                                              value );
+    
+    ERROR( errorCode, "Failed read KGSDisplayTxtLang CenRep key" );
+    INFO_1( "Last selected language = %d", value );
+    return value;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::IsValid
+//
+// ---------------------------------------------------------------------------
+//
+TBool CSsmLangSelCmd::IsValid( const TInt aLanguage ) const
+    {
+    FUNC_LOG;
+    ASSERT_TRACE( iValidLanguages );
+
+    TBool valid( EFalse );
+    TKeyArrayFix keyProp( 0, ECmpTInt );
+    TInt index( KErrNotFound );
+    // Returns zero if element is found.
+    if ( 0 == iValidLanguages->Find( aLanguage, keyProp, index ) )
+        {
+        valid = ETrue;
+        }
+    return valid;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::PrepareNextList
+//
+// ---------------------------------------------------------------------------
+//
+void CSsmLangSelCmd::PrepareNextList()
+    {
+    FUNC_LOG;
+    ASSERT_TRACE( iLangListPref >= EPrimaryLanguages &&
+                  iLangListPref <= ETertiaryLanguages );
+    INFO_1( "Trying preferred language list %d", iLangListPref );
+
+    iState = EQueryListSize;
+    iAdaptation.PrepareSimLanguages(
+        static_cast<TSsmLanguageListPriority>( iLangListPref++ ),
+        iLangListSize, iStatus );
+    SetActive();
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::FetchLanguageListL
+//
+// ---------------------------------------------------------------------------
+//
+void CSsmLangSelCmd::FetchLanguageListL()
+    {
+    FUNC_LOG;
+    INFO_1( "Required language list size = %d", iLangListSize() );
+
+    iState = EQueryListContent;
+    delete iLangList;
+    iLangList = NULL;
+    
+    iLangList = iAdaptation.SimLanguagesArrayL( iLangListSize() );    
+    
+    TInt selectionResult = InterpretResult();
+
+    if ( selectionResult > KErrNone )
+        {
+        StoreLanguageToCentRep( selectionResult );
+        UseLanguage( selectionResult );
+        }
+    else
+        {
+        TryNextList();
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::InterpretResult
+//
+// ---------------------------------------------------------------------------
+//
+TInt CSsmLangSelCmd::InterpretResult()
+    {
+    FUNC_LOG;
+
+    TInt selectedLanguage = KErrNotFound;
+    TInt langCount( iLangListSize() );
+    INFO_1( "Number of languages: %d", langCount );
+
+    for ( TInt i = 0; i < langCount; i++ )
+        {
+        TInt lang = ( *iLangList )[i];
+        INFO_1( "Language: %d", lang );
+
+        TInt nearestMatch = ValidAlternative( lang );
+        if ( nearestMatch > 0 ) // Not an error code
+            {
+            selectedLanguage = nearestMatch;
+            break;
+            }
+        }
+
+    INFO_1( "Selected language %d from list", selectedLanguage );
+    return selectedLanguage;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::ValidAlternative
+//
+// ---------------------------------------------------------------------------
+//
+TInt CSsmLangSelCmd::ValidAlternative( const TInt aLanguage ) const
+    {
+    FUNC_LOG;
+
+    TInt retVal = KErrNotFound;
+
+    if ( IsValid( aLanguage ) )
+        {
+        retVal = aLanguage;
+        }
+    else
+        {
+        for ( TInt i = 0; i < KSsmAlternativeLanguageTableSize; i++ )
+            {
+            if ( KAlternativeLanguageTable[i].iLang1 == aLanguage )
+                {
+                INFO_2( "Alternative %d found for language %d",
+                    KAlternativeLanguageTable[i].iLang2, aLanguage );
+
+                if ( IsValid( KAlternativeLanguageTable[i].iLang2 ) )
+                    {
+                    retVal = KAlternativeLanguageTable[i].iLang2;
+                    break;
+                    }
+                }
+            else if ( KAlternativeLanguageTable[i].iLang2 == aLanguage )
+                {
+                INFO_2( "Alternative %d found for language %d",
+                    KAlternativeLanguageTable[i].iLang1, aLanguage );
+
+                if ( IsValid( KAlternativeLanguageTable[i].iLang1 ) )
+                    {
+                    retVal = KAlternativeLanguageTable[i].iLang1;
+                    break;
+                    }
+                }
+            }
+        }
+
+    return retVal;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::TryNextList
+//
+// ---------------------------------------------------------------------------
+//
+void CSsmLangSelCmd::TryNextList()
+    {
+    FUNC_LOG;
+
+    if ( iLangListPref <= ETertiaryLanguages )
+        {
+        PrepareNextList();
+        }
+    else // All lists exhausted
+        {
+        TInt prevLang = GetLanguageFromCentRep();
+        if ( IsValid( prevLang ) )
+            {
+            UseLanguage( prevLang );
+            }
+        else
+            {
+            INFO( "Previous language not valid, reverting to default" );
+            UseLanguage( iDefaultLanguage );
+            }
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::StoreLanguageToCentRep
+//
+// ---------------------------------------------------------------------------
+//
+void CSsmLangSelCmd::StoreLanguageToCentRep( const TInt aLanguage )
+    {
+    FUNC_LOG;
+    TUid mappedUid = iMapperUtility->CrUid( KCRUidSysLangUtil );
+    CRepository* cenrep = NULL;
+    TRAPD( errorCode, cenrep = CRepository::NewL( mappedUid ) );
+    ERROR_1( errorCode, "Failed to initialize cen rep %d", errorCode );
+    
+    if ( KErrNone == errorCode )
+        {
+        errorCode = cenrep->Set( KSysLangUtilSimLanguage, aLanguage );
+        ERROR_1( errorCode, "Failed to store language code to CentRep, %d", 
+                                                                  errorCode );
+        delete cenrep;
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::GetLanguageFromCentRep
+//
+// ---------------------------------------------------------------------------
+//
+TInt CSsmLangSelCmd::GetLanguageFromCentRep()
+    {
+    FUNC_LOG;
+
+    TInt lang = iDefaultLanguage;
+    TInt errorCode = iMapperUtility->CrValue( KCRUidSysLangUtil,
+                                              KSysLangUtilSimLanguage,
+                                              lang );
+    
+    ERROR_1( errorCode, "Failed to read language code from CenRep %d", 
+             errorCode );
+    return lang;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CSsmLangSelCmd::UseLanguage
+//
+// ---------------------------------------------------------------------------
+//
+void CSsmLangSelCmd::UseLanguage( const TInt aLang )
+    {
+    FUNC_LOG;
+
+    TInt errorCode = aLang;
+    if ( aLang > KErrNone )
+        {
+        errorCode = SsmLanguageLoader::LoadLanguage( aLang );
+        ERROR( errorCode, "Failed to load language" );
+        }
+
+    ERROR( errorCode, "Language selection failed" );
+
+    if ( iClientStatus )
+        {
+        User::RequestComplete( iClientStatus, errorCode );
+        }
+    }
+