idlehomescreen/xmluicontroller/src/contentrenderer.cpp
branchRCL_3
changeset 83 5456b4e8b3a8
child 88 3321d3e205b6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/idlehomescreen/xmluicontroller/src/contentrenderer.cpp	Wed Sep 01 12:32:46 2010 +0100
@@ -0,0 +1,1871 @@
+/*
+* 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:  Content renderer implementation
+*
+*/
+
+// System includes
+#include <e32hashtab.h>
+#include <utf.h>
+#include <gulicon.h>
+
+// User includes
+#include <hscontentpublisher.h>
+#include <hspublisherinfo.h>
+#include "contentrenderer.h"
+#include "appui.h"
+#include "activetransactionstack.h"
+#include "transactionfactoryimpl.h"
+#include "mtransaction.h"
+#include "mtransactionelement.h"
+#include "aixmluiutils.h"
+#include "xmluicontroller.h"
+#include "xmlnodeidgenerator.h"
+#include "aixmluiconstants.h"
+#include "aifweventhandler.h"
+#include "databuffertransactionelement.h"
+#include "newstickertransactionelement.h"
+#include "csspropertymap.h"
+#include "policyevaluator.h"
+#include "debug.h"
+#include "xnuiengineappif.h"
+#include "xnnodeappif.h"
+#include "xnproperty.h"
+#include "mxncomponentinterface.h"
+#include "xntext.h"
+#include "xnbitmap.h"
+#include "xntype.h"
+#include "xnmenuadapter.h"
+#include "xnlistquerydialogadapter.h"
+#include "xnnewsticker.h"
+#include "mxncomponentinterface.h"
+#include "aistrcnv.h"
+#include "contentprioritymap.h"
+#include "ainativeuiplugins.h"
+
+using namespace AiXmlUiController;
+using namespace AiUiDef::xml;
+using namespace XnTextInterface;
+using namespace XnImageInterface;
+
+/**
+ * Cleanup item for cleanup of TPtrHashMapIter
+ */            
+class TMapCleanupItem
+    {
+public:
+    /**
+     * C++ consturctor
+     */
+    TMapCleanupItem( TPtrHashMapIter< TDesC, TInt >& aIterator );
+    
+    /**
+     * Removes the pointers in the map and deletes the objects
+     * referenced by the pointers.
+     */ 
+    void Release();
+            
+private:        
+    TPtrHashMapIter< TDesC, TInt > iIterator;    
+    };
+
+// ----------------------------------------------------------------------------
+// TMapCleanupItem::TMapCleanupItem
+//  
+// ----------------------------------------------------------------------------
+//
+TMapCleanupItem::TMapCleanupItem( TPtrHashMapIter< TDesC, TInt >& aIterator )
+    : iIterator( aIterator )
+    {
+    }
+
+// ----------------------------------------------------------------------------
+// TMapCleanupItem::Release
+//  
+// ----------------------------------------------------------------------------
+//
+void TMapCleanupItem::Release()
+    {
+    // Delete current key and value
+    const TDesC* key( iIterator.CurrentKey() );
+    const TInt* value( iIterator.CurrentValue() );
+    
+    delete key;
+    delete value;
+    
+    // Remove mapping from the map.
+    iIterator.RemoveCurrent();
+    }
+
+// ============================ LOCAL FUNCTIONS ===============================
+
+// ----------------------------------------------------------------------------
+// ContentItemIterator
+// Gets content item iterator
+// ----------------------------------------------------------------------------
+//
+static MAiContentItemIterator* ContentItemIterator( CHsContentPublisher& aPlugin,
+    CHsContentPublisher::TProperty aType )
+    {       
+    return static_cast< 
+        MAiContentItemIterator* >( aPlugin.GetProperty( aType ) );                                     
+    }
+
+// ----------------------------------------------------------------------------
+// ContentPriority
+// Gets the content priority associated in the property element
+// ----------------------------------------------------------------------------
+//
+static TInt ContentPriority( CXnNodeAppIf& aPropertyElement )
+    {
+    TInt32 priority( KErrNotFound );
+    
+    const TDesC8* name( 
+        PropertyValue( aPropertyElement, property::KName ) );
+                                                                                   
+    if ( name && *name == name::KPriority )
+        {
+        const TDesC8* value( 
+            PropertyValue( aPropertyElement, property::KValue ) );
+                                             
+        if ( value )
+            {
+            AiUtility::ParseInt( priority, *value );
+            }
+        }
+        
+    return priority;
+    }
+    
+// ----------------------------------------------------------------------------
+// RemoveNonPriorityElements
+// Remove elements from array which do not contain priority or priority is 
+// not lower than the given value.
+// ----------------------------------------------------------------------------
+//
+static void RemoveNonPriorityElements( RPointerArray< CXnNodeAppIf>& aElements,
+    TInt aLastPriority )
+    {
+    //  Remove non priority elements and higher priority elements
+    TInt elementCount( aElements.Count() );    
+    
+    for ( TInt i = 0; i < elementCount; )
+        {
+        CXnNodeAppIf* current( aElements[i] );
+        
+        // Check name attribute
+        const TDesC8* name( PropertyValue( *current, property::KName ) );
+        
+        if ( !name || *name != name::KPriority )
+            {
+            // Remove current
+            aElements.Remove( i );
+            --elementCount;
+            }
+        else
+            {
+            // Check current priority
+            const TDesC8* value( 
+                PropertyValue( *current, property::KValue ) );
+            
+            if ( !value ) // value not present
+                {
+                aElements.Remove( i );
+                --elementCount;
+                continue;
+                }
+            
+            TInt32 currentPriority( KErrNotFound );
+            
+            if ( AiUtility::ParseInt( currentPriority, *value ) != KErrNone )
+                {
+                // value is not integer
+                aElements.Remove( i );
+                --elementCount;
+                continue;
+                }
+                
+            if ( currentPriority < aLastPriority )
+                {
+                // Keep element and iterate further
+                ++i;
+                }
+            else
+                {
+                // priority is too high
+                aElements.Remove( i );
+                --elementCount;
+                }
+            }
+        }
+    }
+    
+// ----------------------------------------------------------------------------
+// DescendingPriorityOrder
+// Descending priority order for prioritized content selectors. 
+// ----------------------------------------------------------------------------
+//
+static TInt DescendingPriorityOrder( const CXnNodeAppIf& aNode1,
+    const CXnNodeAppIf& aNode2 )
+    {
+    /*
+    * @param aNode1 First node to compare
+    * @param aNode2 Second node to compare
+    * @return 0 nodes have equal priority
+    * @return >0 aNode1 has lower priority
+    * @return <0 aNode2 has lower priority
+    */
+    // Array content has been validated, so no checks are needed
+    const TDesC8* value1( 
+        PropertyValue( aNode1, property::KValue ) );
+                                              
+    const TDesC8* value2( 
+        PropertyValue( aNode2, property::KValue ) );
+                                              
+    TInt32 priority1( KErrNotFound );
+    AiUtility::ParseInt( priority1, *value1 );
+    
+    TInt32 priority2( KErrNotFound );
+    AiUtility::ParseInt( priority2, *value2 );
+    
+    if ( priority1 == priority2 )
+        {
+        return 0;
+        }
+        
+    return ( priority1 < priority2 ) ? 1 : -1;
+    }
+
+// ----------------------------------------------------------------------------
+// RemoveDuplicateContentChangesL
+// Removes duplicate entries in content change array 
+// ----------------------------------------------------------------------------
+//
+static void RemoveDuplicateContentChangesL( RAiPolicyElementArray& aArray )
+    {
+    for ( TInt i = 0; i < aArray.Count(); ++i )
+        {
+        HBufC* id( PropertyValueL( aArray[i].Target(),  
+            AiUiDef::xml::property::KId ) ); 
+                                        
+        if ( id )
+            {
+            CleanupStack::PushL( id );
+            
+            for ( TInt j = i; j < aArray.Count(); ++j )
+                {
+                HBufC* id2( PropertyValueL( aArray[j].Target(), 
+                   AiUiDef::xml::property::KId ) );
+                CleanupStack::PushL( id2 );
+                
+                if ( id2 )
+                    {
+                    // Same id and same policy
+                    if ( i != j && id->Compare( *id2 ) == 0 &&                          
+                     ( aArray[i].Policy().Compare( aArray[j].Policy()) == 0 ) ) 
+                            
+                        {
+                        aArray.Remove( j );
+                        --j;
+                        }
+                    }
+                
+                CleanupStack::PopAndDestroy( id2 );                
+                }
+            
+            CleanupStack::PopAndDestroy( id );
+            }
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CleanupReleaseMapItem
+// Helper to handle cleanup of map iterator 
+// ----------------------------------------------------------------------------
+//
+static void CleanupReleaseMapItem( TAny* aMapCleanupItem )
+    {
+    if ( aMapCleanupItem )
+        {
+        static_cast< TMapCleanupItem* >( aMapCleanupItem )->Release();
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CleanupReleasePushL
+// Helper to push map iterator into cleanup stack. 
+// ----------------------------------------------------------------------------
+//
+static void CleanupReleasePushL( TMapCleanupItem& aCleanupItem )
+    {
+    CleanupStack::PushL( TCleanupItem( CleanupReleaseMapItem, &aCleanupItem ) );
+    }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::CContentRenderer
+// 
+// ----------------------------------------------------------------------------
+//
+CContentRenderer::CContentRenderer( CAppUi& aAppUi )
+    : iAppUi( aAppUi )
+    {
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::ConstructL
+// 
+// ----------------------------------------------------------------------------
+//
+void CContentRenderer::ConstructL()
+    {
+    iContentPriorityMap = AiUtility::CContentPriorityMap::NewL();
+    iPropertyMap = CCssPropertyMap::NewL();
+    iFactory = CTransactionFactoryImpl::NewL(*iContentPriorityMap,
+                                             *iPropertyMap);
+    iStack = CActiveTransactionStack::NewL();
+    iNodeIdGenerator = CXmlNodeIdGenerator::NewL();
+    iTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+    iPolicyEvaluator = CPolicyEvaluator::NewL();
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::NewL
+// 
+// ----------------------------------------------------------------------------
+//
+CContentRenderer* CContentRenderer::NewL( CAppUi& aAppUi )
+    {
+    CContentRenderer* self = new( ELeave ) CContentRenderer( aAppUi );
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::~CContentRenderer
+// 
+// ----------------------------------------------------------------------------
+//
+CContentRenderer::~CContentRenderer()
+    {
+    delete iPolicyEvaluator;
+    
+    if ( iTimer )
+        {
+        iTimer->Cancel();
+        delete iTimer;
+        }
+        
+    delete iNodeIdGenerator;
+    
+    if ( iStack )
+        {
+        while ( !iStack->IsEmpty() )
+            {
+            MTransaction* tr = iStack->Pop();
+            iFactory->ReleaseTransaction( tr );
+            }
+
+        delete iStack;
+        }
+    
+    delete iFactory;
+    
+    iRefreshableUiElements.ResetAndDestroy();
+    
+    delete iPropertyMap;
+    
+    delete iContentPriorityMap;    
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::SetEventHandler
+// 
+// ----------------------------------------------------------------------------
+//
+void CContentRenderer::SetEventHandler( MAiFwEventHandler& aFwEventHandler )
+    {
+    iFwEventHandler = &aFwEventHandler;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::StartTransaction
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::StartTransaction( TInt aTxId )
+    {
+    __PRINT(__DBG_FORMAT("\t[I]\tXML UI: Start transaction id=%d"), aTxId);
+    __HEAP("XML UI: Start transaction");
+    __TICK("XML UI: Start transaction");
+    
+    TRAPD( error, DoStartTransactionL( aTxId ) );
+
+    if ( error )
+        {
+        SetImmediateMode( ETrue );
+        }
+
+    return error;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::Commit
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::Commit( TInt aTxId )
+    {
+    // Remove transaction with aTxId from stack
+    MTransaction* tr( iStack->Remove( aTxId ) );
+
+    if ( tr )
+        {
+        // Commit transaction        
+        RPropertyHashMap propertyHashMap;
+        
+        TBool layoutChanged( EFalse );
+        
+        TRAPD( error, tr->CommitL( layoutChanged, propertyHashMap ) );
+
+        if( error == KErrNone )
+            {
+            TRAP_IGNORE( SetPropertyArraysL( propertyHashMap ) );
+            }
+        
+        propertyHashMap.Close();
+
+        __TICK("XML UI: Commit transaction");
+        __HEAP("XML UI: Commit transaction");
+        __PRINT(__DBG_FORMAT("\t[I]\tXML UI: Commit transaction id=%d"), aTxId);
+       
+        StartContentRefresh();
+        
+        TRAP_IGNORE
+            (
+            iAppUi.UiEngineL()->RenderUIL();                                  //jtm+++
+            ProcessContentChangesL( *tr );
+            );
+                
+        
+        iFactory->ReleaseTransaction( tr );  
+        
+        return error;
+        }
+        
+    return KErrNotSupported;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::ProcessContentChangesL
+// 
+// ----------------------------------------------------------------------------
+//
+void CContentRenderer::ProcessContentChangesL( MTransaction& aTr )
+    {
+    TDblQueIter<CTransactionElement> iter( aTr.ElementIter() );
+    RAiPolicyElementArray contentChangedArray;
+    CleanupClosePushL( contentChangedArray );
+
+    while ( iter )
+          {
+          CTransactionElement* element = iter++;
+          CXnNodeAppIf& target = element->Target();
+          
+          // Find own and parents policy/ContentChanged nodes 
+          iPolicyEvaluator->EvaluateContentChangedPolicyL( target, 
+                  contentChangedArray);
+
+          iPolicyEvaluator->EvaluateContentChangedPolicyL( *(target.ParentL() ), 
+                  contentChangedArray);
+          }
+       
+    ::RemoveDuplicateContentChangesL( contentChangedArray );
+        
+    for ( TInt i = 0; i < contentChangedArray.Count(); ++i )
+        {
+        ProcessContentChangeL( contentChangedArray[i] );
+        }
+    
+    CleanupStack::PopAndDestroy();
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::ProcessContentChangeL
+// 
+// ----------------------------------------------------------------------------
+//
+void CContentRenderer::ProcessContentChangeL( TAiPolicyElement& aElement )
+    {
+    const TDesC8* id( PropertyValue( 
+        aElement.Target(), AiUiDef::xml::property::KId ) ); 
+                                
+    if ( id )
+        {
+        CXnNodeAppIf* targetNode( 
+            FindNodeByIdL( *id, aElement.Target().Namespace() ) );
+        
+        if ( targetNode )
+            {                     
+            if ( aElement.Policy() == AiUiDef::xml::value::KShowTooltips )
+                {
+                targetNode->ShowTooltipsL();
+                }                   
+            }        
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::CancelTransaction
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::CancelTransaction( TInt aTxId )
+    {
+    // Remove transaction with aTxId from stack
+    MTransaction* tr( iStack->Remove( aTxId ) );
+
+    if ( tr )
+        {
+        // Release transaction to factory
+        __TICK("XML UI: Cancel transaction");
+        __HEAP("XML UI: Cancel transaction");
+        __PRINT(__DBG_FORMAT("\t[I]\tXML UI: Cancel transaction id=%d"), aTxId);
+
+        iFactory->ReleaseTransaction( tr );
+
+        return KErrNone;
+        }
+
+    return KErrNotSupported;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::CanPublish
+// 
+// ----------------------------------------------------------------------------
+//
+TBool CContentRenderer::CanPublish( CHsContentPublisher& aPlugin,
+    TInt aContent, TInt aIndex )                                   
+    {
+    TInt error( KErrNone );
+    TInt retval( KErrNone );
+        
+    __PRINTS("*** XML UI: CContentRenderer::CanPublish ***");
+    
+    __PRINT( __DBG_FORMAT( "* Publisher name: %S, uid: 0x%x" ),          
+        &aPlugin.PublisherInfo().Name(), aPlugin.PublisherInfo().Uid().iUid ); 
+                                  
+	__TIME("UC: Content Validation",
+        TRAP( error, retval = CanPublishL( aPlugin, aContent, aIndex ) ) );
+            
+	__HEAP("UC: Content Validation");
+    
+	TBool ret( error == KErrNone && retval == KErrNone );
+	
+	__PRINT( __DBG_FORMAT("*** XML UI: CContentRenderer::CanPublish - done, CanPublish: %d ***"), ret );
+    
+    return ret;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::Publish
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::Publish( CHsContentPublisher& aPlugin, TInt aContent, 
+    TInt aResource, TInt aIndex )
+    {
+	TInt error( KErrNone );
+	TInt retval( KErrNone );
+	
+	__PRINTS("*** XML UI: CContentRenderer::Publish (Resource) ***");
+	
+    __PRINT( __DBG_FORMAT( "* Publisher name: %S, uid: 0x%x" ),          
+        &aPlugin.PublisherInfo().Name(), aPlugin.PublisherInfo().Uid().iUid ); 
+		
+	__TIME("UC: Content Publishing (Resource)",
+    	TRAP( error, retval = DoPublishL( aPlugin, aContent, aResource, aIndex ) ) );
+    
+    __HEAP("UC: Content Publishing (Resource)");
+    
+    if( !error && retval )
+        {
+        error = retval;
+        }
+    
+    __PRINT( __DBG_FORMAT("*** XML UI: CContentRenderer::Publish (Resource) - done, error: %d ***"), error );
+            
+    return error;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::Publish
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::Publish( CHsContentPublisher& aPlugin, TInt aContent, 
+    const TDesC16& aText, TInt aIndex )
+    {
+    TInt error( KErrNone );
+    TInt retval( KErrNone );
+    
+    __PRINTS("*** XML UI: CContentRenderer::Publish (Value-Text) ***");
+    
+    __PRINT( __DBG_FORMAT( "* Publisher name: %S, uid: 0x%x" ),          
+        &aPlugin.PublisherInfo().Name(), aPlugin.PublisherInfo().Uid().iUid ); 
+    
+   	__TIME("UC: Content Publishing (Value-Text)",
+    	TRAP( error, retval = DoPublishL( aPlugin, aContent, aText, aIndex ) ) );
+       	
+    __HEAP("UC: Content Publishing (Value-Text)");
+        
+    if( !error && retval )
+        {
+        error = retval;
+        }
+
+    __PRINT( __DBG_FORMAT("*** XML UI: CContentRenderer::Publish (Value-Text) - done, error: %d ***"), error );
+    
+    return error;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::Publish
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::Publish( CHsContentPublisher& aPlugin, TInt aContent, 
+    const TDesC8& aBuf, TInt aIndex )
+    {
+    TInt error( KErrNone );
+    TInt retval( KErrNone );
+    
+    __PRINTS("*** XML UI: CContentRenderer::Publish (Value-Buf) ***");
+    
+    __PRINT( __DBG_FORMAT( "* Publisher name: %S, uid: 0x%x" ),          
+        &aPlugin.PublisherInfo().Name(), aPlugin.PublisherInfo().Uid().iUid ); 
+    
+    __TIME("UC: Content Publishing (Value-Buf)",
+    	TRAP( error, retval = DoPublishL( aPlugin, aContent, aBuf, aIndex ) ) );
+    
+    __HEAP("UC: Content Publishing (Value-Buf)");
+       
+    if( !error && retval )
+        {
+        error = retval;
+        }
+    
+    __PRINT( __DBG_FORMAT("*** XML UI: CContentRenderer::Publish (Value-Buf) - done, error: %d ***"), error );
+    
+    return error;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::Publish
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::Publish( CHsContentPublisher& aPlugin, TInt aContent,                                
+    RFile& aFile, TInt aIndex )                                
+    {
+    TInt error( KErrNone );
+    TInt retval( KErrNone );
+    	
+	__PRINTS("*** XML UI: CContentRenderer::Publish (Value-RFile) ***");
+	
+    __PRINT( __DBG_FORMAT( "* Publisher name: %S, uid: 0x%x" ),          
+        &aPlugin.PublisherInfo().Name(), aPlugin.PublisherInfo().Uid().iUid ); 
+	
+    __TIME("UC: Content Publishing (Value-RFile)",
+    	TRAP( error, retval = DoPublishL( aPlugin, aContent, aFile, aIndex ) ) );
+
+    __HEAP("UC: Content Publishing (Value-RFile)");
+        
+    if( !error && retval )
+        {
+        error = retval;
+        }
+    
+    __PRINT( __DBG_FORMAT("*** XML UI: CContentRenderer::Publish (Value-RFile) - done, error: %d ***"), error );
+    
+    return error;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::Clean
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::Clean( CHsContentPublisher& aPlugin, TInt aContent, 
+    TInt aIndex )
+    {
+    TInt error( KErrNone );
+    TInt retval( KErrNone );
+            
+    __PRINTS("*** XML UI: CContentRenderer::Clean (Clean) ***");
+    
+    __PRINT( __DBG_FORMAT( "* Publisher name: %S, uid: 0x%x" ),          
+        &aPlugin.PublisherInfo().Name(), aPlugin.PublisherInfo().Uid().iUid ); 
+        
+    __TIME("UC: Content Publishing (Clean)",
+    	TRAP( error, retval = DoCleanL( aPlugin, aContent, aIndex ) ) );
+    
+    __HEAP("UC: Content Publishing (Clean)");
+       
+    if( !error && retval )
+        {
+        error = retval;
+        }
+    
+    __PRINT( __DBG_FORMAT("*** XML UI: CContentRenderer::Clean (Clean) - done, error: %d ***"), error );
+    
+    return error;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::CContentRenderer
+// 
+// ----------------------------------------------------------------------------
+//
+TAny* CContentRenderer::Extension( TUid /*aUid*/ )
+    {
+    // No extensions supported
+    return NULL;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::RequiresSubscription
+// 
+// ----------------------------------------------------------------------------
+//
+TBool CContentRenderer::RequiresSubscription( 
+    const THsPublisherInfo& aPublisherInfo ) const
+    {
+    if ( aPublisherInfo.Namespace() == KNativeUiNamespace )
+        {
+        // Not targeted to this content renderer
+        return EFalse;
+        }
+        
+    return ETrue;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::DoStartTransactionL
+// 
+// ----------------------------------------------------------------------------
+//
+void CContentRenderer::DoStartTransactionL( TInt aTxId )
+    {
+    MTransaction* tr( iFactory->CreateTransactionL( aTxId ) );
+    iStack->Push( tr );
+    
+    SetImmediateMode( EFalse );
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::CanPublishL
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::CanPublishL( CHsContentPublisher& aPlugin,
+    TInt aContent, TInt aIndex )                                    
+    {
+    // Get content item for aContent
+    MAiContentItemIterator* iter( ContentItemIterator(  
+        aPlugin, CHsContentPublisher::EPublisherContent ) );
+    
+    if ( !iter )
+        {
+        return KErrNotSupported;
+        }
+
+    const TAiContentItem& item( iter->ItemL( aContent ) );
+
+    // Lookup ui element
+    const TDesC& nodeId( iNodeIdGenerator->ContentNodeIdL( aPlugin, item ) );
+
+    CXnNodeAppIf* property( FindNodeByClassL( nodeId, aIndex, 
+        aPlugin.PublisherInfo().Namespace() ) ); 
+ 
+    if( !property )
+        {
+        return KErrNotFound;
+        }
+    
+    // Check content priority
+    TInt priority( ContentPriority( *property ) );
+
+    CXnNodeAppIf* target( property->ParentL() );
+    
+    if( !target )
+        {
+        return KErrNotSupported;
+        }
+
+    if ( !AllowPublishByPriority( *target, priority ) )
+        {
+        return KErrAccessDenied;        
+        }
+
+    // Check if content type is supported by target
+    const TDesC8& contentType( ContentType( item ) );
+
+    if ( !iFactory->IsSupported( *target, contentType ) &&
+        target->Type()->Type() != XnPropertyNames::listquerydialog::KListQueryDialog )
+        {
+        return KErrNotSupported;
+        }
+    
+    return KErrNone;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::DoPublishL
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::DoPublishL( CHsContentPublisher& aPlugin, TInt aContent,
+    TInt aResource, TInt aIndex )                                  
+    {
+    TInt retval( KErrNotSupported );
+    
+    const THsPublisherInfo& info( aPlugin.PublisherInfo() );
+
+    // Read ref value.
+    MAiContentItemIterator* resIter( ContentItemIterator( 
+        aPlugin, CHsContentPublisher::EPublisherResources ) );
+    
+    if ( !resIter )
+        {
+        return retval;
+        }
+    
+    const TAiContentItem& ref( resIter->ItemL( aResource ) );
+
+    const TDesC8& refType( ContentType( ref ) );
+
+    // Resolve source node
+    const TDesC& nodeId( iNodeIdGenerator->ResourceNodeIdL( aPlugin, ref ) );
+    
+    HBufC8* nodeId8( CnvUtfConverter::ConvertFromUnicodeToUtf8L( nodeId ) );
+    CleanupStack::PushL( nodeId8 );
+    
+    CXnNodeAppIf* source( NULL );
+    
+    __TIME_MARK( xmlOverhead );
+    
+    source = FindNodeByIdL( *nodeId8, info.Namespace() );
+    
+    __TIME_ENDMARK("XML UI: Lookup node by id", xmlOverhead);
+    __PRINT(__DBG_FORMAT("\t[I]\tXML UI: Lookup node by id=%S"), &nodeId);
+    
+    CleanupStack::PopAndDestroy( nodeId8 );
+    
+    // Fetch content id
+    MAiContentItemIterator* iter( ContentItemIterator( 
+       aPlugin, CHsContentPublisher::EPublisherContent ) );
+    
+    if ( !iter )
+        {
+        return retval;
+        }
+    
+    const TAiContentItem& item( iter->ItemL( aContent ) );
+
+    const TDesC& targetId( iNodeIdGenerator->ContentNodeIdL( aPlugin, item ) );
+    
+    // Check types
+    if ( refType == KContentTypeText )
+        {
+        // Fetch text
+        const TDesC8& text( source->GetPCData() );
+        
+        // Delegate to data publishing function
+        retval = PublishDataL( aPlugin,
+                               targetId,
+                               text,
+                               refType,
+                               aIndex,
+                               source );
+        }
+    else if ( refType.Find( KContentTypeImage ) != KErrNotFound )
+        {
+        // Fetch icon
+        CGulIcon* icon( LoadIconLC( *source ) ); 
+        
+       // Delegate to icon publishing function
+        retval = PublishIconL( aPlugin,
+                               targetId,
+                               icon,
+                               aIndex,
+                               source );
+        
+        CleanupStack::Pop( icon );
+        }
+    
+    return retval;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::DoPublishL
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::DoPublishL( CHsContentPublisher& aPlugin, TInt aContent,                                  
+    const TDesC16& aText, TInt aIndex )                                   
+    {
+    const THsPublisherInfo& info( aPlugin.PublisherInfo() );
+
+    // Resolve content item
+    MAiContentItemIterator* iter( ContentItemIterator( 
+        aPlugin, CHsContentPublisher::EPublisherContent ) ); 
+            
+    if ( !iter )
+        {
+        return KErrNotSupported;
+        }
+    
+    const TAiContentItem& item( iter->ItemL( aContent ) );
+
+    const TDesC8& type( ContentType( item ) );
+
+    if ( type == KContentTypeText )
+        {
+        // Find ui element
+        const TDesC& nodeId( 
+            iNodeIdGenerator->ContentNodeIdL( aPlugin, item ) ); 
+            
+        __TIME_MARK( xmlOverhead );
+
+        CXnNodeAppIf* property( FindNodeByClassL(  
+            nodeId, aIndex, info.Namespace() ) );
+
+        if( !property )
+            {
+            return KErrNotFound;
+            }
+        
+        TInt priority( ContentPriority( *property ) );
+        
+        __TIME_ENDMARK("XML UI: Lookup node by class", xmlOverhead);
+    	__PRINT(__DBG_FORMAT("\t[I]\tXML UI: Lookup node by class=%S"), &nodeId);
+
+        //Navigate to parent
+        CXnNodeAppIf* target( property->ParentL() );
+
+        if( !target )
+            {
+            return KErrNotSupported;
+            }
+        
+        // Check priority
+        if ( AllowPublishByPriority( *target, priority ) )
+            {
+            // Check if target is newsticker
+            MTransactionElement* element( NULL );
+            
+            if ( IsParentNewsticker( *target ) )
+                {                
+                CXnNodeAppIf *parent( target->ParentL() );
+                
+                if( !parent )
+                    {
+                    return KErrNotFound;
+                    }
+                                
+                element = iFactory->CreateNewsTickerTransactionElementL( 
+                        *target, aText, priority, aIndex );
+                }
+            else if( target->Type()->Type() == 
+                     XnListQueryDialogInterface::MXnListQueryDialogInterface::Type())
+                {
+                // Get the data interface for dialog and publish data
+                XnListQueryDialogInterface::MXnListQueryDialogInterface* listQuery( NULL );
+                XnComponentInterface::MakeInterfaceL( listQuery, *target );
+                LeaveIfNull( listQuery, KErrNotSupported );
+                listQuery->ReplaceItemL( aText, aIndex -1 );// plugins publish ordinals not indexes
+                return KErrNone;
+                }
+            else
+                {
+                // Create transaction element for text
+                // Not put to cleanupstack, because element is from our pool!
+                element = iFactory->CreateTextTransactionElementL( *target,
+                                                                    aText,
+                                                                    priority );
+                }
+            
+            iPolicyEvaluator->EvaluateContentPolicyL( 
+                    *target, element->PolicyArray() );
+                                                     
+            iPolicyEvaluator->EvaluateVisibilityPolicyL( 
+                    *target, element->PolicyArray() );
+                                                         
+            ProcessTransactionElementL( element );
+            }
+        else
+            {
+            return KErrAccessDenied;            
+            }
+        }
+    else
+        {
+        return KErrNotSupported;
+        }
+    
+    return KErrNone;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::DoPublishL
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::DoPublishL( CHsContentPublisher& aPlugin, TInt aContent,
+    const TDesC8& aBuf, TInt aIndex )                                   
+    {
+    TInt retval( KErrNotSupported );
+    
+    // resolve content item
+    MAiContentItemIterator* iter( ContentItemIterator( 
+        aPlugin, CHsContentPublisher::EPublisherContent ) ); 
+            
+    if ( !iter )
+        {
+        return retval;
+        }
+    
+    const TAiContentItem& item( iter->ItemL( aContent ) );
+
+    const TDesC8& type( ContentType( item ) );
+    
+    const TDesC& nodeId( iNodeIdGenerator->ContentNodeIdL( aPlugin, item ) );
+
+    if( type == KContentTypeBitmap )
+        {
+        // Unpack icon from pointer
+        CGulIcon* icon( LeaveIfNull( UnpackPtr<CGulIcon>( aBuf ), KErrArgument ) );
+                
+        // Publish icon
+        retval = PublishIconL( aPlugin, nodeId, icon, aIndex );
+        }
+    else if ( type == KContentTypeImageSvg || type == KContentTypeData )        
+        {
+        // Publish data
+        retval = PublishDataL( aPlugin, nodeId, aBuf, type, aIndex );
+        }
+
+    return retval;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::DoPublishL
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::DoPublishL( CHsContentPublisher& aPlugin, TInt aContent,
+    RFile& aFile, TInt aIndex )                                   
+    {
+    const THsPublisherInfo& info( aPlugin.PublisherInfo() );
+    
+    //Resolve content item
+    MAiContentItemIterator* iter( ContentItemIterator( 
+        aPlugin, CHsContentPublisher::EPublisherContent ) ); 
+
+    if ( !iter )
+        {
+        return KErrNotSupported;
+        }
+    
+    const TAiContentItem& item( iter->ItemL( aContent ) );
+
+    const TDesC8& type( ContentType( item ) );
+
+    // Image support
+    if ( type.Find( KContentTypeImage ) != KErrNotFound )
+        {
+        // Find ui element
+        const TDesC& nodeId( iNodeIdGenerator->ContentNodeIdL( aPlugin, item ) );
+
+        CXnNodeAppIf* property( FindNodeByClassL( 
+            nodeId, aIndex, info.Namespace() ) );
+                                        
+        if( !property )
+            {
+            return KErrNotFound;
+            }
+        
+        // Check priority
+        TInt priority( ContentPriority( *property ) );
+        
+        CXnNodeAppIf* target( property->ParentL() );
+        
+        if( !target )
+            {
+            return KErrNotSupported;
+            }
+
+        if ( AllowPublishByPriority( *target, priority ) )
+            {            
+            // Create transaction element for file
+            MTransactionElement* element =
+                iFactory->CreateImageTransactionElementL( 
+                        *target, aFile, priority );
+                                                          
+            iPolicyEvaluator->EvaluateContentPolicyL( 
+                    *target, element->PolicyArray() );
+                                                      
+            iPolicyEvaluator->EvaluateVisibilityPolicyL( 
+                    *target, element->PolicyArray() );
+                                                                     
+            ProcessTransactionElementL( element );
+            }
+        else
+            {
+            return KErrAccessDenied;
+            }
+        }
+    else 
+        {
+        return KErrNotSupported;        
+        }
+    
+    return KErrNone;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::DoCleanL
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::DoCleanL( CHsContentPublisher& aPlugin, TInt aContent,
+    TInt aIndex )                                                
+    {
+    const THsPublisherInfo& info( aPlugin.PublisherInfo() );
+    
+    // Resolve content item
+    MAiContentItemIterator* iter( ContentItemIterator( 
+        aPlugin, CHsContentPublisher::EPublisherContent ) ); 
+            
+    if ( !iter )
+        {
+        return KErrNotSupported;
+        }
+    
+    const TAiContentItem& item( iter->ItemL( aContent ) );
+
+    const TDesC& nodeId( iNodeIdGenerator->ContentNodeIdL( aPlugin, item ) );
+
+    CXnNodeAppIf* property( FindNodeByClassL( 
+        nodeId, aIndex, info.Namespace() ) ); 
+            
+    if( !property )
+        {
+        return KErrNotFound;
+        }
+    
+    TInt priority( ContentPriority( *property ) );
+
+    // Navigate to parent
+    CXnNodeAppIf* target( property->ParentL() );
+
+    if( !target )
+        {
+        return KErrNotSupported;
+        }
+    
+    if ( !AllowPublishByPriority( *target, priority ) )
+        {
+        return KErrAccessDenied;
+        }
+
+    if( target->Type()->Type() ==
+        XnListQueryDialogInterface::MXnListQueryDialogInterface::Type())
+        {
+        // Get the data interface for dialog and delete data
+        XnListQueryDialogInterface::MXnListQueryDialogInterface* listQuery( NULL );
+        XnComponentInterface::MakeInterfaceL( listQuery, *target );
+        LeaveIfNull( listQuery, KErrNotSupported );
+        listQuery->DeleteItem( aIndex -1 );// plugins publish ordinals not indexes
+        return KErrNone;
+        }
+    
+    // Create transaction element for empty content
+    MTransactionElement* element =
+        iFactory->CreateEmptyContentTransactionElementL( 
+                *target, aIndex );
+
+    iPolicyEvaluator->EvaluateEmptyContentPolicyL( 
+            *target, element->PolicyArray() );
+                                                   
+    iPolicyEvaluator->EvaluateVisibilityPolicyL( 
+            *target, element->PolicyArray() );
+                                                   
+    ProcessTransactionElementL( element );
+      
+    if ( priority > KErrNotFound ) // Only for prioritized elements
+        {
+        // Add current ui element into content refresh map
+        HBufC* uiElementId( PropertyValueL( 
+            *target, XnPropertyNames::common::KId ) );
+                                         
+        return RefreshContentL( uiElementId, priority );
+        }
+    
+    return KErrNone;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::SetImmediateMode
+// 
+// ----------------------------------------------------------------------------
+//
+void CContentRenderer::SetImmediateMode( TBool aImmediateMode )
+    {
+    iImmediateMode = aImmediateMode;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::IsImmediateMode
+// 
+// ----------------------------------------------------------------------------
+//
+TBool CContentRenderer::IsImmediateMode() const
+    {
+    return iImmediateMode;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::ProcessTransactionElementL
+// 
+// ----------------------------------------------------------------------------
+//
+void CContentRenderer::ProcessTransactionElementL( 
+    MTransactionElement* aElement )
+    {
+    LeaveIfNull( aElement, KErrArgument );
+    
+    __PRINTS("*** XML UI: CContentRenderer::ProcessTransactionElementL ***");
+    
+    if ( IsImmediateMode() || iStack->IsEmpty() )
+        {      
+        __PRINTS("* Immediate transaction mode, or transaction stack is empty" );
+        
+        // No transaction. Commit element immediately
+        TBool layoutChanged( EFalse );
+        
+        RPropertyHashMap propertyHashMap;
+        CleanupClosePushL( propertyHashMap );
+        
+        aElement->CommitL( layoutChanged, propertyHashMap );
+        SetPropertyArraysL( propertyHashMap );
+        
+        CleanupStack::PopAndDestroy( &propertyHashMap );
+        
+        iFactory->ReleaseTransactionElement( aElement );
+        StartContentRefresh();
+        
+        // Re-layout
+        iAppUi.UiEngineL()->RenderUIL();
+        }
+    else
+        {
+        // Append transaction element to transaction
+        __PRINTS("* Adding transaction element to stack");
+        
+        MTransaction* tr( iStack->Top() );
+        tr->Append( *aElement );
+        }
+    
+    __PRINTS("*** XML UI: CContentRenderer::ProcessTransactionElementL - done ***");
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::FindNodeByClassL
+// 
+// ----------------------------------------------------------------------------
+//
+CXnNodeAppIf* CContentRenderer::FindNodeByClassL( const TDesC& aCid,
+    TInt aIndex, const TDesC8& aNs )                                                  
+    {
+    // Find node
+    HBufC8* classId( CnvUtfConverter::ConvertFromUnicodeToUtf8L( aCid ) );
+    CleanupStack::PushL( classId );
+    
+    RPointerArray<CXnNodeAppIf> nodes( 
+        iAppUi.UiEngineL()->FindNodeByClassL( *classId, aNs ) );
+
+    CleanupStack::PopAndDestroy( classId );
+
+    CleanupClosePushL( nodes );
+
+    for ( TInt i = 0; i < nodes.Count(); ++i )
+        {
+        CXnNodeAppIf* node = nodes[i];
+
+        const TDesC8* name(
+            PropertyValue( *node, AiUiDef::xml::property::KName ) );
+
+        if ( name && ( *name == AiUiDef::xml::name::KOrdinal ) )
+            {
+            const TDesC8* value(
+                PropertyValue( *node, AiUiDef::xml::property::KValue ) );
+
+            if ( value )
+                {
+                // Try to parse index from string either
+                TInt32 index( 0 );
+
+                User::LeaveIfError( AiUtility::ParseInt( index, *value ) );
+
+                if ( index == aIndex )
+                    {
+                    CleanupStack::PopAndDestroy( &nodes );
+                    
+                    return node;
+                    }
+                }
+            }
+        else if ( name && ( *name == AiUiDef::xml::name::KTarget ) )
+            {            
+            const TDesC8* target(
+               PropertyValue( *node, AiUiDef::xml::property::KValue ) );
+            
+            CXnNodeAppIf* targetNode( 
+                FindNodeByIdL( *target, node->Namespace() ) );
+            
+            if ( targetNode )
+                {
+                CleanupStack::PopAndDestroy( &nodes );
+                
+                return targetNode;
+                }
+            }
+        else if ( nodes.Count() == 1 ) // Only one node in class
+            {
+            node = nodes[ 0 ];
+            
+            // No ordinal specified			
+			CleanupStack::PopAndDestroy( &nodes );
+			
+            return node;
+            }
+        }
+    
+    CleanupStack::PopAndDestroy( &nodes );
+    
+    return NULL; // Never reached. Needed to omit compiler warning
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::FindNodeByIdL
+// 
+// ----------------------------------------------------------------------------
+//
+CXnNodeAppIf* CContentRenderer::FindNodeByIdL( const TDesC& aCid, 
+    const TDesC& aNs )
+    {
+    // Find node
+    return LeaveIfNull( 
+        iAppUi.UiEngineL()->FindNodeByIdL( aCid, aNs ), KErrNotFound );                        
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::FindNodeByIdL
+// 
+// ----------------------------------------------------------------------------
+//
+CXnNodeAppIf* CContentRenderer::FindNodeByIdL( const TDesC8& aCid, 
+    const TDesC8& aNs )
+    {
+    // Find node
+    return LeaveIfNull( 
+        iAppUi.UiEngineL()->FindNodeByIdL( aCid, aNs ), KErrNotFound );                        
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::PublishIconL
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::PublishIconL( CHsContentPublisher& aPlugin,
+    const TDesC& aCid, CGulIcon* aIcon, TInt aIndex, CXnNodeAppIf* aResource )
+    {
+    const THsPublisherInfo& info( aPlugin.PublisherInfo() );
+    
+    // Find proiperty element by class
+    CXnNodeAppIf* property( 
+        FindNodeByClassL( aCid, aIndex, info.Namespace() ) );                             
+    
+    if( !property )
+        {
+        return KErrNotFound;
+        }
+    
+    // Get priority information
+    TInt priority( ContentPriority( *property ) );
+    
+    // Navigate to parent
+    CXnNodeAppIf* target( property->ParentL() );
+    
+    if( !target )
+        {
+        return KErrNotFound;
+        }
+
+    // Check priority
+    if ( !AllowPublishByPriority( *target, priority ) )
+        {
+        return KErrAccessDenied;        
+        }
+    
+    MTransactionElement* element =
+        iFactory->CreateImageTransactionElementL( 
+            *target, aIcon, priority );
+
+    if ( aResource )
+        {
+        iPolicyEvaluator->EvaluateResourcePolicyL( 
+            *target, *aResource, element->PolicyArray() );
+
+        iPolicyEvaluator->EvaluateContentPolicyL( 
+            *target, element->PolicyArray() );
+                                                  
+        iPolicyEvaluator->EvaluateVisibilityPolicyL( 
+            *target, element->PolicyArray() );                                                     
+        }
+
+    else
+        {
+        iPolicyEvaluator->EvaluateContentPolicyL( 
+            *target, element->PolicyArray() );
+                                                  
+        iPolicyEvaluator->EvaluateVisibilityPolicyL( 
+            *target, element->PolicyArray() );                                                    
+        }
+
+    ProcessTransactionElementL( element );
+    
+    return KErrNone;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::PublishDataL
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::PublishDataL( CHsContentPublisher& aPlugin,
+    const TDesC& aCid, const TDesC8& aData, const TDesC8& aContentType,
+    TInt aIndex, CXnNodeAppIf* aResource )                                     
+    {
+    const THsPublisherInfo& info( aPlugin.PublisherInfo() );
+    
+    CXnNodeAppIf* property( 
+        FindNodeByClassL( aCid, aIndex, info.Namespace() ) );                             
+
+    if( !property )
+        {
+        return KErrNotFound;
+        }
+    
+    TInt priority( ContentPriority( *property ) );
+    
+    // Navigate to parent
+    CXnNodeAppIf* target( property->ParentL() );
+    
+    if( !target )
+        {
+        return KErrNotFound;
+        }
+
+    if ( !AllowPublishByPriority( *target, priority ) )
+        {
+        return KErrAccessDenied;        
+        }
+
+    if ( !CDataBufferTransactionElement::IsSupported( *target, aContentType ) )
+        {
+        return KErrNotSupported;        
+        }
+        
+    MTransactionElement* element( NULL );
+    
+    if ( aContentType == KContentTypeData )
+        {
+        element = iFactory->CreateDataBufferTransactionElementL( 
+            *target, aData, priority, aCid, aIndex );
+        }
+    else
+        {
+        element = iFactory->CreateDataBufferTransactionElementL(     
+            *target, aData, priority );    
+        }
+                                                       
+    if ( aResource )
+        {
+        iPolicyEvaluator->EvaluateResourcePolicyL( 
+            *target, *aResource, element->PolicyArray() );
+                                                   
+        iPolicyEvaluator->EvaluateContentPolicyL( 
+            *target, element->PolicyArray() );
+                                                  
+        iPolicyEvaluator->EvaluateVisibilityPolicyL( 
+            *target, element->PolicyArray() );                                                     
+        }
+    else
+        {
+        iPolicyEvaluator->EvaluateContentPolicyL( 
+            *target, element->PolicyArray() );
+                                                  
+        iPolicyEvaluator->EvaluateVisibilityPolicyL( 
+            *target, element->PolicyArray() );                                                     
+        }
+
+    ProcessTransactionElementL( element );
+    
+    return KErrNone;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::SetProperty
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::SetProperty( CHsContentPublisher& aPlugin,
+    const TDesC8& aElementId, const TDesC8& aPropertyName, 
+    const TDesC8& aPropertyValue )
+    {
+   return ( SetProperty( aPlugin, aElementId, 
+               aPropertyName, aPropertyValue,
+               MAiContentObserver::EValueString ) );
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::SetProperty
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::SetProperty( CHsContentPublisher& aPlugin,
+    const TDesC8& aElementId, const TDesC8& aPropertyName,        
+    const TDesC8& aPropertyValue, MAiContentObserver::TValueType aValueType )     
+    {
+    TInt error( KErrNone );
+    TInt retval( KErrNone );
+
+    TRAP( error, retval = SetPropertyL( aPlugin, aElementId, aPropertyName,
+            aPropertyValue, aValueType ) );
+    
+    if( !error && retval )
+     {
+     error = retval;
+     }
+    
+    return error;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::SetPropertyL
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::SetPropertyL( CHsContentPublisher& aPlugin,
+    const TDesC8& aElementId, const TDesC8& aPropertyName,    
+    const TDesC8& aPropertyValue, MAiContentObserver::TValueType aValueType )         
+    {
+    TInt err( KErrNone ); 
+    // Find node
+    
+    CXnNodeAppIf* targetNode( 
+        FindNodeByIdL( aElementId, aPlugin.PublisherInfo().Namespace() ) );
+    
+    if ( targetNode )
+       {
+       CXnDomStringPool& sp( targetNode->UiEngineL()->StringPool() );
+              
+       CXnProperty* prop = CXnProperty::NewL( 
+               aPropertyName,
+               aPropertyValue,
+               DomPropertyValueType(aValueType), sp );
+                      
+       CleanupStack::PushL( prop );
+    
+       targetNode->SetPropertyL( prop );
+      
+       CleanupStack::Pop( prop );
+       }
+    else
+       {
+       err = KErrNotFound;
+       }
+    
+    return err;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::DomPropertyValueType
+// 
+// ----------------------------------------------------------------------------
+//
+CXnDomPropertyValue::TPrimitiveValueType CContentRenderer::DomPropertyValueType(     
+    MAiContentObserver::TValueType aValueType )
+    {
+    CXnDomPropertyValue::TPrimitiveValueType type(
+            CXnDomPropertyValue::EUnknown );
+    
+    switch ( aValueType )
+        {
+        case MAiContentObserver::EValueNumber :
+            {
+            type = CXnDomPropertyValue::ENumber;
+            }
+            break;
+        case MAiContentObserver::EValuePercentage :
+            {
+            type = CXnDomPropertyValue::EPercentage;
+            }
+            break;
+        case MAiContentObserver::EValuePx :
+            {
+            type = CXnDomPropertyValue::EPx;
+            }
+            break;
+        case MAiContentObserver::EValueString :
+            {
+            type = CXnDomPropertyValue::EString;
+            }
+            break;
+        case MAiContentObserver::EValueRgbColor :
+            {
+            type = CXnDomPropertyValue::ERgbColor;
+            }
+            break;
+        case MAiContentObserver::EValueUnitValue :
+            {
+            type = CXnDomPropertyValue::EUnitValue;
+            }
+            break;
+        default:
+            {
+            type = CXnDomPropertyValue::EUnknown;
+            }
+        }
+    
+    return type;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::AllowPublishByPriority
+// 
+// ----------------------------------------------------------------------------
+//
+TBool CContentRenderer::AllowPublishByPriority( CXnNodeAppIf& aUiElement,
+    TInt aPriority ) const
+    {
+    // Get ui element id
+    const TDesC8* uiElementId( 
+        PropertyValue( aUiElement, XnPropertyNames::common::KId ) );
+                                                                                        
+    if ( uiElementId )
+        {
+        // compare given priority with the current value of ui element
+        return iContentPriorityMap->OverrideContent( *uiElementId, aPriority );
+        }
+    
+    // priority cannot be used, because ui element does not have id
+    return EFalse; 
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::StartContentRefresh
+// 
+// ----------------------------------------------------------------------------
+//
+void CContentRenderer::StartContentRefresh()
+    {
+    // Cancel ongoing refresh
+    iTimer->Cancel();
+    
+    if ( iRefreshableUiElements.Count() > 0 )
+        {
+        // Refreshable elements exist. Start timer to make refresh asynchronous 
+        iTimer->Start( TTimeIntervalMicroSeconds32( 0 ),
+                       TTimeIntervalMicroSeconds32( 0 ),
+                       TCallBack( RefreshContentCallback, this ) );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::RefreshContentL
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::RefreshContentL( HBufC* aUiElementId,
+    TInt aOldPriority )
+    {
+    if( !aUiElementId )
+        {
+        return KErrArgument;
+        }
+        
+    // Take ownership of aUiElementId
+    CleanupStack::PushL( aUiElementId );
+    
+    if ( !iFwEventHandler )
+        {
+        // Content refresh event cannot be sent
+        CleanupStack::PopAndDestroy( aUiElementId );
+    
+        return KErrNotReady;
+        }
+    
+    // Find current mapping
+    TInt* oldPriority( iRefreshableUiElements.Find( *aUiElementId ) );
+    
+    if ( oldPriority )
+        {
+        // Update mapping
+        *oldPriority = aOldPriority;
+        CleanupStack::PopAndDestroy( aUiElementId );
+        }
+    else
+        {
+        // Create new mapping
+        oldPriority = new( ELeave ) TInt( aOldPriority );
+        CleanupStack::PushL( oldPriority );
+    
+        User::LeaveIfError( iRefreshableUiElements.Insert( aUiElementId,
+                                                           oldPriority ) );
+                                                       
+        CleanupStack::Pop( 2, aUiElementId );
+        }
+    
+    return KErrNone;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::RefreshContentCallback
+// 
+// ----------------------------------------------------------------------------
+//
+TInt CContentRenderer::RefreshContentCallback( TAny* aContentRenderer )
+    {
+    if ( !aContentRenderer )
+        {
+        return KErrArgument;
+        }
+        
+    CContentRenderer* self = 
+        static_cast< CContentRenderer* >( aContentRenderer );
+    
+    TRAP_IGNORE( self->SendRefreshContentEventL() );
+    
+    return KErrNone;
+    }
+
+// ----------------------------------------------------------------------------
+// CContentRenderer::SendRefreshContentEventL
+// 
+// ----------------------------------------------------------------------------
+//
+void CContentRenderer::SendRefreshContentEventL()
+    {
+    /**
+     * Sends Refresh content event to framework.
+     * Event is sent for content selectors with lower priority than the
+     * last content which has been cleaned from ui element.
+     */ 
+
+    // Cancel periodic timer.
+    iTimer->Cancel();
+    
+    // Get ui element id and old content priority
+    TPtrHashMapIter< TDesC, TInt> iter( iRefreshableUiElements );
+    iter.Reset();
+    
+    const TDesC* uiElementId( iter.NextKey() ); // Never NULL
+    TInt priority( *( iter.CurrentValue() ) );
+    
+    //  Cleanup item for iterator 
+    TMapCleanupItem cleanup( iter );
+    CleanupReleasePushL( cleanup );
+    
+    // Lookup ui element
+    CXnNodeAppIf* uiElement( FindNodeByIdL( *uiElementId ) );
+    
+    // Remove current ui element from the map
+    CleanupStack::PopAndDestroy( &cleanup );
+    
+    // Find lower priority content elements associated to this ui element
+    RPointerArray< CXnNodeAppIf > children( uiElement->ChildrenL() );
+    
+    // Remove higher priority content elements
+    RemoveNonPriorityElements( children, priority );
+        
+    // Sort array to descending order
+    children.Sort( TLinearOrder< CXnNodeAppIf >( DescendingPriorityOrder ) );
+    
+    // Send event for content selectors in descending priority order.
+    // Continue until first content gets published or array exhausts.
+    for ( TInt i = 0; i < children.Count(); ++i )
+        {
+        CXnNodeAppIf* current( children[ i ] );
+        
+        // Get content selector
+        const HBufC* contentSelector( 
+            PropertyValueL( *current, XnPropertyNames::common::KClass ) );
+                                                               
+        if ( contentSelector && 
+            iFwEventHandler->RefreshContent( *contentSelector ) )
+            {
+            break;
+            }
+        }
+    
+    // Free content selector array
+    children.Reset();
+    
+    // Continue content refresh for next ui element.
+    StartContentRefresh();    
+    }
+	
+// ----------------------------------------------------------------------------
+// CContentRenderer::IsParentNewsticker
+// 
+// ----------------------------------------------------------------------------
+//
+TBool CContentRenderer::IsParentNewsticker( CXnNodeAppIf& aTarget )
+    {
+    CXnNodeAppIf* parent( NULL );
+    
+    TRAP_IGNORE( parent = aTarget.ParentL() );
+    
+    if ( !parent )
+        {
+        return EFalse;
+        }
+    
+    const TDesC8& type( parent->Type()->Type() ) ;
+            
+    return ( type == XnNewstickerInterface::MXnNewstickerInterface::Type() );
+    }
+	
+
+//  End of File