idlehomescreen/widgetmanager/src/wmwidgetloaderao.cpp
branchRCL_3
changeset 83 5456b4e8b3a8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/idlehomescreen/widgetmanager/src/wmwidgetloaderao.cpp	Wed Sep 01 12:32:46 2010 +0100
@@ -0,0 +1,435 @@
+/*
+* Copyright (c) 2009 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:
+* Active object to load widgets into list
+*
+*/
+
+// INCLUDE FILES
+#include "wmcommon.h"
+#include "wmplugin.h"
+#include "wmresourceloader.h"
+#include "wmpersistentwidgetorder.h"
+#include "wmlistbox.h"
+#include "wmwidgetloaderao.h"
+#include "wminstaller.h"
+#include "wmwidgetorderdata.h"
+
+#include <hscontentcontroller.h> // content control api
+#include <hscontentinfoarray.h> // content control api
+#include <widgetregistryclient.h> // widget reqistry
+#include <avkon.rsg> // avkon resources
+#include <barsread.h> // TResourceReader
+
+// ---------------------------------------------------------------------------
+// CWmWidgetLoaderAo::NewL
+// ---------------------------------------------------------------------------
+//
+CWmWidgetLoaderAo* CWmWidgetLoaderAo::NewL(
+        CWmPlugin& aWmPlugin,
+        CWmListBox& aTargetList )
+    {
+    CWmWidgetLoaderAo* self = new (ELeave) CWmWidgetLoaderAo(
+            aWmPlugin, aTargetList );
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ---------------------------------------------------------------------------
+// CWmWidgetLoaderAo::NewL
+// ---------------------------------------------------------------------------
+//
+CWmWidgetLoaderAo::CWmWidgetLoaderAo(
+        CWmPlugin& aWmPlugin,
+        CWmListBox& aTargetList )
+    : CActive( EPriorityNormal )
+    , iWmPlugin( aWmPlugin )
+    , iWidgetsList( aTargetList )
+    {
+    iWidgetRegistry = NULL;
+    iWidgetOrder = NULL;
+    iLoading = EFalse;
+    }
+
+// ---------------------------------------------------------------------------
+// CWmWidgetLoaderAo::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CWmWidgetLoaderAo::ConstructL()
+    {
+    CActiveScheduler::Add( this );
+    }
+
+// ---------------------------------------------------------------------------
+// CWmWidgetLoaderAo::~CWmWidgetLoaderAo
+// ---------------------------------------------------------------------------
+//
+CWmWidgetLoaderAo::~CWmWidgetLoaderAo()
+    {
+    // cancel ongoing operation
+    Cancel();
+
+    // cleanup and close session
+    Cleanup();
+    CloseSession();
+    }
+
+// ---------------------------------------------------------------------------
+// CWmWidgetLoaderAo::StartLoading
+// ---------------------------------------------------------------------------
+//
+void CWmWidgetLoaderAo::StartLoading()
+    {
+    if ( IsActive() )
+        {
+        return; // already active                
+        }
+
+    // call itself
+    iStatus = KRequestPending;
+    TRequestStatus *pS = (&iStatus);
+    User::RequestComplete( pS, KErrNone );
+    SetActive();
+    }
+
+// ---------------------------------------------------------------------------
+// CWmWidgetLoaderAo::RunL
+// ---------------------------------------------------------------------------
+//
+void CWmWidgetLoaderAo::RunL()
+    {
+    DoLoadWidgetsL();
+    Cleanup();
+    CloseSession();
+    if ( iObserver )
+        {
+        iObserver->LoadDoneL( iWidgetListChanged );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CWmWidgetLoaderAo::RunError
+// ---------------------------------------------------------------------------
+//
+TInt CWmWidgetLoaderAo::RunError( TInt /*aError*/ )
+    {
+    Cleanup();
+    CloseSession();
+    return KErrNone;
+    }
+
+// ---------------------------------------------------------
+// CWmWidgetLoaderAo::DoCancel
+// ---------------------------------------------------------
+//
+void CWmWidgetLoaderAo::DoCancel()
+    {
+    }
+
+// ---------------------------------------------------------
+// CWmWidgetLoaderAo::DoLoadWidgetsL
+// ---------------------------------------------------------
+//
+void CWmWidgetLoaderAo::DoLoadWidgetsL()
+    {
+    iWidgetListChanged = EFalse;
+    // Check if unistallation is ongoing for for some widget
+    // iUninstallUid is null no uninstallation is ongoing
+    iUninstallUid = iWmPlugin.WmInstaller().UninstallUid();
+    
+    // connect to widget registry
+    OpenSessionL();
+    
+    // 1. load the widgets array
+    MHsContentController& controller = iWmPlugin.ContentController();    
+    CHsContentInfoArray* contentInfoArray = CHsContentInfoArray::NewL();
+    CleanupStack::PushL( contentInfoArray );
+    controller.WidgetListL( *contentInfoArray );
+    
+    // 2. load the widget order
+    if ( iWidgetOrder ) { Cleanup(); }    
+    iWidgetOrder = CWmPersistentWidgetOrder::NewL( iWmPlugin.FileServer() );
+    TRAPD( loadError, iWidgetOrder->LoadL() );
+    
+    // 3. prepare the widget data array & sort order array
+    for( TInt i=0; i<iWidgetsList.WidgetDataCount(); ++i )
+        {
+        iWidgetsList.WidgetData(i, ETrue ).SetPersistentWidgetOrder( iWidgetOrder );
+        iWidgetsList.WidgetData(i, ETrue ).SetValid( EFalse );
+        }
+    for( TInt i = 0; i < iWidgetsList.OrderDataArray().Count(); ++i )
+        {
+        iWidgetsList.OrderData(i)->SetPersistentWidgetOrder( iWidgetOrder );
+        }
+    
+    // 4. loop through the content array and compare it against the existing
+    // widget data.
+    TInt widgetsAdded = 0;
+    TInt widgetsChanged = 0;
+    iLoading = ETrue;
+    while( contentInfoArray->Array().Count() > 0 )
+        {
+        CHsContentInfo* contentInfo = contentInfoArray->Array()[0];
+        if ( !contentInfo ) { break; }
+        contentInfoArray->Array().Remove( 0 );
+
+        // check if this widget exists.
+        // if it does, keep the existing one
+        // if it does not, add it
+        CWmWidgetData* existingData = FindWidgetData( *contentInfo );
+        if ( existingData )
+            {
+            // update existing visible widget data
+            existingData->SetValid( ETrue );
+            if ( existingData->ReplaceContentInfo( contentInfo ) )
+                {
+                // Update name to order array if name changed
+                for ( TInt i=0; i < iWidgetsList.OrderDataArray().Count(); i++ )
+                    {
+                    CWmWidgetOrderData* order = iWidgetsList.OrderData(i);
+                    if ( order->EqualsTo( 
+                            existingData->Uid(), existingData->PublisherId() ) )
+                        {
+                        order->UpdateName( existingData->Name() );
+                        }
+                    }
+                ++widgetsChanged;
+                }
+            }
+        else
+            {
+            // add a new widget data
+            TRAP_IGNORE( AddWidgetDataL( contentInfo, widgetsAdded ); );
+            }
+        }
+
+    // 5: finally, remove all UI widgets that during the loading process were
+    // NOT marked as VALID. those widgets do not exist anymore.
+    TInt widgetsRemoved = 0;
+    for( TInt i=0; i<iWidgetsList.WidgetDataCount(); i++ )
+        {
+        if( !iWidgetsList.WidgetData(i, ETrue ).IsValid() )
+            {
+            iWidgetsList.RemoveWidgetData( i, ETrue );
+            ++widgetsRemoved;
+            }
+        }
+    
+    // update listbox
+    if ( widgetsAdded > 0 && !iWidgetsList.IsFindPaneIsVisible() )
+        {
+        iWidgetsList.HandleItemAdditionL();
+        }
+    
+    if ( widgetsRemoved > 0 || widgetsAdded > 0 ||
+        widgetsChanged > 0 )
+        {
+        if ( !iWidgetsList.IsFindPaneIsVisible() )
+            {
+            iWidgetsList.DrawDeferred();
+            }
+        iWidgetListChanged = ETrue;
+        }
+    // 6: cleanup
+    CleanupStack::PopAndDestroy( contentInfoArray );
+
+    // 7. check list empty condition
+    if ( iWidgetsList.WidgetDataCount() == 0 )
+        {
+        TResourceReader rr;
+        CEikonEnv::Static()->CreateResourceReaderLC(
+                rr, R_AVKON_LISTBOX_DEFAULT_EMPTY_TEXT );
+        TPtrC empty= rr.ReadTPtrC();
+        iWidgetsList.View()->SetListEmptyTextL( empty );
+        CleanupStack::PopAndDestroy();
+        iWidgetsList.DrawDeferred();
+        }
+    
+    // 8. store list order if necessary
+    if ( loadError != KErrNone || widgetsAdded > 0 || widgetsRemoved > 0 )
+        {
+        TRAP_IGNORE( iWidgetOrder->StoreL( iWidgetsList.OrderDataArray() ); );
+        }
+    }
+
+// ---------------------------------------------------------
+// CWmWidgetLoaderAo::FindWidgetDataL
+// ---------------------------------------------------------
+//
+CWmWidgetData* CWmWidgetLoaderAo::FindWidgetData(
+        CHsContentInfo& aContentInfo )
+    {
+    CWmWidgetData* data = NULL;
+    for( TInt i=0; i<iWidgetsList.WidgetDataCount() && !data; ++i )
+        {
+        if ( iWidgetsList.WidgetData(i, ETrue ).EqualsTo( aContentInfo ) )
+            {
+            data = &iWidgetsList.WidgetData(i, ETrue );
+            }
+        }
+    return data;
+    }
+
+// ---------------------------------------------------------
+// CWmWidgetLoaderAo::OpenSessionL
+// ---------------------------------------------------------
+//
+void CWmWidgetLoaderAo::OpenSessionL()
+    {
+    if ( !iWidgetRegistry )
+        {
+        iWidgetRegistry = new (ELeave) RWidgetRegistryClientSession();
+        TInt err = iWidgetRegistry->Connect();
+        if ( KErrNone != err )
+            {
+            delete iWidgetRegistry;
+            iWidgetRegistry = NULL;
+            User::Leave( err );
+            }
+        }
+    }
+
+// ---------------------------------------------------------
+// CWmWidgetLoaderAo::CloseSession
+// ---------------------------------------------------------
+//
+void CWmWidgetLoaderAo::CloseSession()
+    {
+    // disconnect widget registry
+    if ( iWidgetRegistry )
+        {
+        iWidgetRegistry->Disconnect();
+        iWidgetRegistry->Close();
+        delete iWidgetRegistry;
+        iWidgetRegistry = NULL;
+        }
+    }
+
+// ---------------------------------------------------------
+// CWmWidgetLoaderAo::AddWidgetDataL
+// ---------------------------------------------------------
+//
+void CWmWidgetLoaderAo::AddWidgetDataL(
+        CHsContentInfo* aContentInfo, TInt& aCount )
+    {
+    CleanupStack::PushL( aContentInfo );
+            
+    // Becouse we show only widgets that can be added we need two arrays
+    // to maintain order data and visible data. 
+    // All widgets are added to listbox's iOrderDataArray and 
+    // widgets that CanBeAdded are added also to iVisibleWidgetArray.
+    CWmWidgetOrderData* order = CWmWidgetOrderData::NewLC(
+            aContentInfo->PublisherId(), 
+            UidFromString( aContentInfo->Uid() ), 
+            aContentInfo->Name(),
+            iWidgetOrder
+            );
+    
+    // add to order data
+    iWidgetsList.AddOrderDataL( order );
+    CleanupStack::Pop( order );
+    
+    if ( aContentInfo->CanBeAdded() )
+        {
+        CWmWidgetData* widgetData = CWmWidgetData::NewL(
+                iWidgetsList.LogoSize(),
+                iWmPlugin.ResourceLoader(),
+                aContentInfo, iWidgetRegistry );
+
+        // widgetdata has taken ownership of contentinfo
+        CleanupStack::Pop( aContentInfo );
+        
+        CleanupStack::PushL( widgetData );
+        
+        widgetData->SetPersistentWidgetOrder( iWidgetOrder );
+        widgetData->SetValid( ETrue );
+        
+        // start uninstall animation if this widget
+        // is currently been unistalled
+        if ( iUninstallUid != KNullUid &&
+            iUninstallUid == widgetData->PublisherUid() )
+            {
+            widgetData->VisualizeUninstallL();
+            }
+        // add to visible data
+        iWidgetsList.AddWidgetDataL( widgetData, EFalse );
+        CleanupStack::Pop( widgetData );
+        aCount++;
+        }
+    else
+        {
+        //delete aContentInfo when it's not added to iVisibleWidgetArray
+        CleanupStack::PopAndDestroy( aContentInfo );
+        }
+    }
+
+// ---------------------------------------------------------------------------
+// CWmWidgetLoaderAo::Cleanup
+// ---------------------------------------------------------------------------
+//
+void CWmWidgetLoaderAo::Cleanup()
+    {
+    iLoading = EFalse;
+    
+    // delete widget order and references to it
+    for( TInt i=0; i<iWidgetsList.WidgetDataCount(); ++i )
+        {
+        iWidgetsList.WidgetData(i, ETrue ).SetPersistentWidgetOrder( NULL );
+        }
+    delete iWidgetOrder;
+    iWidgetOrder = NULL;
+    }
+
+// ----------------------------------------------------
+// CWmWidgetData::UidFromString
+// ----------------------------------------------------
+//
+TUid CWmWidgetLoaderAo::UidFromString( const TDesC8& aUidString ) const
+    {
+    TUid uid( KNullUid );
+    const TInt KHexPrefixLength = 2;
+    if ( aUidString.Length() > KHexPrefixLength )
+        {
+        TUint id = 0;
+        TLex8 lex( aUidString.Mid( KHexPrefixLength ) );
+        if ( lex.Val( id, EHex ) == KErrNone )
+            {
+            uid.iUid = (TInt32)id;
+            }
+        }
+    return uid;
+    }
+
+// ----------------------------------------------------
+// CWmWidgetData::IsLoading
+// ----------------------------------------------------
+//
+TBool CWmWidgetLoaderAo::IsLoading()
+    {
+    return iLoading;
+    }
+
+// ----------------------------------------------------
+// CWmWidgetData::SetObserver
+// ----------------------------------------------------
+//
+void CWmWidgetLoaderAo::SetObserver( MWmWidgetloaderObserver* aObserver )
+    {
+    iObserver = aObserver;
+    }
+
+// end of file
+