idlehomescreen/xmluicontroller/src/aixmluiutils.cpp
changeset 0 f72a12da539e
child 2 08c6ee43b396
equal deleted inserted replaced
-1:000000000000 0:f72a12da539e
       
     1 /*
       
     2 * Copyright (c) 2005-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Common utility functions
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "xnchilditeratorbuilder.h"
       
    20 #include "xnnodeappif.h"
       
    21 #include "xnproperty.h"
       
    22 #include "xndomlist.h"
       
    23 #include "mxndomlistitem.h"
       
    24 #include "xndomproperty.h"
       
    25 #include "xndompropertyvalue.h"
       
    26 #include "xnuiengineappif.h"
       
    27 
       
    28 #include <AknsItemID.h>
       
    29 #include <AknsUtils.h>
       
    30 #include <AknsSkinInstance.h>
       
    31 #include <gulicon.h>
       
    32 #include <SVGEngineInterfaceImpl.h>
       
    33 #include <gdi.h>
       
    34 #include <mifconvdefs.h>
       
    35 #include "xnnode.h"	
       
    36 
       
    37 #include "aixmluiutils.h"
       
    38 #include "aixmluiconstants.h"
       
    39 #include "csspropertymap.h"
       
    40 #include "aipolicyelement.h"
       
    41 #include "transaction.h"
       
    42 #include "debug.h"
       
    43 
       
    44 #include "xnbreadthfirsttreeiterator.h"
       
    45 namespace
       
    46     {
       
    47     
       
    48     /**
       
    49      * CSS Property value update types.
       
    50      */
       
    51     enum TPropertyUpdateType
       
    52         {
       
    53         EAbsoluteValue = 0,
       
    54         EAddition,
       
    55         ESubtraction,
       
    56         EIncrementalAddition,
       
    57         EIncrementalSubtraction
       
    58         };
       
    59     
       
    60     /**
       
    61      *
       
    62      */
       
    63     _LIT8( KAdditionOperator, "+" );
       
    64 
       
    65     _LIT8( KIncrementalAdditionOperator, "++" );
       
    66     
       
    67     _LIT8( KSubtractionOperator, "-" );
       
    68 
       
    69     _LIT8( KIncrementalSubtractionOperator, "--" );
       
    70     
       
    71     const TInt KLenAddSubOperator = 1;
       
    72 
       
    73     const TInt KLenIncrementalOperator = 2;
       
    74          
       
    75     _LIT( KMIFExtension, ".mif" );
       
    76     
       
    77    // _LIT( KSVGExtension, ".svg" );
       
    78     
       
    79     _LIT( KHashmark, "#" );
       
    80     
       
    81     const TUint8 KDoubleQuote = '"';
       
    82     
       
    83     const TUint8 KSingleQuote = '\'';
       
    84     
       
    85     const TInt KLenDoubleQuotes = 2;
       
    86     const TInt KDepthT = 1;
       
    87     
       
    88     class TIconProvider : public MAknIconFileProvider
       
    89     {
       
    90     public:
       
    91         /**
       
    92         * Constructor
       
    93         * @param aFile File handle to use
       
    94         */
       
    95         TIconProvider(RFile& aFile) : iFile(aFile)
       
    96             {
       
    97             }
       
    98     public:
       
    99 
       
   100         /**
       
   101         * Destructor.
       
   102         */
       
   103         virtual ~TIconProvider()
       
   104             {
       
   105             iFile.Close();
       
   106             }
       
   107         // Functions from base classes
       
   108         /**
       
   109         * From MAknIconFileProvider Returns an open file handle to the icon file.
       
   110         * This method should leave if an icon file with specified type does
       
   111         * not exist. That may be the case e.g. with MBM file,
       
   112         * if there are no bitmap icons.
       
   113         *
       
   114         * Note! RFs::ShareProtected must be called to the RFs instance used
       
   115         * for opening the file.
       
   116         *
       
   117         * @param aFile Icon file should be opened in this file handle, which
       
   118         * is an empty file handle, when the AknIcon framework calls this method.
       
   119         * The AknIcon framework takes care of closing the file handle after
       
   120         * having used it.
       
   121         * @param aType Icon file type.
       
   122         */
       
   123         virtual void RetrieveIconFileHandleL(
       
   124             RFile& aFile, const TIconFileType /*aType*/ )
       
   125             {
       
   126             aFile.Duplicate(iFile);
       
   127             }
       
   128 
       
   129         /**
       
   130         * From MAknIconFileProvider With this method, AknIcon framework informs that it does not use
       
   131         * this MAknIconFileProvider instance any more. After this call,
       
   132         * it is ok to delete the object. This can be implemented simply
       
   133         * e.g. by deleting self in this callback.
       
   134         * Normally, this callback is invoked when the icon in question
       
   135         * is deleted.
       
   136         * Note, however, that if the same MAknIconFileProvider instance is
       
   137         * supplied in multiple CreateIcon calls, then it must be accessible
       
   138         * by AknIcon framework until it has signalled a matching amount
       
   139         * of these callbacks.
       
   140         */
       
   141         virtual void Finished()
       
   142             {
       
   143             iFile.Close();
       
   144             delete this;
       
   145             }
       
   146     private:
       
   147         // file to use
       
   148         RFile iFile;        
       
   149     }; 
       
   150     
       
   151      /**
       
   152      * Tests if string ends with given pattern
       
   153      * 
       
   154      * @param aString input string
       
   155      * @param aPattern test pattern
       
   156      * @return ETrue if string ends with given pattern.
       
   157      */
       
   158     TBool EndsWith( const TDesC8& aString, const TDesC8& aPattern )
       
   159         {
       
   160         return ( aString.Right( aPattern.Length() ) == aPattern );
       
   161         }
       
   162 
       
   163   /**
       
   164      * Tests if string ends with given pattern
       
   165      * 
       
   166      * @param aString input string
       
   167      * @param aPattern test pattern
       
   168      * @return ETrue if string ends with given pattern.
       
   169      */
       
   170     TBool EndsWith( const TDesC& aString, const TDesC& aPattern )
       
   171         {
       
   172         return ( aString.Right( aPattern.Length() ) == aPattern );
       
   173         }    
       
   174     /**
       
   175      * Removes pattern from the end of string. Function does not validate
       
   176      * that the pattern is in the end of string. It just cuts out the number
       
   177      * of aPattern length characters from the string.
       
   178      *
       
   179      * @param aString input string
       
   180      * @param aPattern pattern
       
   181      * @return string without pattern.
       
   182      */
       
   183     TPtrC8 Strip( const TDesC8& aString, const TDesC8& aPattern )
       
   184         {
       
   185         return aString.Left( aString.Length() - aPattern.Length() );
       
   186         }
       
   187     
       
   188     /**
       
   189      * Selects a proper string data value type
       
   190      */
       
   191     CXnDomPropertyValue::TPrimitiveValueType SelectStringDataType(
       
   192                                                     const TDesC8& aPropertyName,
       
   193                                                     const TDesC8& aPropertyValue )
       
   194         {
       
   195         if ( aPropertyName == XnPropertyNames::style::common::KDisplay
       
   196              && ( aPropertyValue == XnPropertyNames::style::common::display::KBlock
       
   197                   || aPropertyValue == XnPropertyNames::style::common::display::KNone ) )
       
   198             {
       
   199             return CXnDomPropertyValue::EString;
       
   200             }
       
   201         
       
   202         if ( aPropertyName == XnPropertyNames::style::common::KVisibility
       
   203              && ( aPropertyValue == XnPropertyNames::style::common::visibility::KVisible
       
   204                   || aPropertyValue == XnPropertyNames::style::common::visibility::KHidden ) )
       
   205             {
       
   206             return CXnDomPropertyValue::EString;
       
   207             }
       
   208         if ( aPropertyName == XnPropertyNames::style::common::KNavIndex )
       
   209             {
       
   210             return CXnDomPropertyValue::EIdent;
       
   211             }
       
   212             
       
   213         return CXnDomPropertyValue::EUnknown;
       
   214         }
       
   215     
       
   216     /**
       
   217      * Validates string
       
   218      */
       
   219     TBool IsValidCssString( const TDesC8& aString )
       
   220         {
       
   221         // Null string or unquoted string is not a CSS string
       
   222         if ( aString.Length() < KLenDoubleQuotes )
       
   223             {
       
   224             return EFalse;
       
   225             }
       
   226         
       
   227         const TUint8 quotationMark( aString[0] );    
       
   228         if ( ( quotationMark == KDoubleQuote || quotationMark == KSingleQuote )
       
   229              && aString[ aString.Length() - 1 ] == quotationMark )
       
   230             {
       
   231             return ETrue;
       
   232             }
       
   233         
       
   234         return EFalse;
       
   235         }
       
   236     
       
   237     /**
       
   238      * Removes extra quotes from strings. Assumes that the string is quoted.
       
   239      */ 
       
   240     TPtrC8 RemoveQuotes( const TDesC8& aString )
       
   241         {
       
   242         return aString.Mid( 1, aString.Length() - KLenDoubleQuotes );
       
   243         }
       
   244     
       
   245     /**
       
   246      * Parses a primitive data type of a string.
       
   247      *
       
   248      * @param aInputValue[in]   input value with primitive type information.
       
   249      * @param aStringValue[out] value without type information.
       
   250      * @param aFloatValue       value as float if type is a numerical type.
       
   251      * @param aPrimitiveType[out]        primitive type.
       
   252      * @param aUpdateType[out]  update type
       
   253      */
       
   254     void ParseCSSValue( const TDesC8& aInputValue,
       
   255                         TPtrC8& aStringValue,
       
   256                         TReal& aFloatValue,
       
   257                         CXnDomPropertyValue::TPrimitiveValueType& aPrimitiveType,
       
   258                         TPropertyUpdateType& aUpdateType )
       
   259         {
       
   260         aPrimitiveType = CXnDomPropertyValue::EUnknown;
       
   261         aUpdateType = EAbsoluteValue;
       
   262         
       
   263         TPtrC8 unit;
       
   264         
       
   265         // Recognise type
       
   266         
       
   267         if ( EndsWith( aInputValue, AiUiDef::xml::css::KPercentage ) )
       
   268             {
       
   269             unit.Set( AiUiDef::xml::css::KPercentage );
       
   270             aPrimitiveType = CXnDomPropertyValue::EPercentage;
       
   271             }
       
   272         else if ( EndsWith( aInputValue, AiUiDef::xml::css::KPixel ) )
       
   273             {
       
   274             unit.Set( AiUiDef::xml::css::KPixel );
       
   275             aPrimitiveType = CXnDomPropertyValue::EPx;
       
   276             }
       
   277         else if ( EndsWith( aInputValue, AiUiDef::xml::css::KUnitValue ) )
       
   278             {
       
   279             unit.Set( AiUiDef::xml::css::KUnitValue );
       
   280             aPrimitiveType = CXnDomPropertyValue::EUnitValue;
       
   281             }
       
   282         else if ( IsValidCssString( aInputValue ) )
       
   283             {
       
   284             aPrimitiveType = CXnDomPropertyValue::EString;
       
   285             aStringValue.Set( RemoveQuotes( aInputValue ) );
       
   286             return;
       
   287             }
       
   288             
       
   289         // Validate type
       
   290         switch ( aPrimitiveType )
       
   291             {
       
   292             // Supported float types
       
   293             case CXnDomPropertyValue::EPercentage:
       
   294             case CXnDomPropertyValue::EPx:
       
   295             case CXnDomPropertyValue::EUnitValue: // fallthrough
       
   296                 {
       
   297                 // Remove unit
       
   298                 aStringValue.Set( Strip( aInputValue, unit ) );
       
   299                 
       
   300                 // Determine update type
       
   301                 if ( aStringValue.Find( KIncrementalAdditionOperator ) == 0 )
       
   302                     {
       
   303                     aUpdateType = EIncrementalAddition;
       
   304                     
       
   305                     // Remove sign
       
   306                     aStringValue.Set( aStringValue.Mid( KLenIncrementalOperator ) );
       
   307                     }
       
   308                 else if ( aStringValue.Find( KAdditionOperator ) == 0 )
       
   309                     {
       
   310                     aUpdateType = EAddition;
       
   311                     
       
   312                     // Remove sign
       
   313                     aStringValue.Set( aStringValue.Mid( KLenAddSubOperator ) );
       
   314                     }
       
   315                 else if ( aStringValue.Find( KIncrementalSubtractionOperator ) == 0 )
       
   316                     {
       
   317                     // Use addition, so only one sign has to be removed
       
   318                     aUpdateType = EAddition;
       
   319                     
       
   320                     aStringValue.Set( aStringValue.Mid( KLenAddSubOperator ) );
       
   321                     }
       
   322                 else if ( aStringValue.Find( KSubtractionOperator ) == 0 )
       
   323                     {
       
   324                     // Use addition, so sign does not have to be removed
       
   325                     aUpdateType = EAddition;
       
   326                     }
       
   327 
       
   328                 if ( TLex8( aStringValue ).Val( aFloatValue ) != KErrNone )
       
   329                     {
       
   330                     // Not a numerical value. Restore value
       
   331                     aPrimitiveType = CXnDomPropertyValue::EUnknown;
       
   332                     aUpdateType = EAbsoluteValue;
       
   333                     aStringValue.Set( aInputValue );
       
   334                     }
       
   335                 
       
   336                 break;
       
   337                 }
       
   338             
       
   339             // string types    
       
   340             default:
       
   341                 {
       
   342                 aStringValue.Set( aInputValue );
       
   343                 break;
       
   344                 }
       
   345             
       
   346             }
       
   347         }
       
   348     
       
   349     /**
       
   350      * Updates property value
       
   351      *
       
   352      * @param aValue property value to update.
       
   353      * @param aStringValue new value as string
       
   354      * @param aFloatValue new value as float (for number types)
       
   355      * @param aPrimitiveType type of value
       
   356      * @param aUpdateType type to update the value.
       
   357      */
       
   358     void UpdatePropertyValueL( CXnDomPropertyValue& aValue,
       
   359                                const TDesC8& aStringValue,
       
   360                                const TReal& aFloatValue,
       
   361                                CXnDomPropertyValue::TPrimitiveValueType aPrimitiveType,
       
   362                                TPropertyUpdateType aUpdateType )
       
   363         {
       
   364         switch ( aPrimitiveType )
       
   365             {
       
   366             // Supported float types
       
   367             case CXnDomPropertyValue::EPercentage:
       
   368             case CXnDomPropertyValue::EPx:
       
   369             case CXnDomPropertyValue::EUnitValue: // fallthrough
       
   370                 {
       
   371                 TReal floatValue( aFloatValue );
       
   372                 // Select update type
       
   373                 switch ( aUpdateType )
       
   374                     {
       
   375                     case EAddition:  // fallthrough
       
   376                     case EIncrementalAddition:
       
   377                         {
       
   378                         floatValue += aValue.FloatValueL();
       
   379                         break;
       
   380                         }
       
   381                         
       
   382                     case ESubtraction: // fallthrough
       
   383                     case EIncrementalSubtraction:
       
   384                         {
       
   385                         floatValue = aValue.FloatValueL() - aFloatValue;
       
   386                         break;
       
   387                         }
       
   388                     
       
   389                     case EAbsoluteValue:
       
   390                     default:
       
   391                         {
       
   392                         break;
       
   393                         }
       
   394                     }
       
   395                 
       
   396                 // Set new value as float
       
   397                 aValue.SetFloatValueL( aPrimitiveType, floatValue );
       
   398                 
       
   399                 break;
       
   400                 }
       
   401             
       
   402             // string types
       
   403             case CXnDomPropertyValue::EUnknown:
       
   404                 {
       
   405                 // Use current type
       
   406                 aPrimitiveType = Max( aValue.PrimitiveValueType(), CXnDomPropertyValue::EUnknown );
       
   407                 
       
   408                 // Fall through to update...
       
   409                 }
       
   410                 
       
   411             default: // fallthrough
       
   412                 {
       
   413 				if( aPrimitiveType == CXnDomPropertyValue::ENumber )
       
   414 					{
       
   415 					TReal floatValue;
       
   416 					TLex8( aStringValue ).Val( floatValue );
       
   417 					aValue.SetFloatValueL( aPrimitiveType, floatValue );
       
   418 					}
       
   419 				else
       
   420 					{
       
   421                     // Set new value as string
       
   422                      aValue.SetStringValueL( aPrimitiveType, aStringValue );
       
   423 					}
       
   424                 break;
       
   425                 }
       
   426             }
       
   427         }
       
   428     
       
   429     /**
       
   430      * Creates a new property.
       
   431      *
       
   432      * @param aUiElement ui element to hold the property.
       
   433      * @param aPropertyName name of the property.
       
   434      * @param aPropertyValue value of the property.
       
   435      */
       
   436     void CreatePropertyL( CXnNodeAppIf& aUiElement,
       
   437                           const TDesC8& aPropertyName,
       
   438                           const TDesC8& aPropertyValue )
       
   439         {
       
   440         // Create new property value and property
       
   441         CXnDomPropertyValue* value = CXnDomPropertyValue::NewL(
       
   442                                                 aUiElement.UiEngineL()->StringPool() );
       
   443         CleanupStack::PushL( value );
       
   444         
       
   445         CXnProperty* property = CXnProperty::NewL(
       
   446                                                 aPropertyName,
       
   447                                                 value,
       
   448                                                 aUiElement.UiEngineL()->StringPool() );
       
   449         CleanupStack::Pop( value );
       
   450         CleanupStack::PushL( property );
       
   451         
       
   452         // Parse CSS value
       
   453         TPtrC8 stringValue;
       
   454         TReal floatValue( 0 );
       
   455         CXnDomPropertyValue::TPrimitiveValueType primitiveType(
       
   456                                                 CXnDomPropertyValue::EUnknown );
       
   457         TPropertyUpdateType updateType( EAbsoluteValue );
       
   458         
       
   459         ParseCSSValue( aPropertyValue,
       
   460                        stringValue,
       
   461                        floatValue,
       
   462                        primitiveType,
       
   463                        updateType );
       
   464         
       
   465         if ( primitiveType == CXnDomPropertyValue::EUnknown )
       
   466             {
       
   467             primitiveType = SelectStringDataType( aPropertyName, aPropertyValue );
       
   468             }
       
   469             
       
   470         // Update CSS value               
       
   471         UpdatePropertyValueL( *value,
       
   472                               stringValue,
       
   473                               floatValue,
       
   474                               primitiveType,
       
   475                               updateType );
       
   476         
       
   477         // Add property to UI element                      
       
   478         aUiElement.SetPropertyL( property );
       
   479         
       
   480         CleanupStack::Pop( property );
       
   481         }
       
   482     
       
   483     
       
   484     // Icon utilities
       
   485     
       
   486     _LIT( KSkin, "skin" );
       
   487     const TUint KLeftParenthesis = '(';
       
   488     
       
   489     /**
       
   490      * Resolves skin item id from pattern SKIN( <majorId> <minorId> (<colourGroupId>) ).
       
   491      * The colourGroupId in the syntax is optional, and if no value found then
       
   492      * aColourValue will be -1
       
   493      *
       
   494      * @param aItemId skin item id to fill
       
   495      * @param aColourValue colour value to fill. 
       
   496      * @param aPath   skin item id string     
       
   497      * 
       
   498      * @return ETrue if id was succesfully parsed.
       
   499      */
       
   500     TBool ResolveSkinItemId( TAknsItemID& aItemId, TInt& aColourValue, const TDesC& aPath )
       
   501         {
       
   502         // Syntax: skin( <major> <minor> )
       
   503         TInt pos = aPath.FindF( KSkin );
       
   504         aColourValue = -1;
       
   505         if( pos != KErrNotFound )
       
   506             {
       
   507             // Skip skin token
       
   508             pos += KSkin().Length();
       
   509             
       
   510             // Initialize lexer
       
   511             TLex lex( aPath.Mid( pos ) );
       
   512             lex.SkipSpace();
       
   513             
       
   514             // Check left parenthesis
       
   515             if (lex.Get() != KLeftParenthesis )
       
   516                 {
       
   517                 return EFalse;
       
   518                 }
       
   519             
       
   520             lex.SkipSpace();
       
   521             
       
   522             TInt majorId( 0 );        
       
   523             TInt minorId( 0 );
       
   524             
       
   525             // Resolve major id        
       
   526             TInt error = lex.Val( majorId );
       
   527             
       
   528             // Resolve minor id
       
   529             lex.SkipSpace();
       
   530             error |= lex.Val( minorId );
       
   531             
       
   532             // initilize skin item id object
       
   533             aItemId.Set( majorId, minorId );
       
   534             
       
   535             lex.SkipSpace();
       
   536             TInt colorError = lex.Val( aColourValue );
       
   537             if ( colorError != KErrNone || aColourValue < 0)
       
   538                 {
       
   539                 aColourValue = -1;
       
   540                 }
       
   541                         
       
   542             // Check error
       
   543             return ( error == KErrNone );
       
   544             }
       
   545          
       
   546         return EFalse;
       
   547         }
       
   548         
       
   549 	 /**
       
   550      * Resolves MIF files filename and id from syntax
       
   551      * mif_filename.mif#id. If the syntax is incorrect
       
   552      * aId is -1 and filename zeroed and EFalse is returned
       
   553      *
       
   554      * @param aPath The path to extract the data from
       
   555      * @param aId	Id to fill
       
   556      * @param aFilename Filename to fill
       
   557      * @return ETrue if id was succesfully parsed.
       
   558      */
       
   559     TBool ResolveMifIdAndPathL( const TDesC& aPath, TInt& aId, TDes& aFilename )
       
   560         {
       
   561         // Syntax: mif_filename.mif#index
       
   562         TInt pos = aPath.FindF( KHashmark );
       
   563         aFilename.Zero();
       
   564         if( pos != KErrNotFound )
       
   565             {
       
   566             aFilename = (aPath.Left(pos));
       
   567             if ( ! EndsWith( aFilename, KMIFExtension ) )
       
   568             	{
       
   569             	aFilename.Zero();
       
   570             	return EFalse;
       
   571             	}
       
   572             
       
   573             TLex lex(aPath.Mid(pos+1));
       
   574             TInt error = lex.Val(aId);
       
   575             if ( error != KErrNone )
       
   576             	{
       
   577             	aId = -1;
       
   578             	return EFalse;
       
   579             	}
       
   580             return ETrue;
       
   581             }
       
   582            return EFalse;
       
   583             
       
   584             
       
   585       
       
   586         }        
       
   587 
       
   588     /**
       
   589     * Loads a bitmap icon from a MIF-file loaded to Xuikon by using
       
   590     * <FileResource> tag
       
   591     *
       
   592     * @param aNode Resource node
       
   593     * @param aFilename The filename to load
       
   594     * @param aBitmap The bitmap to fill
       
   595     * @param aBitmapMask The mask to fill
       
   596     * @param aMifId The id of the icon in the MIF-file
       
   597     *
       
   598 	* @return KErrNone if loading was successful KErrNotFound if not
       
   599 	*/
       
   600     TInt LoadMIFBitmapL( CXnNodeAppIf &aNode, 
       
   601     	const TDesC &aPath,
       
   602     	CFbsBitmap*& aBitmap,
       
   603     	CFbsBitmap*& aBitmapMask,
       
   604     	TInt aMifId )
       
   605     	{
       
   606     	RFile tempFile;
       
   607     	    	
       
   608     	if ( aMifId < 0 )
       
   609     		{
       
   610     		return KErrNotFound;
       
   611     		}
       
   612     	  
       
   613     	TInt err = aNode.UiEngineL()->GetThemeResource( aPath, tempFile );
       
   614 
       
   615 		if ( err != KErrNone )
       
   616 			{
       
   617 			tempFile.Close();
       
   618 			return err;
       
   619 			}
       
   620     	
       
   621     	//Requires an open RFile handle
       
   622     	TIconProvider *iconProvider = 
       
   623     		new (ELeave) TIconProvider(tempFile);
       
   624 
       
   625     	CleanupStack::PushL( iconProvider );
       
   626     	// Mask is next after bitmap
       
   627         AknIconUtils::CreateIconL(aBitmap,aBitmapMask, *iconProvider,
       
   628             aMifId+KMifIdFirst,aMifId+KMifIdFirst+1);
       
   629 
       
   630     	CleanupStack::Pop(iconProvider); // iconProvider
       
   631           
       
   632         return KErrNone;
       
   633     	}
       
   634     }
       
   635 
       
   636 namespace AiXmlUiController
       
   637 {
       
   638 
       
   639 RPointerArray< CXnNodeAppIf >
       
   640     FindPropertyElementL( CXnNodeAppIf& aUiElement, const TDesC8& aPropertyClass )
       
   641     {
       
   642     CXnBreadthFirstTreeIterator< CXnNodeAppIf >* iterator = 
       
   643             CXnBreadthFirstTreeIterator< CXnNodeAppIf >::NewL( aUiElement, 
       
   644             KDepthT );
       
   645     CleanupDeletePushL( iterator );
       
   646     
       
   647     RPointerArray< CXnNodeAppIf > nodes;
       
   648     
       
   649     CleanupClosePushL( nodes );
       
   650     
       
   651     CXnNodeAppIf* child = iterator->Value() ;
       
   652     
       
   653     while ( child )
       
   654         {
       
   655         CXnProperty* classProperty = child->GetPropertyL(
       
   656                                             XnPropertyNames::common::KClass );
       
   657         
       
   658         if ( classProperty && ( classProperty->StringValue() == aPropertyClass ) )
       
   659             {
       
   660             User::LeaveIfError( nodes.Append( child ) );
       
   661             }
       
   662         
       
   663         child = iterator->NextL();
       
   664         }
       
   665     
       
   666     CleanupStack::Pop( &nodes );
       
   667     
       
   668     CleanupStack::PopAndDestroy( iterator );
       
   669     
       
   670     return nodes;
       
   671     }
       
   672 
       
   673 void FindPropertyElementL( RPointerArray< CXnNodeAppIf >& aArray, CXnNodeAppIf& aUiElement, const TDesC8& aPropertyClass )
       
   674     {
       
   675     CXnBreadthFirstTreeIterator< CXnNodeAppIf >* iterator = 
       
   676             CXnBreadthFirstTreeIterator< CXnNodeAppIf >::NewL( aUiElement,
       
   677             KDepthT );
       
   678     CleanupDeletePushL( iterator );
       
   679        
       
   680     CXnNodeAppIf* child =  iterator->Value();
       
   681     
       
   682     while ( child )
       
   683         {
       
   684         CXnProperty* classProperty = child->GetPropertyL(
       
   685                                             XnPropertyNames::common::KClass );
       
   686         
       
   687         if ( classProperty && ( classProperty->StringValue() == aPropertyClass ) )
       
   688             {
       
   689             User::LeaveIfError( aArray.Append( child ) );
       
   690             }
       
   691         
       
   692         child = iterator->NextL();
       
   693         }
       
   694    
       
   695     CleanupStack::PopAndDestroy( iterator );
       
   696     }
       
   697 
       
   698 HBufC* PropertyValueL( const CXnNodeAppIf& aUiElement,
       
   699                        const TDesC8& aPropertyName )
       
   700     {
       
   701     CXnProperty* property = aUiElement.GetPropertyL( aPropertyName );
       
   702     
       
   703     if ( property )
       
   704         {
       
   705         return property->StringValueL();
       
   706         }
       
   707         
       
   708     return NULL;
       
   709     }
       
   710 
       
   711 const TDesC8* PropertyValue( const CXnNodeAppIf& aUiElement,
       
   712                              const TDesC8& aPropertyName )
       
   713     {
       
   714     CXnProperty* property = NULL;
       
   715     TRAP_IGNORE( property = aUiElement.GetPropertyL( aPropertyName ) );
       
   716     
       
   717     if ( property )
       
   718         {
       
   719         return &property->StringValue();
       
   720         }
       
   721         
       
   722     return NULL;
       
   723     }
       
   724 
       
   725 void SetPropertyL( CXnNodeAppIf& aUiElement,
       
   726                    const TDesC8& aPropertyName,
       
   727                    const TDesC8& aPropertyValue,
       
   728                    CCssPropertyMap& aPropertyMap )
       
   729     {
       
   730     CXnProperty* property = aUiElement.GetPropertyL( aPropertyName );
       
   731     
       
   732     if ( !property )
       
   733         {
       
   734         // Create new property
       
   735         CreatePropertyL( aUiElement, aPropertyName, aPropertyValue );
       
   736         return;
       
   737         }
       
   738     
       
   739     // Clone property for update
       
   740     property = property->CloneL();
       
   741     CleanupStack::PushL( property );
       
   742     
       
   743     CXnDomProperty* domProperty = property->Property();
       
   744     MXnDomListItem* item = domProperty->PropertyValueList().First();
       
   745 
       
   746     CXnDomPropertyValue* value = static_cast< CXnDomPropertyValue* >( item );
       
   747     
       
   748     if ( value )
       
   749         {
       
   750         TPtrC8 stringValue;
       
   751         TReal floatValue(0);
       
   752                 
       
   753         CXnDomPropertyValue::TPrimitiveValueType primitiveType(
       
   754                                                 CXnDomPropertyValue::EUnknown );
       
   755         TPropertyUpdateType updateType( EAbsoluteValue );
       
   756         
       
   757         ParseCSSValue( aPropertyValue,
       
   758                        stringValue,
       
   759                        floatValue,
       
   760                        primitiveType,
       
   761                        updateType );
       
   762         
       
   763         if ( primitiveType == CXnDomPropertyValue::EUnknown )
       
   764             {
       
   765             primitiveType = SelectStringDataType( aPropertyName, aPropertyValue );
       
   766             }
       
   767         
       
   768         if ( updateType != EAbsoluteValue &&
       
   769              updateType != EIncrementalAddition &&
       
   770              updateType != EIncrementalSubtraction )
       
   771             {
       
   772             // Use original value from property map
       
   773             const TDesC8* elementId = PropertyValue( aUiElement,
       
   774                                                      XnPropertyNames::common::KId );
       
   775             CXnDomPropertyValue* original = NULL;
       
   776             if( elementId )
       
   777                 {
       
   778                 original = aPropertyMap.FindPropertyValue(
       
   779                                                         *elementId,
       
   780                                                         aPropertyName );
       
   781                 }
       
   782             else
       
   783                 {
       
   784                 User::Leave( KErrNotSupported );
       
   785                 }
       
   786             
       
   787             if ( original )
       
   788                 {
       
   789                 // Clone original value 
       
   790                 value = original->CloneL();
       
   791                 CleanupStack::PopAndDestroy( property ); // Old clone
       
   792                 CleanupStack::PushL( value );
       
   793                 property = CXnProperty::NewL( aPropertyName,
       
   794                                               value,
       
   795                                               aUiElement.UiEngineL()->StringPool() );
       
   796                 CleanupStack::Pop( value );
       
   797                 CleanupStack::PushL( property );
       
   798                 }
       
   799             else
       
   800                 {
       
   801                 // store original value
       
   802                 aPropertyMap.StorePropertyValueL( *elementId, *property );
       
   803                 }
       
   804             }
       
   805         
       
   806         UpdatePropertyValueL( *value,
       
   807                               stringValue,
       
   808                               floatValue,
       
   809                               primitiveType,
       
   810                               updateType );
       
   811             
       
   812             aUiElement.SetPropertyL( property );
       
   813             CleanupStack::Pop( property );
       
   814         }
       
   815     else
       
   816         {
       
   817         User::Leave( KErrNotSupported );
       
   818         }
       
   819     }
       
   820 
       
   821 void SetPropertiesToHashMapL( RArray<TAiPolicyElement>& aArray,
       
   822                               CCssPropertyMap& aPropertyMap,
       
   823                               RPropertyHashMap& aPropertyHashMap )
       
   824     {
       
   825     TBool propertyAdded = EFalse;
       
   826     if( !aArray.Count() )
       
   827         {
       
   828         return;
       
   829         }
       
   830         
       
   831     CXnNodeAppIf& uiElement = aArray[0].Target();
       
   832     RPointerArray<CXnProperty>* propertyArray = NULL;
       
   833     
       
   834     propertyArray = aPropertyHashMap.Find( uiElement );
       
   835     
       
   836     if( !propertyArray )
       
   837         {
       
   838         // Create new one.
       
   839         propertyArray = new(ELeave) RPropertyArray;
       
   840         CleanupStack::PushL( propertyArray );
       
   841         aPropertyHashMap.InsertL( &uiElement, propertyArray );
       
   842         CleanupStack::Pop( propertyArray );
       
   843         }
       
   844     
       
   845     for( TInt i = 0; i < aArray.Count(); ++i )
       
   846         {
       
   847         const TDesC8& propertyName = aArray[i].Name();
       
   848         const TDesC8& propertyValue = aArray[i].Value();
       
   849 
       
   850         CXnProperty* property = uiElement.GetPropertyL( propertyName );
       
   851         
       
   852         if ( !property )
       
   853             {
       
   854             // Create new property
       
   855             CreatePropertyL( uiElement, propertyName, propertyValue );
       
   856             propertyAdded = ETrue;
       
   857             continue;
       
   858             }
       
   859         
       
   860         // Clone property for update
       
   861         property = property->CloneL();
       
   862         CleanupStack::PushL( property );
       
   863         
       
   864         CXnDomProperty* domProperty = property->Property();
       
   865         MXnDomListItem* item = domProperty->PropertyValueList().First();
       
   866 
       
   867         CXnDomPropertyValue* value = static_cast< CXnDomPropertyValue* >( item );
       
   868         
       
   869         if ( value )
       
   870             {
       
   871             TPtrC8 stringValue;
       
   872             TReal floatValue(0);
       
   873                     
       
   874             CXnDomPropertyValue::TPrimitiveValueType primitiveType(
       
   875                                                     CXnDomPropertyValue::EUnknown );
       
   876             TPropertyUpdateType updateType( EAbsoluteValue );
       
   877             
       
   878             ParseCSSValue( propertyValue,
       
   879                            stringValue,
       
   880                            floatValue,
       
   881                            primitiveType,
       
   882                            updateType );
       
   883             
       
   884             if ( primitiveType == CXnDomPropertyValue::EUnknown )
       
   885                 {
       
   886                 primitiveType = SelectStringDataType( propertyName, propertyValue );
       
   887                 }
       
   888             
       
   889             if ( updateType != EAbsoluteValue )
       
   890                 {
       
   891                 // Use original value from property map
       
   892                 const TDesC8* elementId = PropertyValue( uiElement,
       
   893                                                          XnPropertyNames::common::KId );
       
   894                 CXnDomPropertyValue* original = NULL;
       
   895                 if( elementId )
       
   896                     {
       
   897                     original = aPropertyMap.FindPropertyValue(
       
   898                                                             *elementId,
       
   899                                                             propertyName );
       
   900                     }
       
   901                 else
       
   902                     {
       
   903                     User::Leave( KErrNotSupported );
       
   904                     }
       
   905                 
       
   906                 if ( original )
       
   907                     {
       
   908                     // Clone original value 
       
   909                     value = original->CloneL();
       
   910                     CleanupStack::PopAndDestroy( property ); // Old clone
       
   911                     CleanupStack::PushL( value );
       
   912                     property = CXnProperty::NewL( propertyName,
       
   913                                                   value,
       
   914                                                   uiElement.UiEngineL()->StringPool() );
       
   915                     CleanupStack::Pop( value );
       
   916                     CleanupStack::PushL( property );
       
   917                     }
       
   918                 else
       
   919                     {
       
   920                     // store original value
       
   921                     aPropertyMap.StorePropertyValueL( *elementId, *property );
       
   922                     }
       
   923                 }
       
   924             
       
   925                 UpdatePropertyValueL( *value,
       
   926                                       stringValue,
       
   927                                       floatValue,
       
   928                                       primitiveType,
       
   929                                       updateType );
       
   930                 propertyArray->AppendL( property );
       
   931                 CleanupStack::Pop( property );
       
   932             }
       
   933         }
       
   934         
       
   935     if( !propertyAdded && !propertyArray->Count() )
       
   936         {
       
   937         User::Leave( KErrNotSupported );
       
   938         }
       
   939     }
       
   940 
       
   941 void SetPropertyArraysL( RPropertyHashMap& aPropertyHashMap )
       
   942     {
       
   943     TPtrHashMapIter<CXnNodeAppIf, RPropertyArray> iter( aPropertyHashMap );
       
   944     iter.Reset();
       
   945     
       
   946     const CXnNodeAppIf* targetNode = (const CXnNodeAppIf*)iter.NextKey();
       
   947     
       
   948     while( targetNode )
       
   949         {
       
   950         CXnNodeAppIf* targetNonConst = const_cast<CXnNodeAppIf*>(targetNode);
       
   951         RPointerArray<CXnProperty>* propertyArray = aPropertyHashMap.Find(*targetNode);
       
   952         if( propertyArray )
       
   953             {
       
   954             targetNonConst->SetPropertyArrayL( propertyArray ); // Assumes ownership
       
   955                                                                 // of CXnProperty's in the array
       
   956                                                                 // but not the array itself.
       
   957             propertyArray->Close(); // Close and delete the array to free all memory.
       
   958             delete propertyArray;
       
   959             aPropertyHashMap.Remove( targetNode ); // Remove the key from hash map
       
   960                                                    // as the array is now destroyed.
       
   961             iter.Reset(); // Reset the iterator to avoid panic.
       
   962             }
       
   963         targetNode =  (CXnNodeAppIf*)iter.NextKey();
       
   964         }
       
   965 
       
   966     }
       
   967 
       
   968 CGulIcon* LoadIconLC( CXnNodeAppIf& aResource )
       
   969     {
       
   970     // Resolve icon path
       
   971     HBufC* pathBuffer = PropertyValueL( aResource, XnPropertyNames::image::KPath );
       
   972     CleanupStack::PushL( pathBuffer );
       
   973   	
       
   974     LeaveIfNull( pathBuffer, KErrNotFound );
       
   975     
       
   976     CFbsBitmap *bitmap = NULL;
       
   977     CFbsBitmap *mask = NULL;
       
   978     CGulIcon* icon = NULL;
       
   979 
       
   980 	TFileName fileName;
       
   981 	TInt mifId(0);
       
   982   
       
   983   	//Assume that the filetype is not supported
       
   984     TInt err = KErrNotSupported;
       
   985     
       
   986     // Resolve icon id    
       
   987     TAknsItemID iconId;
       
   988     
       
   989     // Possible color index
       
   990     TInt colorValue(-1);
       
   991     
       
   992     TBool inSkin = ResolveSkinItemId( iconId, colorValue, *pathBuffer );
       
   993     
       
   994     // SKIN(<major> <minor> (<optionalColourGroup>))
       
   995     if ( inSkin )
       
   996         {
       
   997         // Load from skin
       
   998         MAknsSkinInstance* skin = AknsUtils::SkinInstance();
       
   999         err = KErrNone;
       
  1000         // Load the icon with colour group support but only if it is valid
       
  1001         // see AknsConstants.h for these   
       
  1002         if ( colorValue >= EAknsCIQsnTextColorsCG1 && 
       
  1003              colorValue <= EAknsCIQsnTextColorsCG62 )
       
  1004             {
       
  1005             CFbsBitmap* bitmap = NULL;
       
  1006             CFbsBitmap* mask = NULL;
       
  1007             AknsUtils::CreateColorIconLC(
       
  1008                 skin,
       
  1009                 iconId,
       
  1010                 KAknsIIDQsnTextColors,
       
  1011                 colorValue,
       
  1012                 bitmap,
       
  1013                 mask,
       
  1014                 KNullDesC,  /* no backup */
       
  1015                 0,          /* no backup */
       
  1016                 0,          /* no backup */
       
  1017                 KRgbBlack );
       
  1018             
       
  1019             if ( bitmap )
       
  1020                 {
       
  1021                 icon = CGulIcon::NewL( bitmap, mask );              
       
  1022                 }
       
  1023             else
       
  1024                 {
       
  1025                 err = KErrNotFound;
       
  1026                 }
       
  1027             CleanupStack::Pop( 2 ); // bitmap, mask
       
  1028             }
       
  1029         // No colour group support
       
  1030         else
       
  1031             {
       
  1032             icon = AknsUtils::CreateGulIconL( skin, iconId, KNullDesC, 0, 0 );            
       
  1033             }
       
  1034 
       
  1035     	if ( !icon ) // Syntax correct but icon not found
       
  1036     		{
       
  1037     		err = KErrNotFound;	
       
  1038     		} 
       
  1039         }
       
  1040    	
       
  1041 	// MIF-file <filename.mif>#<index_in_mif>
       
  1042     else if ( ResolveMifIdAndPathL( *pathBuffer, mifId, fileName ) )
       
  1043     	{
       
  1044 		err = LoadMIFBitmapL( aResource, fileName, bitmap, mask, mifId );
       
  1045 		
       
  1046 		if ( err == KErrNone && bitmap )
       
  1047 			{
       
  1048 			// Ownership of bitmap and mask transferred to CGulIcon
       
  1049 			icon = CGulIcon::NewL( bitmap, mask );	
       
  1050 			}
       
  1051 		else // Syntax correct but the icon was not found
       
  1052 			{
       
  1053 			err = KErrNotFound;
       
  1054 			}
       
  1055     	}
       
  1056 	CleanupStack::PopAndDestroy( pathBuffer );      
       
  1057     CleanupStack::PushL( icon );
       
  1058     
       
  1059   	User::LeaveIfError( err );
       
  1060     return icon;
       
  1061     }
       
  1062     
       
  1063 void SetPropertyToNodeL( 
       
  1064     CXnNodeAppIf& aNode, 
       
  1065     const TDesC8& aPropertyName, 
       
  1066     const TDesC8& aNewValueString )
       
  1067 	{
       
  1068 	// Set defined property to defined node.
       
  1069     CXnDomPropertyValue* newValue = CXnDomPropertyValue::NewL(aNode.UiEngineL()->StringPool());
       
  1070     CleanupStack::PushL(newValue);
       
  1071     newValue->SetStringValueL(CXnDomPropertyValue::EString, aNewValueString);
       
  1072     CXnProperty* prop = CXnProperty::NewL(aPropertyName, newValue, aNode.UiEngineL()->StringPool());
       
  1073     CleanupStack::PushL(prop);
       
  1074 	aNode.SetPropertyL(prop);
       
  1075     CleanupStack::Pop(prop);
       
  1076     CleanupStack::Pop(newValue);				        
       
  1077 	}
       
  1078 	
       
  1079 } // namespace AiXmlUiController