diff -r 000000000000 -r 4e1aa6a622a0 sysstatemgmt/syslangutil/ssmlangselcmd/src/ssmlangselcmd.cpp --- /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 +#include +#include + + +/** 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( 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( + KLanguageListGranularity ); + RFs* fsSession = &( const_cast( 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( 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 ); + } + } +