idlehomescreen/xmluicontroller/src/aixmluiutils.cpp
changeset 0 f72a12da539e
child 2 08c6ee43b396
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/idlehomescreen/xmluicontroller/src/aixmluiutils.cpp	Thu Dec 17 08:40:49 2009 +0200
@@ -0,0 +1,1079 @@
+/*
+* Copyright (c) 2005-2007 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:  Common utility functions
+*
+*/
+
+
+#include "xnchilditeratorbuilder.h"
+#include "xnnodeappif.h"
+#include "xnproperty.h"
+#include "xndomlist.h"
+#include "mxndomlistitem.h"
+#include "xndomproperty.h"
+#include "xndompropertyvalue.h"
+#include "xnuiengineappif.h"
+
+#include <AknsItemID.h>
+#include <AknsUtils.h>
+#include <AknsSkinInstance.h>
+#include <gulicon.h>
+#include <SVGEngineInterfaceImpl.h>
+#include <gdi.h>
+#include <mifconvdefs.h>
+#include "xnnode.h"	
+
+#include "aixmluiutils.h"
+#include "aixmluiconstants.h"
+#include "csspropertymap.h"
+#include "aipolicyelement.h"
+#include "transaction.h"
+#include "debug.h"
+
+#include "xnbreadthfirsttreeiterator.h"
+namespace
+    {
+    
+    /**
+     * CSS Property value update types.
+     */
+    enum TPropertyUpdateType
+        {
+        EAbsoluteValue = 0,
+        EAddition,
+        ESubtraction,
+        EIncrementalAddition,
+        EIncrementalSubtraction
+        };
+    
+    /**
+     *
+     */
+    _LIT8( KAdditionOperator, "+" );
+
+    _LIT8( KIncrementalAdditionOperator, "++" );
+    
+    _LIT8( KSubtractionOperator, "-" );
+
+    _LIT8( KIncrementalSubtractionOperator, "--" );
+    
+    const TInt KLenAddSubOperator = 1;
+
+    const TInt KLenIncrementalOperator = 2;
+         
+    _LIT( KMIFExtension, ".mif" );
+    
+   // _LIT( KSVGExtension, ".svg" );
+    
+    _LIT( KHashmark, "#" );
+    
+    const TUint8 KDoubleQuote = '"';
+    
+    const TUint8 KSingleQuote = '\'';
+    
+    const TInt KLenDoubleQuotes = 2;
+    const TInt KDepthT = 1;
+    
+    class TIconProvider : public MAknIconFileProvider
+    {
+    public:
+        /**
+        * Constructor
+        * @param aFile File handle to use
+        */
+        TIconProvider(RFile& aFile) : iFile(aFile)
+            {
+            }
+    public:
+
+        /**
+        * Destructor.
+        */
+        virtual ~TIconProvider()
+            {
+            iFile.Close();
+            }
+        // Functions from base classes
+        /**
+        * From MAknIconFileProvider Returns an open file handle to the icon file.
+        * This method should leave if an icon file with specified type does
+        * not exist. That may be the case e.g. with MBM file,
+        * if there are no bitmap icons.
+        *
+        * Note! RFs::ShareProtected must be called to the RFs instance used
+        * for opening the file.
+        *
+        * @param aFile Icon file should be opened in this file handle, which
+        * is an empty file handle, when the AknIcon framework calls this method.
+        * The AknIcon framework takes care of closing the file handle after
+        * having used it.
+        * @param aType Icon file type.
+        */
+        virtual void RetrieveIconFileHandleL(
+            RFile& aFile, const TIconFileType /*aType*/ )
+            {
+            aFile.Duplicate(iFile);
+            }
+
+        /**
+        * From MAknIconFileProvider With this method, AknIcon framework informs that it does not use
+        * this MAknIconFileProvider instance any more. After this call,
+        * it is ok to delete the object. This can be implemented simply
+        * e.g. by deleting self in this callback.
+        * Normally, this callback is invoked when the icon in question
+        * is deleted.
+        * Note, however, that if the same MAknIconFileProvider instance is
+        * supplied in multiple CreateIcon calls, then it must be accessible
+        * by AknIcon framework until it has signalled a matching amount
+        * of these callbacks.
+        */
+        virtual void Finished()
+            {
+            iFile.Close();
+            delete this;
+            }
+    private:
+        // file to use
+        RFile iFile;        
+    }; 
+    
+     /**
+     * Tests if string ends with given pattern
+     * 
+     * @param aString input string
+     * @param aPattern test pattern
+     * @return ETrue if string ends with given pattern.
+     */
+    TBool EndsWith( const TDesC8& aString, const TDesC8& aPattern )
+        {
+        return ( aString.Right( aPattern.Length() ) == aPattern );
+        }
+
+  /**
+     * Tests if string ends with given pattern
+     * 
+     * @param aString input string
+     * @param aPattern test pattern
+     * @return ETrue if string ends with given pattern.
+     */
+    TBool EndsWith( const TDesC& aString, const TDesC& aPattern )
+        {
+        return ( aString.Right( aPattern.Length() ) == aPattern );
+        }    
+    /**
+     * Removes pattern from the end of string. Function does not validate
+     * that the pattern is in the end of string. It just cuts out the number
+     * of aPattern length characters from the string.
+     *
+     * @param aString input string
+     * @param aPattern pattern
+     * @return string without pattern.
+     */
+    TPtrC8 Strip( const TDesC8& aString, const TDesC8& aPattern )
+        {
+        return aString.Left( aString.Length() - aPattern.Length() );
+        }
+    
+    /**
+     * Selects a proper string data value type
+     */
+    CXnDomPropertyValue::TPrimitiveValueType SelectStringDataType(
+                                                    const TDesC8& aPropertyName,
+                                                    const TDesC8& aPropertyValue )
+        {
+        if ( aPropertyName == XnPropertyNames::style::common::KDisplay
+             && ( aPropertyValue == XnPropertyNames::style::common::display::KBlock
+                  || aPropertyValue == XnPropertyNames::style::common::display::KNone ) )
+            {
+            return CXnDomPropertyValue::EString;
+            }
+        
+        if ( aPropertyName == XnPropertyNames::style::common::KVisibility
+             && ( aPropertyValue == XnPropertyNames::style::common::visibility::KVisible
+                  || aPropertyValue == XnPropertyNames::style::common::visibility::KHidden ) )
+            {
+            return CXnDomPropertyValue::EString;
+            }
+        if ( aPropertyName == XnPropertyNames::style::common::KNavIndex )
+            {
+            return CXnDomPropertyValue::EIdent;
+            }
+            
+        return CXnDomPropertyValue::EUnknown;
+        }
+    
+    /**
+     * Validates string
+     */
+    TBool IsValidCssString( const TDesC8& aString )
+        {
+        // Null string or unquoted string is not a CSS string
+        if ( aString.Length() < KLenDoubleQuotes )
+            {
+            return EFalse;
+            }
+        
+        const TUint8 quotationMark( aString[0] );    
+        if ( ( quotationMark == KDoubleQuote || quotationMark == KSingleQuote )
+             && aString[ aString.Length() - 1 ] == quotationMark )
+            {
+            return ETrue;
+            }
+        
+        return EFalse;
+        }
+    
+    /**
+     * Removes extra quotes from strings. Assumes that the string is quoted.
+     */ 
+    TPtrC8 RemoveQuotes( const TDesC8& aString )
+        {
+        return aString.Mid( 1, aString.Length() - KLenDoubleQuotes );
+        }
+    
+    /**
+     * Parses a primitive data type of a string.
+     *
+     * @param aInputValue[in]   input value with primitive type information.
+     * @param aStringValue[out] value without type information.
+     * @param aFloatValue       value as float if type is a numerical type.
+     * @param aPrimitiveType[out]        primitive type.
+     * @param aUpdateType[out]  update type
+     */
+    void ParseCSSValue( const TDesC8& aInputValue,
+                        TPtrC8& aStringValue,
+                        TReal& aFloatValue,
+                        CXnDomPropertyValue::TPrimitiveValueType& aPrimitiveType,
+                        TPropertyUpdateType& aUpdateType )
+        {
+        aPrimitiveType = CXnDomPropertyValue::EUnknown;
+        aUpdateType = EAbsoluteValue;
+        
+        TPtrC8 unit;
+        
+        // Recognise type
+        
+        if ( EndsWith( aInputValue, AiUiDef::xml::css::KPercentage ) )
+            {
+            unit.Set( AiUiDef::xml::css::KPercentage );
+            aPrimitiveType = CXnDomPropertyValue::EPercentage;
+            }
+        else if ( EndsWith( aInputValue, AiUiDef::xml::css::KPixel ) )
+            {
+            unit.Set( AiUiDef::xml::css::KPixel );
+            aPrimitiveType = CXnDomPropertyValue::EPx;
+            }
+        else if ( EndsWith( aInputValue, AiUiDef::xml::css::KUnitValue ) )
+            {
+            unit.Set( AiUiDef::xml::css::KUnitValue );
+            aPrimitiveType = CXnDomPropertyValue::EUnitValue;
+            }
+        else if ( IsValidCssString( aInputValue ) )
+            {
+            aPrimitiveType = CXnDomPropertyValue::EString;
+            aStringValue.Set( RemoveQuotes( aInputValue ) );
+            return;
+            }
+            
+        // Validate type
+        switch ( aPrimitiveType )
+            {
+            // Supported float types
+            case CXnDomPropertyValue::EPercentage:
+            case CXnDomPropertyValue::EPx:
+            case CXnDomPropertyValue::EUnitValue: // fallthrough
+                {
+                // Remove unit
+                aStringValue.Set( Strip( aInputValue, unit ) );
+                
+                // Determine update type
+                if ( aStringValue.Find( KIncrementalAdditionOperator ) == 0 )
+                    {
+                    aUpdateType = EIncrementalAddition;
+                    
+                    // Remove sign
+                    aStringValue.Set( aStringValue.Mid( KLenIncrementalOperator ) );
+                    }
+                else if ( aStringValue.Find( KAdditionOperator ) == 0 )
+                    {
+                    aUpdateType = EAddition;
+                    
+                    // Remove sign
+                    aStringValue.Set( aStringValue.Mid( KLenAddSubOperator ) );
+                    }
+                else if ( aStringValue.Find( KIncrementalSubtractionOperator ) == 0 )
+                    {
+                    // Use addition, so only one sign has to be removed
+                    aUpdateType = EAddition;
+                    
+                    aStringValue.Set( aStringValue.Mid( KLenAddSubOperator ) );
+                    }
+                else if ( aStringValue.Find( KSubtractionOperator ) == 0 )
+                    {
+                    // Use addition, so sign does not have to be removed
+                    aUpdateType = EAddition;
+                    }
+
+                if ( TLex8( aStringValue ).Val( aFloatValue ) != KErrNone )
+                    {
+                    // Not a numerical value. Restore value
+                    aPrimitiveType = CXnDomPropertyValue::EUnknown;
+                    aUpdateType = EAbsoluteValue;
+                    aStringValue.Set( aInputValue );
+                    }
+                
+                break;
+                }
+            
+            // string types    
+            default:
+                {
+                aStringValue.Set( aInputValue );
+                break;
+                }
+            
+            }
+        }
+    
+    /**
+     * Updates property value
+     *
+     * @param aValue property value to update.
+     * @param aStringValue new value as string
+     * @param aFloatValue new value as float (for number types)
+     * @param aPrimitiveType type of value
+     * @param aUpdateType type to update the value.
+     */
+    void UpdatePropertyValueL( CXnDomPropertyValue& aValue,
+                               const TDesC8& aStringValue,
+                               const TReal& aFloatValue,
+                               CXnDomPropertyValue::TPrimitiveValueType aPrimitiveType,
+                               TPropertyUpdateType aUpdateType )
+        {
+        switch ( aPrimitiveType )
+            {
+            // Supported float types
+            case CXnDomPropertyValue::EPercentage:
+            case CXnDomPropertyValue::EPx:
+            case CXnDomPropertyValue::EUnitValue: // fallthrough
+                {
+                TReal floatValue( aFloatValue );
+                // Select update type
+                switch ( aUpdateType )
+                    {
+                    case EAddition:  // fallthrough
+                    case EIncrementalAddition:
+                        {
+                        floatValue += aValue.FloatValueL();
+                        break;
+                        }
+                        
+                    case ESubtraction: // fallthrough
+                    case EIncrementalSubtraction:
+                        {
+                        floatValue = aValue.FloatValueL() - aFloatValue;
+                        break;
+                        }
+                    
+                    case EAbsoluteValue:
+                    default:
+                        {
+                        break;
+                        }
+                    }
+                
+                // Set new value as float
+                aValue.SetFloatValueL( aPrimitiveType, floatValue );
+                
+                break;
+                }
+            
+            // string types
+            case CXnDomPropertyValue::EUnknown:
+                {
+                // Use current type
+                aPrimitiveType = Max( aValue.PrimitiveValueType(), CXnDomPropertyValue::EUnknown );
+                
+                // Fall through to update...
+                }
+                
+            default: // fallthrough
+                {
+				if( aPrimitiveType == CXnDomPropertyValue::ENumber )
+					{
+					TReal floatValue;
+					TLex8( aStringValue ).Val( floatValue );
+					aValue.SetFloatValueL( aPrimitiveType, floatValue );
+					}
+				else
+					{
+                    // Set new value as string
+                     aValue.SetStringValueL( aPrimitiveType, aStringValue );
+					}
+                break;
+                }
+            }
+        }
+    
+    /**
+     * Creates a new property.
+     *
+     * @param aUiElement ui element to hold the property.
+     * @param aPropertyName name of the property.
+     * @param aPropertyValue value of the property.
+     */
+    void CreatePropertyL( CXnNodeAppIf& aUiElement,
+                          const TDesC8& aPropertyName,
+                          const TDesC8& aPropertyValue )
+        {
+        // Create new property value and property
+        CXnDomPropertyValue* value = CXnDomPropertyValue::NewL(
+                                                aUiElement.UiEngineL()->StringPool() );
+        CleanupStack::PushL( value );
+        
+        CXnProperty* property = CXnProperty::NewL(
+                                                aPropertyName,
+                                                value,
+                                                aUiElement.UiEngineL()->StringPool() );
+        CleanupStack::Pop( value );
+        CleanupStack::PushL( property );
+        
+        // Parse CSS value
+        TPtrC8 stringValue;
+        TReal floatValue( 0 );
+        CXnDomPropertyValue::TPrimitiveValueType primitiveType(
+                                                CXnDomPropertyValue::EUnknown );
+        TPropertyUpdateType updateType( EAbsoluteValue );
+        
+        ParseCSSValue( aPropertyValue,
+                       stringValue,
+                       floatValue,
+                       primitiveType,
+                       updateType );
+        
+        if ( primitiveType == CXnDomPropertyValue::EUnknown )
+            {
+            primitiveType = SelectStringDataType( aPropertyName, aPropertyValue );
+            }
+            
+        // Update CSS value               
+        UpdatePropertyValueL( *value,
+                              stringValue,
+                              floatValue,
+                              primitiveType,
+                              updateType );
+        
+        // Add property to UI element                      
+        aUiElement.SetPropertyL( property );
+        
+        CleanupStack::Pop( property );
+        }
+    
+    
+    // Icon utilities
+    
+    _LIT( KSkin, "skin" );
+    const TUint KLeftParenthesis = '(';
+    
+    /**
+     * Resolves skin item id from pattern SKIN( <majorId> <minorId> (<colourGroupId>) ).
+     * The colourGroupId in the syntax is optional, and if no value found then
+     * aColourValue will be -1
+     *
+     * @param aItemId skin item id to fill
+     * @param aColourValue colour value to fill. 
+     * @param aPath   skin item id string     
+     * 
+     * @return ETrue if id was succesfully parsed.
+     */
+    TBool ResolveSkinItemId( TAknsItemID& aItemId, TInt& aColourValue, const TDesC& aPath )
+        {
+        // Syntax: skin( <major> <minor> )
+        TInt pos = aPath.FindF( KSkin );
+        aColourValue = -1;
+        if( pos != KErrNotFound )
+            {
+            // Skip skin token
+            pos += KSkin().Length();
+            
+            // Initialize lexer
+            TLex lex( aPath.Mid( pos ) );
+            lex.SkipSpace();
+            
+            // Check left parenthesis
+            if (lex.Get() != KLeftParenthesis )
+                {
+                return EFalse;
+                }
+            
+            lex.SkipSpace();
+            
+            TInt majorId( 0 );        
+            TInt minorId( 0 );
+            
+            // Resolve major id        
+            TInt error = lex.Val( majorId );
+            
+            // Resolve minor id
+            lex.SkipSpace();
+            error |= lex.Val( minorId );
+            
+            // initilize skin item id object
+            aItemId.Set( majorId, minorId );
+            
+            lex.SkipSpace();
+            TInt colorError = lex.Val( aColourValue );
+            if ( colorError != KErrNone || aColourValue < 0)
+                {
+                aColourValue = -1;
+                }
+                        
+            // Check error
+            return ( error == KErrNone );
+            }
+         
+        return EFalse;
+        }
+        
+	 /**
+     * Resolves MIF files filename and id from syntax
+     * mif_filename.mif#id. If the syntax is incorrect
+     * aId is -1 and filename zeroed and EFalse is returned
+     *
+     * @param aPath The path to extract the data from
+     * @param aId	Id to fill
+     * @param aFilename Filename to fill
+     * @return ETrue if id was succesfully parsed.
+     */
+    TBool ResolveMifIdAndPathL( const TDesC& aPath, TInt& aId, TDes& aFilename )
+        {
+        // Syntax: mif_filename.mif#index
+        TInt pos = aPath.FindF( KHashmark );
+        aFilename.Zero();
+        if( pos != KErrNotFound )
+            {
+            aFilename = (aPath.Left(pos));
+            if ( ! EndsWith( aFilename, KMIFExtension ) )
+            	{
+            	aFilename.Zero();
+            	return EFalse;
+            	}
+            
+            TLex lex(aPath.Mid(pos+1));
+            TInt error = lex.Val(aId);
+            if ( error != KErrNone )
+            	{
+            	aId = -1;
+            	return EFalse;
+            	}
+            return ETrue;
+            }
+           return EFalse;
+            
+            
+      
+        }        
+
+    /**
+    * Loads a bitmap icon from a MIF-file loaded to Xuikon by using
+    * <FileResource> tag
+    *
+    * @param aNode Resource node
+    * @param aFilename The filename to load
+    * @param aBitmap The bitmap to fill
+    * @param aBitmapMask The mask to fill
+    * @param aMifId The id of the icon in the MIF-file
+    *
+	* @return KErrNone if loading was successful KErrNotFound if not
+	*/
+    TInt LoadMIFBitmapL( CXnNodeAppIf &aNode, 
+    	const TDesC &aPath,
+    	CFbsBitmap*& aBitmap,
+    	CFbsBitmap*& aBitmapMask,
+    	TInt aMifId )
+    	{
+    	RFile tempFile;
+    	    	
+    	if ( aMifId < 0 )
+    		{
+    		return KErrNotFound;
+    		}
+    	  
+    	TInt err = aNode.UiEngineL()->GetThemeResource( aPath, tempFile );
+
+		if ( err != KErrNone )
+			{
+			tempFile.Close();
+			return err;
+			}
+    	
+    	//Requires an open RFile handle
+    	TIconProvider *iconProvider = 
+    		new (ELeave) TIconProvider(tempFile);
+
+    	CleanupStack::PushL( iconProvider );
+    	// Mask is next after bitmap
+        AknIconUtils::CreateIconL(aBitmap,aBitmapMask, *iconProvider,
+            aMifId+KMifIdFirst,aMifId+KMifIdFirst+1);
+
+    	CleanupStack::Pop(iconProvider); // iconProvider
+          
+        return KErrNone;
+    	}
+    }
+
+namespace AiXmlUiController
+{
+
+RPointerArray< CXnNodeAppIf >
+    FindPropertyElementL( CXnNodeAppIf& aUiElement, const TDesC8& aPropertyClass )
+    {
+    CXnBreadthFirstTreeIterator< CXnNodeAppIf >* iterator = 
+            CXnBreadthFirstTreeIterator< CXnNodeAppIf >::NewL( aUiElement, 
+            KDepthT );
+    CleanupDeletePushL( iterator );
+    
+    RPointerArray< CXnNodeAppIf > nodes;
+    
+    CleanupClosePushL( nodes );
+    
+    CXnNodeAppIf* child = iterator->Value() ;
+    
+    while ( child )
+        {
+        CXnProperty* classProperty = child->GetPropertyL(
+                                            XnPropertyNames::common::KClass );
+        
+        if ( classProperty && ( classProperty->StringValue() == aPropertyClass ) )
+            {
+            User::LeaveIfError( nodes.Append( child ) );
+            }
+        
+        child = iterator->NextL();
+        }
+    
+    CleanupStack::Pop( &nodes );
+    
+    CleanupStack::PopAndDestroy( iterator );
+    
+    return nodes;
+    }
+
+void FindPropertyElementL( RPointerArray< CXnNodeAppIf >& aArray, CXnNodeAppIf& aUiElement, const TDesC8& aPropertyClass )
+    {
+    CXnBreadthFirstTreeIterator< CXnNodeAppIf >* iterator = 
+            CXnBreadthFirstTreeIterator< CXnNodeAppIf >::NewL( aUiElement,
+            KDepthT );
+    CleanupDeletePushL( iterator );
+       
+    CXnNodeAppIf* child =  iterator->Value();
+    
+    while ( child )
+        {
+        CXnProperty* classProperty = child->GetPropertyL(
+                                            XnPropertyNames::common::KClass );
+        
+        if ( classProperty && ( classProperty->StringValue() == aPropertyClass ) )
+            {
+            User::LeaveIfError( aArray.Append( child ) );
+            }
+        
+        child = iterator->NextL();
+        }
+   
+    CleanupStack::PopAndDestroy( iterator );
+    }
+
+HBufC* PropertyValueL( const CXnNodeAppIf& aUiElement,
+                       const TDesC8& aPropertyName )
+    {
+    CXnProperty* property = aUiElement.GetPropertyL( aPropertyName );
+    
+    if ( property )
+        {
+        return property->StringValueL();
+        }
+        
+    return NULL;
+    }
+
+const TDesC8* PropertyValue( const CXnNodeAppIf& aUiElement,
+                             const TDesC8& aPropertyName )
+    {
+    CXnProperty* property = NULL;
+    TRAP_IGNORE( property = aUiElement.GetPropertyL( aPropertyName ) );
+    
+    if ( property )
+        {
+        return &property->StringValue();
+        }
+        
+    return NULL;
+    }
+
+void SetPropertyL( CXnNodeAppIf& aUiElement,
+                   const TDesC8& aPropertyName,
+                   const TDesC8& aPropertyValue,
+                   CCssPropertyMap& aPropertyMap )
+    {
+    CXnProperty* property = aUiElement.GetPropertyL( aPropertyName );
+    
+    if ( !property )
+        {
+        // Create new property
+        CreatePropertyL( aUiElement, aPropertyName, aPropertyValue );
+        return;
+        }
+    
+    // Clone property for update
+    property = property->CloneL();
+    CleanupStack::PushL( property );
+    
+    CXnDomProperty* domProperty = property->Property();
+    MXnDomListItem* item = domProperty->PropertyValueList().First();
+
+    CXnDomPropertyValue* value = static_cast< CXnDomPropertyValue* >( item );
+    
+    if ( value )
+        {
+        TPtrC8 stringValue;
+        TReal floatValue(0);
+                
+        CXnDomPropertyValue::TPrimitiveValueType primitiveType(
+                                                CXnDomPropertyValue::EUnknown );
+        TPropertyUpdateType updateType( EAbsoluteValue );
+        
+        ParseCSSValue( aPropertyValue,
+                       stringValue,
+                       floatValue,
+                       primitiveType,
+                       updateType );
+        
+        if ( primitiveType == CXnDomPropertyValue::EUnknown )
+            {
+            primitiveType = SelectStringDataType( aPropertyName, aPropertyValue );
+            }
+        
+        if ( updateType != EAbsoluteValue &&
+             updateType != EIncrementalAddition &&
+             updateType != EIncrementalSubtraction )
+            {
+            // Use original value from property map
+            const TDesC8* elementId = PropertyValue( aUiElement,
+                                                     XnPropertyNames::common::KId );
+            CXnDomPropertyValue* original = NULL;
+            if( elementId )
+                {
+                original = aPropertyMap.FindPropertyValue(
+                                                        *elementId,
+                                                        aPropertyName );
+                }
+            else
+                {
+                User::Leave( KErrNotSupported );
+                }
+            
+            if ( original )
+                {
+                // Clone original value 
+                value = original->CloneL();
+                CleanupStack::PopAndDestroy( property ); // Old clone
+                CleanupStack::PushL( value );
+                property = CXnProperty::NewL( aPropertyName,
+                                              value,
+                                              aUiElement.UiEngineL()->StringPool() );
+                CleanupStack::Pop( value );
+                CleanupStack::PushL( property );
+                }
+            else
+                {
+                // store original value
+                aPropertyMap.StorePropertyValueL( *elementId, *property );
+                }
+            }
+        
+        UpdatePropertyValueL( *value,
+                              stringValue,
+                              floatValue,
+                              primitiveType,
+                              updateType );
+            
+            aUiElement.SetPropertyL( property );
+            CleanupStack::Pop( property );
+        }
+    else
+        {
+        User::Leave( KErrNotSupported );
+        }
+    }
+
+void SetPropertiesToHashMapL( RArray<TAiPolicyElement>& aArray,
+                              CCssPropertyMap& aPropertyMap,
+                              RPropertyHashMap& aPropertyHashMap )
+    {
+    TBool propertyAdded = EFalse;
+    if( !aArray.Count() )
+        {
+        return;
+        }
+        
+    CXnNodeAppIf& uiElement = aArray[0].Target();
+    RPointerArray<CXnProperty>* propertyArray = NULL;
+    
+    propertyArray = aPropertyHashMap.Find( uiElement );
+    
+    if( !propertyArray )
+        {
+        // Create new one.
+        propertyArray = new(ELeave) RPropertyArray;
+        CleanupStack::PushL( propertyArray );
+        aPropertyHashMap.InsertL( &uiElement, propertyArray );
+        CleanupStack::Pop( propertyArray );
+        }
+    
+    for( TInt i = 0; i < aArray.Count(); ++i )
+        {
+        const TDesC8& propertyName = aArray[i].Name();
+        const TDesC8& propertyValue = aArray[i].Value();
+
+        CXnProperty* property = uiElement.GetPropertyL( propertyName );
+        
+        if ( !property )
+            {
+            // Create new property
+            CreatePropertyL( uiElement, propertyName, propertyValue );
+            propertyAdded = ETrue;
+            continue;
+            }
+        
+        // Clone property for update
+        property = property->CloneL();
+        CleanupStack::PushL( property );
+        
+        CXnDomProperty* domProperty = property->Property();
+        MXnDomListItem* item = domProperty->PropertyValueList().First();
+
+        CXnDomPropertyValue* value = static_cast< CXnDomPropertyValue* >( item );
+        
+        if ( value )
+            {
+            TPtrC8 stringValue;
+            TReal floatValue(0);
+                    
+            CXnDomPropertyValue::TPrimitiveValueType primitiveType(
+                                                    CXnDomPropertyValue::EUnknown );
+            TPropertyUpdateType updateType( EAbsoluteValue );
+            
+            ParseCSSValue( propertyValue,
+                           stringValue,
+                           floatValue,
+                           primitiveType,
+                           updateType );
+            
+            if ( primitiveType == CXnDomPropertyValue::EUnknown )
+                {
+                primitiveType = SelectStringDataType( propertyName, propertyValue );
+                }
+            
+            if ( updateType != EAbsoluteValue )
+                {
+                // Use original value from property map
+                const TDesC8* elementId = PropertyValue( uiElement,
+                                                         XnPropertyNames::common::KId );
+                CXnDomPropertyValue* original = NULL;
+                if( elementId )
+                    {
+                    original = aPropertyMap.FindPropertyValue(
+                                                            *elementId,
+                                                            propertyName );
+                    }
+                else
+                    {
+                    User::Leave( KErrNotSupported );
+                    }
+                
+                if ( original )
+                    {
+                    // Clone original value 
+                    value = original->CloneL();
+                    CleanupStack::PopAndDestroy( property ); // Old clone
+                    CleanupStack::PushL( value );
+                    property = CXnProperty::NewL( propertyName,
+                                                  value,
+                                                  uiElement.UiEngineL()->StringPool() );
+                    CleanupStack::Pop( value );
+                    CleanupStack::PushL( property );
+                    }
+                else
+                    {
+                    // store original value
+                    aPropertyMap.StorePropertyValueL( *elementId, *property );
+                    }
+                }
+            
+                UpdatePropertyValueL( *value,
+                                      stringValue,
+                                      floatValue,
+                                      primitiveType,
+                                      updateType );
+                propertyArray->AppendL( property );
+                CleanupStack::Pop( property );
+            }
+        }
+        
+    if( !propertyAdded && !propertyArray->Count() )
+        {
+        User::Leave( KErrNotSupported );
+        }
+    }
+
+void SetPropertyArraysL( RPropertyHashMap& aPropertyHashMap )
+    {
+    TPtrHashMapIter<CXnNodeAppIf, RPropertyArray> iter( aPropertyHashMap );
+    iter.Reset();
+    
+    const CXnNodeAppIf* targetNode = (const CXnNodeAppIf*)iter.NextKey();
+    
+    while( targetNode )
+        {
+        CXnNodeAppIf* targetNonConst = const_cast<CXnNodeAppIf*>(targetNode);
+        RPointerArray<CXnProperty>* propertyArray = aPropertyHashMap.Find(*targetNode);
+        if( propertyArray )
+            {
+            targetNonConst->SetPropertyArrayL( propertyArray ); // Assumes ownership
+                                                                // of CXnProperty's in the array
+                                                                // but not the array itself.
+            propertyArray->Close(); // Close and delete the array to free all memory.
+            delete propertyArray;
+            aPropertyHashMap.Remove( targetNode ); // Remove the key from hash map
+                                                   // as the array is now destroyed.
+            iter.Reset(); // Reset the iterator to avoid panic.
+            }
+        targetNode =  (CXnNodeAppIf*)iter.NextKey();
+        }
+
+    }
+
+CGulIcon* LoadIconLC( CXnNodeAppIf& aResource )
+    {
+    // Resolve icon path
+    HBufC* pathBuffer = PropertyValueL( aResource, XnPropertyNames::image::KPath );
+    CleanupStack::PushL( pathBuffer );
+  	
+    LeaveIfNull( pathBuffer, KErrNotFound );
+    
+    CFbsBitmap *bitmap = NULL;
+    CFbsBitmap *mask = NULL;
+    CGulIcon* icon = NULL;
+
+	TFileName fileName;
+	TInt mifId(0);
+  
+  	//Assume that the filetype is not supported
+    TInt err = KErrNotSupported;
+    
+    // Resolve icon id    
+    TAknsItemID iconId;
+    
+    // Possible color index
+    TInt colorValue(-1);
+    
+    TBool inSkin = ResolveSkinItemId( iconId, colorValue, *pathBuffer );
+    
+    // SKIN(<major> <minor> (<optionalColourGroup>))
+    if ( inSkin )
+        {
+        // Load from skin
+        MAknsSkinInstance* skin = AknsUtils::SkinInstance();
+        err = KErrNone;
+        // Load the icon with colour group support but only if it is valid
+        // see AknsConstants.h for these   
+        if ( colorValue >= EAknsCIQsnTextColorsCG1 && 
+             colorValue <= EAknsCIQsnTextColorsCG62 )
+            {
+            CFbsBitmap* bitmap = NULL;
+            CFbsBitmap* mask = NULL;
+            AknsUtils::CreateColorIconLC(
+                skin,
+                iconId,
+                KAknsIIDQsnTextColors,
+                colorValue,
+                bitmap,
+                mask,
+                KNullDesC,  /* no backup */
+                0,          /* no backup */
+                0,          /* no backup */
+                KRgbBlack );
+            
+            if ( bitmap )
+                {
+                icon = CGulIcon::NewL( bitmap, mask );              
+                }
+            else
+                {
+                err = KErrNotFound;
+                }
+            CleanupStack::Pop( 2 ); // bitmap, mask
+            }
+        // No colour group support
+        else
+            {
+            icon = AknsUtils::CreateGulIconL( skin, iconId, KNullDesC, 0, 0 );            
+            }
+
+    	if ( !icon ) // Syntax correct but icon not found
+    		{
+    		err = KErrNotFound;	
+    		} 
+        }
+   	
+	// MIF-file <filename.mif>#<index_in_mif>
+    else if ( ResolveMifIdAndPathL( *pathBuffer, mifId, fileName ) )
+    	{
+		err = LoadMIFBitmapL( aResource, fileName, bitmap, mask, mifId );
+		
+		if ( err == KErrNone && bitmap )
+			{
+			// Ownership of bitmap and mask transferred to CGulIcon
+			icon = CGulIcon::NewL( bitmap, mask );	
+			}
+		else // Syntax correct but the icon was not found
+			{
+			err = KErrNotFound;
+			}
+    	}
+	CleanupStack::PopAndDestroy( pathBuffer );      
+    CleanupStack::PushL( icon );
+    
+  	User::LeaveIfError( err );
+    return icon;
+    }
+    
+void SetPropertyToNodeL( 
+    CXnNodeAppIf& aNode, 
+    const TDesC8& aPropertyName, 
+    const TDesC8& aNewValueString )
+	{
+	// Set defined property to defined node.
+    CXnDomPropertyValue* newValue = CXnDomPropertyValue::NewL(aNode.UiEngineL()->StringPool());
+    CleanupStack::PushL(newValue);
+    newValue->SetStringValueL(CXnDomPropertyValue::EString, aNewValueString);
+    CXnProperty* prop = CXnProperty::NewL(aPropertyName, newValue, aNode.UiEngineL()->StringPool());
+    CleanupStack::PushL(prop);
+	aNode.SetPropertyL(prop);
+    CleanupStack::Pop(prop);
+    CleanupStack::Pop(newValue);				        
+	}
+	
+} // namespace AiXmlUiController