idlehomescreen/xmluirendering/uiengine/src/xneditor.cpp
changeset 0 f72a12da539e
child 1 5315654608de
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/idlehomescreen/xmluirendering/uiengine/src/xneditor.cpp	Thu Dec 17 08:40:49 2009 +0200
@@ -0,0 +1,1766 @@
+/*
+* Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Manages Ai3 personalization
+*
+*/
+
+// System includes
+#include <StringLoader.h>
+#include <aknlistquerydialog.h> 
+#include <aknnotewrappers.h>
+#include <utf.h>
+#include <AknsWallpaperUtils.h>
+#include <centralrepository.h>
+#include <AknSkinsInternalCRKeys.h>
+#include "../../../inc/ai3.hrh"
+
+#include <xnuiengine.rsg>
+#include <hscontentcontrolui.h>
+#include <hscontentcontrol.h>
+
+// User includes
+#include "xnuiengine.h"
+#include "xnproperty.h"
+#include "xnnode.h"
+#include "xntype.h"
+#include "xntext.h"
+#include "xnappuiadapter.h"
+
+#include "xndomnode.h"
+#include "xndomproperty.h"
+#include "xndompropertyvalue.h"
+#include "xndomlist.h"
+#include "xndomattribute.h"
+#include "hspssapi.h"
+#include "cpssapi.h"
+#include "xneditmode.h"
+#include "xndomdocument.h"
+#include "xnnodeimpl.h"
+#include "xnodt.h"
+#include "xnplugindefs.h"
+
+#include "xnviewmanager.h"
+#include "xnplugindata.h"
+#include "xnrootdata.h"
+#include "xnviewdata.h"
+#include "xnwallpaperview.h"
+
+#include "xneditor.h"
+#include "xnpanic.h"
+
+using namespace hspswrapper;
+using namespace cpswrapper;
+
+// LOCAL CONSTANTS AND MACROS
+_LIT8( KEventPluginUnInstalled, "PluginUninstalled" );
+_LIT8( KEventRootConfActivated, "AppConfActivated" );
+_LIT8( KEventPluginUpdated, "PluginUpdated" );
+_LIT8( KEventPluginActivated, "PluginActivated" );
+_LIT8( KEventPluginInstalled, "PluginInstalled" );
+_LIT8( KEventPluginAdded, "PluginAdded" );
+_LIT8( KEventPluginRemoved, "PluginRemoved" );
+_LIT8( KEventPluginReplaced, "PluginReplaced" );
+
+_LIT8( KAi3Uid, "0x102750f0" );
+
+_LIT8( KEmptyWidgetUid, "0x2001F47F" );
+_LIT8( KDownload, "Editor/DownloadCaption" );
+
+_LIT8( KSingle, "single" );
+_LIT8( KMulti, "multi" );
+
+_LIT8( KWMUi, "WmContentControlUI" );
+
+const TInt32 KMultiInstanceUnlimitedValue = -1;
+const TInt32 KMultiInstanceHiddenValue = 0;
+
+const TUid KDummyUid = { 0x0000000 };
+enum
+    {
+    ECanBeAdded = 0x01,
+    ECanBeRemoved
+    };
+
+// ====================== LOCAL FUNTION PROTOTYPES ============================
+static void DeletePluginInfos( TAny* aObject );
+static void DeleteItemMaps( TAny* aObject );
+static void DeleteWidgetInfo( TAny* aObject );
+
+static TPtrC ParseWidgetName( const CHsContentInfo& aContentInfo );
+static void SetPropertyL( CXnNode& aNode, const TDesC8& aAttribute, 
+                          const TDesC8& aValue );    
+static void ShowErrorNoteL( const TDesC& aMsg );      
+static CXnPluginData* DeterminePlugin( CXnViewManager& aViewManager, 
+                                         CXnNode* aPredicate = NULL );
+static CXnPluginData* DeterminePlugin( 
+                            RPointerArray< CXnPluginData >& aPlugins,                            
+                            const CHsContentInfo& aContentInfo );
+
+// ============================ LOCAL FUNCTIONS ===============================
+
+// ---------------------------------------------------------------------------
+// DeletePluginInfos
+// ---------------------------------------------------------------------------
+// 
+static void DeletePluginInfos( TAny* aObject )
+    {
+    reinterpret_cast<
+        RPointerArray< hspswrapper::CPluginInfo >* >(
+            aObject )->ResetAndDestroy();
+    }
+
+// ---------------------------------------------------------------------------
+// DeleteItemMaps
+// ---------------------------------------------------------------------------
+// 
+static void DeleteItemMaps( TAny* aObject )
+    {
+    reinterpret_cast<
+        RPointerArray< hspswrapper::CItemMap >* >(
+            aObject )->ResetAndDestroy();
+    }
+
+// ---------------------------------------------------------------------------
+// DeleteWidgetInfo
+// ---------------------------------------------------------------------------
+// 
+static void DeleteWidgetInfo( TAny* aObject )    
+    {
+    reinterpret_cast<
+        RPointerArray< CHsContentInfo >* >( aObject )->ResetAndDestroy();
+    }
+
+// ---------------------------------------------------------------------------
+// ParseWidgetName
+// ---------------------------------------------------------------------------
+// 
+static TPtrC ParseWidgetName( const CHsContentInfo& aContentInfo )
+    {
+    TPtrC retval( aContentInfo.Name() );
+
+    TInt pos( retval.Locate( ':' ) );
+
+    if ( pos != KErrNotFound )
+        {
+        retval.Set( retval.Right( retval.Length() - pos - 1 ) );
+        }
+
+    return retval;
+    }
+
+// ---------------------------------------------------------------------------
+// SetPropertyL
+// ---------------------------------------------------------------------------
+// 
+static void SetPropertyL( CXnNode& aNode, 
+    const TDesC8& aAttribute, const TDesC8& aValue )
+    {
+    CXnDomNode* node( aNode.DomNode() );
+    
+    if ( node )
+        {
+        CXnDomStringPool& sp( node->StringPool() );
+
+        // create new property
+        CXnDomPropertyValue* value = CXnDomPropertyValue::NewL( sp );
+        CleanupStack::PushL( value );
+
+        value->SetStringValueL( CXnDomPropertyValue::EString, aValue );
+
+        CXnProperty* prop = CXnProperty::NewL( aAttribute, value, sp );
+                    
+        CleanupStack::Pop( value );
+        CleanupStack::PushL( prop );
+
+        aNode.SetPropertyL( prop );
+
+        CleanupStack::Pop( prop );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// ShowErrorNoteL
+// ---------------------------------------------------------------------------
+// 
+static void ShowErrorNoteL( const TDesC& aMsg )
+    {
+    CAknErrorNote* note = new ( ELeave ) CAknErrorNote;
+    CleanupStack::PushL( note );
+
+    note->ExecuteLD( aMsg );
+
+    CleanupStack::Pop( note );    
+    }
+
+// ---------------------------------------------------------------------------
+// DeterminePlugin
+// Determinates target plugin where widget should be added
+// ---------------------------------------------------------------------------
+// 
+CXnPluginData* DeterminePlugin( CXnViewManager& aViewManager, 
+    CXnNode* aPredicate )
+    {
+    CXnViewData& viewData( aViewManager.ActiveViewData() );
+
+    if ( aPredicate )
+        {
+        CXnPluginData& plugin( viewData.Plugin( aPredicate ) );
+
+        if ( !plugin.Occupied() )
+            {
+            return &plugin;
+            }
+        }
+
+    RPointerArray< CXnNode >& nodes( aViewManager.PluginNodes() );
+
+    for ( TInt i = 0; i < nodes.Count(); i++ )
+        {
+        CXnNode* node( nodes[i] );
+
+        CXnPluginData& plugin( viewData.Plugin( node ) );
+
+        if ( !plugin.Occupied() )
+            {
+            return &plugin;
+            }
+        }
+
+    return NULL;
+    }
+
+// ---------------------------------------------------------------------------
+// DeterminePlugin
+// Determines target plugin based widget info
+// ---------------------------------------------------------------------------
+//
+CXnPluginData* DeterminePlugin( RPointerArray< CXnPluginData >& aPlugins, 
+    const CHsContentInfo& aContentInfo ) 
+    {    
+    for ( TInt i = 0; i < aPlugins.Count(); i++ )
+        {
+        CXnPluginData* plugin( aPlugins[i] );
+        
+        if ( plugin->Occupied() && plugin->PluginId() == aContentInfo.PluginId() )
+            {
+            return plugin;
+            }
+        }
+    
+    return NULL;
+    }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// ---------------------------------------------------------------------------
+// CXnEditor::NewL
+// ---------------------------------------------------------------------------
+// 
+CXnEditor* CXnEditor::NewL( CXnViewManager& aViewManager, 
+    const TDesC8& aUid )
+    {
+    CXnEditor* self = CXnEditor::NewLC( aViewManager, aUid );
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::NewLC
+// ---------------------------------------------------------------------------
+// 
+CXnEditor* CXnEditor::NewLC( CXnViewManager& aViewManager,
+    const TDesC8& aUid )
+    {
+    CXnEditor* self = new ( ELeave ) CXnEditor( aViewManager );
+    CleanupStack::PushL( self );
+    self->ConstructL( aUid );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::CXnEditor
+// ---------------------------------------------------------------------------
+// 
+CXnEditor::CXnEditor( CXnViewManager& aViewManager )
+    : iViewManager( aViewManager ),
+      iWidgetsVisibilityState( ETrue )
+    {
+    iViewManager.AddObserver( *this );
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::ConstructL
+// ---------------------------------------------------------------------------
+// 
+void CXnEditor::ConstructL( const TDesC8& aUid )
+    {
+    iCpsWrapper = CCpsWrapper::NewL( *this );
+    iHspsWrapper = CHspsWrapper::NewL( aUid, this );
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::~CXnEditor
+// ---------------------------------------------------------------------------
+// 
+CXnEditor::~CXnEditor()
+    {
+    iViewManager.RemoveObserver( *this );
+    
+    delete iCpsWrapper;
+    delete iHspsWrapper;
+    delete iPublisherMap;
+    }
+
+// -----------------------------------------------------------------------------
+// CXnEditor::IsCurrentViewFull
+// -----------------------------------------------------------------------------
+//
+TBool CXnEditor::IsCurrentViewFull()
+    {
+    TBool viewFull = ETrue;
+    
+    RPointerArray< CXnPluginData >& plugins( 
+        iViewManager.ActiveViewData().PluginData() );
+                
+    for ( TInt i = 0; i < plugins.Count(); i++ )
+        {
+        if ( !plugins[i]->Occupied() )
+            {
+            viewFull = EFalse;
+            break;
+            }
+        }
+    
+    return viewFull;
+    }
+
+// -----------------------------------------------------------------------------
+// CXnEditor::FilterWidgetListL
+// -----------------------------------------------------------------------------
+//
+void CXnEditor::FilterWidgetListL( CHsContentInfoArray& aContentInfoArray,
+    TBool aIgnoreViewFull )
+    {
+    RPointerArray< CHsContentInfo >& list( aContentInfoArray.Array() );
+    
+    TBool viewFull = ( aIgnoreViewFull ? EFalse : IsCurrentViewFull() );
+    
+    for ( TInt i = 0; i < list.Count(); i++ )
+        {
+        CHsContentInfo* info( list[i] );
+
+        info->SetCanBeAdded( EFalse );
+        info->SetCanBeRemoved( EFalse );
+        
+        TInt result( 0 );
+
+        if ( info->Type() != KKeyTemplate() )
+            {   
+            result = NonTemplateWidgetCanBeAddedRemovedL( *info );            
+            }
+        else
+            {
+            result = TemplateWidgetCanBeAddedRemovedL( *info );
+            }
+        
+        if ( ( result & ECanBeAdded ) && !viewFull )
+            {                        
+            info->SetCanBeAdded( ETrue );            
+            }
+        
+        if ( result & ECanBeRemoved )
+            {
+            info->SetCanBeRemoved( ETrue );
+            }
+        }            
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::TemplateWidgetCanBeAddedRemovedL
+// ---------------------------------------------------------------------------
+// 
+TInt CXnEditor::TemplateWidgetCanBeAddedRemovedL( 
+    CHsContentInfo& aInfo )
+	{
+	TInt retval( 0 );
+	
+	TInt widgetCount( 0 );
+	
+	RPointerArray< CXnPluginData > plugins;
+	CleanupClosePushL( plugins );
+	
+	if ( aInfo.IsWrt() )
+	    {
+	    // Get plugins globally from all pages
+	    iViewManager.PluginDataL( plugins, ETrue );
+	    }
+	else
+	    {
+	    // Get plugins from current page
+	    iViewManager.PluginDataL( plugins, EFalse );
+	    }
+	    	
+	// Get widgets in current configuration
+	for ( TInt i = 0; i < plugins.Count(); i++ )
+		{
+		CXnPluginData* plugin( plugins[i] );
+		
+		if ( !plugin->Occupied() )
+		    {
+		    continue;
+		    }
+		
+		if ( plugin->PublisherName() == aInfo.PublisherId() )
+			{
+			if ( plugin->Removable() )
+			    {
+			    // To enable widget remove
+			    aInfo.SetPluginIdL( plugin->PluginId() );
+			    
+			    retval |= ECanBeRemoved;
+			    }
+			
+			widgetCount++;
+			}
+		}
+
+	if ( widgetCount < aInfo.MaxWidgets() )
+	    {
+	    retval |= ECanBeAdded;
+	    }
+	
+	CleanupStack::PopAndDestroy( &plugins );
+	
+	return retval;
+	}
+
+// ---------------------------------------------------------------------------
+// CXnEditor::NonTemplateWidgetCanBeAddedRemovedL
+//
+// ---------------------------------------------------------------------------
+// 
+TInt CXnEditor::NonTemplateWidgetCanBeAddedRemovedL( 
+    CHsContentInfo& aInfo )
+    {    
+    TInt retval( 0 );
+    
+    TInt widgetCount( 0 );
+
+    CXnViewData& activeView( iViewManager.ActiveViewData() );
+
+    RPointerArray< CXnPluginData >& plugins( activeView.PluginData() );
+
+    for ( TInt i = 0; i < plugins.Count(); i++ )
+        {
+        CXnPluginData* plugin( plugins[i] );
+
+        if ( !plugin->Occupied() )
+            {
+            continue;
+            }        
+        
+        if ( plugin->PluginUid().CompareF( aInfo.Uid() ) == 0 )
+            {
+            if ( plugin->Removable() )
+                {
+                // To enable widget remove
+                aInfo.SetPluginIdL( plugin->PluginId() );
+                
+                retval |= ECanBeRemoved;
+                }
+            
+            widgetCount++;
+            }
+        }
+    
+    if ( widgetCount < aInfo.MaxWidgets() ||
+        aInfo.MaxWidgets() == KMultiInstanceUnlimitedValue )
+        {
+        retval |= ECanBeAdded;        
+        }
+    
+    return retval;
+    }
+
+
+// ---------------------------------------------------------------------------
+// CXnEditor::FilterViewListL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::FilterViewListL( CHsContentInfoArray& aContentInfoArray )
+    {
+    RPointerArray< CHsContentInfo >& list( aContentInfoArray.Array() );
+    
+    RPointerArray< CXnPluginData >& views( 
+        iViewManager.ActiveAppData().PluginData() );
+
+    TInt viewAmount( iViewManager.ViewAmount() );
+    
+    const TInt KMaxViewAmount( 6 );
+    
+    for ( TInt i = 0; i < list.Count(); i++ )
+        {
+        CHsContentInfo* info( list[i] );
+        
+        info->SetCanBeAdded( EFalse );
+        info->SetCanBeRemoved( EFalse );
+
+        for ( TInt j = 0 ; j < views.Count(); j++ )
+            {
+            CXnPluginData* view( views[j] );
+            
+            if ( view->PluginUid().CompareF( info->Uid() ) == 0 )
+                {
+                // To enable view remove
+                info->SetPluginIdL( view->PluginId() );
+                // Last view cannot be removed
+                if ( views.Count() > 1 )
+                    {
+                    info->SetCanBeRemoved( ETrue );
+                    }
+                }
+            }
+        
+        if ( viewAmount < KMaxViewAmount )
+            {
+            info->SetCanBeAdded( ETrue );
+            }
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::RemoveUnRegisteredWidgetL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::RemoveUnRegisteredWidgetL( const TDesC16& aPublisher )
+    {
+    RPointerArray< CXnPluginData > plugins;
+    CleanupClosePushL( plugins );
+    
+    iViewManager.PluginDataL( plugins, ETrue );
+
+    for ( TInt i = 0; i < plugins.Count(); i++ )
+        {
+        CXnPluginData* plugin( plugins[i] );
+        
+        if( plugin->Occupied() && plugin->PublisherName() == aPublisher )
+            {
+            iViewManager.UnloadWidgetFromPluginL( *plugin );                                
+            }
+        }
+    
+    CleanupStack::PopAndDestroy( &plugins );
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::RemoveUnInstalledWidgetL
+// ---------------------------------------------------------------------------
+// 
+void CXnEditor::RemoveUnInstalledWidgetL( const CHsContentInfo& aContentInfo )
+    {
+    RPointerArray< CXnPluginData > plugins;
+    CleanupClosePushL( plugins );
+    
+    iViewManager.PluginDataL( plugins, ETrue );
+    
+    CXnPluginData* plugin( DeterminePlugin( plugins, aContentInfo ) ); 
+                            
+    if ( plugin )
+        {
+        iViewManager.UnloadWidgetFromPluginL( *plugin );
+        }  
+    
+    CleanupStack::PopAndDestroy( &plugins );
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::ReplaceWidgetL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::ReplaceWidgetL( CHsContentInfo& aContentInfo, TBool aUseHsps ) 
+    {
+    RPointerArray< CXnPluginData > plugins;
+    CleanupClosePushL( plugins );
+    
+    iViewManager.PluginDataL( plugins, ETrue );
+    
+    CXnPluginData* match = NULL;
+    
+    for( TInt i = 0; i < plugins.Count(); i++ )
+        {
+        CXnPluginData* plugin( plugins[i] );
+        
+        if( plugin->PluginId() == aContentInfo.PluginId() )
+            {
+            match = plugin;
+            break;
+            }
+        }
+    
+    if( match )
+        {
+        iViewManager.ReplaceWidgetToPluginL( aContentInfo, *match, aUseHsps );
+        }
+    
+    CleanupStack::PopAndDestroy( &plugins );    
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::AddWidgetL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::AddWidgetL()
+    {
+    MHsContentControlUi* ui( 
+        iViewManager.AppUiAdapter().HsContentController( KWMUi ) ); 
+                                                
+    if( ui )
+        {
+        ui->SetContentController( this );
+        ui->Activate();
+        
+        return;
+        }
+    
+    CXnPluginData* plugin( NULL );
+
+    if ( iTargetPlugin )
+        {
+        plugin = DeterminePlugin( iViewManager, iTargetPlugin );               
+        }
+    else
+        {
+        plugin = DeterminePlugin( iViewManager );
+        }
+
+    iTargetPlugin = NULL;
+        
+    CHsContentInfoArray* info = CHsContentInfoArray::NewL();
+    CleanupStack::PushL( info );
+           
+    RPointerArray< CHsContentInfo >& widgets( info->Array() );
+
+    // get installed widgets from HSPS (type: "widget")
+    HSPSPluginsL( widgets, KKeyWidget );
+    // get installed widgets from HSPS
+    TemplatedWidgetsL( widgets );
+    
+    FilterWidgetListL( *info, ETrue );
+                      
+    CDesCArrayFlat* array = new ( ELeave ) CDesCArrayFlat( 8 );
+    CleanupStack::PushL( array );
+    
+    for ( TInt i = 0; i < widgets.Count(); i++ )
+        {
+        CHsContentInfo* widget( widgets[i] );
+        
+        if ( widget->CanBeAdded() )
+            {
+            TPtrC name( ParseWidgetName( *widget ) );
+            
+            array->InsertIsqAllowDuplicatesL( name );            
+            }
+        }
+
+    const TDesC8& ns( iViewManager.ViewNode()->Namespace() );
+
+    CXnNode* link( iViewManager.UiEngine().FindNodeByIdL( KDownload, ns ) );
+
+    if ( link )
+        {
+        CXnText* textIf( NULL );
+
+        XnComponentInterface::MakeInterfaceL( textIf, link->AppIfL() );
+
+        if ( textIf )
+            {
+            const TDesC* text( textIf->Text() );
+
+            if ( text )
+                {
+                // First item is always Download link
+                array->InsertL( 0, *text );
+                }
+            }
+        }
+
+    // Display dialog
+    TInt selectedIndex( 0 );
+
+    CAknListQueryDialog* query =
+        new ( ELeave ) CAknListQueryDialog( &selectedIndex );
+
+    query->PrepareLC( R_LISTQUERY_ADD_WIDGET );
+
+    query->SetItemTextArray( array );
+    query->SetOwnershipType( ELbmDoesNotOwnItemArray );
+
+    // Save dialog pointer for later usage
+    iQuery = query;
+
+    TBool linkSelected( EFalse );
+
+    if ( query->RunLD() )
+        {
+        // Download link is always the first one, if it is defined
+        if ( link && selectedIndex == 0 )
+            {
+            // Activate download link shortcut
+            link->SetStateL( XnPropertyNames::style::common::KActive );
+            link->UnsetStateL( XnPropertyNames::style::common::KActive );
+
+            linkSelected = ETrue;
+            }       
+        else
+            {
+            if ( !plugin )
+                {
+                // No room for new widget, so error note.
+                HBufC* msg = StringLoader::LoadLC( R_QTN_HS_ADD_WIDGET_FULL );                
+                ShowErrorNoteL( *msg );                    
+                CleanupStack::PopAndDestroy( msg );
+                }            
+            }
+                    
+        const TDesC& selectedName( ( *array )[selectedIndex] );
+
+        for ( TInt i = 0; plugin && !linkSelected && i < widgets.Count(); i++ )
+            {
+            CHsContentInfo* widget( widgets[i] );
+
+            TPtrC name( ParseWidgetName( *widget ) );
+
+            if ( selectedName == name )
+                {             
+                TInt ret( iViewManager.LoadWidgetToPluginL( *widget, *plugin ) );
+                
+                if ( ret == KErrNone )
+                    {
+                    CXnNode *node( plugin->Owner()->LayoutNode() );
+
+                    // Analyse added widget
+                    TBool widgetOk( iViewManager.UiEngine().AnalyseAddedWidgetL(
+                            *node ) );
+
+                    if ( !widgetOk )
+                        {
+                        iViewManager.UnloadWidgetFromPluginL( *plugin );
+                        
+                        // Widget doesn't fit to UI 
+                        HBufC* msg = StringLoader::LoadLC(
+                            R_QTN_HS_ADD_WIDGET_FULL );
+                        
+                        ShowErrorNoteL( *msg );
+                        
+                        CleanupStack::PopAndDestroy( msg );
+                        }                    
+                    }
+                
+                break;
+                }
+            }
+        }
+
+    // Dialog ended and deleted by RunLD
+    iQuery = NULL;
+
+    CleanupStack::PopAndDestroy( 2, info ); // array
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::RemoveWidgetL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::RemoveWidgetL( CXnNode* aNode )    
+    {
+    if ( iTargetPlugin )
+        {
+        aNode = iTargetPlugin;               
+        }
+
+    iTargetPlugin = NULL;
+    
+    if ( !aNode )
+        {
+        return;
+        }
+
+    CXnPluginData& plugin( iViewManager.ActiveViewData().Plugin( aNode ) );
+
+    if( plugin.Removable() )
+        {
+        TRAP_IGNORE( iViewManager.UnloadWidgetFromPluginL( plugin ) );
+        }       
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::ReorderWidgetsL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::ReorderWidgetsL( RPointerArray< CXnNode >* aPluginArray )
+    {    
+    if ( !aPluginArray )
+        {
+        return;
+        }
+    
+    CXnViewData& viewData( iViewManager.ActiveViewData() );
+
+    const TDesC8& configurationId( viewData.ConfigurationId() );
+  
+    CDesC8ArrayFlat* ids = new ( ELeave ) CDesC8ArrayFlat( 6 );
+    CleanupStack::PushL( ids );
+
+    for ( TInt i = 0; i < aPluginArray->Count(); i++ )
+        {
+        CXnPluginData& plugin( viewData.Plugin( ( *aPluginArray )[i] ) );
+
+        const TDesC8& id( plugin.PluginId() );
+        
+        if ( id != KNullDesC8 )
+            {
+            ids->AppendL( id );
+            }              
+        }
+
+    iHspsWrapper->MovePluginsL( configurationId, *ids );
+
+    CleanupStack::PopAndDestroy( ids );
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::PublisherInfoL
+// ---------------------------------------------------------------------------
+//
+CPublisherInfo* CXnEditor::PublisherInfoL( const CHsContentInfo& aContentInfo )
+    {
+    if ( !iPublisherMap )
+        {
+        return NULL;
+        }
+
+    RPointerArray< CPublisherInfo >& publisherInfo(
+        iPublisherMap->PublisherInfo() );
+
+    const TDesC& widgetName( aContentInfo.Name() );
+    const TDesC& publisherId( aContentInfo.PublisherId() );
+
+    CPublisherInfo* info = NULL;
+    
+    for ( TInt i = 0; i < publisherInfo.Count(); i++ )
+        {
+        info = publisherInfo[i];
+
+        if ( info->WidgetName() == widgetName &&
+            info->PublisherId() == publisherId )
+            {
+            break;
+            }
+        }
+
+    return info;
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::TemplatedWidgetsL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::TemplatedWidgetsL( RPointerArray< CHsContentInfo >& aWidgets )
+    {
+    RPointerArray< CHsContentInfo > widgetTemplates;
+    CleanupStack::PushL( TCleanupItem( DeleteWidgetInfo, &widgetTemplates ) );
+
+    // Gets all the installed templates from CPS
+    HSPSPluginsL( widgetTemplates, KKeyTemplate );
+
+    delete iPublisherMap;
+    iPublisherMap = NULL;
+
+    iPublisherMap = iCpsWrapper->GetTemplatedPublishersL();
+
+    RPointerArray< CPublisherInfo >& publisherInfo(
+        iPublisherMap->PublisherInfo() );
+
+    for ( TInt i = 0; i < publisherInfo.Count(); i++ )
+        {
+        CPublisherInfo* info( publisherInfo[i] );
+
+        for ( TInt j = 0; j < widgetTemplates.Count(); j++ )
+            {
+            const TDesC& name( widgetTemplates[j]->Name() );
+
+            if ( name == info->TemplateType() )
+                {
+                CHsContentInfo* contentInfo = CHsContentInfo::NewLC();
+
+                contentInfo->SetNameL( info->WidgetName() );
+                contentInfo->SetPublisherIdL( info->PublisherId() );
+                contentInfo->SetMaxWidgets( info->MaxWidgets() );
+                contentInfo->SetUidL( widgetTemplates[j]->Uid() );
+                contentInfo->SetTypeL( widgetTemplates[j]->Type() );
+                contentInfo->SetDescriptionL( info->Description() );
+                contentInfo->SetIconPathL( info->LogoIcon() );
+                                
+                contentInfo->SetIsWrt(  
+                    ( info->ContentType() == KWRTTemplate() ) );
+                                
+                aWidgets.AppendL( contentInfo );
+                CleanupStack::Pop( contentInfo );
+
+                break;
+                }
+            }
+        }
+
+    CleanupStack::PopAndDestroy(); // cleanupitem
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::HSPSPluginsL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::HSPSPluginsL( RPointerArray< CHsContentInfo >& aWidgets,
+    const TDesC8& aType )
+    {
+    RPointerArray< hspswrapper::CPluginInfo > plugins;
+    CleanupStack::PushL( TCleanupItem( DeletePluginInfos, &plugins ) );
+
+    if ( aType == KApplication )
+        {
+        iHspsWrapper->GetAppConfigurationsL( plugins );
+        }
+    else
+        {
+        iHspsWrapper->GetPluginsL( plugins, KPluginInterface, aType );
+        }
+
+    for ( TInt i = 0; i < plugins.Count(); i++ )
+        {
+        if ( plugins[i]->Uid().CompareF( KEmptyWidgetUid ) == 0 )
+            {
+            // Skip empty
+            continue;
+            }
+        
+        CHsContentInfo* contentInfo = CHsContentInfo::NewLC();
+
+        contentInfo->SetNameL( plugins[i]->Name() );
+        contentInfo->SetUidL( plugins[i]->Uid() );
+        contentInfo->SetTypeL( aType );
+        
+        if ( aType == KKeyWidget || aType == KKeyTemplate )
+            {
+            contentInfo->SetMaxWidgets( plugins[i]->MultiInstance() );
+            }
+
+        contentInfo->SetDescriptionL( plugins[i]->Description() );
+        contentInfo->SetIconPathL( plugins[i]->LogoIcon() );
+
+        aWidgets.AppendL( contentInfo );
+        CleanupStack::Pop( contentInfo );
+        }
+
+    CleanupStack::PopAndDestroy( &plugins );
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::ToggleWidgetsVisibiltyL
+// ---------------------------------------------------------------------------
+//
+TBool CXnEditor::ToggleWidgetsVisibiltyL()
+    {
+    RPointerArray< CXnPluginData >& plugins(
+        iViewManager.ActiveViewData().PluginData() );
+
+    TBool useEmpty( iViewManager.ActiveViewData().UseEmptyWidget() );
+    
+    TBool stateChanged( EFalse );
+
+    for ( TInt i = 0; i < plugins.Count(); i++ )
+        {
+        CXnPluginData* plugin( plugins[i] );
+        
+        if( !plugin->Removable() )
+            {
+            // Don't touch to non-removable widget
+            continue;
+            }
+
+        if ( iWidgetsVisibilityState )
+            {            
+            // Currently visible, make invisible
+            stateChanged = ETrue;
+
+            SetPropertyL( *plugin->Owner()->LayoutNode(),
+                XnPropertyNames::style::common::KVisibility,
+                XnPropertyNames::style::common::visibility::KHidden );
+            }
+        else
+            {
+            // Currently invisible, make visible
+            if ( plugin->Occupied() )
+                {
+                stateChanged = ETrue;
+                
+                SetPropertyL( *plugin->Owner()->LayoutNode(),
+                    XnPropertyNames::style::common::KVisibility,
+                    XnPropertyNames::style::common::visibility::KVisible );                
+                }
+            else if( useEmpty )
+                {
+                stateChanged = ETrue;
+                
+                SetPropertyL( *plugin->Owner()->LayoutNode(),
+                    XnPropertyNames::style::common::KVisibility,
+                    XnPropertyNames::style::common::visibility::KBlank );                                    
+                }
+            }
+        }
+
+    if ( stateChanged )
+        {
+        // Update
+        iWidgetsVisibilityState = !iWidgetsVisibilityState;
+        }
+
+    return iWidgetsVisibilityState;
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::WidgetsVisible
+// ---------------------------------------------------------------------------
+//
+TBool CXnEditor::WidgetsVisible() const
+    {
+    return iWidgetsVisibilityState;
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::SetTargetPlugin
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::SetTargetPlugin( CXnNode* aNode )
+    {
+    iTargetPlugin = aNode;
+    }
+
+// ---------------------------------------------------------------------------
+// -----------------------------------------------------------------------------
+// CXnEditor::NotifyViewActivatedL
+// -----------------------------------------------------------------------------
+//
+void CXnEditor::NotifyViewActivatedL( const CXnViewData& aViewData )
+    {
+    RPointerArray< CXnPluginData >& plugins( aViewData.PluginData() );
+    
+    TBool emptyInUse( aViewData.UseEmptyWidget() );
+    TBool editState( iViewManager.UiEngine().EditMode()->EditState() );
+              
+    iWidgetsVisibilityState = EFalse;
+    
+    for ( TInt i = 0; i < plugins.Count(); i++ )
+        {
+        CXnPluginData* plugin( plugins[i] );
+        
+        if ( plugin->Occupied() )
+            {
+            // At least one widget visible
+            iWidgetsVisibilityState = ETrue;                       
+            }
+        
+        if ( plugin->Occupied() || editState )
+            {
+            // Make widget visible
+            SetPropertyL( *plugin->Owner()->LayoutNode(),
+                XnPropertyNames::style::common::KVisibility,
+                XnPropertyNames::style::common::visibility::KVisible );            
+            }              
+        else
+            {            
+            if ( emptyInUse )
+                {
+                // Make empty space blank
+                SetPropertyL( *plugin->Owner()->LayoutNode(),
+                    XnPropertyNames::style::common::KVisibility,
+                    XnPropertyNames::style::common::visibility::KBlank );
+                }
+            else
+                {
+                // Nothing in this plugin hide
+                SetPropertyL( *plugin->Owner()->LayoutNode(),
+                    XnPropertyNames::style::common::KDisplay,
+                    XnPropertyNames::style::common::display::KNone );                
+                }
+            }
+        }                           
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::NotifyConfigureWidgetL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::NotifyConfigureWidgetL( const CHsContentInfo& aContentInfo,
+    CXnPluginData& aPluginData )
+    {
+    if ( aContentInfo.Type() != KKeyTemplate )    	    
+        {
+        // Doesn't need configuration
+        return;
+        }
+
+    const TDesC8& pluginId( aPluginData.PluginId() );
+
+    CHspsConfiguration* pluginConf(
+        iHspsWrapper->GetPluginConfigurationL( pluginId ) );
+
+    CleanupStack::PushL( pluginConf );
+
+    const CPublisherInfo* info = PublisherInfoL( aContentInfo );
+
+    __ASSERT_DEBUG( info != NULL, Panic( EXnInvalidPublisherInfo ) );
+    if ( !info )
+        {
+        User::Leave( KErrBadHandle );
+        }
+    RPointerArray< CItemMap > itemMapListIn;
+    CleanupStack::PushL( TCleanupItem( DeleteItemMaps, &itemMapListIn ) );
+    RPointerArray< CItemMap >& settings = pluginConf->Settings();
+
+    HBufC8* publisherId = CnvUtfConverter::ConvertFromUnicodeToUtf8L(
+        info->PublisherId() );
+    CleanupStack::PushL( publisherId );
+
+    aPluginData.SetPublisherNameL( info->PublisherId() );
+
+    CItemMap* itemMap( 0 );
+    CPropertyMap* property( 0 );
+    CPropertyMap* propertyIn( 0 );
+
+    for ( TInt i = 0; i < settings.Count(); ++i )
+        {
+        CItemMap* readItem = settings[i];
+        itemMap = CItemMap::NewLC();
+        itemMap->SetItemIdL( readItem->ItemId() );
+        const TDesC8& itemName = readItem->ItemName();
+        itemMap->SetItemNameL( itemName );
+
+        RPointerArray< CPropertyMap >& properties = readItem->Properties();
+        for ( int j = 0; j < properties.Count(); ++j )
+            {
+            property = properties[j];
+            propertyIn = CPropertyMap::NewLC();
+            propertyIn->SetNameL( property->Name() );
+            // Dispatching is based on item name
+            if (  itemName == KContentSource() )
+                {
+                propertyIn->SetValueL( *publisherId );
+                }
+            else if ( itemName ==  KContentData() )
+                {
+                // If this default template with full configuration
+                TInt pos = property->Value().LocateReverse( KSepratorChar );
+                if ( KErrNotFound != pos  )
+                    {
+                    propertyIn->SetValueL( property->Value() );
+                    }
+                else
+                    {
+                    HBufC8* contentData = HBufC8::NewLC( publisherId->Length()
+                        + KSeperator().Length()
+                        + property->Value().Length());
+                    contentData->Des().Copy( *publisherId );
+                    contentData->Des().Append( KSeperator );
+                    contentData->Des().Append( property->Value() );
+                    propertyIn->SetValueL( *contentData );
+                    CleanupStack::PopAndDestroy( contentData );
+                    }
+                }
+            else if ( itemName.Find( KPublisher ) != KErrNotFound )
+                {
+                propertyIn->SetValueL( *publisherId );
+                }
+            else if ( !KPubTrigger().Compare( itemName ) )
+                {
+                HBufC8* triggerData = HBufC8::NewLC(
+                    publisherId->Length()
+                    + KSeperator().Length()
+                    + KPublisher().Length()
+                    + KWidgetTriggerName().Length());
+                triggerData->Des().Copy( *publisherId );
+                triggerData->Des().Append( KSeperator );
+                triggerData->Des().Append( KPublisher );
+                triggerData->Des().Append( KWidgetTriggerName );
+
+                propertyIn->SetValueL( *triggerData );
+                CleanupStack::PopAndDestroy( triggerData );
+                }
+            else if ( !KTrigger().Compare( itemName ) )
+                {
+                // If this default template with full configuration
+                TInt pos = property->Value().LocateReverse( KSepratorChar );
+                if ( KErrNotFound != pos )
+                    {
+                    propertyIn->SetValueL( property->Value() );
+                    }
+                else
+                    {
+                    HBufC8* triggerData = HBufC8::NewLC(
+                        publisherId->Length()
+                        + KSeperator().Length()
+                        + property->Value().Length()
+                        + KOpen().Length()
+                        + property->Value().Length()
+                        + KClose().Length() );
+                    triggerData->Des().Copy( *publisherId );
+                    triggerData->Des().Append( KSeperator );
+                    triggerData->Des().Append( property->Value() );
+                    triggerData->Des().Append( KOpen );
+                    triggerData->Des().Append( property->Value() );
+                    triggerData->Des().Append( KClose );
+                    propertyIn->SetValueL( *triggerData );
+                    CleanupStack::PopAndDestroy( triggerData );
+                    }
+                }
+            else
+                {
+                // unrecognized items are not handled
+                }
+            itemMap->AddPropertyMapL( propertyIn );
+            CleanupStack::Pop( propertyIn );
+            }
+        itemMapListIn.AppendL( itemMap );
+        CleanupStack::Pop( itemMap );
+        }
+    iHspsWrapper->SetPluginSettingsL( pluginId, itemMapListIn );
+
+    CleanupStack::PopAndDestroy( publisherId );
+    CleanupStack::PopAndDestroy( &itemMapListIn );
+    CleanupStack::PopAndDestroy( pluginConf );
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::NotifyWidgetAdditionL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::NotifyWidgetAdditionL( const CXnPluginData& aPluginData )
+    {
+    CXnNode* node( aPluginData.Owner()->LayoutNode() );
+
+    // At least one widget is visible
+    iWidgetsVisibilityState = ETrue;
+    
+    // Ensure the new widget is visible
+    SetPropertyL( *node,
+        XnPropertyNames::style::common::KVisibility,
+        XnPropertyNames::style::common::visibility::KVisible );        
+    
+    SetPropertyL( *node,
+        XnPropertyNames::style::common::KDisplay,
+        XnPropertyNames::style::common::display::KBlock );
+    
+    node->SetDirtyL( XnDirtyLevel::ELayoutAndRenderSiblings );
+    
+    WidgetListChanged();
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::NotifyWidgetRemovalL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::NotifyWidgetRemovalL( const CXnPluginData& aPluginData )
+    {
+    CXnNode* node( aPluginData.Owner()->LayoutNode() );
+
+    CXnViewData& viewData( 
+        static_cast< CXnViewData& >( *aPluginData.Parent() ) );
+    
+    TBool emptyInUse( viewData.UseEmptyWidget() );
+    
+    if ( emptyInUse )
+        {        
+        if ( iViewManager.UiEngine().IsEditMode() )
+            {
+            // Ensure the plugin which was holding 
+            // the removed widget is visible when edit mode is active
+            SetPropertyL( *node,
+                XnPropertyNames::style::common::KVisibility,
+                XnPropertyNames::style::common::visibility::KVisible );                   
+            }
+        else
+            {
+            // Ensure the plugin which was holding 
+            // the removed widget is blank now
+            SetPropertyL( *node,
+                XnPropertyNames::style::common::KVisibility,
+                XnPropertyNames::style::common::visibility::KBlank );            
+            }                
+        }
+    else
+        {
+        // Ensure the plugin which was holding the removed widget is invisible
+        SetPropertyL( *node,
+            XnPropertyNames::style::common::KDisplay,
+            XnPropertyNames::style::common::display::KNone );
+                
+        // Reodred layout tree by moving the plugin which was holding the
+        // removed widget as the last one in layout tree's plugin the list
+        CXnNode *parent( node->Parent() );
+
+        RPointerArray< CXnNode >& children( parent->Children() );
+
+        TInt nodeIndex( children.Find( node ) );
+
+        children.Remove( nodeIndex );
+        children.Insert( node, children.Count() - 1 );
+        }
+    
+    node->SetDirtyL( XnDirtyLevel::ERender );
+    
+    iTargetPlugin = NULL;
+    
+    if ( aPluginData.Active() )
+        {
+        CXnViewData& viewData( iViewManager.ActiveViewData() );
+        
+        RPointerArray< CXnPluginData >& plugins( viewData.PluginData() );
+        
+        TBool occupied( EFalse );
+        
+        for ( TInt i = 0; i < plugins.Count(); i++ )
+            {
+            if ( plugins[i]->Occupied() && plugins[i]->Removable() )
+                {
+                occupied = ETrue;
+                break;
+                }
+            }
+        
+        if ( !occupied )
+            {
+            // No more widgets in the active view
+            iWidgetsVisibilityState = EFalse;
+            }               
+        }
+    
+    WidgetListChanged();
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::NotifyViewAdditionL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::NotifyViewAdditionL( const CXnPluginData& /*aPluginData*/ )
+    {
+    ViewListChanged();
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::NotifyViewRemovalL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::NotifyViewRemovalL( const CXnPluginData& /*aPluginData*/ )
+    {
+    ViewListChanged();
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::NotifyWidgetUnregisteredL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::NotifyWidgetUnregisteredL( const TDesC& aPublisher )
+    {
+    RemoveUnRegisteredWidgetL( aPublisher );
+    WidgetListChanged();    
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::NotifyWidgetRegisteredL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::NotifyWidgetRegisteredL()
+    {
+    WidgetListChanged();
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::NotifyViewDeactivatedL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::NotifyViewDeactivatedL( const CXnViewData& /*aViewData*/)
+    {
+    }
+
+// ---------------------------------------------------------------------------
+// CXnEditor::SetWallpaperL
+// ---------------------------------------------------------------------------
+//
+void CXnEditor::SetWallpaperL()
+    {
+    // Display dialog
+    TInt selectedIndex( 0 );
+
+    CAknListQueryDialog* query =
+        new ( ELeave ) CAknListQueryDialog( &selectedIndex );
+    CleanupStack::PushL( query );
+    query->PrepareLC( R_LISTQUERY_CHANGE_WALLPAPER );
+
+    if ( query->RunLD() )
+        {
+        if ( selectedIndex == 0 )
+            {
+            // set wallpaper. No need to check return value. If successful,
+            // avkon calls SkinConfigurationChanged function
+            AknsWallpaperUtils::SetIdleWallpaper(
+                    KNullDesC,
+                    NULL );
+            }
+        else if ( selectedIndex == 1 )
+            {
+            iViewManager.AppUiAdapter().ActivateLocalViewL( KWallpaperViewUid, KDummyUid, KSingle );                
+            }
+        else if ( selectedIndex == 2 )
+            {
+            iViewManager.AppUiAdapter().ActivateLocalViewL( KWallpaperViewUid, KDummyUid, KMulti );                
+            }        
+        }
+    CleanupStack::Pop( query );
+    }
+
+// -----------------------------------------------------------------------------
+// CXnEditor::HandleNotifyL
+// Handles notifications from HSPS wrapper
+// -----------------------------------------------------------------------------
+//
+TInt CXnEditor::HandleNotifyL(
+    const TDesC8& aEvent,
+    const TDesC8& /*aAppConfUid*/,
+    const TDesC8& aPluginName,
+    const TDesC8& aOrigUid,
+    const TDesC8& aPluginUid,
+    const TDesC8& aPluginId )
+    {
+    // Someone else has modified the configuration. Handle UI side here.
+    if( aEvent == KEventPluginAdded ||
+        aEvent == KEventPluginRemoved ||
+        aEvent == KEventPluginReplaced )
+        {
+        if( aOrigUid != KNullDesC8 && 
+            aOrigUid != KAi3Uid )
+            {
+            CHsContentInfo* info = CHsContentInfo::NewLC();
+            
+            info->SetNameL( aPluginName );
+            info->SetUidL( aPluginUid );
+            info->SetPluginIdL( aPluginId );
+            
+            ReplaceWidgetL( *info, EFalse );
+            
+            CleanupStack::PopAndDestroy( info );
+            }
+        }
+    else if ( aEvent == KEventPluginUnInstalled )
+        {
+        CHsContentInfo* info = CHsContentInfo::NewLC();
+
+        info->SetNameL( aPluginName );
+        info->SetUidL( aPluginUid );
+        info->SetPluginIdL( aPluginId );
+
+        RemoveUnInstalledWidgetL( *info );
+        WidgetListChanged();
+
+        CleanupStack::PopAndDestroy( info );
+        }
+    else if ( aEvent == KEventRootConfActivated )
+        {
+        iViewManager.AppUiAdapter().ReloadUiL();
+        }
+    else if ( aEvent == KEventPluginInstalled )
+        {        
+        WidgetListChanged();        
+        }
+    else if ( aEvent == KEventPluginUpdated )
+        {
+        // If the plugin is in use then reload the widget
+        if ( aPluginId.Length() > 0 )
+            {
+            CHsContentInfo* info = CHsContentInfo::NewLC();    
+            info->SetNameL( aPluginName );
+            info->SetUidL( aPluginUid );
+            info->SetPluginIdL( aPluginId );    
+            ReplaceWidgetL( *info );                
+            CleanupStack::PopAndDestroy( info );
+            }
+        WidgetListChanged();
+        }    
+    else if ( aEvent == KEventPluginActivated )
+        {
+        }
+ 
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// CXnEditor::WidgetListChanged
+// -----------------------------------------------------------------------------
+//
+void CXnEditor::WidgetListChanged()
+    {
+    MHsContentControlUi* ui( 
+        iViewManager.AppUiAdapter().HsContentController( KWMUi ) );
+            
+    if( ui )
+        {
+        ui->NotifyWidgetListChanged();
+        }
+    MHsContentControl* srv( iViewManager.AppUiAdapter().HsContentControlSrv() );
+    if ( srv )
+        {
+        srv->NotifyWidgetListChanged();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CXnEditor::ViewListChanged
+// -----------------------------------------------------------------------------
+//
+void CXnEditor::ViewListChanged()
+    {
+    MHsContentControlUi* ui( 
+        iViewManager.AppUiAdapter().HsContentController( KWMUi ) );
+            
+    if( ui )
+        {
+        ui->NotifyViewListChanged();
+        }
+    MHsContentControl* srv( iViewManager.AppUiAdapter().HsContentControlSrv() );
+    if ( srv )
+        {
+        srv->NotifyViewListChanged();
+        }
+    }
+
+// -----------------------------------------------------------------------------
+// CXnEditor::HspsWrapper
+// -----------------------------------------------------------------------------
+//
+CHspsWrapper& CXnEditor::HspsWrapper() const
+    {
+    return *iHspsWrapper;
+    }
+
+// -----------------------------------------------------------------------------
+// from MHsContentController
+// -----------------------------------------------------------------------------
+//
+TInt CXnEditor::WidgetListL( CHsContentInfoArray& aArray )
+    {
+    RPointerArray< CHsContentInfo >& array( aArray.Array() );
+
+    // get installed widgets from HSPS (type: "widget")
+    HSPSPluginsL( array, KKeyWidget );
+    // get installed widgets from HSPS
+    TemplatedWidgetsL( array );
+    
+    FilterWidgetListL( aArray, EFalse );
+    
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// from MHsContentController
+// -----------------------------------------------------------------------------
+//
+TInt CXnEditor::ViewListL( CHsContentInfoArray& aArray )
+    {
+    RPointerArray< CHsContentInfo >& array( aArray.Array() );
+    
+    // get installed views from HSPS 
+    HSPSPluginsL( array, KView );
+    
+    FilterViewListL( aArray );
+    
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// from MHsContentController
+// -----------------------------------------------------------------------------
+//
+TInt CXnEditor::AppListL( CHsContentInfoArray& aArray )
+    {
+    RPointerArray< CHsContentInfo >& array( aArray.Array() );
+    
+    HSPSPluginsL( array, KApplication );
+    
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// from MHsContentController
+// -----------------------------------------------------------------------------
+//
+TInt CXnEditor::AddWidgetL( CHsContentInfo& aInfo )
+    {
+    TInt ret( KErrNone );    
+
+    const TDesC8& type( aInfo.Type() );
+    
+    if ( ( type != KKeyWidget && type != KKeyTemplate ) ||
+         aInfo.Uid() == KNullDesC8 )
+        {
+        // malformed content info
+        return KErrArgument;
+        }
+
+    if ( !aInfo.CanBeAdded() )
+        {
+        // the widget can not be added. Return proper error code
+        if ( IsCurrentViewFull() )
+            {
+            return KHsErrorViewFull;
+            }
+        else
+            {
+            return KHsErrorMaxInstanceCountExceeded;
+            }
+        }
+
+    CXnPluginData* plugin( NULL );
+    
+    if( iTargetPlugin )
+        {
+        plugin = DeterminePlugin( iViewManager, iTargetPlugin );
+        }
+    else
+        {
+        plugin = DeterminePlugin( iViewManager );
+        }
+    
+    iTargetPlugin = NULL;
+    
+    if ( !plugin )
+        {
+        return KErrGeneral;
+        }
+    
+    ret = iViewManager.LoadWidgetToPluginL( aInfo, *plugin );
+    
+    if( ret == KErrNone )
+        {
+        CXnNode* node( plugin->Owner()->LayoutNode() );
+        TBool widgetOk( iViewManager.UiEngine().AnalyseAddedWidgetL( *node ) );
+    
+        if( !widgetOk )
+            {
+            iViewManager.UnloadWidgetFromPluginL( *plugin );
+            
+            ret = KHsErrorDoesNotFit;
+            }        
+        }
+    
+    return ret;
+    }
+
+// -----------------------------------------------------------------------------
+// from MHsContentController
+// -----------------------------------------------------------------------------
+//
+TInt CXnEditor::RemoveWidgetL( CHsContentInfo& aInfo )
+    {
+    if ( !aInfo.CanBeRemoved() || aInfo.PluginId() == KNullDesC8 || 
+        ( aInfo.Type() != KKeyWidget && aInfo.Type() != KKeyTemplate ) )
+        {
+        return KErrArgument;
+        }
+    
+    TInt retval( KErrNotFound );
+    
+    RPointerArray< CXnPluginData > plugins;
+    CleanupClosePushL( plugins );
+    
+    // Search only from active view
+    iViewManager.PluginDataL( plugins );
+    
+    CXnPluginData* plugin( DeterminePlugin( plugins, aInfo ) ); 
+                            
+    if ( plugin && plugin->Removable() )
+        {
+        retval = iViewManager.UnloadWidgetFromPluginL( *plugin );
+        }  
+    
+    CleanupStack::PopAndDestroy( &plugins );
+    
+    return retval;
+    }
+
+// -----------------------------------------------------------------------------
+// from MHsContentController
+// -----------------------------------------------------------------------------
+//
+TInt CXnEditor::AddViewL( CHsContentInfo& aInfo )
+    {
+    if ( !aInfo.CanBeAdded() || aInfo.Uid() == KNullDesC8 || 
+        aInfo.Type() != KView )
+        {
+        return KErrArgument;
+        }
+          
+    return iViewManager.AddViewL( aInfo );
+    }
+
+// -----------------------------------------------------------------------------
+// from MHsContentController
+// -----------------------------------------------------------------------------
+//
+TInt CXnEditor::RemoveViewL( CHsContentInfo& aInfo )
+    {
+    if ( !aInfo.CanBeRemoved() || aInfo.PluginId() == KNullDesC8 || 
+        aInfo.Type() != KView )
+        {
+        return KErrArgument;
+        }
+    
+    return iViewManager.RemoveViewL( aInfo );
+    }
+
+// -----------------------------------------------------------------------------
+// from MHsContentController
+// -----------------------------------------------------------------------------
+//
+TInt CXnEditor::ActivateViewL( CHsContentInfo& aInfo )
+    {
+    if ( aInfo.Type() != KView )
+        {
+        return KErrArgument;
+        }
+    
+    return iViewManager.ActivateViewL( aInfo.PluginId() );
+    }
+
+// -----------------------------------------------------------------------------
+// from MHsContentController
+// -----------------------------------------------------------------------------
+//
+TInt CXnEditor::ActivateAppL( CHsContentInfo& aInfo )
+    {
+    if ( aInfo.Type() != KApplication )
+        {
+        return KErrArgument;
+        }
+    
+    return iViewManager.ActivateAppL( aInfo.Uid() );     
+    }
+
+// End of file