diff -r 000000000000 -r f72a12da539e menufw/hierarchynavigator/hnmetadatamodel/src/hnmdlocalization.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/menufw/hierarchynavigator/hnmetadatamodel/src/hnmdlocalization.cpp Thu Dec 17 08:40:49 2009 +0200 @@ -0,0 +1,476 @@ +/* +* Copyright (c) 2007-2008 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: +* +*/ + + +#include +#include +#include + +#include "hnmdlocalization.h" +#include "hnmdlocalizationelement.h" +#include "hnglobals.h" +#include "hnconvutils.h" +#include "hnutils.h" + +// ======== MEMBER FUNCTIONS ======== + +/** Max param count */ +static const TInt KMaxParamsCount( 10 ); +const TInt KFileExtensionLength( 4 ); + +_LIT(KLocalizationOneDes, "%U"); +_LIT(KLocalizationMoreDes, "%?U"); +_LIT(KLocalizationOneInt, "%N"); +_LIT(KLocalizationMoreInt, "%?N"); + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CHnMdLocalization::ConstructL() + { + iCoeEnv = CCoeEnv::Static(); + ASSERT( iCoeEnv ); + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CHnMdLocalization* CHnMdLocalization::NewL() + { + CHnMdLocalization* self = CHnMdLocalization::NewLC(); + CleanupStack::Pop( self ); + return self; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CHnMdLocalization* CHnMdLocalization::NewLC() + { + CHnMdLocalization* self = new( ELeave ) CHnMdLocalization; + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CHnMdLocalization::AppendLocalizationsL( TXmlEngElement aElement ) + { + RXmlEngNodeList< TXmlEngElement > children; + CleanupClosePushL( children ); + aElement.GetChildElements( children ); + + RPointerArray tempArray; + CleanupClosePushL( tempArray ); + TInt count = children.Count(); + for ( TInt i( 0 ); i < count; i++ ) + { + TXmlEngElement child = children.Next(); + + if ( !child.Name().Compare( KLocalizationElementName8 ) ) + { + RBuf8 namespac; + CleanupClosePushL( namespac ); + if ( child.HasAttributeL( KNameSpaceAttrName8 ) ) + { + HnUtils::SetAttributeL( child, KNameSpaceAttrName8, namespac ); + if ( !IsDuplicateL( namespac ) ) + { + CHnMdLocalizationElement* element = + CHnMdLocalizationElement::NewL( child ); + + AppendElementL( element ); // ownership transfered + } + } + CleanupStack::PopAndDestroy( &namespac ); + } + } + + CleanupStack::PopAndDestroy( &tempArray ); + CleanupStack::PopAndDestroy( &children ); + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +const CHnMdLocalizationElement* CHnMdLocalization::ElementByNamespace( + const TDesC& aNamespace ) const + { + TInt count = iInternalLocalization.Count(); + const CHnMdLocalizationElement* element = NULL; + + for ( TInt i = 0; i < count; i++ ) + { + const CHnMdLocalizationElement* tmp = iInternalLocalization[i]; + if ( !tmp->Namespace().Compare( aNamespace) ) + { + element = tmp; + break; + } + } + if( !element ) + { + count = iDynamicLocalization.Count(); + + for ( TInt i = 0; i < count; i++ ) + { + const CHnMdLocalizationElement* tmp = iDynamicLocalization[i]; + if ( !tmp->Namespace().Compare( aNamespace) ) + { + element = tmp; + break; + } + } + } + + return element; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CHnMdLocalization::CHnMdLocalization() + { + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +CHnMdLocalization::~CHnMdLocalization() + { + iDynamicLocalization.ResetAndDestroy(); + for( TInt i( 0 ); i < iDynamicOffset.Count(); i++ ) + { + iCoeEnv->DeleteResourceFile( iDynamicOffset[i] ); + } + iDynamicOffset.Close(); + + iInternalLocalization.ResetAndDestroy(); + for( TInt i( 0 ); i < iInternalOffset.Count(); i++ ) + { + iCoeEnv->DeleteResourceFile( iInternalOffset[i] ); + } + iInternalOffset.Close(); + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CHnMdLocalization::ReloadResourceFilesL() + { + for( TInt i( 0 ); i < iDynamicLocalization.Count(); i++ ) + { + iDynamicLocalization[i]->LocateLanguageFileL(); + if( iDynamicLocalization[i]->SourcePath() ) + { + TInt offset( 0 ); + TRAPD( err, offset = iCoeEnv->AddResourceFileL( + *(iDynamicLocalization[i]->SourcePath()) ) ); + if ( !err ) + { + iDynamicOffset.AppendL( offset ); + } + } + } + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CHnMdLocalization::ReleaseResourceFiles() + { + iDynamicLocalization.ResetAndDestroy(); + for( TInt i( 0 ); i < iDynamicOffset.Count(); i++ ) + { + iCoeEnv->DeleteResourceFile( iDynamicOffset[i] ); + } + iDynamicOffset.Reset(); + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +void CHnMdLocalization::AppendElementL( CHnMdLocalizationElement* aElement ) + { + if( IsInternalL( aElement->Source() ) ) + { + iInternalLocalization.AppendL( aElement ); + if( IsResourceFile (aElement->Source()) ) + { + TInt offset( 0 ); + TRAPD( err, offset = iCoeEnv->AddResourceFileL( *(aElement->SourcePath()) ) ); + if ( !err ) + { + iInternalOffset.AppendL( offset ); + } + } + } + else + { + iDynamicLocalization.AppendL( aElement ); + if( IsResourceFile (aElement->Source()) ) + { + TInt offset( 0 ); + TRAPD( err, offset = iCoeEnv->AddResourceFileL( *(aElement->SourcePath()) ) ); + if ( !err ) + { + iDynamicOffset.AppendL( offset ); + } + } + } + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TBool CHnMdLocalization::IsDuplicateL( TDesC8& aNamespace ) + { + HBufC* namespac = HnConvUtils::Str8ToStrLC( aNamespace ); + TBool isDuplicate( IsDuplicateL( *namespac ) ); + CleanupStack::PopAndDestroy( namespac ); + return isDuplicate; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TBool CHnMdLocalization::IsDuplicateL( TDesC& aNamespace ) + { + TBool isDuplicate( EFalse ); + + if ( ElementByNamespace( aNamespace ) != NULL ) + { + isDuplicate = ETrue; + } + + return isDuplicate; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TBool CHnMdLocalization::IsInternalL( const TDesC& aName ) + { + TBool isInternal( EFalse ); + _LIT( KDot, "." ); + + TInt offset( aName.Find( KDot ) ); + if( offset != KErrNotFound ) + { + if( aName.Left( offset ).Compare( KFolderSuite ) == KErrNone ) + { + isInternal = ETrue; + } + } + + return isInternal; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +TBool CHnMdLocalization::IsResourceFile( const TDesC& aFileName ) + { + TInt pos = aFileName.Find( KExtension ); + if( aFileName.Right( KFileExtensionLength ).Compare( KExtensionRsc ) ) + { + TBuf<2> tail; + tail.Copy(aFileName.Right(2)); + for (TInt i = 0; i < tail.Length(); i++ ) + { + TChar c = tail[i]; + if ( !c.IsDigit() ) + { + pos = KErrNotFound; + break; + } + } + } + return pos == ( aFileName.Length() - KFileExtensionLength ); + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +HBufC* CHnMdLocalization::LoadL( const TDesC& aResourceName, + const CDesC16Array* aDesParams, const CArrayFix* aIntParams ) + { + TInt position = aResourceName.Locate(':'); + HBufC* res = NULL; + if( position!= KErrNotFound ) + { + TPtrC resourceName = aResourceName.Mid(position + 1); + TPtrC locName = aResourceName.Left(position); + + const CHnMdLocalizationElement* localization = + ElementByNamespace( locName ); + // if there is not namaspace defined, check may it is file in format + // myapp.rsc:id + if (!localization && !IsDuplicateL( locName ) && IsResourceFile( locName )) + { + // let's try to add namespace + CHnMdLocalizationElement* element = + CHnMdLocalizationElement::NewL( locName, locName); + AppendElementL(element); // ownership transfered + localization = ElementByNamespace( locName ); + } + + if( localization && IsResourceFile( localization->Source() ) && localization->SourceExists() ) + { + HBufC8* resourceName8 = HBufC8::NewLC(resourceName.Length()); + resourceName8->Des().Copy(resourceName); + TInt resourceId (KErrNotFound); + TRAPD(err, resourceId = + const_cast(localization)->FindResourceIdL(resourceName8) ); + if ( err != KErrNone ) // maybe it was only number + { + err = HnConvUtils::Str8ToInt(*resourceName8, resourceId); + } + User::LeaveIfError(err); + if ( iCoeEnv->IsResourceAvailableL( resourceId ) ) + { + res = iCoeEnv->AllocReadResourceL( resourceId ); + } + + CleanupStack::PopAndDestroy( resourceName8 ); + } + } + + if (!res) // it mean that we dont have localization item for it + { + res = aResourceName.AllocL(); + } + if ((aDesParams && aDesParams->Count()) || + (aIntParams && aIntParams->Count())) + { + CleanupStack::PushL(res); + HBufC* formatted = FormatTextL(*res, aDesParams, aIntParams); + CleanupStack::PopAndDestroy(res); + res = formatted; + } + + return res; + } + +// --------------------------------------------------------------------------- +// +// --------------------------------------------------------------------------- +// +HBufC* CHnMdLocalization::FormatTextL( const TDesC& aTextToFormat, + const CDesC16Array* aDesParams, const CArrayFix* aIntParams ) + { + HBufC* res = aTextToFormat.AllocL(); + TInt noParams(0); + + if (aDesParams) + noParams += aDesParams->Count(); + if (aIntParams) + noParams += aIntParams->Count(); + + if (noParams > KMaxParamsCount) + User::Leave( KErrNotSupported ); + + // let's check if we have descriptors to format + if( aDesParams && aDesParams->Count() ) + { + // if we have only one we match to %U + if (aDesParams->Count() == 1) + { + if ( res->FindC(KLocalizationOneDes) != KErrNotFound ) + { + TPtrC16 param = aDesParams->MdcaPoint(0); + HBufC* dest = HBufC::NewL( res->Length() + + param.Length() * KMaxParamsCount ); + TPtr destDes(dest->Des()); + StringLoader::Format( destDes, *res, -1, param ); + delete res; + res = dest; + } + } + // and we match for format %(index)U + TBufC<3> descformat(KLocalizationMoreDes); + TInt desIndexUsed(0); + for (TInt i = 0; i < noParams && desIndexUsed < aDesParams->Count(); i++) + { + descformat.Des()[1] = '0'+ i; // replace index infromation + if ( res->FindC( descformat ) != KErrNotFound ) + { + + TPtrC16 param = aDesParams->MdcaPoint(desIndexUsed++); + HBufC* dest = HBufC::NewL( res->Length() + + param.Length() * KMaxParamsCount ); + TPtr destDes(dest->Des()); + StringLoader::Format( destDes, *res, i, param ); + delete res; + res = dest; + } + } + } + // let's check if we have numbers to format + if( aIntParams && aIntParams->Count() ) + { + // if we have only one we match to %N + if (aIntParams->Count() == 1) + { + if ( res->FindC(KLocalizationOneInt) != KErrNotFound ) + { + HBufC* dest = HBufC::NewL( res->Length() + + sizeof(TInt) * KMaxParamsCount ); + TPtr destDes(dest->Des()); + StringLoader::Format( destDes, *res, -1, aIntParams->At(0) ); + delete res; + res = dest; + } + } + // and we match for format %(index)N + TBufC<3> format(KLocalizationMoreInt); + TInt numberUsed(0); + for (TInt i = 0; i < noParams && numberUsed < aIntParams->Count(); i++) + { + format.Des()[1] = '0'+ i; + if ( res->FindC(format) != KErrNotFound ) + { + HBufC* dest = HBufC::NewL( res->Length() + + sizeof(TInt)* KMaxParamsCount ); + TPtr destDes(dest->Des()); + StringLoader::Format( destDes, *res, i, aIntParams->At(numberUsed++) ); + delete res; + res = dest; + } + } + } + return res; + } + +