idlehomescreen/xmluirendering/uiengine/src/xnodtparser.cpp
changeset 0 f72a12da539e
child 2 08c6ee43b396
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/idlehomescreen/xmluirendering/uiengine/src/xnodtparser.cpp	Thu Dec 17 08:40:49 2009 +0200
@@ -0,0 +1,1318 @@
+/*
+* Copyright (c) 2002-2004 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:  ODT parser
+*
+*/
+#include <aisystemuids.hrh>
+#include <xnextrenderingpluginadapter.h>
+#include <ecom/ecom.h>
+#include <ecom/implementationinformation.h>
+
+#include "xnextrenderingpluginwrapper.h"
+
+#include "xnodt.h"
+#include "xndomdocument.h"
+#include "xndomnode.h"
+#include "xndomattribute.h"
+#include "xndomlist.h"
+#include "xnnode.h"
+
+#include "xnecomhandler.h"
+#include "xnuiengine.h"
+#include "xntype.h"
+#include "xncontroladapter.h"
+#include "xnpopupcontroladapter.h"
+#include "xnwidgetextensionadapter.h"
+#include "xnscrollablecontroladapter.h"
+#include "xnlistquerydialogadapter.h"
+
+#include "xncomponent.h"
+#include "xncomponentnodeimpl.h"
+#include "xnviewnodeimpl.h"
+#include "xnviewsnodeimpl.h"
+#include "xnproperty.h"
+#include "xncomponentfactory.h"
+#include "xnarray.h"
+#include "xnviewmanager.h"
+#include "xnplugindata.h"
+#include "xnrootdata.h"
+#include "xnviewdata.h"
+
+#include "xnodtparser.h"
+
+_LIT8( KWidgetBgSkinId, "SKIN(268458534 9886)" );
+
+// CONSTANTS
+_LIT8( KXMLUIMLNodeName, "xmluiml" );
+_LIT8( KViewsNodeName, "views" );
+_LIT8( KViewNodeName, "view" );
+_LIT8( KBoxNodeName, "box" );
+_LIT8( KButtonNodeName, "button" );
+_LIT8( KStylusPopupNodeName, "styluspopup" );
+_LIT8( KListNodeName, "list" );
+_LIT8( KGridNodeName, "grid" );
+_LIT8( KImageNodeName, "image" );
+_LIT8( KTooltipNodeName, "tooltip" );
+_LIT8( KMenuBarNodeName, "menubar" );
+_LIT8( KMenuNodeName, "menu" );
+_LIT8( KMenuItemNodeName, "menuitem" );
+_LIT8( KDynMenuItemNodeName, "dynmenuitem" );
+_LIT8( KWidgetMenuItemNodeName, "widgetmenuitem" );
+_LIT8( KActionsNodeName, "actions" );
+_LIT8( KActionNodeName, "action" );
+_LIT8( KTriggerNodeName, "trigger" );
+_LIT8( KEventNodeName, "event" );
+_LIT8( KTextNodeName, "text" );
+_LIT8( KGridCellTemplateNodeName, "gridcelltemplate" );
+_LIT8( KListRowTemplateNodeName, "listrowtemplate" );
+_LIT8( KMarqueeNodeName, "marquee" );
+_LIT8( KObjectNodeName, "object" );
+_LIT8( KTracksterNodeName, "trackster" );
+_LIT8( KPropertyNodeName, "property" );
+_LIT8( KConfigurationNodeName, "configuration" );
+_LIT8( KNewstickerNodeName, "newsticker" );
+_LIT8( KAttributeNodeName, "attribute" );
+_LIT8( KItemNodeName, "item" );
+_LIT8( KDescNodeName, "desc" );
+_LIT8( KTextZoomNodeName, "textzoom" );
+_LIT8( KVolumeControlNodeName, "volumecontrol" );
+_LIT8( KPluginNodeName, "plugin" );
+_LIT8( KWidgetNodeName, "widget" );
+_LIT8( KSliderNodeName, "slider" );
+_LIT8( KClockNodeName, "clock" );
+_LIT8( KSoftkeyNodeName,"softkey" );
+_LIT8( KConditionalTrigger,"conditional" );
+_LIT8( KCondtionalOn, "true" );
+_LIT8( KListQueryDialogNodeName, "listquerydialog" );
+_LIT8( KSettingsConfigurationNodeName, "settingsconfiguration" );
+_LIT8( KContentSourceNodeName, "contentsource" );
+_LIT8( KMenuExtensionNodeName, "menuextension" );
+_LIT8( KWidgetExtensionNodeName, "widgetextension" );
+_LIT8( KTextEditorNodeName, "texteditor" );
+_LIT8( KActionsHandlerNodeName, "actionshandler" );
+_LIT8( KScrollableBoxNodeName, "scrollablebox" );
+_LIT8( KPopUpNodeName, "popup" );
+
+// LOCAL FUNCTION PROTOTYPES
+#ifdef _XN3_DEBUG_
+#include <flogger.h>
+#include <utf.h>
+static void PrintDomL( CXnDomDocument* aDomDocument );
+#endif
+
+static CXnNode* BuildRootNodeL( CXnUiEngine& aEngine );         
+
+static CXnNode* FindAncestorWhoActAsParent( CXnDomNode& aSource );
+
+static TBool CreateTriggerInLayoutNodeTree( CXnDomNode& aSource );
+
+static void CopyPropertiesFromDomNodeToNodeL(
+    CXnNode& aTarget,
+    CXnDomNode& aSource,
+    CXnDomStringPool& aStringPool );
+static CXnNode* ConstructNodeFromPluginL(
+    CXnEcomHandler& aEcomHandler,
+    CXnDomNode& aSource );
+static CXnNode* ConstructKnownBuiltinNodeL( CXnDomNode& aSource );
+static CXnNode* ConstructGeneralNodeL( CXnDomNode& aSource );
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+    
+// ----------------------------------------------------------------------------
+// CleanupResetAndDestroy()
+// ----------------------------------------------------------------------------
+//
+template<class T>
+static void CleanupResetAndDestroy( TAny* aObj )
+    {
+    if( aObj )
+        {
+        static_cast<T*>( aObj )->ResetAndDestroy();
+        }
+    }  
+
+// ----------------------------------------------------------------------------
+// CleanupResetAndDestroyPushL
+// ----------------------------------------------------------------------------
+//
+template<class T>
+static void CleanupResetAndDestroyPushL(T& aArray)
+    {
+    CleanupStack::PushL( TCleanupItem( &CleanupResetAndDestroy<T>, &aArray ) );
+    }  
+
+#ifdef _XN3_DEBUG_
+_LIT( KLogFolder," xnlayoutengine" );
+_LIT( KLogDom, "dom.log" );
+#define _LOGT( aDescription ) RFileLogger::Write( \
+    KLogFolder, KLogDom, EFileLoggingModeOverwrite, aDescription );
+#define _LOGTFRM1( a, b ) RFileLogger::WriteFormat( \
+    KLogFolder, KLogDom, EFileLoggingModeOverwrite, ( a ), ( b ) )
+#define _LOGTFRM2( a, b, c ) RFileLogger::WriteFormat( \
+    KLogFolder, KLogDom, EFileLoggingModeOverwrite, ( a ), ( b ), ( c ) );
+#define _LOGTFRM3( a, b, c, d ) RFileLogger::WriteFormat( \
+    KLogFolder, KLogDom, EFileLoggingModeOverwrite, ( a ), ( b ), ( c ), ( d ) );
+static const TInt GetNodeDepth( CXnDomNode *aNode )
+    {
+    TInt depth = 0;
+    CXnDomNode* node( aNode );
+    while ( node )
+        {
+        node = node->Parent();
+        if ( node )
+            {
+            depth++;
+            }
+        }
+    return depth;
+    }
+
+//-----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+//
+static HBufC8* GetFixedTextLC(
+    const TDesC8& aText,
+    const TInt aDepth,
+    const TDesC8& aDelim )
+    {
+    HBufC8 *buf = HBufC8::NewL( aDepth * aDelim.Length() + aText.Length() + 1 );
+    TInt i = 0;
+    for ( ; i < aDepth; i++ )
+        {
+        buf->Des().Append( aDelim );
+        }
+    buf->Des().Append( aText );
+    return buf;
+    }
+
+//-----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+//
+static void PrintDomL( CXnDomDocument* aDomDocument )
+    {
+__UHEAP_MARK;
+    TInt attrCount( 0 );
+    TInt propCount( 0 );
+
+    CXnDomDepthIterator* iter = 
+            CXnDomDepthIterator::NewL( *aDomDocument->RootNode() );
+    CleanupStack::PushL( iter );
+
+    _LIT8( KDelim, "\t" );
+    CXnDomNode* nodeParent( NULL );
+    CXnDomNode* node = iter->First();
+    while ( node )
+        {
+        const TInt depth = GetNodeDepth( node );
+
+        HBufC8 *nameBuf = GetFixedTextLC( node->Name(), depth, KDelim );
+        CleanupStack::PushL( nameBuf );
+        const TDesC8& name = nameBuf->Des();
+
+        HBufC8 *nsBuf = GetFixedTextLC( node->Namespace(), depth, KDelim );
+        CleanupStack::PushL( nsBuf );
+        const TDesC8& ns = nsBuf->Des();
+
+        _LOGTFRM2( _L8( "%S -------------------------- %S\n" ), &name, &ns );
+
+        CXnDomList& attrList = node->AttributeList();
+        TInt length( attrList.Length() );
+        attrCount += length;
+
+        for ( TInt i = 0; i < length; i++ )
+            {
+            CXnDomAttribute* attr = static_cast< CXnDomAttribute* >(
+                attrList.Item( i ) );
+
+            HBufC8 *attrBuf = GetFixedTextLC( attr->Name(), depth,  KDelim );
+            CleanupStack::PushL( attrBuf );
+            const TDesC8& attrName = attrBuf->Des();
+
+            const TDesC8& attrValue = attr->Value();
+
+            _LOGTFRM2( _L8( "%S=%S\n" ), &attrName, &attrValue );
+
+            CleanupStack::PopAndDestroy( attrBuf );
+            }
+
+        if ( node->Parent() )
+            {
+            nodeParent = node;
+            }
+        node = iter->NextL();
+
+        CleanupStack::PopAndDestroy( nsBuf );
+        CleanupStack::PopAndDestroy( nameBuf );
+        }
+    CleanupStack::PopAndDestroy( iter );
+
+    _LOGTFRM1( _L8( "****DOM Size: %d ****\n" ), aDomDocument->Size() );
+    _LOGTFRM1( _L8( "****DOM Node Count: %d ****\n" ), aDomDocument->DomNodeCount() );
+    _LOGTFRM1( _L8( "****DOM Attribute Count: %d ****\n" ), attrCount );
+__UHEAP_MARKEND;
+    }
+
+#endif
+// -----------------------------------------------------------------------------
+// BuildRootNodeL()
+// Builds root node
+// -----------------------------------------------------------------------------
+//
+static CXnNode* BuildRootNodeL( CXnUiEngine& aEngine )           
+    {
+    CXnType* type = CXnType::NewL( KXMLUIMLNodeName );
+    CleanupStack::PushL( type );
+
+    CXnNodeImpl* impl = CXnNodeImpl::NewL( type ); 
+        
+    CleanupStack::Pop( type );
+    CleanupStack::PushL( impl );
+
+    CXnNode* node = CXnNode::NewL();
+    node->SetRootNodeImpl( impl );
+    CleanupStack::Pop( impl );
+
+    node->SetUiEngine( aEngine );
+    
+    return node;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+CXnNode* FindAncestorWhoActAsParent( CXnDomNode& aSource )
+    {
+    CXnNode* ret( NULL );
+    CXnDomNode* parent = aSource.Parent();
+
+    while ( !ret && parent )
+        {
+        ret = parent->LayoutNode();
+        parent = parent->Parent();
+        }
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+//
+TBool CreateTriggerInLayoutNodeTree( CXnDomNode& aSource )
+    {
+    TBool ret( EFalse );
+
+    CXnDomAttribute* attribute = static_cast< CXnDomAttribute* >(
+        aSource.AttributeList().FindByName( KConditionalTrigger ) );
+
+    if ( attribute && attribute->Value() == KCondtionalOn )
+        {
+        ret = ETrue;
+        }
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// CopyDomPropertiesFromDomNodeToNodeL
+// -----------------------------------------------------------------------------
+//
+static void CopyDomPropertiesFromDomNodeToNodeL(
+    CXnNode& aTarget,
+    CXnDomNode& aSource )
+    {
+    CXnDomList& propertyList = aSource.PropertyList();
+    for ( TInt count = propertyList.Length() - 1; count >= 0; --count )
+        {
+        CXnDomProperty* domProperty = static_cast< CXnDomProperty* >(
+            propertyList.Item( count ) );
+        CXnProperty* property = CXnProperty::NewSharedL( domProperty );
+        CleanupStack::PushL( property );
+        aTarget.InitializePropertyL( property );
+        CleanupStack::Pop( property );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CopyDomAtributesFromDomNodeToNodeL
+// -----------------------------------------------------------------------------
+//
+static void CopyDomAttributesFromDomNodeToNodeL(
+    CXnNode& aTarget,
+    CXnDomNode& aSource,
+    CXnDomStringPool& aStringPool )
+    {
+    CXnDomList& attributeList = aSource.AttributeList();
+    for ( TInt count = attributeList.Length() - 1; count >= 0; --count )
+        {
+        CXnDomAttribute* attribute = static_cast< CXnDomAttribute* >(
+            attributeList.Item( count ) );
+#ifdef _DEBUG
+        const TDesC8& name = attribute->Name();
+        const TDesC8& attrValue = attribute->Value();
+#endif
+        if ( attribute->ValueStringPoolIndex() == KErrNotFound )
+            {
+            continue;
+            }
+
+        if ( attribute->NameStringPoolIndex() == KErrNotFound )
+            {
+            continue;
+            }
+         CXnDomProperty* clone =
+            CXnDomProperty::NewL( attribute->NameStringPoolIndex(), aStringPool );
+        CleanupStack::PushL( clone );
+        CXnDomPropertyValue* propertyValue =
+            CXnDomPropertyValue::NewL( aStringPool );
+        CleanupStack::PushL( propertyValue );
+        propertyValue->SetStringPoolIndexL(
+            CXnDomPropertyValue::EString, attribute->ValueStringPoolIndex() );
+        CXnDomList& propertyList = clone->PropertyValueList();
+        propertyList.AddItemL( propertyValue );
+        CleanupStack::Pop( propertyValue );
+        CXnProperty* property = CXnProperty::NewL( clone );
+        CleanupStack::Pop( clone );
+        CleanupStack::PushL( property );
+        aTarget.InitializePropertyL( property );
+        CleanupStack::Pop( property );
+        }
+
+    //aSource.DeleteAttributeList();
+    // delete attributes from dom node tree
+    if ( aSource.Name() != KTriggerNodeName )
+        {
+        CXnDomList& attrList = aSource.AttributeList();
+        while ( attrList.Length() )
+            {
+            attrList.DeleteItem( attrList.Length() - 1 );
+            }
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CopyPropertiesFromDomNodeToNodeL
+// -----------------------------------------------------------------------------
+//
+static void CopyPropertiesFromDomNodeToNodeL(
+    CXnNode& aTarget,
+    CXnDomNode& aSource,
+    CXnDomStringPool& aStringPool )
+    {
+    CopyDomPropertiesFromDomNodeToNodeL( aTarget, aSource );
+    CopyDomAttributesFromDomNodeToNodeL( aTarget, aSource, aStringPool );
+    }
+
+// -----------------------------------------------------------------------------
+// ConstructNodeFromPluginL
+// -----------------------------------------------------------------------------
+//
+static CXnNode* ConstructNodeFromPluginL(
+    CXnEcomHandler& aEcomHandler,
+    CXnDomNode& aSource )
+    {
+    CXnNode* returnValue = NULL;
+    const TDesC8& name = aSource.Name();
+
+    CXnArray* componentFactories = CXnArray::NewL();
+    CleanupStack::PushL( componentFactories );
+
+    TUid interfaceUid = { AI3_RENDERING_PLUGIN_ECOM_FACTORY_UID };
+    aEcomHandler.PluginsL( interfaceUid, name, *componentFactories );
+    TInt count = componentFactories->Container().Count();
+    TBool componentNodeImplNeeded = ETrue;
+    // invoke factory chain
+    for ( TInt i = 0; i < count; ++i )
+        {
+        MXnComponentFactory* factory = static_cast< MXnComponentFactory* >(
+            componentFactories->Container()[i] );
+        componentNodeImplNeeded = factory->DoesNodeNeedComponentImplL( name );
+        }
+    CleanupStack::PopAndDestroy( componentFactories );
+    if ( componentNodeImplNeeded )
+        {
+        CXnType* type = CXnType::NewL( name );
+        CleanupStack::PushL( type );
+        CXnComponentNodeImpl* impl = CXnComponentNodeImpl::NewL( type );
+        CleanupStack::Pop( type );
+        CleanupStack::PushL( impl );
+        returnValue = CXnNode::NewL();
+        returnValue->SetComponentNodeImpl( impl );
+        CleanupStack::Pop( impl );
+        }
+    else
+        {
+        if ( name == KActionsNodeName ||
+             name == KActionNodeName ||
+             name == KEventNodeName ||
+             name == KTriggerNodeName ||
+             name == KMenuNodeName ||
+             name == KMenuItemNodeName ||
+             name == KPropertyNodeName ||
+             name == KSoftkeyNodeName )
+            {
+            return ConstructGeneralNodeL( aSource );
+            }
+        }
+    return returnValue;
+    }
+
+// -----------------------------------------------------------------------------
+// ConstructKnownBuiltinNodeL
+// -----------------------------------------------------------------------------
+//
+static CXnNode* ConstructKnownBuiltinNodeL( CXnDomNode& aSource )
+    {
+    CXnNode* returnValue = NULL;
+    const TDesC8& name = aSource.Name();
+    if ( name == KMenuNodeName ||
+         name == KMenuItemNodeName ||
+         name == KPropertyNodeName ||
+         name == KSoftkeyNodeName ||
+         name == KTriggerNodeName )
+        {
+        return ConstructGeneralNodeL( aSource );
+        }
+    CXnType* type = CXnType::NewL( name );
+    CleanupStack::PushL( type );
+    if ( name == KViewsNodeName )
+        {
+        CXnViewsNodeImpl* impl = CXnViewsNodeImpl::NewL( type );
+        CleanupStack::Pop( type );
+        CleanupStack::PushL( impl );
+        returnValue = CXnNode::NewL();
+        returnValue->SetViewsNodeImpl( impl );
+        CleanupStack::Pop( impl );
+        }
+    else if ( name == KViewNodeName )
+        {
+        CXnViewNodeImpl* impl = CXnViewNodeImpl::NewL( type );
+        CleanupStack::Pop( type );
+        CleanupStack::PushL( impl );
+        returnValue = CXnNode::NewL();
+        returnValue->SetViewNodeImpl( impl );
+        CleanupStack::Pop( impl );
+        }
+    else if ( name == KGridCellTemplateNodeName ||
+              name == KListRowTemplateNodeName ||
+              name == KBoxNodeName ||
+              name == KButtonNodeName ||
+              name == KListNodeName ||
+              name == KGridNodeName ||
+              name == KImageNodeName ||
+              name == KMenuBarNodeName ||
+              name == KTooltipNodeName ||
+              name == KMarqueeNodeName ||
+              name == KTextNodeName ||
+              name == KObjectNodeName ||
+              name == KTracksterNodeName ||
+              name == KNewstickerNodeName ||
+              name == KSliderNodeName ||
+              name == KClockNodeName ||
+              name == KStylusPopupNodeName ||
+              name == KPopUpNodeName ||
+              name == KWidgetExtensionNodeName ||
+              name == KTextEditorNodeName )
+        {
+        CXnComponentNodeImpl* impl = CXnComponentNodeImpl::NewL( type );
+        CleanupStack::Pop( type ) ;
+        CleanupStack::PushL( impl );
+        returnValue = CXnNode::NewL();
+        returnValue->SetComponentNodeImpl( impl );
+        CleanupStack::Pop( impl );
+        }
+    else
+        {
+        CleanupStack::PopAndDestroy( type );
+
+        if ( name == KVolumeControlNodeName ||
+             name == KWidgetNodeName ||
+             name == KPluginNodeName )
+            {
+            CXnType* type = CXnType::NewL( KBoxNodeName );
+            CleanupStack::PushL( type );
+            CXnComponentNodeImpl* impl = CXnComponentNodeImpl::NewL( type );
+            CleanupStack::Pop( type );
+            CleanupStack::PushL( impl );
+            returnValue = CXnNode::NewL();
+            returnValue->SetComponentNodeImpl( impl );
+            CleanupStack::Pop( impl );
+            }
+        }
+    return returnValue;
+    }
+
+// -----------------------------------------------------------------------------
+// ConstructGeneralNodeL
+// -----------------------------------------------------------------------------
+//
+static CXnNode* ConstructGeneralNodeL( CXnDomNode& aSource )
+    {
+    CXnType* type = CXnType::NewL( aSource.Name() );
+    CleanupStack::PushL( type );
+    CXnNodeImpl* impl = CXnNodeImpl::NewL( type );
+    CleanupStack::Pop( type );
+    CleanupStack::PushL( impl );
+    CXnNode* tmpNode = CXnNode::NewL();
+    tmpNode->SetImpl( impl );
+    CleanupStack::Pop( impl );
+    return tmpNode;
+    }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CXnODTParser* CXnODTParser::NewL( CXnViewManager& aManager,
+    CXnEcomHandler& aEcomHandler )
+    {
+    CXnODTParser* self = new ( ELeave ) CXnODTParser( aManager, aEcomHandler ); 
+            
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::CXnODTParser
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CXnODTParser::CXnODTParser( CXnViewManager& aManager,
+    CXnEcomHandler& aEcomHandler )
+    : iManager( aManager ), iUiEngine( aManager.UiEngine() ),
+      iEcomHandler( aEcomHandler )
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::~CXnODTParser
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CXnODTParser::~CXnODTParser()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CXnODTParser::ConstructL()
+    {
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::LoadRootL
+// -----------------------------------------------------------------------------
+//
+void CXnODTParser::LoadRootL( CXnRootData& aRootData, TUid /*aAppUid*/ )        
+    {    
+    CXnDomNode* root( aRootData.Owner() );
+    
+    CXnDomStringPool& sp( root->StringPool() );
+    
+    CXnAppUiAdapter& appui( iManager.AppUiAdapter() );
+    
+    // Build root
+    CXnNode* node( BuildRootNodeL( iUiEngine ) );
+    
+    // Let root nodes to know each other
+    CXnDomNode* dom( aRootData.ODT()->DomDocument().RootNode() );    
+    dom->SetLayoutNode( node );
+    node->SetDomNode( dom );
+        
+    CreateNodesL( root, sp, aRootData );
+
+    // root doesn't have any controls   
+    
+    aRootData.SetOccupied();
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::LoadViewL
+// -----------------------------------------------------------------------------
+//
+void CXnODTParser::LoadViewL( CXnViewData& aViewData )
+    {    
+    // <view> element
+    CXnDomNode* view( aViewData.Node() );
+    
+    CXnDomStringPool& sp( view->StringPool() );
+
+    // from <view> element
+    CreateNodesL( view, sp, aViewData );       
+    CreateControlsL( view, aViewData );
+
+    // By default make controls invisible
+    CXnControlAdapter* adapter( view->LayoutNode()->Control() );
+    
+    if( adapter )
+        {
+        adapter->MakeVisible( EFalse );
+        }    
+        
+    aViewData.SetOccupied();
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::DestroyView
+// -----------------------------------------------------------------------------
+//
+void CXnODTParser::DestroyView( CXnViewData& aViewData )
+    {
+    CXnNode* view( aViewData.Node()->LayoutNode() );
+    
+    // Destroy view and all its child nodes
+    CXnNode* parent( view->Parent() );
+    
+    RPointerArray< CXnNode >& children( parent->Children() );
+    
+    TInt index( children.Find( view ) );
+    
+    if ( index != KErrNotFound )
+        {
+        children.Remove( index );
+        
+        delete view;
+        view = NULL;
+        
+        CXnDomNode* owner( aViewData.Owner() );
+        owner->DeleteChild( aViewData.Node() );
+        }    
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::LoadWidgetL
+// -----------------------------------------------------------------------------
+//
+void CXnODTParser::LoadWidgetL( CXnPluginData& aPluginData )
+    {   
+    if ( aPluginData.Empty() )
+        {
+        // Holds "empty" widget
+        return;
+        }
+    
+    // <widget> element
+    CXnDomNode* widget( aPluginData.Node() );
+    
+    CXnDomStringPool& sp( widget->StringPool() );
+
+    // from <widget> element 
+    CreateNodesL( widget, sp, aPluginData );           
+    CreateControlsL( widget, aPluginData );    
+
+    HandleWidgetBackgroundL( widget->LayoutNode() );
+
+    // By default make controls invisible
+    CXnControlAdapter* adapter( widget->LayoutNode()->Control() );
+    
+    if( adapter )
+        {
+        adapter->MakeVisible( EFalse );
+        }   
+    
+    aPluginData.SetOccupied();
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::DestroyWidget
+// -----------------------------------------------------------------------------
+//
+void CXnODTParser::DestroyWidgetL( CXnPluginData& aPluginData )
+    {
+    CXnViewData& parent( 
+        static_cast< CXnViewData& >( *aPluginData.Parent() ) );
+    
+    // Check is any of plugin data's controls in views draw chain and remove
+    CXnControlAdapter* control( parent.Node()->LayoutNode()->Control() );
+
+    RPointerArray< CXnControlAdapter >& controls( control->ChildAdapters() );
+
+    RPointerArray< CXnControlAdapter > pluginControls;
+    CleanupClosePushL( pluginControls );
+
+    aPluginData.ControlsL( pluginControls );
+
+    // Remove from view chain if found
+    for ( TInt i = 0; i < pluginControls.Count(); i++ )
+        {
+        CXnControlAdapter* control( pluginControls[i] );
+
+        TInt index( controls.Find( control ) );
+
+        if ( index != KErrNotFound )
+            {
+            controls.Remove( index );
+            }
+        }
+
+    CleanupStack::PopAndDestroy( &pluginControls );
+    
+    CXnNode* widgetNode( aPluginData.Node()->LayoutNode() );
+        
+    CXnNode* owner( widgetNode->Parent() );
+    
+    RPointerArray< CXnNode >& children( owner->Children() );
+    
+    TInt index( children.Find( widgetNode ) );
+    
+    // Destroy widget and all its child nodes
+    if ( index != KErrNotFound )
+        {
+        children.Remove( index );
+        
+        delete widgetNode;
+        widgetNode = NULL;
+       
+        CXnDomNode* owner( aPluginData.Owner() );
+        owner->DeleteChild( aPluginData.Node() );
+        }
+    
+    owner->Control()->RemoveChildAdapters();
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::CreateNodesL
+// Creates node tree
+// -----------------------------------------------------------------------------
+//
+void CXnODTParser::CreateNodesL(
+    CXnDomNode* aSourceNode,
+    CXnDomStringPool& aSp,    
+    CXnPluginData& aPluginData )
+    {
+    if ( aSourceNode )
+        {
+        ConstructNodeL( *aSourceNode, aSp, aPluginData );
+                     
+        CXnDomList& childList( aSourceNode->ChildNodes() );
+
+        TInt count( childList.Length() );
+
+        for ( TInt i = 0; i < count; ++i )
+            {
+            CreateNodesL(
+                static_cast< CXnDomNode* >( childList.Item( i ) ),
+                aSp, aPluginData );
+            }                              
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::ConstructNodeL
+// Creates layout node and control for it
+// -----------------------------------------------------------------------------
+//
+void CXnODTParser::ConstructNodeL(
+    CXnDomNode& aSource,
+    CXnDomStringPool& aSp,    
+    CXnPluginData& aPluginData )
+    {
+    const TDesC8& name( aSource.Name() );
+    
+    if ( name == KActionsNodeName ||
+         name == KActionNodeName ||
+         name == KEventNodeName ||
+         name == KXMLUIMLNodeName ||
+         name == KAttributeNodeName ||
+         name == KItemNodeName )
+        {
+        return;
+        }
+
+    if ( name == KTriggerNodeName )
+        {
+        if ( !CreateTriggerInLayoutNodeTree( aSource ) )
+            {
+            return;
+            }
+        }
+
+    const TDesC8& parentName( aSource.Parent()->Name() );
+
+    if ( name == KPropertyNodeName &&
+         ( parentName == KTriggerNodeName ||
+           parentName == KEventNodeName ||
+           parentName == KPropertyNodeName ||
+           parentName == KAttributeNodeName ) )
+        {
+        return;
+        }
+
+    CXnNode* node( ConstructKnownBuiltinNodeL( aSource ) ); 
+
+    if ( !node )
+        {
+        node = ConstructNodeFromPluginL( iEcomHandler, aSource );
+        
+        if ( !node )
+            {
+            node = ConstructGeneralNodeL( aSource );
+            
+            if ( !node )
+                {
+                return;
+                }            
+            }
+        }
+
+    if ( name == KMenuBarNodeName ||
+         name == KListQueryDialogNodeName ||
+         name == KMenuNodeName ||
+         name == KMenuItemNodeName ||
+         name == KDynMenuItemNodeName ||
+         name == KWidgetMenuItemNodeName ||
+         name == KPropertyNodeName ||
+         name == KDescNodeName ||
+         name == KTextZoomNodeName ||
+         name == KConfigurationNodeName ||
+         name == KSoftkeyNodeName ||
+         name == KTriggerNodeName ||
+         name == KSettingsConfigurationNodeName ||
+         name == KContentSourceNodeName ||
+         name == KMenuExtensionNodeName ||
+         name == KStylusPopupNodeName ||
+         name == KActionsHandlerNodeName )         
+        {
+        node->SetLayoutCapable( EFalse );
+        }
+
+    CXnNode* parent( FindAncestorWhoActAsParent( aSource ) );
+
+    if( !parent )
+        {
+        delete node;
+        
+        return;
+        }
+    
+    parent->AddChildL( node );
+
+    if ( !parent->IsLayoutCapable() )
+        {
+        node->SetLayoutCapable( EFalse );
+        }
+    
+    aSource.SetLayoutNode( node );
+    node->SetDomNode( &aSource );
+
+    node->SetUiEngine( iUiEngine );
+
+    CopyPropertiesFromDomNodeToNodeL( *node, aSource, aSp );
+           
+    if ( name == KTriggerNodeName )
+        {
+        if ( iUiEngine.IsEditMode() )
+            {
+            node->SetStateL( XnPropertyNames::style::common::KEdit );
+            }
+        }
+            
+    // Mark adaptive layoutable nodes
+    TInt adaptive( XnAdaptive::ENone );
+
+    CXnProperty* width( node->WidthL() );
+
+    if ( width )
+        {
+        const TDesC8& w( width->StringValue() );
+
+        if ( w == XnPropertyNames::style::common::KAdaptive )
+            {
+            adaptive = XnAdaptive::EWidth;
+            }
+        }
+
+    CXnProperty* height( node->HeightL() );
+
+    if ( height )
+        {
+        const TDesC8& h( height->StringValue() );
+
+        if ( h == XnPropertyNames::style::common::KAdaptive )
+            {
+            adaptive |= XnAdaptive::EHeight;
+            }
+        }
+
+    if ( adaptive != XnAdaptive::ENone )
+        {
+        node->SetAdaptiveL( adaptive );
+        }
+       
+    // Collect nodes, which nav-index property is 'appearance' to
+    // an array
+    CXnProperty* navindex( node->NavIndexL() );
+    
+    if ( navindex &&
+         navindex->StringValue() == XnPropertyNames::style::common::KAppearance )
+        {
+        aPluginData.SetAppearanceNodeL( node );
+        }
+    
+    // Collect initial focus nodes.
+    CXnProperty* initialFocusProp( node->InitialFocusL() );
+    
+    if ( initialFocusProp )
+        {
+        aPluginData.SetInitialFocusNodeL( node );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::CreateControlsL()
+// Run control creation 1st phase
+// -----------------------------------------------------------------------------
+//
+void CXnODTParser::CreateControlsL( CXnDomNode* aNode,
+    CXnPluginData& aPluginData )
+    {
+    if ( aNode )
+        {
+        ConstructControlL( aNode->LayoutNode(), aPluginData );
+        
+        CXnDomList& childList( aNode->ChildNodes() );
+
+        TInt count( childList.Length() );
+
+        for ( TInt i = 0; i < count; ++i )
+            {
+            CreateControlsL(
+                static_cast< CXnDomNode* >( childList.Item( i ) ), aPluginData );                
+            }                              
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::ConstructControlL()
+// Run control creation 1st phase
+// -----------------------------------------------------------------------------
+//
+void CXnODTParser::ConstructControlL( CXnNode* aNode,
+    CXnPluginData& aPluginData )
+    {
+    if( !aNode )
+        {
+        return;
+        }
+    
+    CXnComponentNodeImpl* impl( aNode->ComponentNodeImpl() );
+    CXnViewNodeImpl* viewImpl( aNode->ViewNodeImpl() );
+
+    TBool needsCreation( EFalse );
+
+    if ( ( impl && impl->DoesComponentNeedCreation() ) || viewImpl )
+        {
+        needsCreation = ETrue;
+        }
+
+    const TDesC8& name( aNode->Type()->Type() );
+
+    if ( needsCreation )
+        {
+        // Try if builtin control can be created
+        if ( !CreateBuiltInControlL( *aNode, name ) )
+            {
+            // Not builtin, invoke factory chain
+            CreateFactoryControlL( *aNode, name );
+            }
+
+        // Fill plugin data
+        aPluginData.SetControlL( aNode );
+        }
+
+    if ( name == KContentSourceNodeName )
+        {
+        aPluginData.SetContentSourceNodeL( aNode );
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::CreateExternalControlL()
+// Creates external control
+// -----------------------------------------------------------------------------
+//
+TBool CXnODTParser::CreateExternalControlL( CXnNode& aNode,
+    const TDesC8& aName )
+    {
+    CXnExtRenderingPluginAdapter* adapter( NULL );
+    
+    // Get implementations via ECom
+    RImplInfoPtrArray plugins;
+    CleanupResetAndDestroyPushL( plugins );
+
+    REComSession::ListImplementationsL( 
+    	TUid::Uid( AI3_EXTERNAL_RENDERING_PLUGIN_ECOM_UID ), plugins );
+
+    for( TInt i = 0; i < plugins.Count(); i++ )
+        {
+        CImplementationInformation* information( plugins[i] );
+
+        if( information->DataType().Compare( aName ) == 0 )
+            {
+            adapter = CXnExtRenderingPluginAdapter::NewL( 
+            	information->ImplementationUid() );
+            break;
+            } 
+        }
+    CleanupStack::PopAndDestroy(); // plugins
+    
+    if( adapter )
+        {
+        CXnComponent* component = CXnComponent::NewL();
+        CleanupStack::PushL( component );
+
+        CXnControlAdapter* parentAdapter( NULL );
+
+        // Find parent control
+        CXnNode* parent( aNode.Parent() );
+
+        for ( ; parent; parent = parent->Parent() )
+            {
+            parentAdapter = parent->Control();
+
+            if ( parentAdapter )
+                {
+                break;
+                }
+            }
+
+        CXnExtRenderingPluginWrapper* wrapper = 
+        	CXnExtRenderingPluginWrapper::NewL( aNode.PluginIfL(), *adapter );
+        CleanupStack::PushL( wrapper );
+
+        parentAdapter->AppendChildL( *wrapper, aNode );
+        CleanupStack::Pop( wrapper );
+        
+        component->SetControlAdapter( wrapper );
+
+        aNode.ComponentNodeImpl()->SetComponent( component );
+
+        component->SetNode( aNode.PluginIfL() );
+
+        wrapper->SetComponent( component );
+
+        wrapper->SetComponentsToInheritVisibility( ETrue );
+
+        wrapper->ActivateL();
+        
+        CleanupStack::Pop( component );
+
+        return ETrue;
+        }
+    else
+        {
+        return EFalse;
+        }
+    }
+
+// CXnODTParser::CreateFactoryControlL()
+// Creates factory control
+// -----------------------------------------------------------------------------
+//
+void CXnODTParser::CreateFactoryControlL( CXnNode& aNode,
+    const TDesC8& aName )
+    {
+    CXnArray* factories = CXnArray::NewL();
+    CleanupStack::PushL( factories );
+
+    TUid interfaceUid = { AI3_RENDERING_PLUGIN_ECOM_FACTORY_UID };
+
+    iEcomHandler.PluginsL( interfaceUid, aName, *factories );
+
+    CXnComponent* component( NULL );
+
+    TInt count( factories->Container().Count() );
+    
+    // Invoke factory chain
+    for ( TInt i = 0; i < count; i++ )
+        {
+        MXnComponentFactory* factory =
+            static_cast< MXnComponentFactory* >(
+                ( factories->Container() )[i] );
+                 
+        if ( factory->CreateXnComponentL( aNode.PluginIfL(), component ) == 
+            MXnComponentFactory::EXnFactoryResponseComponentConstructed )
+             
+            {
+            // All done
+            break;
+            }
+        }
+
+    CleanupStack::PopAndDestroy( factories );
+    }
+
+// -----------------------------------------------------------------------------
+// CXnODTParser::CreateBuiltInControlL()
+// Creates builtin control
+// -----------------------------------------------------------------------------
+//
+TBool CXnODTParser::CreateBuiltInControlL( CXnNode& aNode,
+    const TDesC8& aName )
+    {
+    if ( aName != KBoxNodeName && aName != KButtonNodeName &&
+         aName != KStylusPopupNodeName && aName != KScrollableBoxNodeName&& 
+         aName != KWidgetExtensionNodeName && 
+                  aName != KPopUpNodeName &&
+		 aName != XnPropertyNames::listquerydialog::KListQueryDialog )         
+        {
+        return CreateExternalControlL( aNode, aName );
+        }
+
+    CXnComponent* component = CXnComponent::NewL();
+    CleanupStack::PushL( component );
+
+    CXnControlAdapter* parentAdapter( NULL );
+
+    CXnProperty* position( aNode.PositionL() );
+
+    if ( position )
+        {
+        const TDesC8& value( position->StringValue() );
+
+        if ( value == XnPropertyNames::style::common::position::KFloating )
+            {
+            // Find view node and append floating control to its compound
+            for ( CXnNode* node = &aNode; node; node = node->Parent() )
+                {
+                if ( node->ViewNodeImpl() )
+                    {
+                    parentAdapter = node->Control();
+
+                    break;
+                    }
+                }
+            }
+        }
+
+    if ( !parentAdapter )
+        {
+        // Find parent control
+        CXnNode* parent( aNode.Parent() );
+
+        for ( ; parent; parent = parent->Parent() )
+            {
+            parentAdapter = parent->Control();
+
+            if ( parentAdapter )
+                {
+                break;
+                }
+            }
+        }
+
+    CXnControlAdapter* adapter( NULL );
+    
+    if( aName == KStylusPopupNodeName )
+        {
+        adapter = CXnPopupControlAdapter::NewL( aNode.PluginIfL() );
+        CleanupStack::PushL( adapter );
+        }
+    else if( aName == KWidgetExtensionNodeName ||
+             aName == KPopUpNodeName )
+        {               
+        adapter = CXnWidgetExtensionAdapter::NewL( aNode.PluginIfL() );
+        CleanupStack::PushL( adapter );        
+        CXnProperty* prop = CXnProperty::NewL( 
+            XnPropertyNames::style::common::KPosition,
+            XnPropertyNames::style::common::position::KFloating,
+            CXnDomPropertyValue::EString, 
+            aNode.UiEngine()->ODT()->DomDocument().StringPool() );
+        CleanupStack::PushL( prop );
+        aNode.SetPropertyL( prop );                    
+        CleanupStack::Pop( prop );                                                        
+        }
+    else if( aName == KScrollableBoxNodeName )
+        {               
+        adapter = CXnScrollableControlAdapter::NewL( aNode.PluginIfL() );
+        CleanupStack::PushL( adapter );
+        }
+    else if( aName == XnPropertyNames::listquerydialog::KListQueryDialog )
+        {
+        CleanupStack::PopAndDestroy( component );
+        CXnListQueryDialog* listQuery = CXnListQueryDialog::NewL();
+        component = static_cast<CXnComponent*>( listQuery );
+        CleanupStack::PushL( component );
+        adapter = CXnListQueryDialogAdapter::NewL( aNode.PluginIfL() );
+        CleanupStack::PushL( adapter );
+        }
+    else
+        {
+        adapter = CXnControlAdapter::NewL( aNode.PluginIfL() );
+        CleanupStack::PushL( adapter );
+        }
+    
+    parentAdapter->AppendChildL( *adapter, aNode );
+    CleanupStack::Pop( adapter );
+    
+    component->SetControlAdapter( adapter );
+
+    aNode.ComponentNodeImpl()->SetComponent( component );
+
+    component->SetNode( aNode.PluginIfL() );
+
+    adapter->SetComponent( component );
+
+    adapter->SetComponentsToInheritVisibility( ETrue );
+
+    adapter->ActivateL();
+    
+    CleanupStack::Pop( component );
+
+    return ETrue;
+    }
+
+// --------------------------------------------------------------------------
+// CXnODTParser::HandleWidgetBackgroundL()
+//
+// --------------------------------------------------------------------------
+//
+void CXnODTParser::HandleWidgetBackgroundL( CXnNode* aWidgetNode )
+    {
+    if( aWidgetNode )
+        {
+        CXnUiEngine* uiengine = aWidgetNode->UiEngine();
+        CXnProperty* bgImageProp = aWidgetNode->BackgroundImageL();
+        CXnProperty* bgColorProp = aWidgetNode->BackgroundColorL();
+        
+        // Set default bg color if it has not been defined by a widget
+        if( !bgImageProp && !bgColorProp && uiengine )
+            {
+            CXnDomPropertyValue* value = CXnDomPropertyValue::NewL(
+                uiengine->ODT()->DomDocument().StringPool() );
+            CleanupStack::PushL( value );
+            value->SetStringValueL( CXnDomPropertyValue::EString, KWidgetBgSkinId );
+        
+            CXnProperty* bgColor = CXnProperty::NewL(
+                XnPropertyNames::appearance::common::KBackGroundColor,
+                value, uiengine->ODT()->DomDocument().StringPool() );
+        
+            CleanupStack::Pop( value );
+            CleanupStack::PushL( bgColor );
+            aWidgetNode->SetPropertyL( bgColor );
+            CleanupStack::Pop( bgColor );
+            }
+        }
+    }
+
+// End of file
+