menufw/hierarchynavigator/hnmetadatamodel/src/hnmdlocalization.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:40:49 +0200
changeset 0 f72a12da539e
child 54 1b758917cafc
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* 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;
    }