diff -r 5f0182e07bfb -r 5456b4e8b3a8 idlehomescreen/xmluirendering/renderingplugins/xnmenufactory/src/xnmenuadapter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/idlehomescreen/xmluirendering/renderingplugins/xnmenufactory/src/xnmenuadapter.cpp Wed Sep 01 12:32:46 2010 +0100 @@ -0,0 +1,2848 @@ +/* +* 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: Implementation for wrapper for a menu +* +*/ + +// System includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +// User includes +#include "xnnodepluginif.h" +#include "xntype.h" +#include "xnproperty.h" + +#include "xndompropertyvalue.h" +#include "xndomproperty.h" +#include "xndomlist.h" + +#include "xnuienginepluginif.h" +#include "xncomponent.h" + +#include "xnappuiadapter.h" +#include "xnbitmap.h" +#include "xnmenuadapter.h" +#include "xncomponentnodeimpl.h" +#include "c_xnutils.h" + +#undef _AVKON_CBA_LSC + +_LIT8( KEditMode, "Menu/EditMode" ); +_LIT8( KNormalMode, "Menu/NormalMode" ); +_LIT8( KContextEditMode, "ContextMenu/EditMode" ); +_LIT8( KContextNormalMode, "ContextMenu/NormalMode" ); +_LIT8( KAlwaysShown, "Menu/AlwaysShown" ); + +_LIT8( KHsShowHelp, "hs_show_help" ); + +const TInt KMenuCommandFirst = 6000; +const TInt KMenuCommandLast = 6199; +const TInt KCBACommandFirst = EAknSoftkeyOptions; +const TInt KCBACommandSecond = EAknSoftkeyBack; +const TInt KCBACommandMiddle = EAknSoftkeyDialler; + +const TInt KXnMenuArrayGranularity = 6; +const TInt KWideScreenWidth = 640; + +using namespace XnPropertyNames; + +static CXnNodePluginIf* FindChildL(CXnNodePluginIf& aNode, + const TDesC8& aType, const TDesC8& aTarget = KNullDesC8); + +class CXnSoftkeyItem: public CBase + { +public: + CXnSoftkeyItem() + : iNode( NULL ), + iPosition( 0 ), + iCommandId( 0 ), + iLabel( NULL ), + iBitmap( NULL ), + iMask( NULL ), + iImageOn( EFalse ), + iInvertMask( EFalse ), + iPreserveAspectRatio( EFalse ), + iUpdateAppearance( ETrue ), + iOwnBitmaps( ETrue ), + iDefault( EFalse ), + iId( KAknsIIDQsnIconColors ), + iBmpFile( NULL ), + iBmp( 0 ), + iBmpM( 0 ) + { + } + + ~CXnSoftkeyItem() + { + Reset(); + } + + void Reset() + { + delete iLabel; + iLabel = NULL; + if ( iOwnBitmaps ) + { + delete iBitmap; + iBitmap = NULL; + delete iMask; + iMask = NULL; + } + else + { + iBitmap = NULL; + iMask = NULL; + } + + iImageOn = EFalse; + iInvertMask = EFalse; + iPreserveAspectRatio = EFalse; + delete iBmpFile; + iBmpFile = NULL; + } + + CXnNodePluginIf* iNode; + TInt iPosition; + TInt iCommandId; + HBufC* iLabel; + CFbsBitmap* iBitmap; + CFbsBitmap* iMask; + TBool iImageOn; + TBool iInvertMask; + TBool iPreserveAspectRatio; + TBool iUpdateAppearance; + TBool iOwnBitmaps; + TBool iDefault; + TAknsItemID iId; + HBufC* iBmpFile; + TInt32 iBmp; + TInt32 iBmpM; + }; + + +inline TAknWindowComponentLayout DoCompose( TAknWindowComponentLayout aLine1, + TAknWindowComponentLayout aLine2 ) + { + return TAknWindowComponentLayout::Compose( aLine1, aLine2 ); + } + +inline TAknTextComponentLayout DoComposeText( TAknWindowComponentLayout aLine1, + TAknTextComponentLayout aLine2 ) + { + return TAknWindowComponentLayout::ComposeText( aLine1, aLine2 ); + } + +// ----------------------------------------------------------------------------- +// IsNodeVisibleL +// +// ----------------------------------------------------------------------------- +// +static TBool IsNodeVisibleL(CXnNodePluginIf& aNode) + { + CXnProperty* propVisibility = aNode.VisibilityL(); + + if( propVisibility ) + { + const TDesC8& visibility = propVisibility->StringValue(); + + if( visibility == XnPropertyNames::style::common::visibility::KHidden ) + { + return EFalse; + } + } + + CXnProperty* propDisplay = aNode.DisplayL(); + + if( propDisplay ) + { + const TDesC8& display = propDisplay->StringValue(); + + if( display == XnPropertyNames::style::common::display::KNone ) + { + return EFalse; + } + } + + CXnProperty* propDisabled = aNode.GetPropertyL( XnPropertyNames::common::KDisabled ); + + if( propDisabled ) + { + const TDesC8& disabled = propDisabled->StringValue(); + + if( disabled == XnPropertyNames::KTrue ) + { + return EFalse; + } + } + + return ETrue; + } + +#ifdef _AVKON_CBA_LSC +// ----------------------------------------------------------------------------- +// +// Calculate touch sensitive softkey area for Top button (landscape) +// ----------------------------------------------------------------------------- +static TRect SoftkeyRectTopTouch() + { + TRect screen; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen ); + + TAknLayoutRect layoutRect; + + TAknWindowComponentLayout rightAreaLayout( + AknLayoutScalable_Avkon::area_side_right_pane( 0 ) ); + + + layoutRect.LayoutRect( screen, DoCompose( rightAreaLayout, + AknLayoutScalable_Avkon::sctrl_sk_top_pane() ).LayoutLine() ); + TRect topSKRect( layoutRect.Rect() ); + + layoutRect.LayoutRect( topSKRect, + AknLayoutScalable_Avkon::aid_touch_sctrl_top().LayoutLine() ); + return layoutRect.Rect(); + } + +// ----------------------------------------------------------------------------- +// +// Calculate touch sensitive softkey area for right button (portrait) +// ----------------------------------------------------------------------------- +static TRect SoftkeyRectRightTouch() + { + TRect screen; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen ); + + TAknLayoutRect layoutRect; + + TAknWindowComponentLayout bottomAreaLayout( + AknLayoutScalable_Avkon::area_bottom_pane( 0 ) ); + + + layoutRect.LayoutRect( screen, DoCompose( bottomAreaLayout, + AknLayoutScalable_Avkon::control_bg_pane() ).LayoutLine() ); + TRect rightSKRect( layoutRect.Rect() ); + layoutRect.LayoutRect( + rightSKRect, + AknLayoutScalable_Avkon::aid_touch_ctrl_right().LayoutLine() ); + return layoutRect.Rect(); + } + +// ----------------------------------------------------------------------------- +// +// Calculate touch sensitive softkey area for left button (portrait) +// ----------------------------------------------------------------------------- +static TRect SoftkeyRectLeftTouch() + { + TRect screen; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen ); + + TAknLayoutRect layoutRect; + + TAknWindowComponentLayout bottomAreaLayout( + AknLayoutScalable_Avkon::area_bottom_pane( 0 ) ); + + + layoutRect.LayoutRect( screen, DoCompose( bottomAreaLayout, + AknLayoutScalable_Avkon::control_bg_pane() ).LayoutLine() ); + TRect leftSKRect( layoutRect.Rect() ); + layoutRect.LayoutRect( + leftSKRect, + AknLayoutScalable_Avkon::aid_touch_ctrl_left().LayoutLine() ); + + return layoutRect.Rect(); + + } + +// ----------------------------------------------------------------------------- +// +// Calculate touch sensitive softkey area for Bottom button (landscape) +// ----------------------------------------------------------------------------- +static TRect SoftkeyRectBottomTouch() + { + TRect screen; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen ); + + TAknLayoutRect layoutRect; + + TAknWindowComponentLayout rightAreaLayout( AknLayoutScalable_Avkon::area_side_right_pane( 0 ) ); + + layoutRect.LayoutRect( screen, DoCompose( rightAreaLayout, + AknLayoutScalable_Avkon::sctrl_sk_bottom_pane() ).LayoutLine() ); + TRect bottomSKRect( layoutRect.Rect() ); + + layoutRect.LayoutRect( bottomSKRect, + AknLayoutScalable_Avkon::aid_touch_sctrl_bottom().LayoutLine() ); + return layoutRect.Rect(); + } +#endif +// ----------------------------------------------------------------------------- +// +// Calculate (whole) softkey area for Bottom button (landscape) +// ----------------------------------------------------------------------------- +static TBool HDLayoutActive() + { + TInt resourceId = 0; + CEikStatusPaneBase* statusPane = CEikStatusPaneBase::Current(); + + if ( statusPane ) // Return the resource ID of app statuspane if it exists. + { + resourceId = statusPane->CurrentLayoutResId(); + } + else // If this app does not have statuspane, then we ask the layout from AknCapServer. + { + resourceId = CAknSgcClient::CurrentStatuspaneResource(); + } + + TBool retVal = EFalse; + + if ( Layout_Meta_Data::IsLandscapeOrientation() ) + { + // Can be widescreen only in landscape orientation. + retVal = ( resourceId == R_AVKON_WIDESCREEN_PANE_LAYOUT_USUAL || + resourceId == R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE || + resourceId == R_AVKON_WIDESCREEN_PANE_LAYOUT_USUAL_FLAT || + resourceId == R_AVKON_WIDESCREEN_PANE_LAYOUT_IDLE_FLAT ); + } + + return retVal; + } + +// ----------------------------------------------------------------------------- +// +// Calculate softkey image graphics area for Bottom button (landscape) +// ----------------------------------------------------------------------------- +static TRect SoftkeyRectBottomGraphics() + { + TRect screen; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen ); + + TAknWindowComponentLayout rightAreaLayout( + AknLayoutScalable_Avkon::area_side_right_pane( 0 ) ); + + TAknWindowComponentLayout bottomSKLayout( + DoCompose( rightAreaLayout, + AknLayoutScalable_Avkon::sctrl_sk_bottom_pane() ) ); + + // Calculate softkey rects. + // Left (bottom in landscape) softkey layout. + TAknLayoutRect leftSoftkeyLayoutRect; + leftSoftkeyLayoutRect.LayoutRect( screen, + bottomSKLayout.LayoutLine() ); + TRect leftSoftKeyButtonRect( leftSoftkeyLayoutRect.Rect() ); + + // Calculate softkey image layout. + // Left (bottom in landscape) softkey layout. + TAknWindowLineLayout leftSoftkeyImageLayout( + DoCompose( + bottomSKLayout, + AknLayoutScalable_Avkon::sctrl_sk_bottom_pane_g1() ).LayoutLine() ); + + + TAknLayoutRect qgn_graf_sk_left; + qgn_graf_sk_left.LayoutRect( screen, leftSoftkeyImageLayout ); + + return qgn_graf_sk_left.Rect(); + } + +// ----------------------------------------------------------------------------- +// +// Calculate softkey image graphics area for Top button (landscape) +// ----------------------------------------------------------------------------- +static TRect SoftkeyRectTopGraphics() + { + TRect screen; + AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, screen ); + + TAknWindowComponentLayout rightAreaLayout( + AknLayoutScalable_Avkon::area_side_right_pane( 0 ) ); + + TAknWindowComponentLayout topSKLayout( + DoCompose( rightAreaLayout, + AknLayoutScalable_Avkon::sctrl_sk_top_pane() ) ); + + // Calculate softkey rects. + // Right (top in landscape) softkey layout. + TAknLayoutRect rightSoftkeyLayoutRect; + rightSoftkeyLayoutRect.LayoutRect( screen, + topSKLayout.LayoutLine() ); + TRect rightSoftKeyButtonRect( rightSoftkeyLayoutRect.Rect() ); + + // Left (bottom in landscape) softkey layout. + // Right (top in landscape) softkey layout. + TAknWindowLineLayout rightSoftkeyImageLayout( + DoCompose( + topSKLayout, + AknLayoutScalable_Avkon::sctrl_sk_top_pane_g1() ).LayoutLine() ); + + TAknLayoutRect qgn_graf_sk_right; + qgn_graf_sk_right.LayoutRect( screen, rightSoftkeyImageLayout ); + return qgn_graf_sk_right.Rect(); + } + + +// ----------------------------------------------------------------------------- +// SoftkeyRectL +// Calculate soft key rect +// ----------------------------------------------------------------------------- +static TRect SoftkeyRectL( CEikButtonGroupContainer& aContainer, TInt aPos, TBool aImageOn ) + { + TRect rect; + + if( AknStatuspaneUtils::StaconPaneActive() ) + { + TInt variety( 0 ); + + if( AknStatuspaneUtils::StaconSoftKeysLeft() ) + { + variety = 1; + } + + TRect parentRect( iAvkonAppUi->ApplicationRect() ); + + switch( aPos ) + { + case CEikButtonGroupContainer::ELeftSoftkeyPosition: + { + TAknWindowComponentLayout layout0( AknLayoutScalable_Avkon::area_bottom_pane( 2 ) ); + TAknWindowComponentLayout layout1( AknLayoutScalable_Avkon::stacon_bottom_pane() ); + + // If clock is shown in stacon, cba area is smaller. + TInt bottomCbaVariety( variety ); + + if( AknStatuspaneUtils::ExtendedStaconPaneActive() ) + { + bottomCbaVariety += 2; + } + + TAknWindowComponentLayout layout2( AknLayoutScalable_Avkon::control_bottom_pane_stacon( bottomCbaVariety ) ); + + if( aImageOn ) + { + // Icon layout + TAknWindowComponentLayout iconLayout( AknLayoutScalable_Avkon::control_bottom_pane_stacon_g1() ); + + TAknWindowComponentLayout lskIconLayout( DoCompose( layout0, + DoCompose( layout1, DoCompose( layout2, iconLayout ) ) ) ); + + TAknWindowLineLayout lskIcon( lskIconLayout.LayoutLine() ); + + TAknLayoutRect qgn_icon_lsk; + + qgn_icon_lsk.LayoutRect( parentRect, lskIcon ); + + rect = qgn_icon_lsk.Rect(); + } + else + { + // Text layout + TAknTextComponentLayout textLayout( AknLayoutScalable_Avkon::control_bottom_pane_stacon_t1( variety ) ); + + TAknTextComponentLayout lskTextLayout( DoComposeText( layout0, + DoComposeText( layout1, DoComposeText( layout2, textLayout ) ) ) ); + + TAknTextLineLayout lskText( lskTextLayout.LayoutLine() ); + + TAknLayoutText qgn_text_lsk; + + qgn_text_lsk.LayoutText( parentRect, lskText ); + + rect = qgn_text_lsk.TextRect(); + } + } + break; + case CEikButtonGroupContainer::ERightSoftkeyPosition: + { + TAknWindowComponentLayout layout0( AknLayoutScalable_Avkon::area_top_pane( 2 ) ); + TAknWindowComponentLayout layout1( AknLayoutScalable_Avkon::stacon_top_pane() ); + + TInt topCbaVariety( variety ); + + if( AknStatuspaneUtils::ExtendedStaconPaneActive() ) + { + topCbaVariety += 4; + } + + TAknWindowComponentLayout layout2( AknLayoutScalable_Avkon::control_top_pane_stacon( topCbaVariety ) ); + + if( aImageOn ) + { + // Icon layout + TAknWindowComponentLayout iconLayout( AknLayoutScalable_Avkon::control_top_pane_stacon_g1() ); + + TAknWindowComponentLayout rskIconLayout( DoCompose( layout0, + DoCompose( layout1, DoCompose( layout2, iconLayout ) ) ) ); + + TAknWindowLineLayout rskIcon( rskIconLayout.LayoutLine() ); + + TAknLayoutRect qgn_icon_rsk; + + qgn_icon_rsk.LayoutRect( parentRect, rskIcon ); + + rect = qgn_icon_rsk.Rect(); + } + else + { + // Text layout + TAknTextComponentLayout textLayout( AknLayoutScalable_Avkon::control_top_pane_stacon_t1( variety ) ); + + TAknTextComponentLayout rskTextLayout( DoComposeText( layout0, + DoComposeText( layout1, DoComposeText( layout2, textLayout ) ) ) ); + + TAknTextLineLayout rskText( rskTextLayout.LayoutLine() ); + + TAknLayoutText qgn_text_rsk; + + qgn_text_rsk.LayoutText( parentRect, rskText ); + + rect = qgn_text_rsk.TextRect(); + } + } + break; + default: + User::Leave( KErrNotSupported ); + break; + + } + } + else + { + TInt textVariety( 0 ); + TInt graphVariety( 0 ); + + TBool mskEnabled( AknLayoutUtils::MSKEnabled() && Layout_Meta_Data::IsMSKEnabled() ); + + if ( mskEnabled ) + { + textVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 3; + graphVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 4; + } + else + { + textVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 0; + graphVariety = Layout_Meta_Data::IsLandscapeOrientation() ? 2 : 4; + } + + CEikCba* cba( static_cast< CEikCba* >( aContainer.ButtonGroup() ) ); + + TRect parentRect( cba->Rect() ); + + switch( aPos ) + { + case CEikButtonGroupContainer::ELeftSoftkeyPosition: + { + if( aImageOn ) + { + if ( HDLayoutActive() && + AKN_LAYOUT_WINDOW_screen.iW == KWideScreenWidth ) + { + rect = SoftkeyRectBottomGraphics(); + } + else + { + + TAknLayoutRect qgn_icon_lsk; + + qgn_icon_lsk.LayoutRect( parentRect, + AknLayoutScalable_Avkon::control_pane_g1( graphVariety ).LayoutLine() ); + + rect = qgn_icon_lsk.Rect(); + } + } + else + { + TAknLayoutText qgn_text_lsk; + + qgn_text_lsk.LayoutText( parentRect, + AknLayoutScalable_Avkon::control_pane_t1( textVariety ).LayoutLine() ); + + rect = qgn_text_lsk.TextRect(); + } + } + break; + case CEikButtonGroupContainer::ERightSoftkeyPosition: + { + if( aImageOn ) + { + if ( HDLayoutActive() && + AKN_LAYOUT_WINDOW_screen.iW == KWideScreenWidth ) + { + rect = SoftkeyRectTopGraphics(); + } + else + { + TAknLayoutRect qgn_icon_rsk; + + qgn_icon_rsk.LayoutRect( parentRect, + AknLayoutScalable_Avkon::control_pane_g2( graphVariety ).LayoutLine() ); + + rect = qgn_icon_rsk.Rect(); + } + } + else + { + TAknLayoutText qgn_text_rsk; + + qgn_text_rsk.LayoutText( parentRect, + AknLayoutScalable_Avkon::control_pane_t2( textVariety ).LayoutLine() ); + + rect = qgn_text_rsk.TextRect(); + } + } + break; + case CEikButtonGroupContainer::EMiddleSoftkeyPosition: + { + if( !mskEnabled || aImageOn ) + { + // No msk, or asking image size for msk + User::Leave( KErrNotSupported ); + } + else + { + TAknLayoutText qgn_text_msk; + + qgn_text_msk.LayoutText( parentRect, + AknLayoutScalable_Avkon::control_pane_t3( textVariety ).LayoutLine() ); + + rect = qgn_text_msk.TextRect(); + } + } + break; + default: + User::Leave( KErrNotFound ); + break; + } + } + + return rect; + } +// ----------------------------------------------------------------------------- +// Get softkey image rect +// ----------------------------------------------------------------------------- +static TRect SoftkeyImageRect(CEikButtonGroupContainer& aContainer, TInt aPosition) + { + TRect ret; +#ifndef _AVKON_CBA_LSC + TAknLayoutRect softkeyImg; + CEikCba* cba( static_cast< CEikCba* >( aContainer.ButtonGroup() ) ); + TRect parentRect( cba->Rect() ); + + if(Layout_Meta_Data::IsLandscapeOrientation()) + { + if(aPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition) + { + TAknWindowComponentLayout wcl = AknLayoutScalable_Avkon::control_pane_g1(2); + softkeyImg.LayoutRect(parentRect,wcl.LayoutLine() ); + } + else if(aPosition == CEikButtonGroupContainer::ERightSoftkeyPosition) + { + TAknWindowComponentLayout wcl = AknLayoutScalable_Avkon::control_pane_g2(2); + softkeyImg.LayoutRect(parentRect,wcl.LayoutLine() ); + } + } + else + { + if(aPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition) + { + TAknWindowComponentLayout wcl = AknLayoutScalable_Avkon::control_pane_g1(4); + softkeyImg.LayoutRect(parentRect,wcl.LayoutLine() ); + } + else if(aPosition == CEikButtonGroupContainer::ERightSoftkeyPosition) + { + TAknWindowComponentLayout wcl = AknLayoutScalable_Avkon::control_pane_g2(4); + softkeyImg.LayoutRect(parentRect,wcl.LayoutLine() ); + + } + } + ret = softkeyImg.Rect(); +#else + if ( Layout_Meta_Data::IsLandscapeOrientation() ) + { + if(aPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition) + { + ret = SoftkeyRectTopTouch(); + } + else if(aPosition == CEikButtonGroupContainer::ERightSoftkeyPosition) + { + ret = SoftkeyRectBottomTouch(); + } + } + else // portrait + { + if(aPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition) + { + ret = SoftkeyRectLeftTouch(); + } + else if(aPosition == CEikButtonGroupContainer::ERightSoftkeyPosition) + { + ret = SoftkeyRectRightTouch(); + } + } +#endif + return ret; + } + +// ----------------------------------------------------------------------------- +// CopyBitmapLC +// Copy bitmap +// ----------------------------------------------------------------------------- +static CFbsBitmap* CopyBitmapL( const CFbsBitmap* aBitmap ) + { + CFbsBitmap* copy = new ( ELeave ) CFbsBitmap; + CleanupStack::PushL( copy ); + + copy->Create( aBitmap->SizeInPixels(), aBitmap->DisplayMode() ); + + CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL( copy ); + CleanupStack::PushL( dev ); + + CFbsBitGc* gc = CFbsBitGc::NewL(); + CleanupStack::PushL( gc ); + + gc->Activate( dev ); + gc->BitBlt( TPoint( 0, 0 ), aBitmap ); + + CleanupStack::PopAndDestroy( 2 ); // gc, dev + + CleanupStack::Pop( copy ); + + return copy; + } + +// ----------------------------------------------------------------------------- +// MenuTypeL +// This is used to deactivate "active applications" menu item using the theme +// Get the "menutype" property from menubar and check if it has value +// "menuoptions" (default) or "menuoptionsnotaskswapper" and return +// correct menu type. +// ----------------------------------------------------------------------------- +static CEikMenuBar::TMenuType MenuTypeL( CXnNodePluginIf& aMenubarNode ) + { + CEikMenuBar::TMenuType menuType( CEikMenuBar::EMenuOptions ); + + CXnProperty* property( aMenubarNode.GetPropertyL( XnPropertyNames::menu::KMenuType ) ); + + if( property ) + { + if( property->StringValue() == XnPropertyNames::menu::menutype::KMenuOptionsNoTaskSwapper ) + { + menuType = CEikMenuBar::EMenuOptionsNoTaskSwapper; + } + } + + return menuType; + } + +// ----------------------------------------------------------------------------- +// FindChildL +// +// ----------------------------------------------------------------------------- +static CXnNodePluginIf* FindChildL( CXnNodePluginIf& aNode, + const TDesC8& aType, const TDesC8& aTarget ) + { + RPointerArray children( aNode.ChildrenL() ); + CleanupClosePushL( children ); + + CXnNodePluginIf* retval( NULL ); + + for( TInt i = 0; i < children.Count(); i++ ) + { + CXnNodePluginIf* child( children[i] ); + + if( child->Type()->Type() == aType ) + { + if( aTarget == KNullDesC8 ) + { + retval = child; + break; + } + else + { + CXnProperty* target( child->GetPropertyL( KXnTarget ) ); + + if( target && target->StringValue() == aTarget ) + { + retval = child; + break; + } + + CXnProperty* source( child->GetPropertyL( KXnSource ) ); + + if( source && source->StringValue() == aTarget ) + { + retval = child; + break; + } + } + } + } + + CleanupStack::PopAndDestroy( &children ); + + return retval; + } + +// ----------------------------------------------------------------------------- +// FindWidgetElementL +// +// ----------------------------------------------------------------------------- +// +static CXnNodePluginIf* FindWidgetElementL( CXnNodePluginIf& aPluginNode ) + { + CXnNodePluginIf* retval( NULL ); + + RPointerArray< CXnNodePluginIf > children( aPluginNode.ChildrenL() ); + CleanupClosePushL( children ); + + for ( TInt i = 0; i < children.Count(); i++ ) + { + CXnNodePluginIf* node( children[i] ); + + if ( node->AppIfL().InternalDomNodeType() == XnPropertyNames::KWidget ) + { + retval = node; + break; + } + } + + CleanupStack::PopAndDestroy( &children ); + + return retval; + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::NewL +// Symbian static 1st phase constructor +// ----------------------------------------------------------------------------- +// +CXnMenuAdapter* CXnMenuAdapter::NewL( CXnControlAdapter* aParent, CXnNodePluginIf& aNode ) + { + CXnMenuAdapter* self = new( ELeave ) CXnMenuAdapter; + + CleanupStack::PushL( self ); + self->ConstructL( aParent, aNode ); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::ConstructL( CXnControlAdapter* /*aParent*/, CXnNodePluginIf& aNode ) + { + iRootNode = &aNode; + + CXnControlAdapter::ConstructL( aNode ); + + iUiEngine = iRootNode->UiEngineL(); + + CAknAppUi* appui( iAvkonAppUi ); + + iPreviousMenuPaneId = appui->StatusPane()->CurrentLayoutResId(); + + CEikMenuBar* current( iEikonEnv->AppUiFactory()->SwapMenuBar( NULL ) ); + appui->RemoveFromStack( current ); + + delete current; + current = NULL; + + InitSoftkeyItemsL(); + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::CXnMenuAdapter +// C++ default constructor +// ----------------------------------------------------------------------------- +// +CXnMenuAdapter::CXnMenuAdapter(): + iMenuItems( KXnMenuArrayGranularity ), + iIdCounter( KMenuCommandFirst ) + { + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::~CXnMenuAdapter +// C++ destructor +// ----------------------------------------------------------------------------- +// +CXnMenuAdapter::~CXnMenuAdapter() + { + StopDisplayingMenu(); + + if ( iAvkonAppUi ) + { + iAvkonAppUi->RemoveFromStack( iMenuBar ); + } + + if ( iMenuBar ) + { + delete iMenuBar; + } + + iSoftkeyItems.ResetAndDestroy(); + iMenuItems.Reset(); + } + +// ----------------------------------------------------------------------------- +// Create scaled bitmap from source bitmap. +// ----------------------------------------------------------------------------- +// +void CreateScaledBitmapL( + const TRect& aRect, + CFbsBitmap*& aTrgBitmap, + CFbsBitmap* aSrcBitmap, + TBool aPreserveAspectRatio ) + { + TRect destRect = aRect; + + if( aPreserveAspectRatio ) + { + // Calculate the bitmap image dimensions so that it uses maximum space + // of the given rectangle and maintains aspect ratio. + TInt srcHeight = aSrcBitmap->SizeInPixels().iHeight; + TInt srcWidth = aSrcBitmap->SizeInPixels().iWidth; + TReal scaleRatio( 1 ); //no scale as defaul + + // If any dimension is 0, then we do not bother to scale + if( aRect.Width() > 0 && aRect.Height() > 0 ) + { + TReal xRatio = ( (TReal )srcWidth / ( TReal )aRect.Width() ); + TReal yRatio = ( ( TReal )srcHeight / ( TReal )aRect.Height() ); + + //Find out appropriate scaling factor + xRatio > yRatio ? ( scaleRatio = xRatio ) : ( scaleRatio = yRatio ); + } + + // Scale the size for target bitmap + destRect.SetHeight( srcHeight / scaleRatio ); + destRect.SetWidth( srcWidth / scaleRatio ); + } + + aTrgBitmap = new ( ELeave ) CFbsBitmap; + CleanupStack::PushL( aTrgBitmap ); + + // It is allowed to create zero height or width bitmap. + TInt err( aTrgBitmap->Create( destRect.Size(), aSrcBitmap->DisplayMode() ) ); + + if( err == KErrNone ) + { + CXnUtils::ScaleBitmapL( destRect, aTrgBitmap, aSrcBitmap ); + } + + // we do not own the bitmap so just Pop. + CleanupStack::Pop( aTrgBitmap ); + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::PrepareSoftkeyImageL +// Make a copy of originals and scale them to right size. +// Finally place the scaled icon to right position of drawing area. +// ----------------------------------------------------------------------------- +CEikImage* CXnMenuAdapter::PrepareSoftkeyImageL( const CXnSoftkeyItem& aItem, const TSize& aSize ) + { + CFbsBitmap* bitmap( NULL ); + CFbsBitmap* mask( NULL ); + + // Start from bitmap + CFbsBitmap* source( aItem.iBitmap ); + + TInt count( 0 ); + + // Go through bitmap and mask + for( TInt i = 0; i < 2; i++ ) + { + if( !source ) + { + source = aItem.iMask; + continue; + } + + CFbsBitmap* scaled( NULL ); + + TScaleMode mode( aItem.iPreserveAspectRatio ? EAspectRatioPreserved : EAspectRatioNotPreserved ); + + if( AknIconUtils::IsMifIcon( source ) ) + { + AknIconUtils::SetSize( source, aSize, mode ); + + scaled = CopyBitmapL( source ); + } + else + { + CreateScaledBitmapL( TRect( aSize ), scaled, source, mode == EAspectRatioPreserved ); + } + + CleanupStack::PushL( scaled ); + + if( !aItem.iPreserveAspectRatio ) + { + count++; + + if( i == 0 ) + { + bitmap = scaled; + } + else + { + mask = scaled; + } + } + else + { + CFbsBitmap* target = new ( ELeave ) CFbsBitmap; + CleanupStack::PushL( target ); + + // Target is size of whole draw area + User::LeaveIfError( target->Create( aSize, source->DisplayMode() ) ); + + CFbsBitmapDevice* dev = CFbsBitmapDevice::NewL( target ); + CleanupStack::PushL( dev ); + + CFbsBitGc* gc = CFbsBitGc::NewL(); + CleanupStack::PushL( gc ); + + gc->Activate( dev ); + + gc->SetBrushStyle( CGraphicsContext::ESolidBrush ); + gc->SetPenStyle( CGraphicsContext::ENullPen ); + + if( aItem.iInvertMask ) + { + // White, with full transparent alpha channel + gc->SetBrushColor( TRgb( 0x00FFFFFF, 0 ) ); + } + else + { + // Black, with full transparent alpha channel + gc->SetBrushColor( TRgb( 0x00000000, 0 ) ); + } + + // Make whole target area transparent + gc->DrawRect( TRect( aSize ) ); + + TPoint iconPos; + + switch( AknLayoutUtils::CbaLocation() ) + { + case AknLayoutUtils::EAknCbaLocationBottom: + // Rsk must be moved to right, lsk is in correct place by default + if ( aItem.iPosition != CEikButtonGroupContainer::ELeftSoftkeyPosition ) + { + iconPos.iX = aSize.iWidth - scaled->SizeInPixels().iWidth; + } + break; + case AknLayoutUtils::EAknCbaLocationRight: + // Rsk and lsk must be moved to right + iconPos.iX = aSize.iWidth - scaled->SizeInPixels().iWidth; + break; + case AknLayoutUtils::EAknCbaLocationLeft: + // Already in correct position + default: + break; + } + + // Align horizontally to center + iconPos.iY = iconPos.iX ? 0 : ( ( aSize.iHeight - scaled->SizeInPixels().iHeight ) / 2 ); + + gc->SetBrushStyle( CGraphicsContext::ENullBrush ); + + // Blit image to correct position + gc->BitBlt( iconPos, scaled ); + + CleanupStack::PopAndDestroy( 2, dev ); + + CleanupStack::Pop( target ); + + CleanupStack::PopAndDestroy( scaled ); + + CleanupStack::PushL( target ); + count++; + + if( i == 0 ) + { + bitmap = target; + } + else + { + mask = target; + } + + + } + + // Go with mask next + source = aItem.iMask; + } + + // Takes ownership of scaled bitmap and mask + CEikImage* image = new ( ELeave ) CEikImage; + + image->SetPictureOwnedExternally( EFalse ); + image->SetPicture( bitmap, mask ); + + CleanupStack::Pop( count ); + + return image; + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::SetSoftkeyAppearanceL +// +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::SetSoftkeyAppearanceL( CXnSoftkeyItem& aItem ) + { + if( iContainer && IsNodeVisibleL( *aItem.iNode) ) + { + if( aItem.iImageOn ) + { + ChangeSoftkeyImageL( aItem ); + } + else if( aItem.iLabel )// change label + { + if ( aItem.iPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition ) + { + EikSoftkeyImage::SetLabel( iContainer, ETrue ); + } + else if ( aItem.iPosition == CEikButtonGroupContainer::ERightSoftkeyPosition ) + { + EikSoftkeyImage::SetLabel( iContainer, EFalse ); + } + + iContainer->SetCommandL( aItem.iPosition, aItem.iCommandId, *aItem.iLabel ); + } + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::InitSoftkeyItemsL +// +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::InitSoftkeyItemsL() + { + // No layout calulations needed + iRootNode->SetLayoutCapable( EFalse ); + + // create softkeyitems to hold data + + RPointerArray< CXnNodePluginIf > children( iRootNode->ChildrenL() ); + CleanupClosePushL( children ); + CXnSoftkeyItem* item(0); + for(TInt i=0;iType()->Type() == XnPropertyNames::softkey::KNodeName) + { + item = AppendSoftkeyItemL(children[i]); + if(item) + { + item->iDefault = ETrue; + } + } + } + CleanupStack::PopAndDestroy( &children ); + + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::InitSoftkeyItemL +// +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::InitSoftkeyItemImageL( CXnSoftkeyItem& aItem) + { + CXnNodePluginIf* node( aItem.iNode ); + + // No layout calulations needed + node->SetLayoutCapable( EFalse ); + + if ( aItem.iPosition == CEikButtonGroupContainer::EMiddleSoftkeyPosition ) + { + aItem.iImageOn = ETrue; + return; + } + + CXnProperty* pathProp( node->PathL() ); + if( pathProp ) + { + HBufC* bitmapPath( NULL ); + HBufC* maskPath( NULL ); + + bitmapPath = pathProp->StringValueL(); + CleanupStack::PushL( bitmapPath ); + TInt count( 1 ); + + CXnProperty* maskProp( node->MaskPathL() ); + + if( maskProp ) + { + maskPath = maskProp->StringValueL(); + CleanupStack::PushL( maskPath ); + count++; + } + + CFbsBitmap* bitmap( NULL ); + CFbsBitmap* mask( NULL ); + + // Call base class to get bitmap and mask + GetBitmapAndMask( bitmapPath ? *bitmapPath : KNullDesC(), + maskPath ? *maskPath : KNullDesC(), + bitmap, mask ); + + aItem.iImageOn = ETrue; + aItem.iBitmap = bitmap; + aItem.iMask = mask; + + CXnProperty* maskInvertedProp( node->GetPropertyL( XnPropertyNames::image::KMaskInverted ) ); + + if( maskInvertedProp ) + { + if( maskInvertedProp->StringValue() == XnPropertyNames::KTrue ) + { + aItem.iInvertMask = ETrue; + } + } + + CXnProperty* aspectRatioProp( node->GetPropertyL( XnPropertyNames::image::KS60AspectRatio ) ); + + if( aspectRatioProp ) + { + if( aspectRatioProp->StringValue() == XnPropertyNames::image::KPreserve ) + { + aItem.iPreserveAspectRatio = ETrue; + } + } + + CleanupStack::PopAndDestroy( count ); // path and/or mask + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::IsMskAvailable +// +// ----------------------------------------------------------------------------- +// +TBool CXnMenuAdapter::IsMskAvailable() + { + if( AknLayoutUtils::MSKEnabled() && Layout_Meta_Data::IsMSKEnabled() ) + { + return ETrue; + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::AddMenuItemL +// +// ----------------------------------------------------------------------------- +// +TInt CXnMenuAdapter::AddMenuItemL( TInt aParentIndex, + CXnNodePluginIf* aNode, RPointerArray< const TDesC8 >& aGroups ) + { + if ( !aNode ) + { + return 0; + } + + const TDesC8& name( aNode->Type()->Type() ); + + TInt retval( 0 ); + + TBool showByGroup( EFalse ); + + const TDesC8* id( NULL ); + + CXnProperty* prop( aNode->IdL() ); + + if( prop ) + { + id = &prop->StringValue(); + } + else + { + // If menuitem doesn't have id, group doesn't affect to it + showByGroup = ETrue; + } + + if( name == KXnMenuItem || + name == KXnDynMenuItem || + name == KXnWidgetMenuItem ) + { + const TDesC8& ns( aNode->Namespace() ); + + for( TInt i = 0; !showByGroup && i < aGroups.Count(); i++ ) + { + const TDesC8& groupId( *(aGroups)[i] ); + + CXnNodePluginIf* group( iUiEngine->FindNodeByIdL( groupId, ns ) ); + + if( group ) + { + RPointerArray< CXnNodePluginIf > + children( group->ChildrenL() ); + + CleanupClosePushL( children ); + + for( TInt j = 0; j < children.Count(); j++ ) + { + CXnProperty* prop( children[j]->GetPropertyL( + XnPropertyNames::action::KName ) ); + + if( prop ) + { + const TDesC8& name( prop->StringValue() ); + + if( name == *id ) + { + // The menuitem belongs to defined group + showByGroup = ETrue; + break; + } + } + } + + CleanupStack::PopAndDestroy( &children ); + } + } + + if( !showByGroup || !IsNodeVisibleL( *aNode ) ) + { + // Menuitem is invisible + return retval; + } + } + + TXnMenuItem item; + + item.iAutomaticSP = ETrue; + + item.iParentIndex = aParentIndex; + item.iData.iFlags = 0; + + CXnNodePluginIf* menuItem( NULL ); + + if( name == KXnMenuItem || name == KXnDynMenuItem ) + { + menuItem = aNode; + } + else if( name == KXnWidgetMenuItem ) + { + TRAP_IGNORE( menuItem = FindWidgetMenuItemL( aNode ) ); + } + + if( menuItem ) + { + const TDesC8& type( menuItem->Type()->Type() ); + + // check first if label comes from view + CXnProperty* label( aNode->LabelL() ); + + if ( !label ) + { + // get label from widget + label = menuItem->LabelL(); + } + + if( label ) + { + HBufC* itemLabel = label->StringValueL(); + item.iData.iText.Copy( *itemLabel ); + delete itemLabel; + } + else + { + item.iData.iText.Copy( KNullDesC ); + } + + TBool okToAdd( ETrue ); + + if( type == KXnDynMenuItem ) + { + okToAdd = EFalse; + + if( iObserver ) + { + okToAdd = iObserver->DynInitMenuItemL( menuItem->AppIfL() ); + } + } + + if( okToAdd ) + { + if ( id && *id == KHsShowHelp ) + { + // Help command id must be EAknCmdHelp to get editing input options + // shown correctly + item.iData.iCommandId = EAknCmdHelp; + } + else + { + item.iData.iCommandId = iIdCounter++; + } + + item.iData.iCascadeId = 0; + item.iNode = menuItem; + item.iIsCascade = EFalse; + iMenuItems.AppendL( item ); + + retval = 1; + } + } + + if( name == KXnMenu ) + { + // main level menu or submenu (cascade) + item.iData.iCommandId = iIdCounter++; + + if( aParentIndex == -1 ) + { + item.iData.iCascadeId = R_AVKON_MENUPANE_EMPTY; + } + else + { + item.iData.iCascadeId = iIdCounter++; + } + + item.iNode = aNode; + item.iIsCascade = ETrue; + iMenuItems.AppendL( item ); + + TInt currentIndex( iMenuItems.Count() - 1 ); + + RPointerArray< CXnNodePluginIf > children( aNode->ChildrenL() ); + CleanupClosePushL( children ); + + TInt count( 0 ); + + for( TInt i = 0; i < children.Count(); i++ ) + { + count += AddMenuItemL( currentIndex, children[i], aGroups ); + } + + if( aParentIndex != -1 && count == 0 ) + { + // Empty submenu, don't show it + iMenuItems.Delete( currentIndex ); + // Reverse counter as well + iIdCounter -= 2; + } + + CleanupStack::PopAndDestroy( &children ); + + retval = count; + } + + return retval; + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::PopulateMenuL +// +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::PopulateMenuL() + { + iMenuItems.Reset(); + + iIdCounter = KMenuCommandFirst; + + RPointerArray< const TDesC8 > groups; + CleanupClosePushL( groups ); + + if ( !iUiEngine->IsTextEditorActive() ) + { + if( iUiEngine->EditMode() ) + { + groups.AppendL( + iContextMenu ? &KContextEditMode : &KEditMode ); + } + else + { + groups.AppendL( + iContextMenu ? &KContextNormalMode : &KNormalMode ); + } + } + + if ( !iContextMenu ) + { + groups.AppendL( &KAlwaysShown ); + } + + // Recursively add menuitems + AddMenuItemL( -1, iMenuBarNode, groups ); + + CleanupStack::PopAndDestroy( &groups ); + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::OfferKeyEventL +// ----------------------------------------------------------------------------- +// +TKeyResponse CXnMenuAdapter::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType) + { + TKeyResponse resp( EKeyWasNotConsumed ); + + if( IsMenuFocused() && aKeyEvent.iScanCode == EStdKeyNo ) + { + StopDisplayingMenu(); + + iKeyEventNode = NULL; + + return resp; + } + + TInt pos( KErrNotFound ); + + if( aKeyEvent.iScanCode == EStdKeyDevice0 ) + { + pos = CEikButtonGroupContainer::ELeftSoftkeyPosition; + } + else if( aKeyEvent.iScanCode == EStdKeyDevice1 ) + { + pos = CEikButtonGroupContainer::ERightSoftkeyPosition; + } + else if( aKeyEvent.iScanCode == EStdKeyDevice3 ) + { + pos = CEikButtonGroupContainer::EMiddleSoftkeyPosition; + } + + CXnSoftkeyItem* softkey( NULL ); + + if ( pos != KErrNotFound ) + { + softkey = SoftkeyItemL( pos ); + } + + if ( softkey ) + { + CXnNodePluginIf* node( softkey->iNode ); + + if( aType == EEventKeyDown ) + { + iKeyEventNode = node; + } + + if( node && node == iKeyEventNode ) + { + // Let base class handle the event + resp = CXnControlAdapter::OfferKeyEventL( aKeyEvent, aType ); + } + } + + if( aType == EEventKeyUp ) + { + iKeyEventNode = NULL; + } + + return resp; + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::HandlePointerEventL +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::HandlePointerEventL( const TPointerEvent& aPointerEvent ) + { + CXnNodePluginIf* node( FindSoftkeyItemByPosition( aPointerEvent.iParentPosition ) ); + + if( aPointerEvent.iType == TPointerEvent::EButton1Down ) + { + // The sofkey node which received the button down event + iPointerEventNode = node; + } + + if( node && node == iPointerEventNode ) + { + iUiEngine->DisableRenderUiLC(); + + // Handle event if location is in the grabbing node's area + CXnControlAdapter::HandlePointerEventL( aPointerEvent ); + + CleanupStack::PopAndDestroy(); + } + + if( aPointerEvent.iType == TPointerEvent::EButton1Up ) + { + // Reset grabbing node after the up event + iPointerEventNode = NULL; + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::DoEnterPowerSaveModeL +// Enter power save mode +// ----------------------------------------------------------------------------- +void CXnMenuAdapter::DoEnterPowerSaveModeL(TModeEvent /*aEvent*/) + { + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::DoExitPowerSaveModeL +// Enter power save mode +// ----------------------------------------------------------------------------- +void CXnMenuAdapter::DoExitPowerSaveModeL(TModeEvent /*aEvent*/) + { + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::RestoreMenuL +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::RestoreMenuL( CCoeControl* aMenuControl, TInt aResourceId, + TMenuType aType ) + { + // let all menu pane resources propogate to default implementation, + // otherwise panic when trying to display menu + if ( aType == MEikMenuObserver::EMenuPane ) + { + if ( !( KMenuCommandFirst <= aResourceId && + aResourceId <= KMenuCommandLast ) + && aResourceId != R_AVKON_MENUPANE_EMPTY ) + { + MEikMenuObserver::RestoreMenuL( aMenuControl,aResourceId, aType ); + } + else + { + AddItemsToMenuPaneL( ( CEikMenuPane* )aMenuControl, aResourceId ); + } + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::DynInitMenuPaneL +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::DynInitMenuPaneL( TInt aResourceId, + CEikMenuPane* aMenuPane ) + { + if ( aResourceId == R_AVKON_MENUPANE_EMPTY ) + { + RestoreMenuL( aMenuPane, aResourceId, MEikMenuObserver::EMenuPane ); + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::SetEmphasis +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::SetEmphasis( CCoeControl* aMenuControl, + TBool aEmphasis ) + { + if ( iMenuBar && aMenuControl == iMenuBar ) + { + CXnAppUiAdapter* appui( + static_cast< CXnAppUiAdapter* >( iAvkonAppUi ) ); + + if ( aEmphasis && !iMenuShown ) + { + iMenuShown = ETrue; + + TRAP_IGNORE( appui->AddToStackL( appui->View(), + iMenuBar, + ECoeStackPriorityMenu ) ); + + iMenuBar->MakeVisible( ETrue ); + } + else if ( !aEmphasis && iMenuShown ) + { + iMenuShown = EFalse; + + appui->RemoveFromStack( iMenuBar ); + + iMenuBar->MakeVisible( EFalse ); + } + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::ProcessCommandL +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::ProcessCommandL( TInt aCommand ) + { + if ( ( KMenuCommandFirst <= aCommand && aCommand <= KMenuCommandLast ) || + aCommand == EAknCmdHelp ) + { + // find item for this command + for ( TInt i = 0; i< iMenuItems.Count(); i++ ) + { + if ( iMenuItems[i].iData.iCommandId == aCommand ) + { + CXnNodePluginIf* node( iMenuItems[i].iNode ); + + if ( node ) + { + StopDisplayingMenu(); + + iUiEngine->DisableRenderUiLC(); + + node->SetStateL( XnPropertyNames::style::common::KActive ); + + CleanupStack::PopAndDestroy(); + + break; + } + } + } + } + else + { + StopDisplayingMenu(); + + if( aCommand == EEikCmdEditPaste ) + { + // Paste event for AknCcpuSupport + TKeyEvent pasteEvent = + { EKeyF18, EEikCmdEditPaste, EModifierCtrl, 1 }; + + iCoeEnv->SimulateKeyEventL( pasteEvent, EEventKey ); + } + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::SetContainerL +// +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::SetContainerL( CEikButtonGroupContainer& aContainer ) + { + User::LeaveIfNull( &aContainer ); + + TBool updateNeeded( EFalse ); + + TInt statusPaneId( iAvkonAppUi->StatusPane()->CurrentLayoutResId() ); + + if(iPreviousMenuPaneId != statusPaneId) + { + updateNeeded = ETrue; + iPreviousMenuPaneId = statusPaneId; + } + + if((&aContainer) && (iContainer != &aContainer || updateNeeded)) + { + iUpdateLskAppearance = ETrue; + iUpdateMskAppearance = ETrue; + iUpdateRskAppearance = ETrue; + } + + iContainer = &aContainer; + + CEikCba* cba( static_cast< CEikCba* >( aContainer.ButtonGroup() ) ); + cba->SetButtonGroupFlags( cba->ButtonGroupFlags() | EEikCbaFlagSemiTransparent ); + + UpdateSoftkeyAppearancesL(); + } + +//-------------------------------------------------------------- +// CXnMenuAdapter::IsMenuFocused +// ------------------------------------------------------------ +TBool CXnMenuAdapter::IsMenuFocused() + { + return iMenuShown; + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::TryDisplayingMenuL +// Displays options menu +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::TryDisplayingMenuL( const TDesC& aMenuNodeId, + TBool aContextMenu ) + { + HBufC8* id = CnvUtfConverter::ConvertFromUnicodeToUtf8L( aMenuNodeId ); + CleanupStack::PushL( id ); + CXnNodePluginIf* node( iUiEngine->FindNodeByIdL( *id, iRootNode->Namespace() ) ); + CleanupStack::PopAndDestroy( id ); + + iContextMenu = aContextMenu; + + if( node && node->Type()->Type() == KXnMenu ) + { + TryDisplayingMenuL(); + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::TryDisplayingMenuL +// Displays options menu if it is defined for the softkey item +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::TryDisplayingMenuL() + { + StopDisplayingMenu(); + + CreateMenuBarL(); + + if ( iMenuBar ) + { + CEikMenuBarTitle* title = new( ELeave ) CEikMenuBarTitle; + CleanupStack::PushL( title ); + + title->iData.iMenuPaneResourceId = R_AVKON_MENUPANE_EMPTY; + title->iTitleFlags = 0; + + // this cannot be done earlyer, than this callback + iMenuBar->TitleArray()->AddTitleL( title ); + CleanupStack::Pop( title ); + + iMenuBar->TryDisplayMenuBarL(); + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::StopDisplayingMenu +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::StopDisplayingMenu() + { + if( iMenuBar ) + { + iMenuBar->StopDisplayingMenuBar(); + } + } + +// --------------------------------------------------------------------------- +// CXnMenuAdapter::CreateMenuBarL +// --------------------------------------------------------------------------- +// +void CXnMenuAdapter::CreateMenuBarL() + { + if ( iMenuBar ) + { + // All ready created + return; + } + + // Create + RPointerArray< CXnNodePluginIf > children( iRootNode->ChildrenL() ); + CleanupClosePushL( children ); + + for( TInt i = 0; i < children.Count(); i++ ) + { + CXnNodePluginIf* node( children[i] ); + + TPtrC8 type( node->Type()->Type() ); + + // Currently only one menubar is allowed, + // but it can be assigned to any of the CBAs + // To change this, we have to create and maintain a list of menubars + if( type == KXnMenu ) + { + iMenuBarNode = node; + + iMenuBar = new ( ELeave ) CEikMenuBar; + iMenuBar->ConstructL( this ); + iMenuBar->SetMenuType( MenuTypeL( *iRootNode ) ); + + // All done + break; + } + } + CleanupStack::PopAndDestroy( &children ); + } + +//-------------------------------------------------------------- +// CXnMenuAdapter::HandleResourceChange +// Handles a change to the control's resources of type aType +// ------------------------------------------------------------ +void CXnMenuAdapter::HandleResourceChange( TInt aType ) + { + if( iMenuBar ) + { + iMenuBar->HandleResourceChange( aType ); + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::SetSoftKeyImageL +// +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::SetSoftKeyImageL( + CFbsBitmap* aBitmap, + CFbsBitmap* aMask, + XnMenuInterface::MXnMenuInterface::TSoftKeyPosition aPos, + CXnNodeAppIf* aNode, + TBool aPreserveAspectRatio, TBool aInvertMask, + TBool aTransferOwnership) + { + if( ( !aBitmap && !aMask ) || aPos == XnMenuInterface::MXnMenuInterface::ECenter ) + { + // No images present and image can be set only to lsk or rsk + User::Leave( KErrArgument ); + } + + CXnSoftkeyItem* softkey(NULL); + + if( aPos == XnMenuInterface::MXnMenuInterface::ELeft) + { + if( aNode ) + { + softkey = SoftkeyItemL( aNode ); + } + else + { + softkey = SoftkeyItemL(CEikButtonGroupContainer::ELeftSoftkeyPosition); + } + iUpdateLskAppearance = ETrue; + } + else if(aPos == XnMenuInterface::MXnMenuInterface::ERight) + { + if( aNode ) + { + softkey = SoftkeyItemL( aNode ); + } + else + { + softkey = SoftkeyItemL(CEikButtonGroupContainer::ERightSoftkeyPosition); + } + iUpdateRskAppearance = ETrue; + } + + if(softkey) + { + softkey->Reset(); + softkey->iImageOn = ETrue; + + // Save new icon data + softkey->iBitmap = aBitmap; + softkey->iMask = aMask; + softkey->iPreserveAspectRatio = aPreserveAspectRatio; + softkey->iInvertMask = aInvertMask; + softkey->iOwnBitmaps = aTransferOwnership; + // Image set, mark node as dirty + softkey->iNode->SetDirtyL(); + + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::SetSoftKeyImageL +// +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::SetSoftKeyImageL( const TAknsItemID& aId, + const TDesC& aBmpFile, + const TInt32 aBmp, + const TInt32 aBmpM, + XnMenuInterface::MXnMenuInterface::TSoftKeyPosition aPos, + TBool /*aEnable*/ ) + { + CXnSoftkeyItem* softkey( NULL ); + + switch( aPos ) + { + case XnMenuInterface::MXnMenuInterface::ECenter: + { + softkey = SoftkeyItemL( CEikButtonGroupContainer::EMiddleSoftkeyPosition ); + iUpdateMskAppearance = ETrue; + break; + } + // Currently only MSK icon updating supported here + case XnMenuInterface::MXnMenuInterface::ELeft: + case XnMenuInterface::MXnMenuInterface::ERight: + default: + { + break; + } + } + + if( softkey ) + { + softkey->Reset(); + softkey->iImageOn = ETrue; + + // Save new icon data + softkey->iBitmap = NULL; + softkey->iMask = NULL; + softkey->iPreserveAspectRatio = EFalse; + softkey->iInvertMask = EFalse; + softkey->iOwnBitmaps = ETrue; + delete softkey->iBmpFile; + softkey->iBmpFile = NULL; + softkey->iBmpFile = aBmpFile.AllocL(); + softkey->iId.Set( aId ); + softkey->iBmp = aBmp; + softkey->iBmpM = aBmpM; + + // Image set, mark node as dirty + softkey->iNode->SetDirtyL(); + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::SetSoftKeyTextL +// +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::SetSoftKeyTextL( const TDesC& aText, + XnMenuInterface::MXnMenuInterface::TSoftKeyPosition aPos ) + { + CXnSoftkeyItem* softkey(NULL); + + switch( aPos ) + { + case XnMenuInterface::MXnMenuInterface::ELeft: + softkey = SoftkeyItemL(CEikButtonGroupContainer::ELeftSoftkeyPosition); + iUpdateLskAppearance = ETrue; + break; + case XnMenuInterface::MXnMenuInterface::ERight: + softkey = SoftkeyItemL(CEikButtonGroupContainer::ERightSoftkeyPosition); + iUpdateRskAppearance = ETrue; + break; + case XnMenuInterface::MXnMenuInterface::ECenter: + softkey = SoftkeyItemL(CEikButtonGroupContainer::EMiddleSoftkeyPosition); + iUpdateMskAppearance = ETrue; + break; + default: + break; + } + if(softkey) + { + softkey->Reset(); + + softkey->iImageOn = EFalse; + + softkey->iLabel = aText.AllocL(); + // Text set, mark parent as dirty + softkey->iNode->SetDirtyL(); + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::SetSoftKeyL +// +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::SetSoftKeyL( CXnNodePluginIf* aSoftkeyNode, + XnMenuInterface::MXnMenuInterface::TSoftKeyPosition aPos ) + { + + CXnSoftkeyItem* item = AppendSoftkeyItemL(aSoftkeyNode); + switch(aPos) + { + case XnMenuInterface::MXnMenuInterface::ELeft: + if(item) + { + iVisibleLSK = item; + } + else + { + iVisibleLSK = NULL; + } + iUpdateLskAppearance = ETrue; + break; + case XnMenuInterface::MXnMenuInterface::ECenter: + if(item) + { + iVisibleMSK = item; + } + else + { + iVisibleMSK = NULL; + } + iUpdateMskAppearance = ETrue; + break; + case XnMenuInterface::MXnMenuInterface::ERight: + if(item) + { + iVisibleRSK = item; + } + else + { + iVisibleRSK = NULL; + } + iUpdateRskAppearance = ETrue; + break; + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::SoftKeyL +// +// ----------------------------------------------------------------------------- +// +CXnNodePluginIf* CXnMenuAdapter::SoftKeyL( XnMenuInterface::MXnMenuInterface::TSoftKeyPosition aPos ) + { + CXnNodePluginIf* node(NULL); + CXnSoftkeyItem* item = SoftkeyItemL(aPos); + if(item) + { + node = item->iNode; + } + return node; + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::KeyEventNode +// +// ----------------------------------------------------------------------------- +// +CXnNodePluginIf* CXnMenuAdapter::KeyEventNode() + { + return iKeyEventNode; + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::HandleScreenDeviceChangedL +// +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::HandleScreenDeviceChangedL() + { + CXnSoftkeyItem* left = + SoftkeyItemL(CEikButtonGroupContainer::ELeftSoftkeyPosition); + + CXnSoftkeyItem* middle = + SoftkeyItemL(CEikButtonGroupContainer::EMiddleSoftkeyPosition); + CXnSoftkeyItem* right = + SoftkeyItemL(CEikButtonGroupContainer::ERightSoftkeyPosition); + + if(left && left->iImageOn) + { + iUpdateLskAppearance = ETrue; + left->iNode->SetDirtyL(); + } + if(right && right->iImageOn) + { + iUpdateRskAppearance = ETrue; + right->iNode->SetDirtyL(); + } + if(middle && middle->iImageOn) + { + iUpdateMskAppearance = ETrue; + middle->iNode->SetDirtyL(); + } + CXnControlAdapter::HandleScreenDeviceChangedL(); + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::HandleMenuPropertyChangeL +// Change softkey appearance +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::HandleMenuPropertyChangeL(CXnNodePluginIf* aNode, CXnProperty* aProperty) + { + if ( !aNode || !aProperty ) + { + return; + } + + const TDesC8& type( aNode->Type()->Type() ); + + if ( type != softkey::KNodeName) + { + return; + } + + // Find target softkey + CXnSoftkeyItem* softkey( SoftkeyItemL( aNode ) ); + + if ( !softkey ) + { + return; + } + + SetUpdateAppearanceL( softkey ); + + const TDesC8* name( &KNullDesC8() ); + + if ( aProperty ) + { + name = &aProperty->Property()->Name(); + } + + if ( *name == menu::KLabel ) + { + softkey->Reset(); + softkey->iImageOn = EFalse; + softkey->iLabel = aProperty->StringValueL(); + } + else if ( *name == style::common::KDisplay ) + { + if ( aProperty->StringValue() == XnPropertyNames::style::common::display::KNone ) + { + if ( softkey->iPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition ) + { + EikSoftkeyImage::SetLabel( iContainer,ETrue ); + iContainer->SetCommandL( CEikButtonGroupContainer::ELeftSoftkeyPosition,KCBACommandFirst, KNullDesC ); + } + else if ( softkey->iPosition == CEikButtonGroupContainer::ERightSoftkeyPosition ) + { + EikSoftkeyImage::SetLabel( iContainer,EFalse ); + iContainer->SetCommandL( CEikButtonGroupContainer::ERightSoftkeyPosition,KCBACommandSecond, KNullDesC ); + } + else if ( softkey->iPosition == CEikButtonGroupContainer::EMiddleSoftkeyPosition ) + { + iContainer->SetCommandL( CEikButtonGroupContainer::EMiddleSoftkeyPosition,KCBACommandMiddle, KNullDesC ); + } + } + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::SetObserver +// +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::SetObserver( XnMenuInterface::MXnMenuObserver& aObserver ) + { + iObserver = &aObserver; + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::RemoveObserver +// +// ----------------------------------------------------------------------------- +// +void CXnMenuAdapter::RemoveObserver() + { + iObserver = NULL; + } + +// --------------------------------------------------------------------------- +// CXnMenuAdapter::FindSoftKeyNodeByPosition +// --------------------------------------------------------------------------- +// +TBool CXnMenuAdapter::FindSoftKeyNodeByPosition( + const TPoint& aPosition, + CXnNodePluginIf*& aNode ) + { + CXnNodePluginIf* ret = FindSoftkeyItemByPosition(aPosition); + aNode = ret; + return (ret?ETrue:EFalse); + } +// --------------------------------------------------------------------------- +// CXnMenuAdapter::ButtonTouchableRectByPosition +// Gets a CBA button rectangle. Touchable are is larger than controls rect +// --------------------------------------------------------------------------- +// +TRect CXnMenuAdapter::ButtonTouchableRectByPosition( TInt aPosition) + { + TRect rect( 0, 0, 0, 0 ); + + TRect button1Rect( 0, 0, 0, 0 ); + TRect button2Rect( 0, 0, 0, 0 ); + TRect buttonMSKRect( 0, 0, 0, 0 ); + + // In touch layouts the button areas are read from the + // layout data because they are larger than the actual + // control size. +#ifndef _AVKON_CBA_LSC + CCoeControl* container = iContainer->ButtonGroup()->AsControl(); + TRect containerRect(container->PositionRelativeToScreen(),container->Size()); + TAknLayoutRect layoutRect; + layoutRect.LayoutRect( + containerRect, + AknLayoutScalable_Avkon::control_pane_g6( 0 ).LayoutLine() ); + button1Rect = layoutRect.Rect(); + + layoutRect.LayoutRect( + containerRect, + AknLayoutScalable_Avkon::control_pane_g8( 0 ).LayoutLine() ); + button2Rect = layoutRect.Rect(); + + layoutRect.LayoutRect( + containerRect, + AknLayoutScalable_Avkon::control_pane_g7( 0 ).LayoutLine() ); + buttonMSKRect = layoutRect.Rect(); +#else + if ( Layout_Meta_Data::IsLandscapeOrientation() ) + { + button1Rect = SoftkeyRectTopTouch(); + button2Rect= SoftkeyRectBottomTouch(); + + } + else // portrait + { + button1Rect = SoftkeyRectLeftTouch(); + button2Rect = SoftkeyRectRightTouch(); + } +#endif + + switch ( aPosition ) + { + case CEikButtonGroupContainer::ELeftSoftkeyPosition: + { + rect = button1Rect; + break; + } + + case CEikButtonGroupContainer::ERightSoftkeyPosition: + { + rect = button2Rect; + break; + } + + case CEikButtonGroupContainer::EMiddleSoftkeyPosition: + { + rect = buttonMSKRect; + break; + } + + default: + { + break; + } + } + + + return rect; + } + +// --------------------------------------------------------------------------- +// CXnMenuAdapter::FindSoftkeyNodeL +// --------------------------------------------------------------------------- +// +CXnNodePluginIf* CXnMenuAdapter::FindSoftkeyNodeL(const TDesC8& aNodeType) + { + CXnNodePluginIf* ret(0); + + RPointerArray< CXnNodePluginIf > children( iRootNode->ChildrenL() ); + CleanupClosePushL( children ); + for(TInt i=0;iType()->Type() == XnPropertyNames::softkey::KNodeName) + { + if( SoftkeyPlaceL(*children[i]) == aNodeType + && IsNodeVisibleL( *children[i]) ) + { + ret = children[i]; + break; + } + + } + } + CleanupStack::PopAndDestroy( &children ); + return ret; + } + +// --------------------------------------------------------------------------- +// CXnMenuAdapter::UpdateSoftkeyAppearancesL +// --------------------------------------------------------------------------- +// +void CXnMenuAdapter::UpdateSoftkeyAppearancesL() + { + + if(iUpdateLskAppearance) + { + CXnSoftkeyItem* left = + SoftkeyItemL(CEikButtonGroupContainer::ELeftSoftkeyPosition); + if( left ) + { + SetSoftkeyAppearanceL(*left); + } + iUpdateLskAppearance = EFalse; + } + if(iUpdateRskAppearance) + { + CXnSoftkeyItem* right = + SoftkeyItemL(CEikButtonGroupContainer::ERightSoftkeyPosition); + if(right) + { + SetSoftkeyAppearanceL(*right); + } + iUpdateRskAppearance = EFalse; + } + if(iUpdateMskAppearance) + { + CXnSoftkeyItem* middle = + SoftkeyItemL(CEikButtonGroupContainer::EMiddleSoftkeyPosition); + if(middle) + { + SetSoftkeyAppearanceL(*middle); + } + iUpdateMskAppearance = EFalse; + } + } +// --------------------------------------------------------------------------- +// CXnMenuAdapter::ChangeSoftkeyImageL +// --------------------------------------------------------------------------- +// +void CXnMenuAdapter::ChangeSoftkeyImageL(const CXnSoftkeyItem& aSoftkey) + { + if ( aSoftkey.iPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition || + aSoftkey.iPosition == CEikButtonGroupContainer::ERightSoftkeyPosition ) + { + TSize size; + if(AknLayoutUtils::PenEnabled()) + { + size = SoftkeyImageRect(*iContainer,aSoftkey.iPosition).Size(); + } + else + { + size = SoftkeyRectL( *iContainer,aSoftkey.iPosition, aSoftkey.iImageOn ).Size(); + } + + CEikImage* image( PrepareSoftkeyImageL( aSoftkey, size ) ); + TBool left(ETrue); + + if(aSoftkey.iPosition != CEikButtonGroupContainer::ELeftSoftkeyPosition) + { + left = EFalse; + } + EikSoftkeyImage::SetImage( iContainer, *image, left ); + } + else if ( aSoftkey.iBmpFile ) + { + CEikCba* cba = static_cast< CEikCba* >( iContainer->ButtonGroup() ); + // use iAvkonAppUi + CAknAppUi* appUi = static_cast( CEikonEnv::Static()->AppUi() ); + cba->UpdateMSKIconL( + aSoftkey.iId, + aSoftkey.iBmpFile->Des(), + aSoftkey.iBmp, + aSoftkey.iBmpM, + ETrue ); + } + } + +// --------------------------------------------------------------------------- +// CXnMenuAdapter::AddItemsToMenuPaneL +// --------------------------------------------------------------------------- +// +void CXnMenuAdapter::AddItemsToMenuPaneL(CEikMenuPane* aMenuPane, TInt aResourceId) + { + TInt parentIndexForNotification( 0 ); + + for ( TInt i = 0; i< iMenuItems.Count(); i++ ) + { + // find items belong to this pane + TInt parent( iMenuItems[i].iParentIndex ); + + if ( parent >= 0 ) + { + TInt cid( iMenuItems[parent].iData.iCascadeId ); + + if ( cid == aResourceId ) + { + if ( parent > 0 ) + { + parentIndexForNotification = parent; + break; + } + } + } + } + + TBool selectionEnabled( EFalse ); + TBool isRadio( EFalse ); + + if ( parentIndexForNotification != 0 ) + { + CXnNodePluginIf* node( iMenuItems[parentIndexForNotification].iNode ); + + CXnProperty* property( node->GetPropertyL( _L8( "selectiontype" ) ) ); + + if ( property && property->StringValue() == _L8( "multi" ) ) + { + selectionEnabled = ETrue; + } + else if ( property && property->StringValue() == _L8( "single" ) ) + { + selectionEnabled = ETrue; + isRadio = ETrue; + } + + node->SetStateL( XnPropertyNames::style::common::KActive ); + node->UnsetStateL( XnPropertyNames::style::common::KActive ); + } + + PopulateMenuL(); + + for ( TInt i = 0; i< iMenuItems.Count(); i++ ) + { + // find items belong to this pane + TInt parent( iMenuItems[i].iParentIndex ); + + if ( parent >= 0 ) + { + TInt cid( iMenuItems[parent].iData.iCascadeId ); + + if ( cid == aResourceId ) + { + if ( selectionEnabled ) + { + if ( !isRadio ) + { + iMenuItems[i].iData.iFlags |= + EEikMenuItemCheckBox; + } + else + { + iMenuItems[i].iData.iFlags |= + EEikMenuItemRadioStart| + EEikMenuItemRadioMiddle| + EEikMenuItemRadioEnd; + } + } + + aMenuPane->AddMenuItemL( iMenuItems[i].iData ); + + if ( selectionEnabled ) + { + CXnProperty* property( + iMenuItems[i].iNode->GetPropertyL( XnPropertyNames::menu::KChecked ) ); + + if ( property && property->StringValue() == XnPropertyNames::KTrue ) + { + aMenuPane->SetItemButtonState( + iMenuItems[i].iData.iCommandId, EEikMenuItemSymbolOn ); + } + } + } + } + } // for end + } + +// --------------------------------------------------------------------------- +// CXnMenuAdapter::AppendSoftkeyItemL +// --------------------------------------------------------------------------- +// +CXnSoftkeyItem* CXnMenuAdapter::AppendSoftkeyItemL(CXnNodePluginIf* aNode) + { + if(!aNode) + { + return NULL; + } + CXnProperty* property = + aNode->GetPropertyL( XnPropertyNames::softkey::KTypeAttribute ); + if(!property) + { + return NULL; + } + const TDesC8& skType = property->StringValue(); + if( skType != XnPropertyNames::softkey::type::KRight && + skType != XnPropertyNames::softkey::type::KLeft && + skType != XnPropertyNames::softkey::type::KMiddle ) + { + return NULL; + } + for( TInt i=0; iiNode == aNode ) + { + return iSoftkeyItems[i]; + } + } + CXnSoftkeyItem* softkey(0); + softkey = new (ELeave) CXnSoftkeyItem; + CleanupStack::PushL(softkey); + + if ( skType == XnPropertyNames::softkey::type::KRight ) + { + softkey->iPosition = CEikButtonGroupContainer::ERightSoftkeyPosition; + softkey->iCommandId = KCBACommandSecond; + } + else if ( skType == XnPropertyNames::softkey::type::KLeft ) + { + softkey->iPosition = CEikButtonGroupContainer::ELeftSoftkeyPosition; + softkey->iCommandId = KCBACommandFirst; + } + else + { + softkey->iPosition = CEikButtonGroupContainer::EMiddleSoftkeyPosition; + softkey->iCommandId = KCBACommandMiddle; + } + + softkey->iNode = aNode; + + CXnProperty* labelProp( aNode->LabelL() ); + CXnProperty* targetProp( aNode->GetPropertyL(KXnTarget) ); + + if(labelProp) + { + softkey->iImageOn = EFalse; + softkey->iLabel = labelProp->StringValueL(); + } + else if(targetProp) + { + softkey->iImageOn = EFalse; + softkey->iLabel = FindSoftkeyLabelL(aNode); + } + else + { + InitSoftkeyItemImageL( *softkey ); + } + + softkey->iUpdateAppearance = ETrue; + iSoftkeyItems.AppendL(softkey); + CleanupStack::Pop(softkey); + return softkey; + } +// --------------------------------------------------------------------------- +// CXnMenuAdapter::SoftkeyPlaceL +// --------------------------------------------------------------------------- +// +const TDesC8& CXnMenuAdapter::SoftkeyPlaceL(CXnNodePluginIf& aNode) + { + CXnProperty* property = + aNode.GetPropertyL( XnPropertyNames::softkey::KTypeAttribute ); + + if( property) + { + return property->StringValue(); + } + return KNullDesC8; + + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::FindSoftkeyItemByPosition +// +// ----------------------------------------------------------------------------- +CXnNodePluginIf* CXnMenuAdapter::FindSoftkeyItemByPosition( const TPoint& aPosition ) + { + CXnNodePluginIf* softkey(0); + TRAP_IGNORE( softkey = DoFindSoftkeyItemByPositionL( aPosition ) ); + return softkey; + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::DoFindSoftkeyItemByPositionL +// +// ----------------------------------------------------------------------------- +CXnNodePluginIf* CXnMenuAdapter::DoFindSoftkeyItemByPositionL( const TPoint& aPosition ) + { + TRect lsk( ButtonTouchableRectByPosition(CEikButtonGroupContainer::ELeftSoftkeyPosition) ); + TRect rsk( ButtonTouchableRectByPosition(CEikButtonGroupContainer::ERightSoftkeyPosition) ); + TRect msk( ButtonTouchableRectByPosition(CEikButtonGroupContainer::EMiddleSoftkeyPosition) ); + + CXnNodePluginIf* softkey(NULL); + CXnSoftkeyItem* item(NULL); + if ( lsk.Contains(aPosition) ) + { + item = SoftkeyItemL(CEikButtonGroupContainer::ELeftSoftkeyPosition); + } + else if(msk.Contains(aPosition)) + { + item = SoftkeyItemL(CEikButtonGroupContainer::EMiddleSoftkeyPosition); + } + else if( rsk.Contains(aPosition) ) + { + item = SoftkeyItemL(CEikButtonGroupContainer::ERightSoftkeyPosition); + } + if(item) + { + softkey = item->iNode; + } + return softkey; + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +CXnSoftkeyItem* CXnMenuAdapter::SoftkeyItemL(TInt aPosition) + { + CXnSoftkeyItem* softkeyItem(0); + if(iVisibleLSK && aPosition == CEikButtonGroupContainer::ELeftSoftkeyPosition) + { + return iVisibleLSK; + } + else if(iVisibleRSK && aPosition == CEikButtonGroupContainer::ERightSoftkeyPosition) + { + return iVisibleRSK; + } + else if(iVisibleMSK && aPosition == CEikButtonGroupContainer::EMiddleSoftkeyPosition) + { + return iVisibleMSK; + } + + // return default + for(TInt i=0;iiPosition == aPosition && + softkeyItem->iDefault && + IsNodeVisibleL(*softkeyItem->iNode)) + { + return softkeyItem; + } + } + return NULL; + } + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- +CXnSoftkeyItem* CXnMenuAdapter::SoftkeyItemL(CXnNodePluginIf* aNode) + { + CXnSoftkeyItem* softkeyItem(0); + for(TInt i=0;iiNode == aNode) + { + return softkeyItem; + } + } + return NULL; + } + +CXnSoftkeyItem* CXnMenuAdapter::SoftkeyItemL(CXnNodeAppIf* aNode) + { + CXnSoftkeyItem* softkeyItem(0); + for(TInt i=0;iiNode->AppIfL()) == aNode) + { + return softkeyItem; + } + } + return NULL; + } +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + +void CXnMenuAdapter::SetUpdateAppearanceL(CXnSoftkeyItem* aItem) + { + if ( aItem && IsNodeVisibleL( *aItem->iNode ) ) + { + aItem->iNode->SetDirtyL(); + + switch ( aItem->iPosition ) + { + case CEikButtonGroupContainer::ELeftSoftkeyPosition: + iUpdateLskAppearance = ETrue; + iVisibleLSK = NULL; + break; + case CEikButtonGroupContainer::EMiddleSoftkeyPosition: + iUpdateMskAppearance = ETrue; + iVisibleMSK = NULL; + break; + case CEikButtonGroupContainer::ERightSoftkeyPosition: + iUpdateRskAppearance = ETrue; + iVisibleRSK = NULL; + break; + } + } + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::FindWidgetMenuItemL +// +// ----------------------------------------------------------------------------- +CXnNodePluginIf* CXnMenuAdapter::FindWidgetMenuItemL( CXnNodePluginIf* aNode ) + { + CXnNodePluginIf* focusedNode( iUiEngine->FocusedNodeL() ); + + CXnNodePluginIf* menuItem( NULL ); + + if ( focusedNode && aNode ) + { + // Get element + CXnNodePluginIf& pluginNode( iUiEngine->PluginNodeL( focusedNode ) ); + + CXnNodePluginIf* widget( FindWidgetElementL( pluginNode ) ); + + CXnNodePluginIf* widgetExtNode( NULL ); + + if( widget ) + { + widgetExtNode = FindChildL( *widget, KXnMenuExtension ); + } + + if( !widgetExtNode ) + { + widgetExtNode = focusedNode; + } + + if ( widgetExtNode ) + { + CXnProperty* prop( aNode->GetPropertyL( KXnSource ) ); + + if ( prop ) + { + const TDesC8& source( prop->StringValue() ); + + // Try to find + menuItem = FindChildL( *widgetExtNode, + KXnMenuItem, + source ); + + if ( !menuItem ) + { + // Try to find + menuItem = FindChildL( *widgetExtNode, + KXnDynMenuItem, + source ); + } + } + } + } + + if( menuItem && IsNodeVisibleL( *menuItem ) ) + { + return menuItem; + } + + return NULL; + } + +// ----------------------------------------------------------------------------- +// CXnMenuAdapter::FindSoftkeyLabelL +// +// ----------------------------------------------------------------------------- +HBufC* CXnMenuAdapter::FindSoftkeyLabelL( CXnNodePluginIf* aNode ) + { + if( !aNode ) + { + return NULL; + } + + CXnProperty* targerProp( aNode->GetPropertyL( KXnTarget ) ); + + if ( targerProp && iRootNode ) + { + CXnNodePluginIf* widgetSoftkeyNode( + FindChildL( *iRootNode, + KXnWidgetSoftkey, + targerProp->StringValue() ) ); + + if ( widgetSoftkeyNode ) + { + CXnProperty* label( widgetSoftkeyNode->LabelL() ); + + if( label ) + { + return label->StringValueL(); + } + } + } + + return NULL;; + } + +//end of file