--- /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 );
+ }
+ }
+