diff -r 072a9626b290 -r 09d657f1ee00 sysstatemgmt/syslangutil/src/syslangutil.cpp --- a/sysstatemgmt/syslangutil/src/syslangutil.cpp Wed Aug 18 11:03:14 2010 +0300 +++ b/sysstatemgmt/syslangutil/src/syslangutil.cpp Thu Sep 02 21:48:26 2010 +0300 @@ -1,5 +1,5 @@ /* -* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +* Copyright (c) 2009 - 2010 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" @@ -23,16 +23,25 @@ #include "syslangutiltrace.h" #include "ssmmapperutilitystatic.h" #include "syslangutilprivatecrkeys.h" +#include "ssmcommonlocale.h" +#include const TInt KReadBufSize = 10; -const TInt KLangArraySize = 20; +const TInt KLangArraySize = 10; +//Maximum number of retries for starting cenrep transaction. +const TInt KMaxCountForReiteration = 5; // R&D support: Use language file in Starters internal directory for module // testing purposes. #ifdef __STARTER_MODULE_TEST_SUPPORT__ _LIT( KLanguagesIni, "C:\\private\\100059C9\\languages.txt" ); + _LIT( KRegionsIni, "C:\\private\\100059C9\\regions.txt" ); + _LIT( KCollationsIni, "C:\\private\\100059C9\\collations.txt" ); + #else // __STARTER_MODULE_TEST_SUPPORT__ _LIT( KLanguagesIni, "z:\\resource\\bootdata\\languages.txt" ); + _LIT( KRegionsIni, "z:\\resource\\bootdata\\regions.txt" ); + _LIT( KCollationsIni, "z:\\resource\\bootdata\\collations.txt" ); #endif // __STARTER_MODULE_TEST_SUPPORT__ // ============================ MEMBER FUNCTIONS =============================== @@ -351,3 +360,172 @@ FUNC_EXIT_TRACE; return aRFs; } + +// ----------------------------------------------------------------------------- +// SysLangUtil::ChangeLanguage +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt SysLangUtil::ChangeLanguage(const TInt aLanguageCode) + { + API_FUNC_ENTRY_TRACE; + TRAPD( errorCode, LoadDllL( KGSDisplayTxtLang,aLanguageCode, KLanguageDllNameBase ) ); + FUNC_EXIT_RET_TRACE( errorCode ); + return errorCode; + } + + +// ----------------------------------------------------------------------------- +// SysLangUtil::ChangeRegion +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt SysLangUtil::ChangeRegion(const TInt aRegionCode) + { + API_FUNC_ENTRY_TRACE; + TRAPD( errorCode, LoadDllL( KGSRegion, aRegionCode, KRegionDllNameBase ) ); + FUNC_EXIT_RET_TRACE( errorCode ); + return errorCode; + } + +// ----------------------------------------------------------------------------- +// SysLangUtil::ChangeCollation +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt SysLangUtil::ChangeCollation(const TInt aCollationCode) + { + API_FUNC_ENTRY_TRACE; + TRAPD( errorCode, LoadDllL( KGSCollation, aCollationCode, KCollationDllNameBase ) ); + FUNC_EXIT_RET_TRACE( errorCode ); + return errorCode; + } + + +// ----------------------------------------------------------------------------- +// SysLangUtil::GetInstalledRegions +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt SysLangUtil::GetInstalledRegions(CArrayFixFlat*& aRegions, RFs* aFileServerSession ) + { + API_FUNC_ENTRY_TRACE; + TRAPD(err, ReadFileL(aRegions, KRegionsIni, aFileServerSession )); + FUNC_EXIT_RET_TRACE( err ); + return err; + } + +// ----------------------------------------------------------------------------- +// SysLangUtil::GetInstalledCollations +// +// ----------------------------------------------------------------------------- +// +EXPORT_C TInt SysLangUtil::GetInstalledCollations(CArrayFixFlat*& aCollations, RFs* aFileServerSession ) + { + API_FUNC_ENTRY_TRACE; + TRAPD(err, ReadFileL(aCollations, KCollationsIni, aFileServerSession )); + FUNC_EXIT_RET_TRACE( err ); + return err; + } + +void SysLangUtil::LoadDllL( const TUint32 aCategory,const TInt aCode, const TDesC& aDllNameBase ) + { + CRepository* cenrep = NULL; + TUint32 keyInfo; + cenrep = CRepository::NewLC( KCRUidCommonEngineKeys ); + + // Re-iterate through StartTransaction, if errorCode returned is KErrLocked + TInt errorCode = KErrLocked; + //Counter to restrict re-iteration. + TInt counter = KMaxCountForReiteration; + while ( KErrLocked == errorCode && counter > 0 ) + { + errorCode = cenrep->StartTransaction(CRepository::EConcurrentReadWriteTransaction); + --counter; + } + User::LeaveIfError(errorCode); + cenrep->CleanupCancelTransactionPushL(); + User::LeaveIfError(cenrep->Set( aCategory, aCode)); + + TBuf extension; + extension.Format( KDllExtensionFormat, aCode ); + + // Padd ".1" to ".001" for compatibility. + for( ; extension.Length() < KMinDllExtensionLength ;) + { + extension.Insert( KDllExtensionPaddingPosition, + KDllExtensionPadding ); + } + + TBuf dllName( aDllNameBase ); + dllName.Append( extension ); + + //Loading DLL + TExtendedLocale extLocale; + extLocale.LoadSystemSettings(); + errorCode = extLocale.LoadLocaleAspect( dllName ); + ERROR_TRACE_2( "LoadLocaleAspect returned error %d while loading dll %S" ,errorCode, &dllName ); + User::LeaveIfError(errorCode); + + User::LeaveIfError(extLocale.SaveSystemSettings()); + errorCode = cenrep->CommitTransaction(keyInfo); + if ( KErrNone != errorCode ) + { + ERROR_TRACE_2( "CommitTransaction() error: Key Info %d for setting Category %d", keyInfo, aCategory ); + User::Leave(errorCode); + } + CleanupStack::PopAndDestroy();// for CleanupCancelTransactionPushL() + CleanupStack::PopAndDestroy(cenrep); + User::LeaveIfError(TLocale().Set()); + } + +void SysLangUtil::ReadFileL(CArrayFixFlat*& aArray, const TDesC& aFilePath, RFs* aFileServerSession ) + { + TBool hadFS = EFalse; + TInt err = KErrNone; + if ( aArray ) + { + delete aArray; + aArray = NULL; + } + aArray = new(ELeave) CArrayFixFlat( KLangArraySize ); + + aFileServerSession = CheckFS( aFileServerSession, hadFS, err ); + User::LeaveIfError(err); + RFile file; + CleanupClosePushL(file); + err = file.Open(*aFileServerSession, aFilePath, EFileStream | EFileRead | EFileShareReadersOnly ); + ERROR_TRACE_2( "SysLangUtil::ReadFileL() : Opening the file : %S failed with error : %d", &aFilePath, err) ; + User::LeaveIfError(err); + + // Prepare Reader + TFileText reader; + reader.Set( file ); + err = reader.Seek( ESeekStart ); + if ( !err ) + { + TBuf readBuf; + for ( TInt i = 0; !reader.Read( readBuf ) && readBuf.Length(); ++i ) + { + TLex lex( readBuf ); + lex.SkipSpace(); + TInt value; + err = lex.Val( value ); + if ( err ) + { + break; + } + // IGNORE the Leave + TRAP_IGNORE( aArray->AppendL( value )); + readBuf.Zero(); + } + } + CleanupStack::PopAndDestroy(&file); + if ( !hadFS ) + { + aFileServerSession->Close(); + delete aFileServerSession; + aFileServerSession = NULL; + } + } +