--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gssettingsuis/Gs/GSFramework/src/GSParentPlugin.cpp Wed Sep 01 12:20:44 2010 +0100
@@ -0,0 +1,719 @@
+/*
+* Copyright (c) 2005-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: Base class for plugins containing other plugins. Asynchronous
+* loading of plugins is used.
+*
+*/
+
+
+// INCLUDE FILES
+#include <gsparentplugin.h>
+#include <gsparentcontainer.h>
+#include <gsplugininterface.h>
+#include "GsLogger.h"
+#include <gscommon.hrh>
+#include <gsparentpluginrsc.rsg>
+#include <gsfwviewuids.h>
+#include <avkon.rsg>
+
+#include <aknlists.h>
+#include <ConeResLoader.h>
+#include <featmgr.h>
+#include <akntitle.h>
+#include <aknViewAppUi.h>
+#include <bautils.h>
+#include <eikmenup.h>
+#include <eikbtgpc.h>
+#include <hlplch.h>
+#include <StringLoader.h>
+#include <layoutmetadata.cdl.h>
+// Middle Softkey control ID.
+const TInt KGSMSKControlID = 3;
+const TInt KGSMSKLength = 256;
+const TInt KGSPluginArrayInitSize = 10;
+
+// ========================= MEMBER FUNCTIONS ================================
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::CGSParentPlugin()
+//
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CGSParentPlugin::CGSParentPlugin()
+ : iResourceLoader( *iCoeEnv )
+ {
+ }
+
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::BaseConstructL()
+//
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CGSParentPlugin::BaseConstructL(
+ TInt aViewRscId,
+ TInt aTitleRscId )
+ {
+ iTitleRscId = aTitleRscId;
+ iSelectedPluginUid = KGSNoneSelected;
+ iTopPluginUid = KGSNoneSelected;
+
+ __GSLOGSTRING( "[CGSParentPlugin] ConstructL()" );
+ iAppUi = AppUi();
+ iPosition.Reset();
+ OpenLocalizedResourceFileL( KGSParentPluginResourceFileName,
+ iResourceLoader );
+ CAknView::BaseConstructL( aViewRscId );
+
+ if( !iOptionFlags[ EGSLoadChildrenOnActivation ] )
+ {
+ StartAsyncPluginLoadL();
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::StartAsyncPluginLoadL()
+//
+//
+// ---------------------------------------------------------------------------
+//
+void CGSParentPlugin::StartAsyncPluginLoadL()
+ {
+ //Initialize array and start loading plugins into it.
+ iPluginArray = new (ELeave) CArrayPtrFlat<CGSPluginInterface>( KGSPluginArrayInitSize );
+ iPluginLoader = CGSPluginLoader::NewL( iAppUi );
+ iPluginLoader->SetObserver( this );
+ iPluginLoader->LoadAsyncL( KGSPluginInterfaceUid, Id(), iPluginArray );
+ }
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::UpperLevelViewUid()
+//
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TUid CGSParentPlugin::UpperLevelViewUid()
+ {
+ __GSLOGSTRING( "[CGSParentPlugin] UpperLevelViewUid()" );
+ return iPrevViewId.iViewUid;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::~CGSParentPlugin()
+//
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CGSParentPlugin::~CGSParentPlugin()
+ {
+ __GSLOGSTRING( "[CGSParentPlugin] ~CGSParentPlugin" );
+ if ( iPluginLoader )
+ {
+ iPluginLoader->AbortAsyncLoad();
+ }
+ delete iPluginLoader;
+
+ if ( iPluginArray )
+ {
+ iPluginArray->Reset();//Do not destroy - Plugins are owned by iAppUi
+ }
+ delete iPluginArray;
+ iResourceLoader.Close();
+
+ if( iContainer )
+ {
+ iAppUi->RemoveFromViewStack( *this, iContainer );
+ delete iContainer;
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::OpenLocalizedResourceFileL()
+//
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CGSParentPlugin::OpenLocalizedResourceFileL(
+ const TDesC& aResourceFileName,
+ RConeResourceLoader& aResourceLoader )
+ {
+ RFs &fsSession = CCoeEnv::Static()->FsSession();
+
+ // Find the resource file:
+ TParse parse;
+ parse.Set( aResourceFileName, &KDC_RESOURCE_FILES_DIR, NULL );
+ TFileName fileName( parse.FullName() );
+
+ // Get language of resource file:
+ BaflUtils::NearestLanguageFile( fsSession, fileName );
+
+ // Open resource file:
+ aResourceLoader.OpenL( fileName );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::DoActivateL()
+//
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CGSParentPlugin::DoActivateL( const TVwsViewId& aPrevViewId,
+ TUid /*aCustomMessageId*/,
+ const TDesC8& /*aCustomMessage*/ )
+ {
+ __GSLOGSTRING( "[CGSParentPlugin::DoActivateL]" );
+ iPrevViewId = aPrevViewId;
+
+ // If iPluginArray does not exist. Lazy loading is enabled and should start
+ // loading now.
+ if( !iPluginArray )
+ {
+ StartAsyncPluginLoadL();
+ }
+
+ // Set priority only after plugin loader is created in
+ // StartAsyncPluginLoadL.
+ iPluginLoader->RequestPriority( CActive::EPriorityHigh );
+
+ //if( iContainer )
+ // {
+ // iAppUi->RemoveFromViewStack( *this, iContainer );
+ // delete iContainer;
+ // iContainer=NULL;
+ // }
+
+ if ( !iContainer )
+ {
+ ConstructContainerL();
+
+ // Set the empty text of list box.
+ _LIT( KEmptyText, "" );
+ TBuf<1> empty( KEmptyText );
+ iContainer->SetListBoxEmptyTextL( empty );
+
+ // Update listbox from already existing iPluginArray:
+ iContainer->UpdateListBoxL();
+ if ( iPosition.iCurrentItemIndex != -1 )
+ {
+ if ( iIsLandscapeOrientation == Layout_Meta_Data::IsLandscapeOrientation() )
+ {
+ iContainer->RestoreListBoxPositionL( iPosition, EFalse );
+ }
+ else
+ {
+ iContainer->RestoreListBoxPositionL( iPosition, ETrue );
+ }
+ }
+ iAppUi->AddToViewStackL(*this, iContainer);
+ // Navigating to parent view will reset all child plugin selected indexes:
+ for( TInt i = 0; i < iPluginArray->Count(); i++ )
+ {
+ CGSPluginInterface* plugin = iPluginArray->operator[]( i );
+ plugin->ResetSelectedItemIndex();
+ }
+
+ iMskCommandId = EAknSoftkeyOpen;
+
+ SetMiddleSoftKeyLabelL( R_QTN_MSK_OPEN, EAknSoftkeyOpen );
+ CheckMiddleSoftkeyLabelL();
+
+ // If this view was launched from external source, use "exit" as RSK
+ if (iPrevViewId.iAppUid != KUidGS)
+ {
+ CEikButtonGroupContainer* cbaGroup = Cba();
+ if (cbaGroup)
+ {
+ HBufC* rightSKText = StringLoader::LoadLC(
+ R_GS_PARENTPLUGIN_CBA_EXIT);
+ TPtr rskPtr = rightSKText->Des();
+ cbaGroup->SetCommandL(2, EAknSoftkeyExit, *rightSKText);
+ CleanupStack::PopAndDestroy(rightSKText);
+ }
+ }
+
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::DoDeactivate()
+//
+//
+// ---------------------------------------------------------------------------
+EXPORT_C void CGSParentPlugin::DoDeactivate()
+ {
+ __GSLOGSTRING( "[CGSParentPlugin::DoDeactivate]" );
+
+ iPluginLoader->RequestPriority( CActive::EPriorityLow );
+
+ if ( iContainer )
+ {
+ iPosition.Reset();
+ TRAPD( err, iContainer->StoreListBoxPositionL( iPosition ) );
+ iIsLandscapeOrientation = Layout_Meta_Data::IsLandscapeOrientation();
+
+ iAppUi->RemoveFromViewStack(*this, iContainer);
+ delete iContainer;
+ iContainer = NULL;
+ }
+ __GSLOGSTRING( "[CGSParentPlugin::DoDeactivate] Done" );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::ConstructContainerL()
+//
+//
+// ---------------------------------------------------------------------------
+//
+void CGSParentPlugin::ConstructContainerL()
+ {
+ iContainer = new( ELeave ) CGSParentContainer;
+ iContainer->SetMopParent( this );
+
+ TRAPD
+ (
+ error,
+ iContainer->ConstructL(
+ ClientRect() ,
+ AppUi(),
+ iPluginArray,
+ iTitleRscId,
+ this,
+ ListBoxType() )
+ );
+
+ if ( error )
+ {
+ delete iContainer;
+ iContainer = NULL;
+ User::Leave( error );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::HandleCommandL()
+//
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CGSParentPlugin::HandleCommandL( TInt aCommand )
+ {
+ __GSLOGSTRING1( "[CGSParentPlugin] HandleCommandL(%d)", aCommand );
+
+ switch ( aCommand )
+ {
+ case EAknSoftkeyBack:
+ __GSLOGSTRING1( "[CGSParentPlugin] Returning to view 0x%X",
+ UpperLevelViewUid().iUid );
+ iAppUi->ActivateLocalViewL( UpperLevelViewUid() );
+ break;
+ // These all should be handled similarily:
+ case EAknSoftkeyOpen:
+ case EGSCmdAppChange:
+ case EGSCmdAppOpen:
+ if( iContainer && iPluginArray->Count() > 0 )
+ {
+ CGSPluginInterface* selectedPlugin =
+ iContainer->SelectedPlugin();
+
+ if ( NULL != selectedPlugin )
+ {
+ switch( selectedPlugin->ItemType() )
+ {
+ // In these cases the plugin is a view:
+ case EGSItemTypeSingleLarge:
+ case EGSItemTypeSetting:
+ case EGSItemTypeSettingIcon:
+ iAppUi->ActivateLocalViewL( selectedPlugin->Id() );
+ break;
+ // In these cases the plugin is a dialog:
+ case EGSItemTypeSettingDialog:
+ case EGSItemTypeSingleLargeDialog:
+ selectedPlugin->HandleSelection(
+ EGSSelectionByMenu );
+ break;
+ }
+ }
+
+ }
+ break;
+ case EGSMSKCmdAppChange:
+ iContainer->HandleSelectionKeyL();
+ break;
+ case EAknCmdHelp:
+ {
+ if( FeatureManager::FeatureSupported( KFeatureIdHelp ) )
+ {
+ HlpLauncher::LaunchHelpApplicationL(
+ iEikonEnv->WsSession(), iAppUi->AppHelpContextL() );
+ }
+ break;
+ }
+ default:
+ iAppUi->HandleCommandL( aCommand );
+ break;
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::HandlePluginLoaded()
+//
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CGSParentPlugin::HandlePluginLoaded( KGSPluginLoaderStatus aStatus )
+ {
+ __GSLOGSTRING1( "[CGSParentPlugin::HandlePluginLoaded] aStatus:%d", aStatus );
+
+ switch( aStatus )
+ {
+ case MGSPluginLoadObserver::EGSSuccess:
+ // Should not update each time when plugin is loaded, only when
+ // finished loading spesific view plugins?
+ break;
+ case MGSPluginLoadObserver::EGSFinished:
+ if( iContainer )
+ {
+ TRAPD( ignore, iContainer->UpdateListBoxL(); );
+ if( ignore != KErrNone )
+ {
+ __GSLOGSTRING1(
+ "[CGSParentPlugin] HandlePluginLoaded error:%d",
+ ignore );
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::TransferDynamicPluginL()
+//
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CGSParentPlugin::TransferDynamicPluginL( CGSPluginInterface* aPlugin )
+ {
+ __GSLOGSTRING1( "[CGSParentPlugin] CGSParentPlugin::TransferDynamicPluginL() - plugin id: 0x%x added to appUi.", aPlugin->Id() );
+
+ CleanupStack::PushL( aPlugin );
+ iAppUi->AddViewL( aPlugin );
+ CleanupStack::Pop( aPlugin );
+
+ // Add to the overall plugin array for this parent plugin
+ iPluginArray->AppendL( aPlugin );
+
+ // Resort the plugins so that they are in order
+ iPluginLoader->SortPluginsL( iPluginArray );
+
+ // Update the listbox with the new information
+ HandlePluginLoaded( MGSPluginLoadObserver::EGSSuccess );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::ListBoxType()
+// Default implementation. Overwrite if different type of listbox is needed.
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C TGSListboxTypes CGSParentPlugin::ListBoxType()
+ {
+ return EGSListBoxTypeSingleLarge;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CGSParentPlugin::UpdateView()
+//
+//
+// ---------------------------------------------------------------------------
+//
+EXPORT_C void CGSParentPlugin::UpdateView()
+ {
+ __GSLOGSTRING( "[CGSParentPlugin::UpdateView]" );
+ TRAP_IGNORE
+ (
+ if( iContainer )
+ {
+ iContainer->UpdateListBoxL();
+ }
+ );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CGSParentPlugin::ResetSelectedItemIndex()
+//
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGSParentPlugin::ResetSelectedItemIndex()
+ {
+ iSelectedPluginUid = KGSNoneSelected;
+ if( iContainer )
+ {
+ iContainer->ListBox()->SetCurrentItemIndex( 0 );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CGSParentPlugin::SetOptionFlags()
+//
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGSParentPlugin::SetOptionFlags( TBitFlags& aOptionFlags )
+ {
+ iOptionFlags = aOptionFlags;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CGSParentPlugin::OptionFlags()
+//
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C const TBitFlags& CGSParentPlugin::OptionFlags() const
+ {
+ return iOptionFlags;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CGSParentPlugin::DynInitMenuPaneL()
+//
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGSParentPlugin::DynInitMenuPaneL( TInt /*aResourceId*/,
+ CEikMenuPane* aMenuPane )
+ {
+ // Check what is the plugin's desired menu item type for activating the
+ // plugin. If it doesn't match to the item defined by parent plugin menu
+ // resource, change the item dynamically.
+ if ( iContainer->SelectedPlugin() )
+ {
+ CGSPluginInterface* selectedPlugin = iContainer->SelectedPlugin();
+ TGSMenuActivationItems desiredItemType = selectedPlugin->MenuActivationItem();
+
+ // Append new item after this position, delete item in this position.
+ TInt removableItemPos;
+
+ // MSK command should be identical to the desired activation command in
+ // options menu. Posibilities are such as 'open' (also as default),
+ // 'change' or custom text.
+ // Note: Activation item in options menu is depending on the highlighted
+ // child plugin's MenuActivationItem() function.
+ switch( desiredItemType )
+ {
+ case EGSMenuActivationItemDefault:
+ case EGSMenuActivationItemOpen:
+ if( aMenuPane->MenuItemExists( EGSCmdAppChange, removableItemPos ) )
+ {
+ aMenuPane->AddMenuItemsL( R_GS_MENU_ITEM_OPEN, removableItemPos );
+ aMenuPane->DeleteBetweenMenuItems( removableItemPos, removableItemPos );
+ }
+ break;
+
+ case EGSMenuActivationItemChange:
+ if( aMenuPane->MenuItemExists( EAknSoftkeyOpen, removableItemPos ) )
+ {
+ aMenuPane->AddMenuItemsL( R_GS_MENU_ITEM_CHANGE, removableItemPos );
+ aMenuPane->DeleteBetweenMenuItems( removableItemPos, removableItemPos );
+ }
+ break;
+
+ case EGSMenuActivationItemCustom:
+ {
+ // Using EGSCmdAppChange as EGSMenuActivationItemCustom
+ // functionality is same as for EGSMenuActivationItemChange.
+ // Here we're replacing EGSCmdAppChange always because we
+ // cannot be sure whether it's the actual custom command
+ // already or just EAknSoftkeyOpen. Custom commands will be set
+ // to use the same command ID (EGSCmdAppChange).
+ //
+ CEikMenuPaneItem::SData menuItem;
+ selectedPlugin->GetValue( EGSCustomMenuActivationText, menuItem.iText );
+ menuItem.iCommandId = EGSCmdAppChange;
+ menuItem.iCascadeId = 0;
+ menuItem.iFlags = 0;
+
+ if( aMenuPane->MenuItemExists( EGSCmdAppChange, removableItemPos ) )
+ {
+ // Add custom item before 'change' and then remove 'change'
+ if( menuItem.iText.Length() > 0)
+ {
+ aMenuPane->AddMenuItemL( menuItem, EGSCmdAppChange );
+ }
+ aMenuPane->DeleteBetweenMenuItems( removableItemPos, removableItemPos );
+ }
+ else if( aMenuPane->MenuItemExists( EAknSoftkeyOpen, removableItemPos ) )
+ {
+ // Add custom item before 'open' and then remove 'open'
+ if( menuItem.iText.Length() > 0 )
+ {
+ aMenuPane->AddMenuItemL( menuItem, EAknSoftkeyOpen );
+ }
+ aMenuPane->DeleteBetweenMenuItems( removableItemPos, removableItemPos );
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CGSParentPlugin::GetHelpContext()
+//
+//
+// -----------------------------------------------------------------------------
+//
+EXPORT_C void CGSParentPlugin::GetHelpContext( TCoeHelpContext& /*aContext*/ )
+ {
+ // Default implementation does nothing.
+ }
+
+// -----------------------------------------------------------------------------
+// When this method is called, view checks based on highlight focus, if the MSK
+// label is correct.
+// -----------------------------------------------------------------------------
+//
+void CGSParentPlugin::CheckMiddleSoftkeyLabelL()
+ {
+ if ( iContainer->SelectedPlugin() )
+ {
+ // Remove current MSK
+ RemoveCommandFromMSK( iMskCommandId );
+
+ CGSPluginInterface* selectedPlugin = iContainer->SelectedPlugin();
+ TGSMenuActivationItems desiredItemType =
+ selectedPlugin->MenuActivationItem();
+
+ switch( desiredItemType )
+ {
+ case EGSMenuActivationItemChange:
+ SetMiddleSoftKeyLabelL( R_QTN_MSK_CHANGE, EGSMSKCmdAppChange );
+ iMskCommandId = EGSMSKCmdAppChange;
+ break;
+ case EGSMenuActivationItemOpen:
+ case EGSMenuActivationItemDefault:
+ SetMiddleSoftKeyLabelL( R_QTN_MSK_OPEN, EAknSoftkeyOpen );
+ iMskCommandId = EAknSoftkeyOpen;
+ break;
+ case EGSMenuActivationItemCustom:
+ {
+ HBufC* mskText = HBufC::NewLC( KGSMSKLength );
+ TPtr mskPtr = mskText->Des();
+ selectedPlugin->GetValue( EGSCustomMenuActivationText, mskPtr );
+ SetMiddleSoftKeyLabelTextL( mskPtr, EGSMSKCmdAppChange );
+ CleanupStack::PopAndDestroy( mskText );
+ break;
+ }
+ default:
+ // Use 'open' as default
+ SetMiddleSoftKeyLabelL( R_QTN_MSK_OPEN, EAknSoftkeyOpen );
+ iMskCommandId = EAknSoftkeyOpen;
+ break;
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// Remove unnecessary commands from Middle softkey.
+// -----------------------------------------------------------------------------
+//
+void CGSParentPlugin::RemoveCommandFromMSK( TInt aMskCommandId )
+ {
+ CEikButtonGroupContainer* cbaGroup = Cba();
+ if ( cbaGroup )
+ {
+ cbaGroup->RemoveCommandFromStack( KGSMSKControlID, aMskCommandId );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Sets middle softkey label.
+// ---------------------------------------------------------------------------
+//
+void CGSParentPlugin::SetMiddleSoftKeyLabelL(
+ const TInt aResourceId, const TInt aCommandId )
+ {
+ CEikButtonGroupContainer* cbaGroup = Cba();
+ if ( cbaGroup )
+ {
+ HBufC* middleSKText = StringLoader::LoadLC( aResourceId );
+ TPtr mskPtr = middleSKText->Des();
+ cbaGroup->AddCommandToStackL(
+ KGSMSKControlID,
+ aCommandId,
+ mskPtr );
+ CleanupStack::PopAndDestroy( middleSKText );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Sets middle softkey label.
+// ---------------------------------------------------------------------------
+//
+void CGSParentPlugin::SetMiddleSoftKeyLabelTextL(
+ const TPtr aMskLabel, const TInt aCommandId )
+ {
+ CEikButtonGroupContainer* cbaGroup = Cba();
+ if ( cbaGroup )
+ {
+ cbaGroup->AddCommandToStackL(
+ KGSMSKControlID,
+ aCommandId,
+ aMskLabel );
+ }
+ }
+
+// ---------------------------------------------------------------------------
+// Returns selected plugin.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CGSPluginInterface* CGSParentPlugin::SelectedPlugin()
+ {
+ CGSPluginInterface* selectedPlugin = NULL;
+ if( iContainer )
+ {
+ selectedPlugin = iContainer->SelectedPlugin();
+ }
+ return selectedPlugin;
+ }
+
+
+void CGSParentPlugin::RequestPriority( CActive::TPriority aPriority )
+ {
+ iPluginLoader->RequestPriority( aPriority );
+ __GSLOGSTRING2( "[CGSParentPlugin::RequestPriority] 0x%X aPriority:%d", Id().iUid, aPriority );
+ }
+
+// End of File