--- /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 <coemain.h>
+#include <bautils.h>
+#include <StringLoader.h>
+
+#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<CHnMdLocalizationElement> 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<TInt>* 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<CHnMdLocalizationElement*>(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<TInt>* 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;
+ }
+
+