diff -r 000000000000 -r f72a12da539e idlehomescreen/xmluirendering/uiengine/src/xnnodeimpl.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/idlehomescreen/xmluirendering/uiengine/src/xnnodeimpl.cpp Thu Dec 17 08:40:49 2009 +0200 @@ -0,0 +1,10400 @@ +/* +* Copyright (c) 2002-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: Implementation part of bridge pattern in CXnNode +* +*/ + +// System includes +#include +#include +#include + +// User includes +#include "xnnodeimpl.h" +#include "xnnode.h" +#include "xnpropertylist.h" +#include "xnproperty.h" +#include "xnuiengine.h" +#include "xnappuiadapter.h" +#include "xncontroladapter.h" +#include "xnpopupcontroladapter.h" +#include "xnmenuadapter.h" +#include "xndomlist.h" +#include "xndomdocument.h" +#include "xnpointerarray.h" +#include "xnodt.h" +#include "xntype.h" +#include "xndomnode.h" +#include "xndomattribute.h" +#include "xndompropertyvalue.h" +#include "xnpopup.h" +#include "c_xnutils.h" +#include "xneditmode.h" +#include "xneditor.h" +#include "xntext.h" +#include "xnhittest.h" +#include "xnscrollablecontroladapter.h" +#include "xnviewdata.h" +#include "xnpanic.h" +#include "xnlistquerydialogadapter.h" +#include "xneffectmanager.h" +#include "xnviewadapter.h" + +// Local constants +_LIT8( KRef, "ref" ); +_LIT8( KId, "id" ); +_LIT8( KName, "name" ); +_LIT8( KToolTip, "tooltip" ); +_LIT8( KMenuBar, "menubar" ); + +_LIT8( KActionsHandler, "actionshandler" ); + +const TReal KS60ScrollbarDefaultWidth = 1.5; +const TReal KS60ScrollbarDefaultMargin = 0.25; +const TReal KS60ScrollbarDefaultWidthPenEnabled = 3; +const TReal KS60ScrollbarDefaultMarginPenEnabled = 0.5; +const TInt KUnitMaxLen = 2; +const TInt KOneView = 1; + +_LIT8( KPseudoClassFocus, "focus" ); +_LIT8( KPseudoClassPressedDown, "presseddown" ); +_LIT8( KPseudoClassPassiveFocus, "passivefocus" ); +_LIT8( KPseudoClassHold, "hold" ); +_LIT8( KPseudoClassHover, "hover" ); +_LIT8( KPseudoClassLink, "link" ); +_LIT8( KPseudoClassVisited, "visited" ); +_LIT8( KPseudoClassActive, "active" ); +_LIT8( KPseudoClassEdit, "edit" ); + +_LIT8( KCompound, "compound" ); +_LIT8( KTrue, "true" ); +_LIT8( KDisplay, "display" ); +_LIT8( KBlock, "block" ); +_LIT8( KNone, "none" ); +_LIT8( KGainEnd, "gainend" ); +_LIT8( KLoseEnd, "loseend" ); + +// Local classes +struct TXnTimedTrigger + { + CXnNodeImpl* iNodeImpl; + CXnUiEngine* iEngine; + CXnNode* iNode; + CXnNode* iEventData; + CXnDomNode* iActionNode; + CXnDomNode* iTriggerNode; + }; + +struct CGridPropertyCache : public CBase + { + CXnProperty* iVisibleRows; + CXnProperty* iGridColumns; + CXnProperty* iGridOrientation; + CXnProperty* iGridVerDirection; + CXnProperty* iGridHorDirection; + CXnProperty* iFocusHorLooping; + CXnProperty* iFocusVerLooping; + CXnProperty* iGridScrollBarWidth; + CXnProperty* iGridScrollBarMargin; + }; + +struct CLayoutPropertyCache : public CBase + { + CLayoutPropertyCache() : + iWidths( 1 ), + iHeights( 1 ), + iMarginLefts( 1 ), + iMarginRights( 1 ), + iBorderLefts( 1 ), + iBorderRights( 1 ), + iPaddingLefts( 1 ), + iPaddingRights( 1 ), + iMarginTops( 1 ), + iMarginBottoms( 1 ), + iBorderTops( 1 ), + iBorderBottoms( 1 ), + iPaddingTops( 1 ), + iPaddingBottoms( 1 ), + iBorderWidths( 1 ), + iBlockProgressions( 1 ), + iDirections( 1 ), + iPositions( 1 ), + iMaxHeights( 1 ), + iMinHeights( 1 ), + iMaxWidths( 1 ), + iMinWidths( 1 ), + iDisplays( 2 ), + iVisibilities( 1 ), + iLefts( 1 ), + iRights( 1 ), + iTops( 1 ), + iBottoms( 1 ), + iBorderLeftStyles( 1 ), + iBorderRightStyles( 1 ), + iBorderTopStyles( 1 ), + iBorderBottomStyles( 1 ), + iBorderStyles( 1 ), + iDisplayPriorities( 1 ), + iNavIndexes( 1 ), + iBackgroundColors( 1 ), + iBackgroundImages( 1 ), + iFocusBackgrounds( 2 ) + { + } + + ~CLayoutPropertyCache() + { + iWidths.Reset(); + iHeights.Reset(); + iMarginLefts.Reset(); + iMarginRights.Reset(); + iBorderLefts.Reset(); + iBorderRights.Reset(); + iPaddingLefts.Reset(); + iPaddingRights.Reset(); + iMarginTops.Reset(); + iMarginBottoms.Reset(); + iBorderTops.Reset(); + iBorderBottoms.Reset(); + iPaddingTops.Reset(); + iPaddingBottoms.Reset(); + iBorderWidths.Reset(); + iBlockProgressions.Reset(); + iDirections.Reset(); + iPositions.Reset(); + iMaxHeights.Reset(); + iMinHeights.Reset(); + iMaxWidths.Reset(); + iMinWidths.Reset(); + iDisplays.Reset(); + iVisibilities.Reset(); + iLefts.Reset(); + iRights.Reset(); + iTops.Reset(); + iBottoms.Reset(); + iBorderLeftStyles.Reset(); + iBorderRightStyles.Reset(); + iBorderTopStyles.Reset(); + iBorderBottomStyles.Reset(); + iBorderStyles.Reset(); + iDisplayPriorities.Reset(); + iNavIndexes.Reset(); + iBackgroundColors.Reset(); + iZIndexes.Reset(); + iBackgroundImages.Reset(); + iFocusBackgrounds.Reset(); + } + + CXnProperty* iWidth; + RPointerArray< CXnProperty > iWidths; + CXnProperty* iHeight; + RPointerArray< CXnProperty > iHeights; + CXnProperty* iMarginLeft; + RPointerArray< CXnProperty > iMarginLefts; + CXnProperty* iMarginRight; + RPointerArray< CXnProperty > iMarginRights; + CXnProperty* iBorderLeft; + RPointerArray< CXnProperty > iBorderLefts; + CXnProperty* iBorderRight; + RPointerArray< CXnProperty > iBorderRights; + CXnProperty* iPaddingLeft; + RPointerArray< CXnProperty > iPaddingLefts; + CXnProperty* iPaddingRight; + RPointerArray< CXnProperty > iPaddingRights; + CXnProperty* iMarginTop; + RPointerArray< CXnProperty > iMarginTops; + CXnProperty* iMarginBottom; + RPointerArray< CXnProperty > iMarginBottoms; + CXnProperty* iBorderTop; + RPointerArray< CXnProperty > iBorderTops; + CXnProperty* iBorderBottom; + RPointerArray< CXnProperty > iBorderBottoms; + CXnProperty* iPaddingTop; + RPointerArray< CXnProperty > iPaddingTops; + CXnProperty* iPaddingBottom; + RPointerArray< CXnProperty > iPaddingBottoms; + CXnProperty* iBorderWidth; + RPointerArray< CXnProperty > iBorderWidths; + CXnProperty* iBlockProgression; + RPointerArray< CXnProperty > iBlockProgressions; + CXnProperty* iDirection; + RPointerArray< CXnProperty > iDirections; + CXnProperty* iPosition; + RPointerArray< CXnProperty > iPositions; + CXnProperty* iMaxHeight; + RPointerArray< CXnProperty > iMaxHeights; + CXnProperty* iMinHeight; + RPointerArray< CXnProperty > iMinHeights; + CXnProperty* iMaxWidth; + RPointerArray< CXnProperty > iMaxWidths; + CXnProperty* iMinWidth; + RPointerArray< CXnProperty > iMinWidths; + CXnProperty* iDisplay; + RPointerArray< CXnProperty > iDisplays; + CXnProperty* iVisibility; + RPointerArray< CXnProperty > iVisibilities; + CXnProperty* iLeft; + RPointerArray< CXnProperty > iLefts; + CXnProperty* iRight; + RPointerArray< CXnProperty > iRights; + CXnProperty* iTop; + RPointerArray< CXnProperty > iTops; + CXnProperty* iBottom; + RPointerArray< CXnProperty > iBottoms; + CXnProperty* iBorderLeftStyle; + RPointerArray< CXnProperty > iBorderLeftStyles; + CXnProperty* iBorderRightStyle; + RPointerArray< CXnProperty > iBorderRightStyles; + CXnProperty* iBorderTopStyle; + RPointerArray< CXnProperty > iBorderTopStyles; + CXnProperty* iBorderBottomStyle; + RPointerArray< CXnProperty > iBorderBottomStyles; + CXnProperty* iBorderStyle; + RPointerArray< CXnProperty > iBorderStyles; + CXnProperty* iBorderImage; + CXnProperty* iDisplayPriority; + RPointerArray< CXnProperty > iDisplayPriorities; + CXnProperty* iNavIndex; + RPointerArray< CXnProperty > iNavIndexes; + CXnProperty* iZIndex; + RPointerArray< CXnProperty > iZIndexes; + CXnProperty* iBackgroundColor; + RPointerArray< CXnProperty > iBackgroundColors; + CXnProperty* iBackgroundImage; + RPointerArray< CXnProperty > iBackgroundImages; + CXnProperty* iFocusBackground; + RPointerArray< CXnProperty > iFocusBackgrounds; + }; + +// Local function prototypes +static TBool IsTriggerRunnableL( CXnDomNode& aTriggerNode ); +static CXnNode* RefNodeL( + CXnNodeImpl* aThis, CXnProperty* aRef, CXnUiEngine* aUiEngine ); +static const TDesC8* CheckRefAttributeL( CXnProperty* aRef ); +static TBool DoMatchTriggerForKeyEventL( + const TKeyEvent& aKeyEvent, + TEventCode aType, + CXnDomNode& aTriggerNode ); +static void GetFocusCandidatesL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnDomNode& aEventNode, + RPointerArray< CXnNode >& aFocusCandidates ); +static void RunAppUiNotificationL( CXnUiEngine& aEngine, CXnNode& aNode, + CXnDomNode& aEventNode, CXnDomNode& aTriggerNode, CXnNode& aEventData ); +static void RunAppExit( CXnUiEngine& aEngine ); +static void RunFullScreenEffectL( + CXnUiEngine& aEngine, CXnDomNode& aEventNode ); +static void RunActivateViewL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnDomNode& aEventNode ); +static void RunActivateNextViewL( CXnUiEngine& aEngine ); +static void RunActivatePreviousViewL( CXnUiEngine& aEngine ); +static void RunAddViewL( CXnUiEngine& aEngine ); +static void RunRemoveViewL( CXnUiEngine& aEngine ); +static void RunActivateL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnDomNode& aEventNode ); +static void RunDeactivateL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnDomNode& aEventNode ); +static void RunSystemSetPCDataL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, const TDesC8& aId, + const TDesC8& aData ); +static void GetNumberValues( const TDesC8& aData, TReal& aNumber, + CXnDomPropertyValue::TPrimitiveValueType& aValueType ); +static void RunSystemSetNumberL( CXnUiEngine& aEngine, CXnNode* aNode, + const TDesC8& aName, const RPointerArray< HBufC8 >& aValues ); +static void RunSystemSetRGBL( CXnUiEngine& aEngine, CXnNode* aNode, + const TDesC8& aName, const RPointerArray< HBufC8 >& aValues ); +static void RunSystemSetStringL( + CXnUiEngine& aEngine, CXnNode* aNode, const TDesC8& aName, + const RPointerArray< HBufC8 >& aValues, + const CXnDomPropertyValue::TPrimitiveValueType aValueType ); +static void GetSystemSetDataL( CXnDomNode& aDomNode, HBufC8*& aId, + const TDesC8** aPseudoClass = NULL, const TDesC8** aName = NULL, + RPointerArray< HBufC8 >* aValues = NULL, const TDesC8** aType = NULL, + TBool aSettings = EFalse, const TDesC8& aProvidedId = KNullDesC8, + const TDesC8** aClassId = NULL ); +static void RunSystemSetL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnDomNode& aEventNode, + TBool aSettings = EFalse, const TDesC8& aId = KNullDesC8 ); +static void RunTryDisplayingMenuL( + CXnUiEngine& aEngine, CXnDomNode& aEventNode ); +static void RunTryDisplayingStylusPopupL( + CXnNodeImpl* aThis, CXnNode& aNode, CXnUiEngine& aEngine, + CXnDomNode& aEventNode ); +static void RunTryDisplayingListQueryDialogL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnDomNode& aEventNode ); +static void RunSetInitialFocusL( CXnUiEngine& aEngine ); +static void ResolveTriggerDelayL( + CXnUiEngine& aEngine, CXnDomNode& aNode, TInt& aDelay ); +static TBool RunEventL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnNode& aNode, + CXnDomNode& aEventNode, CXnDomNode& aTriggerNode, CXnNode& aEventData ); +static void RunEventsL( CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnNode& aNode, + CXnDomNode& aActionNode, CXnDomNode& aTriggerNode, CXnNode& aEventData ); +static TBool DoMatchTriggerForHighLevelKeyEventL( CXnNode& aNode, + const TKeyEvent& aKeyEvent, TEventCode aType, const TDesC8& highLevelKey ); +static TBool MatchTriggerForKeyEventL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnNode& aNode, + const TKeyEvent& aKeyEvent, TEventCode aType, + CXnDomNode& aActionNode, CXnDomNode& aTriggerNode ); +static TBool MatchTriggerForEventL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnNode& aNode, + CXnNode& aEventData, CXnDomNode& aActionNode, CXnDomNode& aTriggerNode, + TInt aSource ); +static TBool MatchActionForKeyEventL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnNode& aNode, + const TKeyEvent& aKeyEvent, TEventCode aType, CXnDomNode& aActionNode ); +static TBool IsTriggerActiveL( CXnDomNode& aNode ); +static TBool MatchActionForEventL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnNode& aNode, + CXnNode& aEventData, CXnDomNode& aActionNode, TInt aSource ); +static CXnNode* FindLoopedFocusableNodeL( CXnNode& aNode, TBool aForward ); +static CXnNode* FindNextFocusableNodeByNavIndexL( CXnNode& aNode, TBool aForward ); +static TBool FindNextFocusableNodeL( CXnNode& aNode, TBool aForward ); +static CXnNode* FindNextNodeFromRightL( + RPointerArray< CXnNode >& aArray, CXnNode& aNode, TBool stayInNamespace = EFalse, CXnUiEngine* aEngine = NULL ); +static CXnNode* FindNextNodeFromLeftL( + RPointerArray< CXnNode >& aArray, CXnNode& aNode, TBool stayInNamespace = EFalse, CXnUiEngine* aEngine = NULL ); +static CXnNode* FindNextNodeFromBelowL( + RPointerArray< CXnNode >& aArray, CXnNode& aNode, TBool stayInNamespace = EFalse ); +static CXnNode* FindNextNodeFromAboveL( + RPointerArray< CXnNode >& aArray, CXnNode& aNode, TBool stayInNamespace = EFalse ); +static CXnNode* FindPluginNode( CXnNode& aNode ); +static TBool DoInternalFocusChangeL( + CXnUiEngine& aEngine, CXnNode& aNode, const TKeyEvent& aKeyEvent, + TEventCode aType ); +static TBool DoTriggerKeyEventL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnNode& aNode, + const TKeyEvent& aKeyEvent, TEventCode aType ); +static void DoTriggerEventL( + CXnNodeImpl* aThis, CXnUiEngine& aEngine, CXnNode& aNode, + CXnNode& aActionsParent, CXnNode& aEventData, TInt aSource ); +static TBool DoReceiveFocusL( CXnNode& aNode, CXnUiEngine& aEngine ); +static CXnNode* BuildActivateTriggerNodeL( CXnUiEngine& aUiEngine ); +static void DoSetActiveL( CXnNode& aNode, CXnUiEngine& aUiEngine ); +static void InformPropertyChangeL( CXnNode& aNode, CXnProperty* aProperty = NULL ); +static CXnNode* BuildEventTypeNodeL( TEventCode aType, CXnUiEngine& aUiEngine ); +static CXnNode* BuildModifiersNodeL( + const TKeyEvent& aKeyEvent, CXnUiEngine& aUiEngine ); +static CXnNode* BuildKeyCodeNodeL( + const TKeyEvent& aKeyEvent, CXnUiEngine& aUiEngine ); +static CXnNode* BuildScanCodeNodeL( + const TKeyEvent& aKeyEvent, CXnUiEngine& aUiEngine ); +static CXnNode* BuildRepeatsNodeL( + const TKeyEvent& aKeyEvent, CXnUiEngine& aUiEngine ); +static void BuildPropertyNodesL( CXnNode& aNode, const TKeyEvent& aKeyEvent, + TEventCode aType, CXnUiEngine& aUiEngine ); +static CXnNode* BuildKeyTriggerNodeL( const TKeyEvent& aKeyEvent, TEventCode aType, + CXnUiEngine& aUiEngine ); +static CXnDomPropertyValue* GetNavIndexL( CXnNode& aNode ); +static CXnNode* BackwardL( CXnNode& aNode ); +static CXnNode* ForwardL( CXnNode& aNode ); +static CXnNode* BackwardLoopL( CXnNode& aNode ); +static CXnNode* ForwardLoopL( CXnNode& aNode ); +static TInt CompareNavIndexesL( + CXnDomPropertyValue* aCurrentPropertyValue, + CXnDomPropertyValue* aNextPropertyValue ); +static void ReplaceOrAppend( + CXnProperty* aProperty, RPointerArray< CXnProperty >& aArray, + TBool aAppendOnly ); +static TBool DisplayValueMatchL( CXnNode& aNode, const TDesC8& aDisplayValue ); +static void SetStringPropertyToNodeL( + CXnDomStringPool& aStringPool, CXnNode& aNode, + const TDesC8& aPropertyName, const TDesC8& aPropertyValue ); +static void SetFloatPropertyToNodeL( + CXnDomStringPool& aStringPool, CXnNode& aNode, + const TDesC8& aPropertyName, TReal aPropertyValue, + CXnDomPropertyValue::TPrimitiveValueType aValueType ); +static CXnNode* FindYoungestSiblingWithDisplayL( + RPointerArray< CXnNode >& aSiblingArray, + const TDesC8& aDisplayValue, + TInt& aIndex ); +static CXnNode* FindOldestSiblingWithDisplayL( + RPointerArray< CXnNode >& aSiblingArray, + const TDesC8& aDisplayValue, + TInt& aIndex ); +static TBool IsCompoundNodeL( CXnNode* aNode ); +static void NotifyScrollNodeL( CXnNode* aNode, TBool aBegin, TBool aGainEnd ); +static void DoCompoundNodeBeginKeyL( + RPointerArray< CXnNode >& aChildren, CXnNode* aFocusedNode ); +static void DoCompoundNodeEndKeyL( + RPointerArray< CXnNode >& aChildren, CXnNode* aFocusedNode ); +static void DoCompoundNodeScrollingL( + CXnNode& aFocusedNode, + const TKeyEvent& aKeyEvent, + TEventCode aType ); +static CXnNode* BuildTriggerNodeL( + CXnUiEngine& aUiEngine, const TDesC8& aTriggerName ); +static CXnNode* IsNodeNavigableL( CXnNode* aParent ); +static TBool IsNodeNavigableL( CXnNode& aNode, TBool aIgnoreDropped = EFalse ); +static TInt DirtyLevelFromPropertyL( CXnNode& aNode, const TDesC8& aPropName ); +static TBool IsNodeDisplayedL( + CXnNode& aNode, TBool aCheckVisiblity = EFalse, TBool aCheckParent = ETrue ); +static void EnableStatePropertyL( + CXnNode& aNode, + CXnDomProperty::TPseudoClass aPseudoClass, + CXnProperty* ( CXnNode::* aGetCachedPropertyL )(), + CXnProperty*& aProperty, + RPointerArray< CXnProperty >& aArray, TInt& aLevel, + TBool aInformChange = EFalse ); +static void DisableStatePropertyL( + CXnNode& aNode, + CXnDomProperty::TPseudoClass aPseudoClass, + CXnProperty* ( CXnNode::* aGetCachedPropertyL )(), + CXnProperty*& aProperty, + RPointerArray< CXnProperty >& aArray, + RArray< CXnDomProperty::TPseudoClass >& aStates, TInt& aLevel, + TBool aInformChange = EFalse ); +static TBool MatchTitleScrollTriggerL( + CXnNode& aEventData, CXnDomNode& aTriggerNode ); + +// ============================= LOCAL FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// Checks whether trigger is runnable +// ----------------------------------------------------------------------------- +// +TBool IsTriggerRunnableL( CXnDomNode& aTriggerNode ) + { + TBool ret( ETrue ); + CXnNode* layoutNode = aTriggerNode.LayoutNode(); + if ( layoutNode ) + { + CXnProperty* display = + layoutNode->GetPropertyL( XnPropertyNames::style::common::KDisplay ); + + if ( display && display->StringValue() == + XnPropertyNames::style::common::display::KNone ) + { + ret = EFalse; + } + } + return ret; + } + +// ----------------------------------------------------------------------------- +// DirtyLevelFromPropertyL +// ----------------------------------------------------------------------------- +// +static TInt DirtyLevelFromPropertyL( CXnNode& aNode, const TDesC8& aPropName ) + { + if ( aPropName == XnPropertyNames::style::common::KDisplay || + aPropName == XnPropertyNames::style::common::KBlockProgression || + aPropName == XnPropertyNames::style::common::KDirection || + aPropName == XnPropertyNames::style::common::KPosition || + aPropName == XnPropertyNames::style::common::KTop || + aPropName == XnPropertyNames::style::common::KLeft || + aPropName == XnPropertyNames::style::common::KBottom || + aPropName == XnPropertyNames::style::common::KRight || + aPropName == XnPropertyNames::style::common::KWidth || + aPropName == XnPropertyNames::style::common::KHeight || + aPropName == XnPropertyNames::style::common::KMinWidth || + aPropName == XnPropertyNames::style::common::KMaxWidth || + aPropName == XnPropertyNames::style::common::KMinHeight || + aPropName == XnPropertyNames::style::common::KMaxHeight || + aPropName == XnPropertyNames::style::common::KS60DisplayPriority || + aPropName == XnPropertyNames::style::common::KMarginTop || + aPropName == XnPropertyNames::style::common::KMarginRight || + aPropName == XnPropertyNames::style::common::KMarginBottom || + aPropName == XnPropertyNames::style::common::KMarginLeft || + aPropName == XnPropertyNames::style::common::KBorderWidth || + aPropName == XnPropertyNames::style::common::KBorderTopWidth || + aPropName == XnPropertyNames::style::common::KBorderRightWidth || + aPropName == XnPropertyNames::style::common::KBorderBottomWidth || + aPropName == XnPropertyNames::style::common::KBorderLeftWidth || + aPropName == XnPropertyNames::style::common::KBorderLeftWidth || + aPropName == XnPropertyNames::style::common::KPaddingRight || + aPropName == XnPropertyNames::style::common::KPaddingBottom || + aPropName == XnPropertyNames::style::common::KPaddingLeft ) + { + TInt retval( XnDirtyLevel::ELayoutAndRenderSiblings ); + + CXnProperty* prop( aNode.PositionL() ); + + if ( prop ) + { + const TDesC8& value( prop->StringValue() ); + + if ( value == XnPropertyNames::style::common::position::KAbsolute || + value == XnPropertyNames::style::common::position::KFloating ) + { + retval = XnDirtyLevel::ELayoutAndRender; + } + } + + if ( aNode.Type()->Type() == KToolTip ) + { + retval = XnDirtyLevel::ELayoutAndRender; + } + + return retval; + } + else + { + return XnDirtyLevel::ERender; + } + } + +// ----------------------------------------------------------------------------- +// IsNodeDisplayedL +// Check whether a node is displayed or not +// ----------------------------------------------------------------------------- +// +static TBool IsNodeDisplayedL( + CXnNode& aNode, + TBool aCheckVisiblity, + TBool aCheckParent ) + { + if ( !aNode.IsLayoutCapable() ) + { + return EFalse; + } + + if ( aCheckVisiblity ) + { + CXnProperty* visibilityProp( aNode.VisibilityL() ); + + // Am I visible? + if ( visibilityProp ) + { + const TDesC8& visibility( visibilityProp->StringValue() ); + + if ( visibility != XnPropertyNames::style::common::visibility::KVisible ) + { + return EFalse; + } + } + } + + // Am I displayed? + CXnProperty* displayProp( aNode.DisplayL() ); + + if ( displayProp ) + { + const TDesC8& display( displayProp->StringValue() ); + + if ( display != XnPropertyNames::style::common::display::KBlock ) + { + return EFalse; + } + } + + if ( aCheckParent ) + { + CXnNode* parent( aNode.Parent() ); + + // Is my parent displayed? + for ( ; parent; parent = parent->Parent() ) + { + CXnProperty* displayProp( parent->DisplayL() ); + + if ( displayProp ) + { + const TDesC8& display( displayProp->StringValue() ); + + if ( display != XnPropertyNames::style::common::display::KBlock ) + { + return EFalse; + } + } + } + } + + return ETrue; + } + +// ----------------------------------------------------------------------------- +// IsNodeNavigableL +// Check whether a node or its child is navigable, ignores dropped state +// ----------------------------------------------------------------------------- +// +static CXnNode* IsNodeNavigableL( CXnNode* aParent ) + { + if ( IsNodeNavigableL( *aParent, ETrue ) ) + { + return aParent; + } + + RPointerArray< CXnNode >& children( aParent->Children() ); + + TInt count( children.Count() ); + + CXnNode* retval = NULL; + for ( TInt i = 0; i < count; i++ ) + { + retval = IsNodeNavigableL( children[i] ); + if ( retval ) + { + return retval; + } + } + + return NULL; + } + +// ----------------------------------------------------------------------------- +// IsNodeNavigableL() +// Check if node can be navigated +// ----------------------------------------------------------------------------- +// +static TBool IsNodeNavigableL( CXnNode& aNode, TBool aIgnoreDropped ) + { + if ( !aNode.IsLayoutCapable() || ( !aIgnoreDropped && aNode.IsDropped() ) ) + { + return EFalse; + } + + CXnProperty* displayProp( aNode.DisplayL() ); + + if ( displayProp ) + { + const TDesC8& display( displayProp->StringValue() ); + + if ( display != XnPropertyNames::style::common::display::KBlock ) + { + return EFalse; + } + } + + CXnProperty* visibilityProp( aNode.VisibilityL() ); + + if ( visibilityProp ) + { + const TDesC8& visibility( visibilityProp->StringValue() ); + + if ( visibility != XnPropertyNames::style::common::visibility::KVisible ) + { + return EFalse; + } + } + + CXnProperty* focusableProp( + aNode.GetPropertyL( XnPropertyNames::common::KFocusable ) ); + + if ( focusableProp ) + { + const TDesC8& focus( focusableProp->StringValue() ); + + if ( focus != XnPropertyNames::KTrue ) + { + return EFalse; + } + } + else + { + return EFalse; + } + CXnProperty* disabledProp( + aNode.GetPropertyL( XnPropertyNames::common::KDisabled ) ); + + if ( disabledProp ) + { + const TDesC8& disabled( disabledProp->StringValue() ); + + if ( disabled == XnPropertyNames::KTrue ) + { + return EFalse; + } + } + + // The node can be navigated. Then check parents display and visibilty properties + CXnNode* parent( aNode.Parent() ); + + for ( ; parent; parent = parent->Parent() ) + { + CXnProperty* displayProp( parent->DisplayL() ); + + if ( displayProp ) + { + const TDesC8& display( displayProp->StringValue() ); + + if ( display != XnPropertyNames::style::common::display::KBlock ) + { + return EFalse; + } + } + + CXnProperty* visibilityProp( parent->VisibilityL() ); + + if ( visibilityProp ) + { + const TDesC8& visibility( visibilityProp->StringValue() ); + + if ( visibility != XnPropertyNames::style::common::visibility::KVisible ) + { + return EFalse; + } + } + } + + return ETrue; + } + +// ----------------------------------------------------------------------------- +// EnableStatePropertyL() +// ----------------------------------------------------------------------------- +// +static void EnableStatePropertyL( + CXnNode& aNode, + CXnDomProperty::TPseudoClass aPseudoClass, + CXnProperty* ( CXnNode::* aGetCachedPropertyL )(), + CXnProperty*& aProperty, + RPointerArray< CXnProperty >& aArray, TInt& aLevel, + TBool aInformChange ) + { + TBool doInform( EFalse ); + + for ( TInt i = aArray.Count() - 1; i >= 0; --i ) + { + if ( aArray[i]->Property()->PseudoClass() == aPseudoClass ) + { + CXnProperty* temp( aArray[i] ); + + if ( aLevel < XnDirtyLevel::ELayoutAndRenderSiblings || + aInformChange ) + { + TInt level( XnDirtyLevel::ENone ); + + // Get current cached prop + CXnProperty* prop( ( aNode.*aGetCachedPropertyL )() ); + + if ( !temp && prop ) + { + level = DirtyLevelFromPropertyL( + aNode, prop->Property()->Name() ); + } + else if ( ( temp && !prop ) || + ( temp && prop && !prop->EqualsL( *temp ) ) ) + { + level = DirtyLevelFromPropertyL( + aNode, temp->Property()->Name() ); + } + + if ( aInformChange && ( level != XnDirtyLevel::ENone ) ) + { + doInform = ETrue; + } + + if ( level > aLevel && aNode.IsLayoutCapable()) + { + aLevel = level; + } + } + + aProperty = temp; + + if ( doInform ) + { + // Property is changed + InformPropertyChangeL( aNode, temp ); + } + + break; + } + } + } + +// ----------------------------------------------------------------------------- +// DisableStatePropertyL() +// ----------------------------------------------------------------------------- +// +static void DisableStatePropertyL( + CXnNode& aNode, + CXnDomProperty::TPseudoClass aPseudoClass, + CXnProperty* ( CXnNode::* aGetCachedPropertyL )(), + CXnProperty*& aProperty, + RPointerArray< CXnProperty >& aArray, + RArray< CXnDomProperty::TPseudoClass >& aStates, TInt& aLevel, + TBool aInformChange ) + { + CXnProperty* currentStateProperty( NULL ); + + TBool doInform( EFalse ); + + if ( aProperty && aProperty->Property()->PseudoClass() == aPseudoClass ) + { + // Is there an other pseudo state where to return? + for ( TInt i = aArray.Count() - 1; !currentStateProperty && i >= 0; --i ) + { + for ( TInt j = aStates.Count() - 1; j >= 0; --j ) + { + if ( aArray[i]->Property()->PseudoClass() == aStates[j] && + aArray[i]->Property()->PseudoClass() != aPseudoClass ) + { + currentStateProperty = aArray[i]; + break; + } + } + } + + // No, use the property from state "none" + for ( TInt i = aArray.Count() - 1; !currentStateProperty && i >= 0; --i ) + { + for ( TInt j = aStates.Count() - 1; j >= 0; --j ) + { + if ( aArray[i]->Property()->PseudoClass() == CXnDomProperty::ENone && + aArray[i]->Property()->PseudoClass() != aPseudoClass ) + { + currentStateProperty = aArray[i]; + break; + } + } + } + + CXnProperty* temp( currentStateProperty ); + + if ( aLevel < XnDirtyLevel::ELayoutAndRenderSiblings || aInformChange ) + { + TInt level( XnDirtyLevel::ENone ); + + // Get current cached prop + CXnProperty* prop( ( aNode.*aGetCachedPropertyL )() ); + + if ( !temp && prop ) + { + level = DirtyLevelFromPropertyL( aNode, prop->Property()->Name() ); + } + else if ( ( temp && !prop ) || ( temp && prop && !prop->EqualsL( *temp ) ) ) + { + level = DirtyLevelFromPropertyL( aNode, temp->Property()->Name() ); + } + + if ( aInformChange && ( level != XnDirtyLevel::ENone ) ) + { + doInform = ETrue; + } + + if ( level > aLevel && aNode.IsLayoutCapable()) + { + aLevel = level; + } + } + + aProperty = temp; + + if ( doInform ) + { + // Property is changed + InformPropertyChangeL( aNode, temp ); + } + } + } + +// ----------------------------------------------------------------------------- +// EnableStatePropertiesL() +// ----------------------------------------------------------------------------- +// +static void EnableStatePropertiesL( + CXnNode& aNode, + CXnDomProperty::TPseudoClass aPseudoClass, + CLayoutPropertyCache*& aLayoutPropertyCache ) + { + if ( !aLayoutPropertyCache ) + { + aLayoutPropertyCache = new ( ELeave ) CLayoutPropertyCache; + } + + TInt level( XnDirtyLevel::ENone ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::WidthL, + aLayoutPropertyCache->iWidth, + aLayoutPropertyCache->iWidths, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::HeightL, + aLayoutPropertyCache->iHeight, + aLayoutPropertyCache->iHeights, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::MarginLeftL, + aLayoutPropertyCache->iMarginLeft, + aLayoutPropertyCache->iMarginLefts, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::MarginRightL, + aLayoutPropertyCache->iMarginRight, + aLayoutPropertyCache->iMarginRights, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderLeftL, + aLayoutPropertyCache->iBorderLeft, + aLayoutPropertyCache->iBorderLefts, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderRightL, + aLayoutPropertyCache->iBorderRight, + aLayoutPropertyCache->iBorderRights, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::PaddingLeftL, + aLayoutPropertyCache->iPaddingLeft, + aLayoutPropertyCache->iPaddingLefts, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::PaddingRightL, + aLayoutPropertyCache->iPaddingRight, + aLayoutPropertyCache->iPaddingRights, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::MarginTopL, + aLayoutPropertyCache->iMarginTop, + aLayoutPropertyCache->iMarginTops, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::MarginBottomL, + aLayoutPropertyCache->iMarginBottom, + aLayoutPropertyCache->iMarginBottoms, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderTopL, + aLayoutPropertyCache->iBorderTop, + aLayoutPropertyCache->iBorderTops, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderBottomL, + aLayoutPropertyCache->iBorderBottom, + aLayoutPropertyCache->iBorderBottoms, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::PaddingTopL, + aLayoutPropertyCache->iPaddingTop, + aLayoutPropertyCache->iPaddingTops, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::PaddingBottomL, + aLayoutPropertyCache->iPaddingBottom, + aLayoutPropertyCache->iPaddingBottoms, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderWidthL, + aLayoutPropertyCache->iBorderWidth, + aLayoutPropertyCache->iBorderWidths, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BlockProgressionL, + aLayoutPropertyCache->iBlockProgression, + aLayoutPropertyCache->iBlockProgressions, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::DirectionL, + aLayoutPropertyCache->iDirection, + aLayoutPropertyCache->iDirections, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::PositionL, + aLayoutPropertyCache->iPosition, + aLayoutPropertyCache->iPositions, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::MaxHeightL, + aLayoutPropertyCache->iMaxHeight, + aLayoutPropertyCache->iMaxHeights, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::MinHeightL, + aLayoutPropertyCache->iMinHeight, + aLayoutPropertyCache->iMinHeights, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::MaxWidthL, + aLayoutPropertyCache->iMaxWidth, + aLayoutPropertyCache->iMaxWidths, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::MinWidthL, + aLayoutPropertyCache->iMinWidth, + aLayoutPropertyCache->iMinWidths, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::DisplayL, + aLayoutPropertyCache->iDisplay, + aLayoutPropertyCache->iDisplays, level, ETrue ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::VisibilityL, + aLayoutPropertyCache->iVisibility, + aLayoutPropertyCache->iVisibilities, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::LeftL, + aLayoutPropertyCache->iLeft, + aLayoutPropertyCache->iLefts, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::RightL, + aLayoutPropertyCache->iRight, + aLayoutPropertyCache->iRights, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::TopL, + aLayoutPropertyCache->iTop, + aLayoutPropertyCache->iTops, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BottomL, + aLayoutPropertyCache->iBottom, + aLayoutPropertyCache->iBottoms, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderLeftStyleL, + aLayoutPropertyCache->iBorderLeftStyle, + aLayoutPropertyCache->iBorderLeftStyles, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderRightStyleL, + aLayoutPropertyCache->iBorderRightStyle, + aLayoutPropertyCache->iBorderRightStyles, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderTopStyleL, + aLayoutPropertyCache->iBorderTopStyle, + aLayoutPropertyCache->iBorderTopStyles, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderBottomStyleL, + aLayoutPropertyCache->iBorderBottomStyle, + aLayoutPropertyCache->iBorderBottomStyles, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderStyleL, + aLayoutPropertyCache->iBorderStyle, + aLayoutPropertyCache->iBorderStyles, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::DisplayPriorityL, + aLayoutPropertyCache->iDisplayPriority, + aLayoutPropertyCache->iDisplayPriorities, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::NavIndexL, + aLayoutPropertyCache->iNavIndex, + aLayoutPropertyCache->iNavIndexes, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::ZIndexL, + aLayoutPropertyCache->iZIndex, + aLayoutPropertyCache->iZIndexes, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BackgroundColorL, + aLayoutPropertyCache->iBackgroundColor, + aLayoutPropertyCache->iBackgroundColors, level ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::BackgroundImageL, + aLayoutPropertyCache->iBackgroundImage, + aLayoutPropertyCache->iBackgroundImages, level, ETrue ); + + EnableStatePropertyL( + aNode, aPseudoClass, CXnNode::FocusBackgroundL, + aLayoutPropertyCache->iFocusBackground, + aLayoutPropertyCache->iFocusBackgrounds, level ); + + aNode.SetDirtyL( level ); + } + +// ----------------------------------------------------------------------------- +// DisableStatePropertiesL() +// ----------------------------------------------------------------------------- +// +static void DisableStatePropertiesL( + CXnNode& aNode, + CXnDomProperty::TPseudoClass aPseudoClass, + RArray< CXnDomProperty::TPseudoClass >& aStates, + CLayoutPropertyCache*& aLayoutPropertyCache ) + { + if ( !aLayoutPropertyCache ) + { + aLayoutPropertyCache = new ( ELeave ) CLayoutPropertyCache; + } + + TInt level( XnDirtyLevel::ENone ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::WidthL, + aLayoutPropertyCache->iWidth, + aLayoutPropertyCache->iWidths, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::HeightL, + aLayoutPropertyCache->iHeight, + aLayoutPropertyCache->iHeights, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::MarginLeftL, + aLayoutPropertyCache->iMarginLeft, + aLayoutPropertyCache->iMarginLefts, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::MarginRightL, + aLayoutPropertyCache->iMarginRight, + aLayoutPropertyCache->iMarginRights, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderLeftL, + aLayoutPropertyCache->iBorderLeft, + aLayoutPropertyCache->iBorderLefts, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderRightL, + aLayoutPropertyCache->iBorderRight, + aLayoutPropertyCache->iBorderRights, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::PaddingLeftL, + aLayoutPropertyCache->iPaddingLeft, + aLayoutPropertyCache->iPaddingLefts, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::PaddingRightL, + aLayoutPropertyCache->iPaddingRight, + aLayoutPropertyCache->iPaddingRights, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::MarginTopL, + aLayoutPropertyCache->iMarginTop, + aLayoutPropertyCache->iMarginTops, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::MarginBottomL, + aLayoutPropertyCache->iMarginBottom, + aLayoutPropertyCache->iMarginBottoms, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderTopL, + aLayoutPropertyCache->iBorderTop, + aLayoutPropertyCache->iBorderTops, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderBottomL, + aLayoutPropertyCache->iBorderBottom, + aLayoutPropertyCache->iBorderBottoms, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::PaddingTopL, + aLayoutPropertyCache->iPaddingTop, + aLayoutPropertyCache->iPaddingTops, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::PaddingBottomL, + aLayoutPropertyCache->iPaddingBottom, + aLayoutPropertyCache->iPaddingBottoms, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderWidthL, + aLayoutPropertyCache->iBorderWidth, + aLayoutPropertyCache->iBorderWidths, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BlockProgressionL, + aLayoutPropertyCache->iBlockProgression, + aLayoutPropertyCache->iBlockProgressions, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::DirectionL, + aLayoutPropertyCache->iDirection, + aLayoutPropertyCache->iDirections, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::PositionL, + aLayoutPropertyCache->iPosition, + aLayoutPropertyCache->iPositions, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::MaxHeightL, + aLayoutPropertyCache->iMaxHeight, + aLayoutPropertyCache->iMaxHeights, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::MinHeightL, + aLayoutPropertyCache->iMinHeight, + aLayoutPropertyCache->iMinHeights, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::MaxWidthL, + aLayoutPropertyCache->iMaxWidth, + aLayoutPropertyCache->iMaxWidths, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::MinWidthL, + aLayoutPropertyCache->iMinWidth, + aLayoutPropertyCache->iMinWidths, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::DisplayL, + aLayoutPropertyCache->iDisplay, + aLayoutPropertyCache->iDisplays, aStates, level, ETrue ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::VisibilityL, + aLayoutPropertyCache->iVisibility, + aLayoutPropertyCache->iVisibilities, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::LeftL, + aLayoutPropertyCache->iLeft, + aLayoutPropertyCache->iLefts, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::RightL, + aLayoutPropertyCache->iRight, + aLayoutPropertyCache->iRights, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::TopL, + aLayoutPropertyCache->iTop, + aLayoutPropertyCache->iTops, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BottomL, + aLayoutPropertyCache->iBottom, + aLayoutPropertyCache->iBottoms, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderLeftStyleL, + aLayoutPropertyCache->iBorderLeftStyle, + aLayoutPropertyCache->iBorderLeftStyles, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderRightStyleL, + aLayoutPropertyCache->iBorderRightStyle, + aLayoutPropertyCache->iBorderRightStyles, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderTopStyleL, + aLayoutPropertyCache->iBorderTopStyle, + aLayoutPropertyCache->iBorderTopStyles, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderBottomStyleL, + aLayoutPropertyCache->iBorderBottomStyle, + aLayoutPropertyCache->iBorderBottomStyles, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BorderStyleL, + aLayoutPropertyCache->iBorderStyle, + aLayoutPropertyCache->iBorderStyles, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::DisplayPriorityL, + aLayoutPropertyCache->iDisplayPriority, + aLayoutPropertyCache->iDisplayPriorities, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::NavIndexL, + aLayoutPropertyCache->iNavIndex, + aLayoutPropertyCache->iNavIndexes, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::ZIndexL, + aLayoutPropertyCache->iZIndex, + aLayoutPropertyCache->iZIndexes, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BackgroundColorL, + aLayoutPropertyCache->iBackgroundColor, + aLayoutPropertyCache->iBackgroundColors, aStates, level ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::BackgroundImageL, + aLayoutPropertyCache->iBackgroundImage, + aLayoutPropertyCache->iBackgroundImages, aStates, level, ETrue ); + + DisableStatePropertyL( + aNode, aPseudoClass, CXnNode::FocusBackgroundL, + aLayoutPropertyCache->iFocusBackground, + aLayoutPropertyCache->iFocusBackgrounds, aStates, level ); + + aNode.SetDirtyL( level ); + } + +// ----------------------------------------------------------------------------- +// AllocateLayoutCache() +// ----------------------------------------------------------------------------- +// +static TBool AllocateLayoutCache( CLayoutPropertyCache*& aLayoutPropertyCache ) + { + if ( !aLayoutPropertyCache ) + { + aLayoutPropertyCache = new CLayoutPropertyCache; + } + + return aLayoutPropertyCache ? ETrue : EFalse; + } + +// ----------------------------------------------------------------------------- +// DoSetCachedProperty() +// ----------------------------------------------------------------------------- +// +static void DoSetCachedProperty( + CXnProperty* aProperty,\ + CXnProperty*& aCachedPropertyToSet, + RPointerArray< CXnProperty >& aArray, + TBool aInitializing, + TBool aArrayOnly ) + { + ReplaceOrAppend( aProperty, aArray, aInitializing ); + + if ( !aArrayOnly ) + { + aCachedPropertyToSet = aProperty; + } + } + +// ----------------------------------------------------------------------------- +// SetCachedProperty() +// ----------------------------------------------------------------------------- +// +static void SetCachedProperty( + CXnProperty* aProperty, + CLayoutPropertyCache*& aLayoutPropertyCache, + CXnProperty*& aRef, + CXnProperty*& aName, + CXnProperty*& aValue, + CXnProperty*& aLabel, + CXnProperty*& aInitialFocus, + CXnProperty*& aClass, + CXnProperty*& aId, + CXnProperty*& aPath, + CXnProperty*& aMaskPath, + CGridPropertyCache*& aGridPropertyCache, + TBool aInitializing, + TBool aArrayOnly) + { + const TDesC8& name = aProperty->Property()->Name(); + if ( !AllocateLayoutCache( aLayoutPropertyCache ) ) + { + return; + } + if ( name == XnPropertyNames::common::KId ) + { + aId = aProperty; + } + else if ( name == XnPropertyNames::common::KClass ) + { + aClass = aProperty; + } + else if ( name == XnPropertyNames::style::common::KWidth ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iWidth, + aLayoutPropertyCache->iWidths, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KHeight ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iHeight, + aLayoutPropertyCache->iHeights, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KBlockProgression ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBlockProgression, + aLayoutPropertyCache->iBlockProgressions, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KDirection ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iDirection, + aLayoutPropertyCache->iDirections, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KPosition ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iPosition, + aLayoutPropertyCache->iPositions, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KDisplay ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iDisplay, + aLayoutPropertyCache->iDisplays, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KVisibility ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iVisibility, + aLayoutPropertyCache->iVisibilities, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::action::KName ) + { + aName = aProperty; + } + else if ( name == XnPropertyNames::action::KValue ) + { + aValue = aProperty; + } + else if ( name == XnPropertyNames::menu::KLabel ) + { + aLabel = aProperty; + } + else if ( name == XnPropertyNames::image::KPath ) + { + aPath = aProperty; + } + else if ( name == XnPropertyNames::image::KMaskPath ) + { + aMaskPath = aProperty; + } + else if ( name == KRef ) + { + aRef = aProperty; + } + else if ( name == XnPropertyNames::style::common::KMarginLeft ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iMarginLeft, + aLayoutPropertyCache->iMarginLefts, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KMarginRight ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iMarginRight, + aLayoutPropertyCache->iMarginRights, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KBorderLeftWidth ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBorderLeft, + aLayoutPropertyCache->iBorderLefts, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KBorderRightWidth ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBorderRight, + aLayoutPropertyCache->iBorderRights, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KPaddingLeft ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iPaddingLeft, + aLayoutPropertyCache->iPaddingLefts, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KPaddingRight ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iPaddingRight, + aLayoutPropertyCache->iPaddingRights, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KMarginTop ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iMarginTop, + aLayoutPropertyCache->iMarginTops, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KMarginBottom ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iMarginBottom, + aLayoutPropertyCache->iMarginBottoms, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KBorderTopWidth ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBorderTop, + aLayoutPropertyCache->iBorderTops, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KBorderBottomWidth ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBorderBottom, + aLayoutPropertyCache->iBorderBottoms, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KPaddingTop ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iPaddingTop, + aLayoutPropertyCache->iPaddingTops, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KPaddingBottom ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iPaddingBottom, + aLayoutPropertyCache->iPaddingBottoms, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KBorderWidth ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBorderWidth, + aLayoutPropertyCache->iBorderWidths, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KMaxHeight ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iMaxHeight, + aLayoutPropertyCache->iMaxHeights, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KMinHeight ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iMinHeight, + aLayoutPropertyCache->iMinHeights, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KMaxWidth ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iMaxWidth, + aLayoutPropertyCache->iMaxWidths, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KMinWidth ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iMinWidth, + aLayoutPropertyCache->iMinWidths, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KLeft ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iLeft, + aLayoutPropertyCache->iLefts, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KRight ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iRight, + aLayoutPropertyCache->iRights, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KTop ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iTop, + aLayoutPropertyCache->iTops, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KBottom ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBottom, + aLayoutPropertyCache->iBottoms, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::appearance::common::KBorderLeftStyle ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBorderLeftStyle, + aLayoutPropertyCache->iBorderLeftStyles, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::appearance::common::KBorderRightStyle ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBorderRightStyle, + aLayoutPropertyCache->iBorderRightStyles, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::appearance::common::KBorderTopStyle ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBorderTopStyle, + aLayoutPropertyCache->iBorderTopStyles, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::appearance::common::KBorderBottomStyle ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBorderBottomStyle, + aLayoutPropertyCache->iBorderBottomStyles, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::appearance::common::KBorderStyle ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBorderStyle, + aLayoutPropertyCache->iBorderStyles, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::appearance::common::KBorderImage ) + { + aLayoutPropertyCache->iBorderImage = aProperty; + } + else if ( name == XnPropertyNames::style::common::KZIndex ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iZIndex, + aLayoutPropertyCache->iZIndexes, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::appearance::common::KBackGroundColor ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBackgroundColor, + aLayoutPropertyCache->iBackgroundColors, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::appearance::common::KBackGroundImage ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iBackgroundImage, + aLayoutPropertyCache->iBackgroundImages, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::appearance::common::KFocusBackground ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iFocusBackground, + aLayoutPropertyCache->iFocusBackgrounds, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::style::common::KS60DisplayPriority ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iDisplayPriority, + aLayoutPropertyCache->iDisplayPriorities, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::common::KInitialFocus ) + { + aInitialFocus = aProperty; + } + else if ( name == XnPropertyNames::style::common::KNavIndex ) + { + DoSetCachedProperty( + aProperty, + aLayoutPropertyCache->iNavIndex, + aLayoutPropertyCache->iNavIndexes, + aInitializing, aArrayOnly ); + } + else if ( name == XnPropertyNames::grid::KS60VisibleRows ) + { + if ( !aGridPropertyCache ) + { + aGridPropertyCache = new CGridPropertyCache; + } + if ( aGridPropertyCache ) + { + aGridPropertyCache->iVisibleRows = aProperty; + } + } + else if ( name == XnPropertyNames::grid::KS60GridColumns ) + { + if ( !aGridPropertyCache ) + { + aGridPropertyCache = new CGridPropertyCache; + } + if ( aGridPropertyCache ) + { + aGridPropertyCache->iGridColumns = aProperty; + } + } + else if ( name == XnPropertyNames::grid::KS60GridOrientation ) + { + if ( !aGridPropertyCache ) + { + aGridPropertyCache = new CGridPropertyCache; + } + if ( aGridPropertyCache ) + { + aGridPropertyCache->iGridOrientation = aProperty; + } + } + else if ( name == XnPropertyNames::grid::KS60GridVerDirection ) + { + if ( !aGridPropertyCache ) + { + aGridPropertyCache = new CGridPropertyCache; + } + if ( aGridPropertyCache ) + { + aGridPropertyCache->iGridVerDirection = aProperty; + } + } + else if ( name == XnPropertyNames::grid::KS60GridHorDirection ) + { + if ( !aGridPropertyCache ) + { + aGridPropertyCache = new CGridPropertyCache; + } + if ( aGridPropertyCache ) + { + aGridPropertyCache->iGridHorDirection = aProperty; + } + } + else if ( name == XnPropertyNames::grid::KS60FocusHorLooping ) + { + if ( !aGridPropertyCache ) + { + aGridPropertyCache = new CGridPropertyCache; + } + if ( aGridPropertyCache ) + { + aGridPropertyCache->iFocusHorLooping = aProperty; + } + } + else if ( name == XnPropertyNames::grid::KS60FocusVerLooping ) + { + if ( !aGridPropertyCache ) + { + aGridPropertyCache = new CGridPropertyCache; + } + if ( aGridPropertyCache ) + { + aGridPropertyCache->iFocusVerLooping = aProperty; + } + } + else if ( name == XnPropertyNames::grid::KS60GridScrollbarWidth ) + { + if ( !aGridPropertyCache ) + { + aGridPropertyCache = new CGridPropertyCache; + } + if ( aGridPropertyCache ) + { + aGridPropertyCache->iGridScrollBarWidth = aProperty; + } + } + else if ( name == XnPropertyNames::grid::KS60GridScrollbarMargin ) + { + if ( !aGridPropertyCache ) + { + aGridPropertyCache = new CGridPropertyCache; + } + if ( aGridPropertyCache ) + { + aGridPropertyCache->iGridScrollBarMargin = aProperty; + } + } + } + +// ----------------------------------------------------------------------------- +// ReplaceOrAppend() +// ----------------------------------------------------------------------------- +// +static void ReplaceOrAppend( + CXnProperty* aProperty, + RPointerArray< CXnProperty >& aArray, + TBool aAppendOnly ) + { + if ( !aAppendOnly ) + { + for ( TInt i = aArray.Count() - 1; i >= 0; --i ) + { + if ( aArray[i] == aProperty ) + { + aArray.Remove( i ); + } + else if ( aArray[i]->Property()->PseudoClass() == + aProperty->Property()->PseudoClass() && + aArray[i]->Property()->Name() == + aProperty->Property()->Name() ) + { + aArray.Remove( i ); + } + } + } + aArray.Append( aProperty ); + } + +// ----------------------------------------------------------------------------- +// IsPropertyPseudoClass() +// ----------------------------------------------------------------------------- +// +static TBool IsPropertyPseudoClass( + CXnDomProperty::TPseudoClass aPseudoClass, + RArray< CXnDomProperty::TPseudoClass >& aArray ) + { + for ( TInt i = aArray.Count() - 1; i >= 0; --i ) + { + if ( aArray[i] == aPseudoClass ) + { + return ETrue; + } + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// InsertPropertyPseudoClassL() +// ----------------------------------------------------------------------------- +// +static void InsertPropertyPseudoClassL( + CXnDomProperty::TPseudoClass aPseudoClass, + RArray< CXnDomProperty::TPseudoClass >& aArray ) + { + if ( !IsPropertyPseudoClass( aPseudoClass, aArray ) ) + { + User::LeaveIfError( aArray.Append( aPseudoClass ) ); + } + } + +// ----------------------------------------------------------------------------- +// BuildEventTypeNodeL +// ----------------------------------------------------------------------------- +// +static CXnNode* BuildEventTypeNodeL( TEventCode aType, CXnUiEngine& aUiEngine ) + { + CXnNode* node = CXnNode::NewL(); + CleanupStack::PushL( node ); + CXnType* type = CXnType::NewL( XnPropertyNames::action::KProperty ); + CleanupStack::PushL( type ); + CXnNodeImpl* impl = CXnNodeImpl::NewL( type ); + CleanupStack::Pop( type ); + node->SetImpl( impl ); + node->SetUiEngine( aUiEngine ); + CXnDomPropertyValue* nameValue = CXnDomPropertyValue::NewL( + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::PushL( nameValue ); + nameValue->SetStringValueL( + CXnDomPropertyValue::EString, + XnPropertyNames::action::trigger::name::keyevent::KEventType ); + CXnProperty* name = CXnProperty::NewL( + XnPropertyNames::action::KName, + nameValue, aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::Pop( nameValue ); + CleanupStack::PushL( name ); + node->SetPropertyL( name ); + CleanupStack::Pop( name ); + CXnDomPropertyValue* valueValue = CXnDomPropertyValue::NewL( + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::PushL( valueValue ); + valueValue->SetFloatValueL( CXnDomPropertyValue::ENumber, aType ); + CXnProperty* value = CXnProperty::NewL( + XnPropertyNames::action::KValue, valueValue, + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::Pop( valueValue ); + CleanupStack::PushL( value ); + node->SetPropertyL( value ); + CleanupStack::Pop( value ); + CleanupStack::Pop( node ); + return node; + } + +// ----------------------------------------------------------------------------- +// BuildModifiersNodeL +// ----------------------------------------------------------------------------- +// +static CXnNode* BuildModifiersNodeL( + const TKeyEvent& aKeyEvent, + CXnUiEngine& aUiEngine ) + { + CXnNode* node = CXnNode::NewL(); + CleanupStack::PushL( node ); + CXnType* type = CXnType::NewL( XnPropertyNames::action::KProperty ); + CleanupStack::PushL( type ); + CXnNodeImpl* impl = CXnNodeImpl::NewL( type ); + CleanupStack::Pop( type ); + node->SetImpl( impl ); + node->SetUiEngine( aUiEngine ); + CXnDomPropertyValue* nameValue = CXnDomPropertyValue::NewL( + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::PushL( nameValue ); + nameValue->SetStringValueL( + CXnDomPropertyValue::EString, + XnPropertyNames::action::trigger::name::keyevent::KModifiers ); + CXnProperty* name = CXnProperty::NewL( + XnPropertyNames::action::KName, + nameValue, + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::Pop( nameValue ); + CleanupStack::PushL( name ); + node->SetPropertyL( name ); + CleanupStack::Pop( name ); + CXnDomPropertyValue* valueValue = CXnDomPropertyValue::NewL( + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::PushL( valueValue ); + valueValue->SetFloatValueL( + CXnDomPropertyValue::ENumber, aKeyEvent.iModifiers ); + CXnProperty* value = CXnProperty::NewL( + XnPropertyNames::action::KValue, + valueValue, + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::Pop( valueValue ); + CleanupStack::PushL( value ); + node->SetPropertyL( value ); + CleanupStack::Pop( value ); + CleanupStack::Pop( node ); + return node; + } + +// ----------------------------------------------------------------------------- +// BuildKeyCodeNodeL +// ----------------------------------------------------------------------------- +// +static CXnNode* BuildKeyCodeNodeL( + const TKeyEvent& aKeyEvent, + CXnUiEngine& aUiEngine ) + { + CXnNode* node = CXnNode::NewL(); + CleanupStack::PushL( node ); + CXnType* type = CXnType::NewL( XnPropertyNames::action::KProperty ); + CleanupStack::PushL( type ); + CXnNodeImpl* impl = CXnNodeImpl::NewL( type ); + CleanupStack::Pop( type ); + node->SetImpl( impl ); + node->SetUiEngine( aUiEngine ); + CXnDomPropertyValue* nameValue = CXnDomPropertyValue::NewL( + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::PushL( nameValue ); + nameValue->SetStringValueL( + CXnDomPropertyValue::EString, + XnPropertyNames::action::trigger::name::keyevent::KKeyCode ); + CXnProperty* name = CXnProperty::NewL( + XnPropertyNames::action::KName, + nameValue, + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::Pop( nameValue ); + CleanupStack::PushL( name ); + node->SetPropertyL( name ); + CleanupStack::Pop( name ); + CXnDomPropertyValue* valueValue = CXnDomPropertyValue::NewL( + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::PushL( valueValue ); + valueValue->SetFloatValueL( CXnDomPropertyValue::ENumber, aKeyEvent.iCode ); + CXnProperty* value = CXnProperty::NewL( + XnPropertyNames::action::KValue, + valueValue, + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::Pop( valueValue ); + CleanupStack::PushL( value ); + node->SetPropertyL( value ); + CleanupStack::Pop( value ); + CleanupStack::Pop( node ); + return node; + } + +// ----------------------------------------------------------------------------- +// BuildScanCodeNodeL +// ----------------------------------------------------------------------------- +// +static CXnNode* BuildScanCodeNodeL( + const TKeyEvent& aKeyEvent, + CXnUiEngine& aUiEngine ) + { + CXnNode* node = CXnNode::NewL(); + CleanupStack::PushL( node ); + CXnType* type = CXnType::NewL( XnPropertyNames::action::KProperty ); + CleanupStack::PushL( type ); + CXnNodeImpl* impl = CXnNodeImpl::NewL( type ); + CleanupStack::Pop( type ); + node->SetImpl( impl ); + node->SetUiEngine( aUiEngine ); + CXnDomPropertyValue* nameValue = CXnDomPropertyValue::NewL( + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::PushL( nameValue ); + nameValue->SetStringValueL( + CXnDomPropertyValue::EString, + XnPropertyNames::action::trigger::name::keyevent::KScanCode ); + CXnProperty* name = CXnProperty::NewL( + XnPropertyNames::action::KName, + nameValue, + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::Pop( nameValue ); + CleanupStack::PushL( name ); + node->SetPropertyL( name ); + CleanupStack::Pop( name ); + CXnDomPropertyValue* valueValue = CXnDomPropertyValue::NewL( + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::PushL( valueValue ); + valueValue->SetFloatValueL( + CXnDomPropertyValue::ENumber, aKeyEvent.iScanCode ); + CXnProperty* value = CXnProperty::NewL( + XnPropertyNames::action::KValue, + valueValue, + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::Pop( valueValue ); + CleanupStack::PushL( value ); + node->SetPropertyL( value ); + CleanupStack::Pop( value ); + CleanupStack::Pop( node ); + return node; + } + +// ----------------------------------------------------------------------------- +// BuildRepeatsNodeL +// ----------------------------------------------------------------------------- +// +static CXnNode* BuildRepeatsNodeL( + const TKeyEvent& aKeyEvent, + CXnUiEngine& aUiEngine ) + { + CXnNode* node = CXnNode::NewL(); + CleanupStack::PushL( node ); + CXnType* type = CXnType::NewL( XnPropertyNames::action::KProperty ); + CleanupStack::PushL( type ); + CXnNodeImpl* impl = CXnNodeImpl::NewL( type ); + CleanupStack::Pop( type ); + node->SetImpl( impl ); + node->SetUiEngine( aUiEngine ); + CXnDomPropertyValue* nameValue = CXnDomPropertyValue::NewL( + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::PushL( nameValue ); + nameValue->SetStringValueL( + CXnDomPropertyValue::EString, + XnPropertyNames::action::trigger::name::keyevent::KRepeats ); + CXnProperty* name = CXnProperty::NewL( + XnPropertyNames::action::KName, + nameValue, + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::Pop( nameValue ); + CleanupStack::PushL( name ); + node->SetPropertyL( name ); + CleanupStack::Pop( name ); + CXnDomPropertyValue* valueValue = CXnDomPropertyValue::NewL( + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::PushL( valueValue ); + valueValue->SetFloatValueL( + CXnDomPropertyValue::ENumber, aKeyEvent.iRepeats ); + CXnProperty* value = CXnProperty::NewL( + XnPropertyNames::action::KValue, + valueValue, + aUiEngine.ODT()->DomDocument().StringPool()) ; + CleanupStack::Pop( valueValue ); + CleanupStack::PushL( value ); + node->SetPropertyL( value ); + CleanupStack::Pop( value ); + CleanupStack::Pop( node ); + return node; + } + +// ----------------------------------------------------------------------------- +// BuildActivateTriggerNodeL +// ----------------------------------------------------------------------------- +// +static CXnNode* BuildActivateTriggerNodeL( CXnUiEngine& aUiEngine ) + { + CXnNode* node = CXnNode::NewL(); + CleanupStack::PushL( node ); + CXnType* type = CXnType::NewL( XnPropertyNames::action::KTrigger ); + CleanupStack::PushL( type ); + CXnNodeImpl* impl = CXnNodeImpl::NewL( type ); + CleanupStack::Pop( type ); + node->SetImpl( impl ); + node->SetUiEngine( aUiEngine ); + CXnDomPropertyValue* nameValue = CXnDomPropertyValue::NewL( + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::PushL( nameValue ); + nameValue->SetStringValueL( CXnDomPropertyValue::EString, + XnPropertyNames::action::trigger::name::KActivate ); + CXnProperty* name = CXnProperty::NewL( + XnPropertyNames::action::trigger::KName, + nameValue, + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::Pop( nameValue ); + CleanupStack::PushL( name ); + node->SetPropertyL( name ); + CleanupStack::Pop( name ); + CleanupStack::Pop( node ); + return node; + } + +// ----------------------------------------------------------------------------- +// BuildPropertyNodesL +// ----------------------------------------------------------------------------- +// +static void BuildPropertyNodesL( + CXnNode& aNode, + const TKeyEvent& aKeyEvent, + TEventCode aType, + CXnUiEngine& aUiEngine ) + { + CXnNode* eventType = BuildEventTypeNodeL( aType, aUiEngine ); + CleanupStack::PushL( eventType ); + aNode.AddChildL( eventType ); + CleanupStack::Pop( eventType ); + CXnNode* modifiers = BuildModifiersNodeL( aKeyEvent, aUiEngine ); + CleanupStack::PushL( modifiers ); + aNode.AddChildL( modifiers ); + CleanupStack::Pop( modifiers ); + CXnNode* keyCode = BuildKeyCodeNodeL( aKeyEvent, aUiEngine ); + CleanupStack::PushL( keyCode ); + aNode.AddChildL( keyCode ); + CleanupStack::Pop( keyCode ); + CXnNode* scanCode = BuildScanCodeNodeL( aKeyEvent, aUiEngine ); + CleanupStack::PushL( scanCode ); + aNode.AddChildL( scanCode ); + CleanupStack::Pop( scanCode ); + CXnNode* repeats = BuildRepeatsNodeL( aKeyEvent, aUiEngine ); + CleanupStack::PushL( repeats ); + aNode.AddChildL( repeats ); + CleanupStack::Pop( repeats ); + } + +// ----------------------------------------------------------------------------- +// BuildKeyTriggerNodeL +// ----------------------------------------------------------------------------- +// +static CXnNode* BuildKeyTriggerNodeL( + const TKeyEvent& aKeyEvent, + TEventCode aType, + CXnUiEngine& aUiEngine ) + { + CXnNode* node = CXnNode::NewL(); + CleanupStack::PushL( node ); + CXnType* type = CXnType::NewL( XnPropertyNames::action::KTrigger ); + CleanupStack::PushL( type ); + CXnNodeImpl* impl = CXnNodeImpl::NewL( type ); + CleanupStack::Pop( type ); + node->SetImpl( impl ); + node->SetUiEngine( aUiEngine ); + CXnDomPropertyValue* nameValue = CXnDomPropertyValue::NewL( + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::PushL( nameValue ); + nameValue->SetStringValueL( + CXnDomPropertyValue::EString, + XnPropertyNames::action::trigger::name::KKeyEvent ); + CXnProperty* name = CXnProperty::NewL( + XnPropertyNames::action::trigger::KName, + nameValue, + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::Pop( nameValue ); + CleanupStack::PushL( name ); + node->SetPropertyL( name ); + CleanupStack::Pop( name ); + BuildPropertyNodesL( *node, aKeyEvent, aType, aUiEngine ); + CleanupStack::Pop( node ); + return node; + } + +// ----------------------------------------------------------------------------- +// PseudoClassFromName +// ----------------------------------------------------------------------------- +// +static CXnDomProperty::TPseudoClass PseudoClassFromName( const TDesC8& aName ) + { + if ( aName == KPseudoClassFocus ) + { + return CXnDomProperty::EFocus; + } + else if ( aName == KPseudoClassPassiveFocus ) + { + return CXnDomProperty::EPassiveFocus; + } + else if ( aName == KPseudoClassHold ) + { + return CXnDomProperty::EHold; + } + else if ( aName == KPseudoClassHover ) + { + return CXnDomProperty::EHover; + } + else if ( aName == KPseudoClassLink ) + { + return CXnDomProperty::ELink; + } + else if ( aName == KPseudoClassVisited ) + { + return CXnDomProperty::EVisited; + } + else if ( aName == KPseudoClassActive ) + { + return CXnDomProperty::EActive; + } + else if ( aName == KPseudoClassEdit ) + { + return CXnDomProperty::EEdit; + } + else if ( aName == KPseudoClassPressedDown ) + { + return CXnDomProperty::EPressedDown; + } + return CXnDomProperty::ENone; + } + +// ----------------------------------------------------------------------------- +// PseudoClassName +// ----------------------------------------------------------------------------- +// +static const TDesC8& PseudoClassName( CXnDomProperty::TPseudoClass aPseudoClass ) + { + switch ( aPseudoClass ) + { + case CXnDomProperty::EFocus: + return KPseudoClassFocus; + case CXnDomProperty::EPassiveFocus: + return KPseudoClassPassiveFocus; + case CXnDomProperty::EHold: + return KPseudoClassHold; + case CXnDomProperty::EHover: + return KPseudoClassHover; + case CXnDomProperty::ELink: + return KPseudoClassLink; + case CXnDomProperty::EVisited: + return KPseudoClassVisited; + case CXnDomProperty::EActive: + return KPseudoClassActive; + case CXnDomProperty::EEdit: + return KPseudoClassEdit; + default: + return KNullDesC8; + } + } + +// ----------------------------------------------------------------------------- +// CheckRefAttributeL +// ----------------------------------------------------------------------------- +// +static const TDesC8* CheckRefAttributeL( CXnProperty* aRef ) + { + if ( !aRef ) + { + return NULL; + } + + return &aRef->StringValue(); + } + +// ----------------------------------------------------------------------------- +// DoMatchTriggerForKeyEventL +// ----------------------------------------------------------------------------- +// +static TBool DoMatchTriggerForKeyEventL( + const TKeyEvent& aKeyEvent, TEventCode aType, + CXnDomNode& aTriggerNode ) + { + TInt triggerEventType = EEventKeyDown; + TInt triggerKeyCode = 0; + TInt triggerScanCode = 0; + TInt triggerModifiers = 0; + CXnDomList& triggerChildren = aTriggerNode.ChildNodes(); + TInt triggerCount = triggerChildren.Length(); + TBool triggerScanCodeSet = EFalse; + TBool triggerKeyCodeSet = EFalse; + for ( TInt i = 0; i < triggerCount; ++i ) + { + CXnDomNode* node = static_cast< CXnDomNode* >( + triggerChildren.Item( i ) ); + CXnDomList& attrs = node->AttributeList(); + CXnDomAttribute* nameAttribute = static_cast< CXnDomAttribute* >( + attrs.FindByName( XnPropertyNames::action::KName ) ); + CXnDomAttribute* valueAttribute = static_cast< CXnDomAttribute* >( + attrs.FindByName( XnPropertyNames::action::KValue ) ); + if ( nameAttribute->Value() == + XnPropertyNames::action::trigger::name::keyevent::KEventType ) + { + TLex8 lex( valueAttribute->Value() ); + lex.Val( triggerEventType ); + } + else if ( nameAttribute->Value() == + XnPropertyNames::action::trigger::name::keyevent::KModifiers ) + { + TLex8 lex( valueAttribute->Value() ); + lex.Val( triggerModifiers ); + } + else if ( nameAttribute->Value() == + XnPropertyNames::action::trigger::name::keyevent::KKeyCode ) + { + TLex8 lex( valueAttribute->Value() ); + lex.Val( triggerKeyCode ); + triggerKeyCodeSet = ETrue; + } + else if ( nameAttribute->Value() == + XnPropertyNames::action::trigger::name::keyevent::KScanCode ) + { + TLex8 lex( valueAttribute->Value() ); + lex.Val( triggerScanCode ); + triggerScanCodeSet = ETrue; + } + } + return + aType == triggerEventType && + ( triggerKeyCodeSet ? ( aKeyEvent.iCode == triggerKeyCode ) : ETrue ) && + ( triggerScanCodeSet ? ( aKeyEvent.iScanCode == triggerScanCode ) : ETrue ) && + ( ( aKeyEvent.iModifiers & 0xFFFFFFFE ) == ( triggerModifiers & 0xFFFFFFFE ) ); + } + +// ----------------------------------------------------------------------------- +// MatchTriggerForKeyEventL +// ----------------------------------------------------------------------------- +// +static TBool MatchTriggerForKeyEventL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnNode& aNode, + const TKeyEvent& aKeyEvent, + TEventCode aType, + CXnDomNode& aActionNode, + CXnDomNode& aTriggerNode ) + { + CXnDomList& attrs = aTriggerNode.AttributeList(); + CXnDomAttribute* attribute = static_cast< CXnDomAttribute* >( + attrs.FindByName(XnPropertyNames::action::trigger::KName ) ); + if ( !attribute ) + { + return EFalse; + } + + const TDesC8& nameString = attribute->Value(); + if ( nameString == KNullDesC8 ) + { + return EFalse; + } + if ( nameString == XnPropertyNames::action::trigger::name::KKeyEvent ) + { + TBool match = DoMatchTriggerForKeyEventL( aKeyEvent, aType, aTriggerNode ); + if ( match ) + { + CXnNode* eventNode = BuildKeyTriggerNodeL( aKeyEvent, aType, aEngine ); + CleanupStack::PushL( eventNode ); + RunEventsL( aThis, aEngine, aNode, aActionNode, aTriggerNode, *eventNode ); + CleanupStack::PopAndDestroy( eventNode ); + } + return match; + } + else if ( aType == EEventKey && + ( nameString == XnPropertyNames::action::trigger::name::KUp || + nameString == XnPropertyNames::action::trigger::name::KDown || + nameString == XnPropertyNames::action::trigger::name::KLeft || + nameString == XnPropertyNames::action::trigger::name::KRight ) ) + { + TBool match = DoMatchTriggerForHighLevelKeyEventL( + aNode, aKeyEvent, aType, nameString ); + if ( match ) + { + CXnNode* eventNode = BuildKeyTriggerNodeL( aKeyEvent, aType, aEngine ); + CleanupStack::PushL( eventNode ); + RunEventsL( aThis, aEngine, aNode, aActionNode, aTriggerNode, *eventNode ); + CleanupStack::PopAndDestroy( eventNode ); + } + return match; + } + else if ( aKeyEvent.iScanCode == EStdKeyDevice3 && + aKeyEvent.iRepeats > 0 && + nameString == XnPropertyNames::action::trigger::name::KHold ) + { + CXnNode* eventNode = BuildKeyTriggerNodeL( aKeyEvent, aType, aEngine ); + CleanupStack::PushL( eventNode ); + RunEventsL( aThis, aEngine, aNode, aActionNode, aTriggerNode, *eventNode ); + CleanupStack::PopAndDestroy( eventNode ); + return ETrue; + } + else if ( ( ( aKeyEvent.iScanCode == EStdKeyDevice0 ) || + ( aKeyEvent.iScanCode == EStdKeyDevice1 ) ) && + aKeyEvent.iRepeats > 0 && + nameString == XnPropertyNames::action::trigger::name::KHold ) + { + CXnNode* eventNode = BuildKeyTriggerNodeL( aKeyEvent, aType, aEngine ); + CleanupStack::PushL( eventNode ); + RunEventsL( aThis, aEngine, aNode, aActionNode, aTriggerNode, *eventNode ); + CleanupStack::PopAndDestroy( eventNode ); + return ETrue; + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// MatchTimedTriggerPropertiesL +// ----------------------------------------------------------------------------- +// +static TBool MatchTimedTriggerPropertiesL( CXnDomNode& aTriggerNode ) + { + CXnDomList& children = aTriggerNode.ChildNodes(); + TInt count = children.Length(); + if ( count > 0 ) + { + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* child = static_cast< CXnDomNode* >( children.Item( i ) ); + const TDesC8& name = child->AttributeValue( XnPropertyNames::action::KName ); + if ( name == XnPropertyNames::action::trigger::KDelay ) + { + return ETrue; + } + } + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// MatchStylusTriggerL +// ----------------------------------------------------------------------------- +// +static TBool MatchStylusTriggerL( + CXnNode& aMatchingTriggerNode, + CXnDomNode& aTreeTriggerNode ) + { + TInt ret( EFalse ); + + CXnDomList& treeChildren = aTreeTriggerNode.ChildNodes(); + TInt treeCount = treeChildren.Length(); + + RPointerArray< CXnNode >& matchingChildren = aMatchingTriggerNode.Children(); + TInt matchCount = matchingChildren.Count(); + + if ( treeCount == 0 ) + { + // If stylus-trigger does not have properties, trigger is run with stylus up. + for ( TInt i = 0; i < matchCount; ++i ) + { + CXnNode* node = matchingChildren[i]; + CXnProperty* nameProperty = node->NameL(); + if ( nameProperty ) + { + const TDesC8& name = nameProperty->StringValue(); + if ( name == + XnPropertyNames::action::trigger::name::stylus::KStylusEventType ) + { + CXnProperty* valueProperty = node->ValueL(); + if ( valueProperty ) + { + const TDesC8& name = valueProperty->StringValue(); + if ( name == XnPropertyNames::action::trigger::name::KDownAndUp ) + { + return ETrue; + } + } + } + } + } + return EFalse; + } + + // Fetch trigger data defined in the theme + TInt treeTriggerState( 1 ); + HBufC8* treeTriggerType( NULL ); + for ( TInt i = 0; i < treeCount; ++i ) + { + CXnDomNode* domNode = static_cast< CXnDomNode* >( treeChildren.Item( i ) ); + CXnDomList& attrs = domNode->AttributeList(); + CXnDomAttribute* nameAttribute = static_cast< CXnDomAttribute* >( + attrs.FindByName( XnPropertyNames::action::KName ) ); + CXnDomAttribute* valueAttribute = static_cast< CXnDomAttribute* >( + attrs.FindByName( XnPropertyNames::action::KValue ) ); + if ( nameAttribute->Value() == + XnPropertyNames::action::trigger::name::stylus::KStylusState ) + { + TLex8 lex( valueAttribute->Value() ); + lex.Val( treeTriggerState ); + } + else if ( nameAttribute->Value() == + XnPropertyNames::action::trigger::name::stylus::KStylusEventType ) + { + // just in case + if ( treeTriggerType ) + { + CleanupStack::PopAndDestroy( treeTriggerType ); + treeTriggerType = NULL; + } + const TDesC8& value = valueAttribute->Value(); + treeTriggerType = HBufC8::NewL( value.Length() ); + TPtr8 ptr = treeTriggerType->Des(); + ptr = value; + CleanupStack::PushL( treeTriggerType ); + } + } + + // If not defined, use the default value 'up' + if ( !treeTriggerType ) + { + treeTriggerType = HBufC8::NewL( 10 ); + TPtr8 ptr = treeTriggerType->Des(); + ptr.Append( XnPropertyNames::action::trigger::name::KDownAndUp ); + CleanupStack::PushL( treeTriggerType ); + } + + // Fetch matching trigger data. + TInt matchTriggerState( 1 ); + HBufC8* matchTriggerType( NULL ); + for ( TInt i = 0; i < matchCount; ++i ) + { + CXnNode* matchNode = matchingChildren[i]; + CXnProperty* nameProperty = matchNode->NameL(); + CXnProperty* valueProperty = matchNode->ValueL(); + if ( nameProperty && valueProperty ) + { + if ( nameProperty->StringValue() == + XnPropertyNames::action::trigger::name::stylus::KStylusState ) + { + TLex8 lex( valueProperty->StringValue() ); + lex.Val( matchTriggerState ); + } + else if ( nameProperty->StringValue() == + XnPropertyNames::action::trigger::name::stylus::KStylusEventType ) + { + // just in case + if ( matchTriggerType ) + { + CleanupStack::PopAndDestroy( matchTriggerType ); + matchTriggerType = NULL; + } + const TDesC8& value = valueProperty->StringValue(); + matchTriggerType = HBufC8::NewL( value.Length() ); + TPtr8 ptr = matchTriggerType->Des(); + ptr = value; + CleanupStack::PushL( matchTriggerType ); + } + } + } + + if ( treeTriggerState == matchTriggerState ) + { + // just in case + if ( !matchTriggerType ) + { + ret = EFalse; + } + else if ( treeTriggerType->Des() == matchTriggerType->Des() ) + { + ret = ETrue; + } + // still, if trigger type is 'KUp' it should match to 'KDownAndUp' event + else if ( treeTriggerType->Des() == + XnPropertyNames::action::trigger::name::KUp ) + { + if ( matchTriggerType->Des() == + XnPropertyNames::action::trigger::name::KDownAndUp ) + { + ret = ETrue; + } + } + } + if ( matchTriggerType ) + { + CleanupStack::PopAndDestroy( matchTriggerType ); + } + if ( treeTriggerType ) + { + CleanupStack::PopAndDestroy( treeTriggerType ); + } + return ret; + } + +// ----------------------------------------------------------------------------- +// MatchActivateTriggerPropertiesL +// Checks if triggered node properties match +// ones defined in theme +// ----------------------------------------------------------------------------- +// +static TBool MatchActivateTriggerPropertiesL( + CXnNode& aEventData, + CXnDomNode& aTriggerNode ) + { + RPointerArray< CXnNode >& eventChildren = aEventData.Children(); + TInt eventCount = eventChildren.Count(); + + if ( eventCount ) + { + CXnNode* node = eventChildren[0]; + CXnProperty* nameProperty = node->NameL(); + CXnProperty* valueProperty = node->ValueL(); + + if ( !nameProperty || !valueProperty ) + { + return EFalse; + } + + const TDesC8& name = nameProperty->StringValue(); + + if ( name == XnPropertyNames::action::trigger::name::keyevent::KEventType ) + { + const TDesC8& valueName = valueProperty->StringValue(); + + CXnDomList& children = aTriggerNode.ChildNodes(); + TInt count = children.Length(); + + if ( ( valueName == _L8( "3" ) ) ) //keydown + { + // check that no eventype has been defined + if ( !count ) + { + return EFalse; + } + } + else if ( ( valueName == _L8( "2" ) ) ) //keyup + { + ///check that some eventtype has been defined + if ( !count ) + { + return EFalse; + } + + CXnDomNode* node = static_cast< CXnDomNode* >( children.Item( 0 ) ); + CXnDomList& attrs = node->AttributeList(); + CXnDomAttribute* nameAttribute = static_cast< CXnDomAttribute* >( + attrs.FindByName( XnPropertyNames::action::KName ) ); + CXnDomAttribute* valueAttribute = static_cast< CXnDomAttribute* >( + attrs.FindByName( XnPropertyNames::action::KValue ) ); + + const TDesC8& name = nameAttribute->Value(); + + // check that eventype name matches + if ( name != + XnPropertyNames::action::trigger::name::keyevent::KEventType ) + { + return EFalse; + } + else + { + //check that eventype value matches + const TDesC8& valueName = valueAttribute->Value(); + if ( valueName != _L8( "2" ) ) + { + return EFalse; + } + } + } + } + } + + return ETrue; + } + +// ----------------------------------------------------------------------------- +// MatchScreenDeviceChangePropertiesL +// Checks if triggered node properties match +// ones defined in theme +// ----------------------------------------------------------------------------- +// +static TBool MatchScreenDeviceChangePropertiesL( + CXnNode& aEventData, + CXnDomNode& aTriggerNode ) + { + CXnDomList& attributeList( aTriggerNode.AttributeList() ); + + const TDesC8& reason( + XnPropertyNames::action::trigger::name::uidefinitionmodification::KReason ); + + CXnDomAttribute* attribute( static_cast< CXnDomAttribute* > + ( attributeList.FindByName( reason ) ) ); + + if ( !attribute ) + { + // Reason not defined, run events for plain screendevicechange trigger + return ETrue; + } + + const TDesC8& value( attribute->Value() ); + + if ( value == + XnPropertyNames::action::trigger::name::uidefinitionmodification::reason::KLandscape || + value == + XnPropertyNames::action::trigger::name::uidefinitionmodification::reason::KPortrait ) + { + CXnProperty* reasonProp( aEventData.GetPropertyL( reason ) ); + + if ( reasonProp ) + { + const TDesC8& reasonValue( reasonProp->StringValue() ); + + if ( reasonValue == value ) + { + return ETrue; + } + } + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// MatchSwipeTriggerL +// Check if trigger matches the one defined in theme +// ----------------------------------------------------------------------------- +// +static TBool MatchSwipeTriggerL( + CXnNode& aEventData, + CXnDomNode& aTriggerNode ) + { + CXnDomList& attributeList( aTriggerNode.AttributeList() ); + + const TDesC8& reason( XnPropertyNames::action::trigger::name::swipe::KDirection); + + CXnDomAttribute* attribute( static_cast< CXnDomAttribute* > + ( attributeList.FindByName( reason ) ) ); + + if ( !attribute ) + { + // Reason not defined + return EFalse; + } + + const TDesC8& value( attribute->Value() ); + + if ( value == XnPropertyNames::action::trigger::name::swipe::direction::KLeft || + value == XnPropertyNames::action::trigger::name::swipe::direction::KRight ) + { + CXnProperty* reasonProp( aEventData.GetPropertyL( reason ) ); + + if ( reasonProp ) + { + const TDesC8& reasonValue( reasonProp->StringValue() ); + + if ( reasonValue == value ) + { + return ETrue; + } + } + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// MatchValueAttributeTriggerL +// Check if trigger matches the one defined in theme +// ----------------------------------------------------------------------------- +// +static TBool MatchValueAttributeTriggerL( CXnNode& aEventData, + CXnDomNode& aTriggerNode ) + { + CXnDomList& attributeList( aTriggerNode.AttributeList() ); + + const TDesC8& reason( XnPropertyNames::action::KValue ); + + CXnDomAttribute* attribute( static_cast< CXnDomAttribute* > + ( attributeList.FindByName( reason ) ) ); + + if ( !attribute ) + { + // Reason not defined + return EFalse; + } + + const TDesC8& value( attribute->Value() ); + + CXnProperty* reasonProp( aEventData.GetPropertyL( reason ) ); + + if ( reasonProp ) + { + const TDesC8& reasonValue( reasonProp->StringValue() ); + + if ( reasonValue == value ) + { + return ETrue; + } + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// MatchTitleScrollTriggerL +// ----------------------------------------------------------------------------- +// +static TBool MatchTitleScrollTriggerL(CXnNode& aEventData, + CXnDomNode& aTriggerNode ) + { + CXnDomList& attributeList( aTriggerNode.AttributeList() ); + + const TDesC8& reason( XnPropertyNames::action::trigger::name::KTitleIndex ); + + CXnDomAttribute* attribute( static_cast< CXnDomAttribute* > + ( attributeList.FindByName( reason ) ) ); + + if ( !attribute ) + { + // Reason not defined + return ETrue; + } + else + { + const TDesC8& value( attribute->Value() ); + + CXnProperty* reasonProp( aEventData.GetPropertyL( reason ) ); + + if ( reasonProp ) + { + const TDesC8& reasonValue( reasonProp->StringValue() ); + + if ( reasonValue == value ) + { + return ETrue; + } + } + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// MatchTriggerForEventL +// ----------------------------------------------------------------------------- +// +static TBool MatchTriggerForEventL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnNode& aNode, + CXnNode& aEventData, + CXnDomNode& aActionNode, + CXnDomNode& aTriggerNode, + TInt aSource ) + { + const TDesC8& nameString( aTriggerNode.AttributeValue( KName ) ); + + if ( nameString == KNullDesC8 ) + { + return EFalse; + } + + CXnProperty* eventName( aEventData.NameL() ); + const TDesC8& eventNameString( eventName->StringValue() ); + + if ( nameString == eventNameString ) + { + if ( nameString == XnPropertyNames::action::trigger::name::KStylus ) + { + if ( !MatchStylusTriggerL( aEventData, aTriggerNode ) ) + { + return EFalse; + } + } + // Check if triggernode properties match the ones defined in theme + // This is for identifying keyup in activate-trigger + else if ( nameString == XnPropertyNames::action::trigger::name::KActivate ) + { + if ( !MatchActivateTriggerPropertiesL( aEventData, aTriggerNode ) ) + { + return EFalse; + } + } + // Check if the trigger is timed trigger + else if ( MatchTimedTriggerPropertiesL( aTriggerNode ) ) + { + if ( !aThis->PeriodicTimer() ) + { + aThis->CreatePeriodicL(); + } + + if ( !aThis->PeriodicTimer()->IsActive() ) + { + TXnTimedTrigger* params = new ( ELeave ) TXnTimedTrigger; + CleanupStack::PushL( params ); + + params->iNodeImpl = aThis; + params->iEngine = &aEngine; + params->iNode = &aNode; + params->iEventData = &aEventData; + params->iActionNode = &aActionNode; + params->iTriggerNode = &aTriggerNode; + + TInt delay( 0 ); + + ResolveTriggerDelayL( aEngine, aTriggerNode, delay ); + aNode.SetTriggerDelay( delay ); + + CleanupStack::Pop( params ); + + aThis->PeriodicTimer()->Start( + TTimeIntervalMicroSeconds32( delay ), + TTimeIntervalMicroSeconds32( delay ), + TCallBack( CXnNodeImpl::PeriodicEventL, params ) ); + + return ETrue; + } + else + { + return EFalse; + } + } + else if ( nameString == XnPropertyNames::action::trigger::name::KTitleToScroll || + nameString == XnPropertyNames::action::trigger::name::KTitleScrolled ) + { + if ( !MatchTitleScrollTriggerL( aEventData, aTriggerNode ) ) + { + return EFalse; + } + } + else if ( nameString == + XnPropertyNames::action::trigger::name::KScreenDeviceChange ) + { + if ( !MatchScreenDeviceChangePropertiesL( aEventData, aTriggerNode ) ) + { + return EFalse; + } + } + else if ( nameString == XnPropertyNames::action::trigger::name::KSwipe ) + { + if ( !MatchSwipeTriggerL( aEventData, aTriggerNode ) ) + { + return EFalse; + } + } + else if ( nameString == XnPropertyNames::action::trigger::name::KWidgetAmount || + nameString == XnPropertyNames::action::trigger::name::KCallState || + nameString == XnPropertyNames::action::trigger::name::KEditMode ) + { + if ( !MatchValueAttributeTriggerL( aEventData, aTriggerNode ) ) + { + return EFalse; + } + } + else if ( aSource != XnEventSource::EUnknown ) + { + CXnDomAttribute* attr = static_cast< CXnDomAttribute* > + ( aTriggerNode.AttributeList().FindByName( + XnPropertyNames::common::KEventFilter ) ); + if ( attr ) + { + if ( attr->Value().Find(XnPropertyNames::action::trigger::name::KStylus) + != KErrNotFound && + aSource == XnEventSource::EStylus ) + { + return EFalse; + } + else if ( attr->Value().Find(XnPropertyNames::action::trigger::name::KKeyEvent) + != KErrNotFound && + aSource == XnEventSource::EKey ) + { + return EFalse; + } + } + } + + RunEventsL( aThis, aEngine, aNode, aActionNode, aTriggerNode, aEventData ); + + return ETrue; + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// GetFocusCandidatesL +// ----------------------------------------------------------------------------- +// +static void GetFocusCandidatesL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnDomNode& aEventNode, + RPointerArray< CXnNode >& aFocusCandidates ) + { + CXnDomList& children( aEventNode.ChildNodes() ); + + TInt count( children.Length() ); + + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* dnode( static_cast< CXnDomNode* >( children.Item( i ) ) ); + + const TDesC8& type( dnode->Name() ); + + // Is the event's node child a property? + if ( type == XnPropertyNames::action::KProperty ) + { + CXnDomList& attributeList( dnode->AttributeList() ); + + CXnDomAttribute* attribute( static_cast< CXnDomAttribute* > + ( attributeList.FindByName( XnPropertyNames::action::KValue ) ) ); + + if ( attribute ) + { + CXnNode* node( aEngine.FindNodeByIdL( + attribute->Value(), aThis->Namespace() ) ); + + if ( node ) + { + aFocusCandidates.AppendL( node ); + } + } + } + } + } + +// ----------------------------------------------------------------------------- +// RunPassiveFocusChangeL +// ----------------------------------------------------------------------------- +// +static void RunPassiveFocusChangeL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnDomNode& aEventNode, + const TDesC8& aString ) + { + CXnDomList& children = aEventNode.ChildNodes(); + TInt count = children.Length(); + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* dnode = static_cast< CXnDomNode* >( children.Item( i ) ); + const TDesC8& type = dnode->Name(); + if ( type == XnPropertyNames::action::KProperty ) + { + CXnDomList& attrs = dnode->AttributeList(); + CXnDomAttribute* attribute = static_cast< CXnDomAttribute* >( + attrs.FindByName(XnPropertyNames::action::KValue ) ); + if ( attribute ) + { + CXnNode* node = aEngine.FindNodeByIdL( + attribute->Value(), aThis->Namespace() ); + if ( node ) + { + if ( aString == XnPropertyNames::action::event::KSetPassiveFocus ) + { + aEngine.AddPassiveFocusedNodeL( node ); + } + else if ( aString == XnPropertyNames::action::event::KResetPassiveFocus ) + { + aEngine.RemovePassiveFocusedNodeL( node ); + } + else if ( aString == XnPropertyNames::action::event::KSetActiveFocus ) + { + CXnNode* previousNode = aEngine.FocusedNode(); + if ( previousNode != node ) + { + if ( IsNodeNavigableL( *node ) ) + { + node->SetStateL( XnPropertyNames::style::common::KFocus ); + aEngine.AddPassiveFocusedNodeL( previousNode ); + break; + } + } + } + } + } + } + } + } + +// ----------------------------------------------------------------------------- +// RunAppUiNotificationL +// ----------------------------------------------------------------------------- +// +static void RunAppUiNotificationL( + CXnUiEngine& aEngine, + CXnNode& aNode, + CXnDomNode& aEventNode, + CXnDomNode& aTriggerNode, + CXnNode& aEventData ) + { + CXnAppUiAdapter& adapter( aEngine.AppUiAdapter() ); + + adapter.HandleXuikonEventL( + aNode.AppIfL(), aEventData.AppIfL(), aTriggerNode, aEventNode ); + } + +// ----------------------------------------------------------------------------- +// RunAppExit +// ----------------------------------------------------------------------------- +// +static void RunAppExit( CXnUiEngine& aEngine ) + { + CXnAppUiAdapter& adapter( aEngine.AppUiAdapter() ); + + adapter.Exit(); + } + +// ----------------------------------------------------------------------------- +// RunFullScreenEffectL +// ----------------------------------------------------------------------------- +// +static void RunFullScreenEffectL( CXnUiEngine& aEngine, CXnDomNode& aEventNode ) + { + CXnDomList& list( aEventNode.AttributeList() ); + const TDesC8& effectid( XnPropertyNames::common::KEffectId ); + CXnDomAttribute* attribute( static_cast< CXnDomAttribute* > + ( list.FindByName( effectid ) ) ); + + if ( attribute ) + { + const TDesC8& value( attribute->Value() ); + TLex8 lex( value ); + TInt effect; + lex.Val( effect ); + aEngine.AppUiAdapter().EffectManager()->BeginFullscreenEffectL( + effect, aEngine.ViewManager()->ActiveViewData() ); + } + } + +// ----------------------------------------------------------------------------- +// RunActivateViewL +// ----------------------------------------------------------------------------- +// +static void RunActivateViewL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnDomNode& aEventNode ) + { + CXnDomList& children( aEventNode.ChildNodes() ); + + TInt count( children.Length() ); + + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* node = static_cast< CXnDomNode* >( children.Item( i ) ); + + const TDesC8& type( node->Name() ); + + if ( type == XnPropertyNames::action::KProperty ) + { + const TDesC8& id( node->AttributeValue( XnPropertyNames::action::KValue ) ); + + CXnNode* viewNode( aEngine.FindNodeByIdL( id, aThis->Namespace() ) ); + + if ( viewNode ) + { + aEngine.ActivateViewL( *viewNode ); + } + } + } + } + +// ----------------------------------------------------------------------------- +// RunActivateNextViewL +// ----------------------------------------------------------------------------- +// +static void RunActivateNextViewL( CXnUiEngine& aEngine ) + { + aEngine.ViewManager()->ActivateNextViewL(); + } + +// ----------------------------------------------------------------------------- +// RunActivatePreviousViewL +// ----------------------------------------------------------------------------- +// +static void RunActivatePreviousViewL( CXnUiEngine& aEngine ) + { + aEngine.ViewManager()->ActivatePreviousViewL(); + } + +// ----------------------------------------------------------------------------- +// RunAddViewL +// ----------------------------------------------------------------------------- +// +static void RunAddViewL( CXnUiEngine& aEngine ) + { + aEngine.ViewManager()->AddViewL(); + } + +// ----------------------------------------------------------------------------- +// RunRemoveViewL +// ----------------------------------------------------------------------------- +// +static void RunRemoveViewL( CXnUiEngine& aEngine ) + { + aEngine.ViewManager()->RemoveViewL(); + } + +// ----------------------------------------------------------------------------- +// RunActivateL +// ----------------------------------------------------------------------------- +// +static void RunActivateL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnDomNode& aEventNode ) + { + CXnDomList& children = aEventNode.ChildNodes(); + TInt count = children.Length(); + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* dnode = static_cast< CXnDomNode* >( children.Item( i ) ); + const TDesC8& type = dnode->Name(); + if ( type == XnPropertyNames::action::KProperty ) + { + const TDesC8& id = dnode->AttributeValue( KId ); + CXnNode* node = aEngine.FindNodeByIdL( id, aThis->Namespace() ); + if ( node ) + { + node->SetStateL( XnPropertyNames::style::common::KActive ); + return; + } + } + } + + CXnNode* focused( aEngine.FocusedNode() ); + + if ( focused ) + { + focused->SetStateL( XnPropertyNames::style::common::KActive ); + } + } + +// ----------------------------------------------------------------------------- +// RunEditL +// ----------------------------------------------------------------------------- +// +static void RunEditL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnDomNode& aEventNode ) + { + TBool keyEditMode(EFalse); + + aEngine.DisableRenderUiLC(); + + // Set plugins to edit state + RPointerArray< CXnPluginData>& plugins( + aEngine.ViewManager()->ActiveViewData().PluginData() ); + + CXnDomStringPool& sp( aEventNode.StringPool() ); + + CXnDomList& children( aEventNode.ChildNodes() ); + + TInt count( children.Length() ); + + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* dnode = static_cast< CXnDomNode* >( children.Item( i ) ); + const TDesC8& type = dnode->Name(); + + if ( type == XnPropertyNames::action::KProperty ) + { + const TDesC8& name = dnode->AttributeValue( + XnPropertyNames::action::event::systemset::KName ); + const TDesC8& value = dnode->AttributeValue( + XnPropertyNames::action::event::systemset::KValue ); + + if ( name != KNullDesC8 && value != KNullDesC8 ) + { + // Find node by id + if ( name == XnPropertyNames::common::KId ) + { + CXnNode* node( aEngine.FindNodeByIdL( value, aThis->Namespace() ) ); + + if ( node ) + { + node->SetStateL( XnPropertyNames::style::common::KEdit ); + } + } + // Find nodes by class + else if ( name == XnPropertyNames::common::KClass ) + { + CXnPointerArray* array = aEngine.FindNodeByClassL( value ); + CleanupStack::PushL( array ); + + if ( array ) + { + const TInt count( array->Container().Count() ); + + for ( TInt i = 0; i < count; ++i ) + { + CXnNode* node( static_cast< CXnNode* >( + array->Container()[i] ) ); + + CXnProperty* editable( node->GetPropertyL( + XnPropertyNames::style::common::edit::KEditable ) ); + + if ( !editable || + editable->StringValue() != XnPropertyNames::KFalse ) + { + node->SetStateL( XnPropertyNames::style::common::KEdit ); + } + } + } + + CleanupStack::PopAndDestroy( array ); + } + else if ( name == XnPropertyNames::common::KKeyMoveMode ) + { + if ( value == XnPropertyNames::KTrue ) + { + keyEditMode = ETrue; + } + } + } + } + } + if ( keyEditMode ) + { + for ( TInt i = 0; i < plugins.Count(); i++ ) + { + if ( plugins[i]->Occupied() ) + { + CXnNode* node( plugins[i]->Owner()->LayoutNode() ); + + node->SetStateL( XnPropertyNames::style::common::KEdit ); + } + } + + aEngine.EditMode()->SetEditModeL( CXnEditMode::EKeyMove ); + + // Put focus to parent plugin if focused node is not a plugin already + CXnNode* focusedNode = aEngine.FocusedNode(); + + if ( focusedNode && focusedNode->DomNode()->Name() != _L8( "plugin" ) ) + { + for ( CXnNode* candidate = + focusedNode; candidate; candidate = candidate->Parent() ) + { + if ( candidate->DomNode()->Name() == _L8( "plugin" ) ) + { + candidate->SetStateL( XnPropertyNames::style::common::KFocus ); + break; + } + } + } + } + else + { + TBool useEmpty( aEngine.ViewManager()->ActiveViewData().UseEmptyWidget() ); + + for ( TInt i = 0; i < plugins.Count(); i++ ) + { + CXnNode* node( plugins[i]->Owner()->LayoutNode() ); + + node->SetStateL( XnPropertyNames::style::common::KEdit ); + + if ( !plugins[i]->Occupied() && useEmpty ) + { + // Make empty space visible + SetStringPropertyToNodeL( sp, *node, + XnPropertyNames::style::common::KVisibility, + XnPropertyNames::style::common::visibility::KVisible ); + } + } + + aEngine.EditMode()->SetEditModeL( CXnEditMode::EDragAndDrop ); + } + + CleanupStack::PopAndDestroy(); + + aEngine.AppUiAdapter().ViewAdapter().UpdateRskByModeL(); + } + +// ----------------------------------------------------------------------------- +// RunResetEditL +// ----------------------------------------------------------------------------- +// +static void RunResetEditL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnDomNode& aEventNode ) + { + TBool keyEditMode( + aEngine.EditMode()->EditState() == CXnEditMode::EKeyMove ); + + CXnDomList& children( aEventNode.ChildNodes() ); + + TInt count( children.Length() ); + + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* dnode = static_cast< CXnDomNode* >( children.Item( i ) ); + const TDesC8& type = dnode->Name(); + + if ( type == XnPropertyNames::action::KProperty ) + { + const TDesC8& name = dnode->AttributeValue( + XnPropertyNames::action::event::systemset::KName ); + const TDesC8& value = dnode->AttributeValue( + XnPropertyNames::action::event::systemset::KValue ); + + if ( name != KNullDesC8 && value != KNullDesC8 ) + { + if ( name == XnPropertyNames::common::KId ) + { + CXnNode* node( aEngine.FindNodeByIdL( value, aThis->Namespace() ) ); + + if ( node ) + { + node->UnsetStateL( + XnPropertyNames::style::common::KEdit ); + } + } + else if ( name == XnPropertyNames::common::KClass ) + { + CXnPointerArray* array( aEngine.FindNodeByClassL( value ) ); + CleanupStack::PushL( array ); + + const TInt count = array->Container().Count(); + + for ( TInt i = 0; i < count; ++i ) + { + CXnNode* node = static_cast< CXnNode* >( + array->Container()[i] ); + + if ( node && + node->IsStateSet( XnPropertyNames::style::common::KEdit ) ) + { + node->UnsetStateL( XnPropertyNames::style::common::KEdit ); + } + } + + CleanupStack::PopAndDestroy( array ); + } + } + } + } + + RPointerArray< CXnPluginData>& plugins( + aEngine.ViewManager()->ActiveViewData().PluginData() ); + + CXnDomStringPool& sp( aEventNode.StringPool() ); + + if ( keyEditMode ) + { + for ( TInt i = 0; i < plugins.Count(); i++ ) + { + if ( plugins[i]->Occupied() ) + { + CXnNode* node( plugins[i]->Owner()->LayoutNode() ); + + node->UnsetStateL( XnPropertyNames::style::common::KEdit ); + } + } + } + else + { + TBool useEmpty( aEngine.ViewManager()->ActiveViewData().UseEmptyWidget() ); + + for ( TInt i = 0; i < plugins.Count(); i++ ) + { + CXnNode* node( plugins[i]->Owner()->LayoutNode() ); + + node->UnsetStateL( XnPropertyNames::style::common::KEdit ); + + if ( !plugins[i]->Occupied() && useEmpty ) + { + // Make empty space blank + SetStringPropertyToNodeL( sp, *node, + XnPropertyNames::style::common::KVisibility, + XnPropertyNames::style::common::visibility::KBlank ); + } + } + } + + aEngine.EditMode()->SetEditModeL( CXnEditMode::ENone ); + + aEngine.AppUiAdapter().ViewAdapter().UpdateRskByModeL(); + } + +// ----------------------------------------------------------------------------- +// RunDeactivateL +// ----------------------------------------------------------------------------- +// +static void RunDeactivateL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnDomNode& aEventNode ) + { + CXnDomList& children = aEventNode.ChildNodes(); + TInt count = children.Length(); + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* dnode = static_cast< CXnDomNode* >( children.Item( i ) ); + const TDesC8& type = dnode->Name(); + if ( type == XnPropertyNames::action::KProperty ) + { + const TDesC8& id = dnode->AttributeValue( KId ); + CXnNode* node = aEngine.FindNodeByIdL( id, aThis->Namespace() ); + if ( node ) + { + node->UnsetStateL( XnPropertyNames::style::common::KActive ); + } + } + } + } + +// ----------------------------------------------------------------------------- +// RunSystemSetPCDataL +// ----------------------------------------------------------------------------- +// +static void RunSystemSetPCDataL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + const TDesC8& aId, + const TDesC8& aData ) + { + CXnNode* node = aEngine.FindNodeByIdL( aId, aThis->Namespace() ); + + if ( node ) + { + node->SetPCDataL( aData ); + } + } + +// ----------------------------------------------------------------------------- +// GetNumberValues +// ----------------------------------------------------------------------------- +// +static void GetNumberValues( + const TDesC8& aData, + TReal& aNumber, + CXnDomPropertyValue::TPrimitiveValueType& aValueType ) + { + TLex8 lex( aData ); + lex.Val( aNumber ); + TPtrC8 rest = lex.Remainder(); + if ( rest.FindF( _L8( "%" ) ) != KErrNotFound ) + { + aValueType = CXnDomPropertyValue::EPercentage; + } + else if (rest.FindF( _L8( "em" ) ) != KErrNotFound ) + { + aValueType = CXnDomPropertyValue::EEms; + } + else if ( rest.FindF( _L8( "ex" ) ) != KErrNotFound ) + { + aValueType = CXnDomPropertyValue::EExs; + } + else if ( rest.FindF( _L8( "px" ) ) != KErrNotFound ) + { + aValueType = CXnDomPropertyValue::EPx; + } + else if ( rest.FindF( _L8( "u" ) ) != KErrNotFound ) + { + aValueType = CXnDomPropertyValue::EUnitValue; + } + else if ( rest.FindF( _L8( "cm" ) ) != KErrNotFound ) + { + aValueType = CXnDomPropertyValue::ECm; + } + else if ( rest.FindF( _L8( "mm" ) ) != KErrNotFound ) + { + aValueType = CXnDomPropertyValue::EMm; + } + else if ( rest.FindF( _L8( "in" ) ) != KErrNotFound ) + { + aValueType = CXnDomPropertyValue::EIn; + } + else if ( rest.FindF( _L8( "pt" ) ) != KErrNotFound ) + { + aValueType = CXnDomPropertyValue::EPt; + } + else if ( rest.FindF( _L8( "pc" ) ) != KErrNotFound ) + { + aValueType = CXnDomPropertyValue::EPc; + } + else + { + aValueType = CXnDomPropertyValue::ENumber; + } + } + +// ----------------------------------------------------------------------------- +// RunSystemSetNumberL +// ----------------------------------------------------------------------------- +// +static void RunSystemSetNumberL( + CXnUiEngine& aEngine, + CXnNode* aNode, + const TDesC8& aName, + const RPointerArray< HBufC8 >& aValues ) + { + if ( aNode ) + { + CXnDomStringPool& sp = aEngine.ODT()->DomDocument().StringPool(); + CXnDomProperty* prop = CXnDomProperty::NewL( aName, sp ); + CleanupStack::PushL( prop ); + + for ( TInt i = 0; i < aValues.Count(); i++ ) + { + const TDesC8& value = ( *aValues[i] ); + + CXnDomPropertyValue* propVal = CXnDomPropertyValue::NewL( sp ); + CleanupStack::PushL( propVal ); + + CXnDomPropertyValue::TPrimitiveValueType type; + TReal realValue; + + GetNumberValues( value, realValue, type ); + propVal->SetFloatValueL( type, realValue ); + + prop->PropertyValueList().AddItemL( propVal ); + CleanupStack::Pop( propVal ); + } + + CXnProperty* propertyValue = CXnProperty::NewL( prop ); + + CleanupStack::Pop( prop ); + CleanupStack::PushL( propertyValue ); + + aNode->SetPropertyL( propertyValue ); + + CleanupStack::Pop( propertyValue ); + } + } + +// ----------------------------------------------------------------------------- +// RunSystemSetRGBL +// ----------------------------------------------------------------------------- +// +static void RunSystemSetRGBL( + CXnUiEngine& aEngine, + CXnNode* aNode, + const TDesC8& aName, + const RPointerArray< HBufC8 >& aValues ) + { + if ( aNode ) + { + CXnDomStringPool& sp = aEngine.ODT()->DomDocument().StringPool(); + CXnDomProperty* prop = CXnDomProperty::NewL( aName, sp ); + CleanupStack::PushL( prop ); + + for ( TInt i = 0; i < aValues.Count(); i++ ) + { + const TDesC8& value = ( *aValues[i] ); + + CXnDomPropertyValue* propVal = CXnDomPropertyValue::NewL( sp ); + CleanupStack::PushL( propVal ); + + TRgb rgb; + + if ( CXnUtils::GetRgbValue( rgb, value ) ) + { + propVal->SetRgbColorL( rgb ); + prop->PropertyValueList().AddItemL( propVal ); + CleanupStack::Pop( propVal ); + } + else + { + CleanupStack::PopAndDestroy( propVal ); + } + } + + CXnProperty* propertyValue = CXnProperty::NewL( prop ); + + CleanupStack::Pop( prop ); + CleanupStack::PushL( propertyValue ); + + aNode->SetPropertyL( propertyValue ); + + CleanupStack::Pop( propertyValue ); + } + } + +// ----------------------------------------------------------------------------- +// RunSystemSetStringL +// ----------------------------------------------------------------------------- +// +static void RunSystemSetStringL( + CXnUiEngine& aEngine, + CXnNode* aNode, + const TDesC8& aName, + const RPointerArray< HBufC8 >& aValues, + const CXnDomPropertyValue::TPrimitiveValueType aValueType ) + { + if ( aNode ) + { + CXnDomStringPool& sp = aEngine.ODT()->DomDocument().StringPool(); + CXnDomProperty* prop = CXnDomProperty::NewL( aName, sp ); + CleanupStack::PushL( prop ); + + for ( TInt i = 0; i < aValues.Count(); i++ ) + { + const TDesC8& value = ( *aValues[i] ); + + CXnDomPropertyValue* propVal = CXnDomPropertyValue::NewL( sp ); + CleanupStack::PushL( propVal ); + + propVal->SetStringValueL( aValueType, value ); + prop->PropertyValueList().AddItemL( propVal ); + CleanupStack::Pop( propVal ); + } + + CXnProperty* propertyValue = CXnProperty::NewL( prop ); + + CleanupStack::Pop( prop ); + CleanupStack::PushL( propertyValue ); + + aNode->SetPropertyL( propertyValue ); + + CleanupStack::Pop( propertyValue ); + } + } + +// ----------------------------------------------------------------------------- +// RunResetStylusCounterL +// ----------------------------------------------------------------------------- +// +static void RunResetStylusCounterL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + const TDesC8& aId ) + { + CXnNode* node( aEngine.FindNodeByIdL( aId, aThis->Namespace() ) ); + + if ( node ) + { + CXnControlAdapter* adapter( node->Control() ); + + if ( adapter ) + { + adapter->ResetStylusCounter(); + } + } + } + +// ----------------------------------------------------------------------------- +// GetSystemSetDataL +// ----------------------------------------------------------------------------- +// +static void GetSystemSetDataL( + CXnDomNode& aDomNode, + HBufC8*& aId, + const TDesC8** aPseudoClass, + const TDesC8** aName, + RPointerArray< HBufC8 >* aValues, + const TDesC8** aType, + TBool aSettings, + const TDesC8& aProvidedId, + const TDesC8** aClassId ) + { + CXnDomList& children = aDomNode.ChildNodes(); + + if ( aSettings ) + { + aId = aProvidedId.AllocL(); + } + + TInt count = children.Length(); + + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* node = static_cast< CXnDomNode* >( children.Item( i ) ); + const TDesC8& nodeType = node->Name(); + + if ( nodeType == XnPropertyNames::action::KProperty ) + { + const TDesC8& name = node->AttributeValue( + XnPropertyNames::action::event::systemset::KName ); + const TDesC8& value = node->AttributeValue( + XnPropertyNames::action::event::systemset::KValue ); + + if ( !aSettings && + ( name == XnPropertyNames::action::event::systemset::KId ) ) + { + HBufC8* utfName = HBufC8::NewL( value.Length() ); + TPtr8 ptr = utfName->Des(); + ptr = value; + aId = utfName; + } + else if ( name == XnPropertyNames::action::event::systemset::KPseudoClass ) + { + *aPseudoClass = &value; + } + else if ( name == XnPropertyNames::action::event::systemset::KName ) + { + *aName = &value; + } + else if ( name == XnPropertyNames::action::event::systemset::KValue ) + { + if ( aValues ) + { + HBufC8* valueH = HBufC8::NewLC( value.Length() + KUnitMaxLen ); + TPtr8 ptr( valueH->Des() ); + ptr.Append( value ); + aValues->AppendL( valueH ); //take ownership + CleanupStack::Pop( valueH ); + } + } + else if ( name == XnPropertyNames::action::event::systemset::KType ) + { + *aType = &value; + } + else if ( name == XnPropertyNames::action::event::systemset::KUnit ) + { + if ( value.Length() > KUnitMaxLen ) + { +#ifdef _XN_DEBUG_ + RDebug::Print( _L( "xnnodeimpl GetSystemSetDataL - unexpected length of type string" ) ); +#endif + User::Leave( KErrNotSupported ); + } + if ( aValues ) + { + TInt index = aValues->Count() - 1; + HBufC8* valueH = ( *aValues )[index]; + TPtr8 ptr( valueH->Des() ); + ptr.Append( value ); + } + } + else if ( name == XnPropertyNames::action::event::systemset::KClass ) + { + *aClassId = &value; + } + } + } + } + +// ----------------------------------------------------------------------------- +// RunTryDisplayingMenuL +// ----------------------------------------------------------------------------- +// +static void RunTryDisplayingMenuL( CXnUiEngine& aEngine, CXnDomNode& aEventNode ) + { + CXnNode* menubar( aEngine.MenuBarNode() ); + + if ( menubar ) + { + CXnDomList& children( aEventNode.ChildNodes() ); + + TInt count( children.Length() ); + + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* node = static_cast< CXnDomNode* >( children.Item( i ) ); + + const TDesC8& type( node->Name() ); + + if ( type == XnPropertyNames::action::KProperty ) + { + const TDesC8& id( node->AttributeValue( XnPropertyNames::action::KValue ) ); + + if ( id != KNullDesC8 ) + { + HBufC* menuId( CnvUtfConverter::ConvertToUnicodeFromUtf8L( id ) ); + CleanupStack::PushL( menuId ); + + XnMenuInterface::MXnMenuInterface* menuIf( NULL ); + XnComponentInterface::MakeInterfaceL( menuIf, menubar->AppIfL() ); + + if ( menuIf ) + { + menuIf->TryDisplayingMenuBarL( *menuId ); + } + + CleanupStack::PopAndDestroy( menuId ); + } + } + } + } + } + +// ----------------------------------------------------------------------------- +// RunTryDisplayingListQueryDialogL +// ----------------------------------------------------------------------------- +// +static void RunTryDisplayingListQueryDialogL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnDomNode& aEventNode ) + { + CXnDomList& children( aEventNode.ChildNodes() ); + + TInt count( children.Length() ); + + if ( count > 0 ) + { + CXnDomNode* node = static_cast< CXnDomNode* >( children.Item( 0 ) ); + + const TDesC8& type( node->Name() ); + + if ( type == XnPropertyNames::action::KProperty ) + { + const TDesC8& id( + node->AttributeValue( XnPropertyNames::action::KValue ) ); + + if ( id != KNullDesC8 ) + { + CXnNode* dialog( aEngine.FindNodeByIdL( id, aThis->Namespace() ) ); + + if ( dialog && dialog->Type()->Type() == XnPropertyNames::listquerydialog::KListQueryDialog ) + { + CXnListQueryDialogAdapter* adapter = + static_cast< CXnListQueryDialogAdapter* > ( dialog->Control() ); + + adapter->TryDisplayingDialogL(); + } + + } + } + } + } + +// ----------------------------------------------------------------------------- +// RunTryDisplayingStylusPopupL +// ----------------------------------------------------------------------------- +// +static void RunTryDisplayingStylusPopupL( + CXnNodeImpl* aThis, + CXnNode& aNode, + CXnUiEngine& aEngine, + CXnDomNode& aEventNode ) + { + CXnDomList& children( aEventNode.ChildNodes() ); + + TInt count( children.Length() ); + + if ( count > 0 ) + { + CXnDomNode* node = static_cast< CXnDomNode* >( children.Item( 0 ) ); + + const TDesC8& type( node->Name() ); + + if ( type == XnPropertyNames::action::KProperty ) + { + const TDesC8& id( node->AttributeValue( + XnPropertyNames::action::KValue ) ); + + if ( id != KNullDesC8 ) + { + CXnNode* popup( aEngine.FindNodeByIdL( id, aThis->Namespace() ) ); + + if ( popup && popup->Type()->Type() == _L8("styluspopup") ) + { + CXnPopupControlAdapter* adapter = + static_cast< CXnPopupControlAdapter* > ( popup->Control() ); + + adapter->TryDisplayingStylusPopupL( aNode ); + } + } + } + } + } + +// ----------------------------------------------------------------------------- +// RunSetInitialFocusL +// ----------------------------------------------------------------------------- +// +static void RunSetInitialFocusL( CXnUiEngine& aEngine ) + { + TBool editState( aEngine.EditMode()->EditState() ); + + CXnViewManager* manager( aEngine.ViewManager() ); + + RPointerArray< CXnNode >& pluginNodes( manager->PluginNodes() ); + + if ( editState ) + { + TBool pluginFocused( EFalse ); + + for ( TInt i = 0; i < pluginNodes.Count(); i++ ) + { + CXnNode* node( pluginNodes[i] ); + + if ( node->IsStateSet( XnPropertyNames::style::common::KFocus ) ) + { + pluginFocused = ETrue; + break; + } + } + + if ( !pluginFocused ) + { + for ( TInt i = 0; i < pluginNodes.Count(); i++ ) + { + CXnNode* node( pluginNodes[i] ); + + node->SetStateWithoutNotificationL( + XnPropertyNames::style::common::KFocus ); + + if ( node->IsStateSet( + XnPropertyNames::style::common::KFocus ) ) + { + break; + } + } + } + } + else + { + CXnViewData& viewData( manager->ActiveViewData() ); + + RPointerArray< CXnPluginData > plugins; + CleanupClosePushL( plugins ); + + for( TInt i = 0; i < pluginNodes.Count(); i++ ) + { + CXnPluginData& data( viewData.Plugin( pluginNodes[i] ) ); + + if( data.Occupied() ) + { + plugins.AppendL( &data ); + } + } + + plugins.Append( &viewData ); + + RPointerArray< CXnNode > list; + CleanupClosePushL( list ); + + for( TInt i = 0; i < plugins.Count(); i++ ) + { + plugins[i]->InitialFocusNodesL( list ); + } + + for ( TInt i = 0; i < list.Count(); i++ ) + { + CXnNode* node( list[i] ); + + node->SetStateWithoutNotificationL( + XnPropertyNames::style::common::KFocus ); + + if ( node->IsStateSet( XnPropertyNames::style::common::KFocus ) ) + { + break; + } + } + + CleanupStack::PopAndDestroy( 2, &plugins ); // list + } + } + +// ----------------------------------------------------------------------------- +// RunSystemSetL +// ----------------------------------------------------------------------------- +// +static void RunSystemSetL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnDomNode& aEventNode, + TBool aSettings, + const TDesC8& aId ) + { + HBufC8* id = NULL; + const TDesC8* pseudoClass = NULL; + const TDesC8* name = NULL; + const TDesC8* type = NULL; + const TDesC8* classId = NULL; + + RPointerArray< HBufC8 > values; + CleanupResetAndDestroyPushL( values ); + + GetSystemSetDataL( + aEventNode, id, &pseudoClass, &name, + &values, &type, aSettings, aId, &classId ); + + CleanupStack::PushL( id ); + + if ( !name && id ) + { + for ( TInt i = 0; i < values.Count(); i++ ) + { + const TDesC8* value = values[i]; + + RunSystemSetPCDataL( aThis, aEngine, *id, *value ); + } + } + else if ( name && id && type ) + { + CXnNode* node = aEngine.FindNodeByIdL( *id, aThis->Namespace() ); + + if ( *type == XnPropertyNames::action::event::systemset::type::KString ) + { + RunSystemSetStringL( + aEngine, node, *name, values, CXnDomPropertyValue::EString ); + } + else if ( *type == + XnPropertyNames::action::event::systemset::type::KNumeric ) + { + RunSystemSetNumberL( + aEngine, node, *name, values ); + } + else if ( *type == XnPropertyNames::action::event::systemset::type::KRGB ) + { + RunSystemSetRGBL( + aEngine, node, *name, values ); + } + else if ( *type == XnPropertyNames::action::event::systemset::type::KUrl ) + { + RunSystemSetStringL( + aEngine, node, *name, values, CXnDomPropertyValue::EUri ); + } + else if ( *type == + XnPropertyNames::action::event::systemset::type::KAttribute ) + { + RunSystemSetStringL( + aEngine, node, *name, values, CXnDomPropertyValue::EAttr ); + } + } + else if ( name && classId && type ) + { + CXnPointerArray* array = aEngine.FindNodeByClassL( *classId ); + CleanupStack::PushL( array ); + + const TInt count = array->Container().Count(); + + for ( TInt i = 0; i < count; ++i ) + { + CXnNode* node = static_cast< CXnNode* >(array->Container()[i]); + if ( *type == XnPropertyNames::action::event::systemset::type::KString ) + { + RunSystemSetStringL( + aEngine, node, *name, values, CXnDomPropertyValue::EString ); + } + else if ( *type == + XnPropertyNames::action::event::systemset::type::KNumeric ) + { + RunSystemSetNumberL( + aEngine, node, *name, values ); + } + else if ( *type == XnPropertyNames::action::event::systemset::type::KRGB ) + { + RunSystemSetRGBL( + aEngine, node, *name, values ); + } + else if ( *type == XnPropertyNames::action::event::systemset::type::KUrl ) + { + RunSystemSetStringL( + aEngine, node, *name, values, CXnDomPropertyValue::EUri ); + } + else if ( *type == + XnPropertyNames::action::event::systemset::type::KAttribute ) + { + RunSystemSetStringL( + aEngine, node, *name, values, CXnDomPropertyValue::EAttr ); + } + } + CleanupStack::PopAndDestroy( array ); + } + + CleanupStack::PopAndDestroy( 2, &values ); + } + +// ----------------------------------------------------------------------------- +// ResolveTriggerDelayL +// ----------------------------------------------------------------------------- +// +static void ResolveTriggerDelayL( + CXnUiEngine& /*aEngine*/, + CXnDomNode& aNode, + TInt& aDelay ) + { + CXnDomList& children = aNode.ChildNodes(); + for ( TInt i = 0; i < children.Length(); i++ ) + { + CXnDomNode* child = static_cast< CXnDomNode* >( children.Item( i ) ); + const TDesC8& name = child->AttributeValue( XnPropertyNames::action::KName ); + if ( name == XnPropertyNames::action::trigger::KDelay ) + { + const TDesC8& value = child->AttributeValue( XnPropertyNames::action::KValue ); + if ( value != KNullDesC8 ) + { + TInt triggerDelay( 0 ); + TLex8 lex; + lex.Assign( value ); + lex.Val( triggerDelay ); + aDelay = triggerDelay; + } + } + } + } + +// ----------------------------------------------------------------------------- +// RunEventL +// ----------------------------------------------------------------------------- +// +static TBool RunEventL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnNode& aNode, + CXnDomNode& aEventNode, + CXnDomNode& aTriggerNode, + CXnNode& aEventData ) + { + const TDesC8& nameString( aEventNode.AttributeValue( KName ) ); + + if ( nameString == KNullDesC8 ) + { + return EFalse; + } + + const TDesC8& system( XnPropertyNames::action::event::KSystemPrefix() ); + + if ( nameString.Find( system ) != 0 ) + { + // event doesn't contain "system/" prefix + RunAppUiNotificationL( aEngine, aNode, + aEventNode, aTriggerNode, aEventData ); + } + else if ( nameString == XnPropertyNames::action::event::KSetFocus ) + { + RPointerArray< CXnNode > focusCandidates; + CleanupClosePushL( focusCandidates ); + + GetFocusCandidatesL( aThis, aEngine, aEventNode, focusCandidates ); + + TBool retval( aNode.RunFocusChangeL( focusCandidates ) ); + + CleanupStack::PopAndDestroy( &focusCandidates ); + + return retval; + } + else if ( nameString == XnPropertyNames::action::event::KSetInitialFocus ) + { + RunSetInitialFocusL( aEngine ); + return ETrue; + } + else if ( nameString == XnPropertyNames::action::event::KSet ) + { + RunSystemSetL( aThis, aEngine, aEventNode ); + return ETrue; + } + else if ( nameString == XnPropertyNames::action::event::KSetPassiveFocus || + nameString == XnPropertyNames::action::event::KResetPassiveFocus || + nameString == XnPropertyNames::action::event::KSetActiveFocus ) + { + RunPassiveFocusChangeL( aThis, aEngine, aEventNode, nameString ); + return ETrue; + } + else if ( nameString == XnPropertyNames::action::event::KClearPassiveFocuses ) + { + aEngine.ClearPassiveFocusedNodesL(); + return ETrue; + } + else if ( nameString == XnPropertyNames::action::event::KSetEditMode ) + { + RunEditL( aThis, aEngine, aEventNode ); + return ETrue; + } + else if ( nameString == XnPropertyNames::action::event::KResetEditMode ) + { + RunResetEditL( aThis, aEngine, aEventNode ); + return ETrue; + } + else if ( nameString == XnPropertyNames::action::event::KResetStylusCounter ) + { + HBufC8* id( NULL ); + + GetSystemSetDataL( aEventNode, id ); + CleanupStack::PushL( id ); + + RunResetStylusCounterL( aThis, aEngine, *id ); + + CleanupStack::PopAndDestroy( id ); + + return EFalse; + } + else if ( nameString == XnPropertyNames::action::event::KRunAddWidgetQuery ) + { + aEngine.Editor()->AddWidgetL(); + } + else if ( nameString == XnPropertyNames::action::event::KRemoveFocusedWidget ) + { + aEngine.Editor()->RemoveWidgetL( aEngine.FocusedNode() ); + } + else if ( nameString == XnPropertyNames::action::event::KRunFullScreenEffect ) + { + RunFullScreenEffectL( aEngine, aEventNode ); + } + else if ( nameString == XnPropertyNames::action::event::KActivateNextView ) + { + RunActivateNextViewL( aEngine ); + } + else if ( nameString == XnPropertyNames::action::event::KActivatePreviousView ) + { + RunActivatePreviousViewL( aEngine ); + } + else if ( nameString == XnPropertyNames::action::event::KAddView ) + { + RunAddViewL( aEngine ); + } + else if ( nameString == XnPropertyNames::action::event::KRemoveView ) + { + RunRemoveViewL( aEngine ); + } + else if ( nameString == XnPropertyNames::action::event::KActivateView ) + { + RunActivateViewL( aThis, aEngine, aEventNode ); + } + else if ( nameString == XnPropertyNames::action::event::KActivate ) + { + RunActivateL( aThis, aEngine, aEventNode ); + return ETrue; + } + else if ( nameString == XnPropertyNames::action::event::KActivateSelectedItem ) + { + CXnNode* focusedNode = aEngine.FocusedNode(); + if ( focusedNode ) + { + CXnNode* activate = BuildActivateTriggerNodeL( aEngine ); + CleanupStack::PushL( activate ); + focusedNode->ReportXuikonEventL( *activate ); + CleanupStack::PopAndDestroy( activate ); + } + return EFalse; + } + else if ( nameString == XnPropertyNames::action::event::KDeactivate ) + { + RunDeactivateL( aThis, aEngine, aEventNode ); + return ETrue; + } + else if ( nameString == XnPropertyNames::action::event::KExit ) + { + RunAppExit( aEngine ); + } + else if ( nameString == XnPropertyNames::action::event::KTryDisplayingMenu ) + { + RunTryDisplayingMenuL( aEngine, aEventNode ); + } + else if ( nameString == + XnPropertyNames::action::event::KTryDisplayingListQueryDialog ) + { + RunTryDisplayingListQueryDialogL( aThis, aEngine, aEventNode ); + } + else if ( nameString == XnPropertyNames::action::event::KTryDisplayingStylusPopup ) + { + RunTryDisplayingStylusPopupL( aThis, aNode, aEngine, aEventNode ); + return ETrue; + } + else if ( nameString == XnPropertyNames::action::event::KToggleWidgetsVisibilty ) + { + aEngine.Editor()->ToggleWidgetsVisibiltyL(); + + // check if focused widget need to be changed + CXnNode* focused( aEngine.FocusedNode() ); + + if ( !focused || !IsNodeNavigableL( focused ) ) + { + RunSetInitialFocusL( aEngine ); + } + + return ETrue; + } + else if ( nameString == XnPropertyNames::action::event::KReportEnterEditMode ) + + { + CXnNode* trigger( BuildTriggerNodeL( aEngine, + XnPropertyNames::action::trigger::name::KEditMode ) ); + CleanupStack::PushL( trigger ); + + CXnDomStringPool& sp( aEngine.ODT()->DomDocument().StringPool() ); + + CXnProperty* value( CXnProperty::NewL( + XnPropertyNames::action::KValue, + XnPropertyNames::action::trigger::name::editmode::KEnter, + CXnDomPropertyValue::EString, sp ) ); + CleanupStack::PushL( value ); + + trigger->SetPropertyL( value ); + CleanupStack::Pop( value ); + + aEngine.ActiveView()->ReportXuikonEventL( *trigger ); + + CleanupStack::PopAndDestroy( trigger ); + + return ETrue; + } + else if( nameString == XnPropertyNames::action::event::KReportExitEditMode ) + { + CXnNode* trigger( BuildTriggerNodeL( aEngine, + XnPropertyNames::action::trigger::name::KEditMode ) ); + CleanupStack::PushL( trigger ); + + CXnDomStringPool& sp( aEngine.ODT()->DomDocument().StringPool() ); + + CXnProperty* value( CXnProperty::NewL( + XnPropertyNames::action::KValue, + XnPropertyNames::action::trigger::name::editmode::KExit, + CXnDomPropertyValue::EString, sp ) ); + CleanupStack::PushL( value ); + + trigger->SetPropertyL( value ); + CleanupStack::Pop( value ); + + aEngine.ActiveView()->ReportXuikonEventL( *trigger ); + + CleanupStack::PopAndDestroy( trigger ); + + return ETrue; + } + else if ( nameString == XnPropertyNames::action::event::KRestartTriggerTimer ) + { + TInt delay( 0 ); + + ResolveTriggerDelayL( aEngine, aEventNode, delay ); + + if ( delay > 0 ) + { + aNode.RestartTimedTrigger( delay ); + } + else + { + TTimeIntervalMicroSeconds32 delayms = aNode.TriggerDelay(); + aNode.RestartTimedTrigger( delayms.Int() ); + } + + return ETrue; + } + else if ( nameString == XnPropertyNames::action::event::KCancelTriggerTimer ) + { + aNode.RestartTimedTrigger(); + return ETrue; + } + else if ( nameString == XnPropertyNames::action::event::KSetWallpaper ) + { + aEngine.Editor()->SetWallpaperL(); + return ETrue; + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// RunEventsL +// ----------------------------------------------------------------------------- +// +static void RunEventsL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnNode& aNode, + CXnDomNode& aActionNode, + CXnDomNode& aTriggerNode, + CXnNode& aEventData ) + { + CXnDomList& children = aActionNode.ChildNodes(); + TInt count = children.Length(); + TBool render = EFalse; + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* node = static_cast< CXnDomNode* >(children.Item( i ) ); + const TDesC8& type = node->Name(); + if ( type == XnPropertyNames::action::KEvent ) + { + TBool tmp = RunEventL( + aThis, aEngine, aNode, *node, aTriggerNode, aEventData ); + if ( !render ) + { + render = tmp; + } + } + } + if ( render ) + { + aEngine.RenderUIL( NULL ); + } + } + +// ----------------------------------------------------------------------------- +// DoMatchTriggerForHighLevelKeyEventL +// ----------------------------------------------------------------------------- +// +static TBool DoMatchTriggerForHighLevelKeyEventL( + CXnNode& aNode, + const TKeyEvent& aKeyEvent, + TEventCode aType, + const TDesC8& aHighLevelKey ) + { + const TDesC8* key; + + switch ( aKeyEvent.iCode ) + { + case EKeyLeftArrow: + key = &XnPropertyNames::action::trigger::name::KLeft; + break; + case EKeyRightArrow: + key = &XnPropertyNames::action::trigger::name::KRight; + break; + case EKeyUpArrow: + key = &XnPropertyNames::action::trigger::name::KUp; + break; + case EKeyDownArrow: + key = &XnPropertyNames::action::trigger::name::KDown; + break; + default: + key = NULL; + break; + } + + if ( !key || aType != EEventKey ) + { + return EFalse; + } + + CXnNode* parent( aNode.Parent() ); + + if ( !parent || aNode.ViewNodeImpl() ) + { + if ( *key == aHighLevelKey ) + { + return ETrue; + } + } + else + { + const TDesC8* direction( + &XnPropertyNames::style::common::direction::KLTR ); + const TDesC8* orientation( + &XnPropertyNames::style::common::block_progression::KTB ); + + CXnProperty* directionProperty( parent->DirectionL() ); + + if ( directionProperty ) + { + direction = &directionProperty->StringValue(); + } + + CXnProperty* orientationProperty( parent->BlockProgressionL() ); + + if ( orientationProperty ) + { + orientation = &orientationProperty->StringValue(); + } + + if ( *direction == XnPropertyNames::style::common::direction::KLTR && + ( *orientation == XnPropertyNames::style::common::block_progression::KLR || + *orientation == XnPropertyNames::style::common::block_progression::KRL ) ) + { + if ( *key == aHighLevelKey ) + { + return ETrue; + } + } + else if ( *direction == XnPropertyNames::style::common::direction::KRTL && + ( *orientation == XnPropertyNames::style::common::block_progression::KLR || + *orientation == XnPropertyNames::style::common::block_progression::KRL ) ) + { + if ( *key == XnPropertyNames::action::trigger::name::KRight && + aHighLevelKey == XnPropertyNames::action::trigger::name::KLeft ) + { + return ETrue; + } + + if ( *key == XnPropertyNames::action::trigger::name::KLeft && + aHighLevelKey == XnPropertyNames::action::trigger::name::KRight ) + { + return ETrue; + } + + if ( *key == XnPropertyNames::action::trigger::name::KDown && + aHighLevelKey == XnPropertyNames::action::trigger::name::KDown ) + { + return ETrue; + } + + if ( *key == XnPropertyNames::action::trigger::name::KUp && + aHighLevelKey == XnPropertyNames::action::trigger::name::KUp ) + { + return ETrue; + } + } + else if ( *direction == XnPropertyNames::style::common::direction::KLTR && + *orientation == XnPropertyNames::style::common::block_progression::KTB ) + { + if ( *key == XnPropertyNames::action::trigger::name::KUp && + aHighLevelKey == XnPropertyNames::action::trigger::name::KLeft ) + { + return ETrue; + } + + if ( *key == XnPropertyNames::action::trigger::name::KDown && + aHighLevelKey == XnPropertyNames::action::trigger::name::KRight ) + { + return ETrue; + } + + if ( *key == XnPropertyNames::action::trigger::name::KLeft && + aHighLevelKey == XnPropertyNames::action::trigger::name::KDown ) + { + return ETrue; + } + + if ( *key == XnPropertyNames::action::trigger::name::KRight && + aHighLevelKey == XnPropertyNames::action::trigger::name::KUp ) + { + return ETrue; + } + } + else if ( *direction == XnPropertyNames::style::common::direction::KRTL && + *orientation == XnPropertyNames::style::common::block_progression::KTB ) + { + if ( *key == XnPropertyNames::action::trigger::name::KDown && + aHighLevelKey == XnPropertyNames::action::trigger::name::KLeft ) + { + return ETrue; + } + + if ( *key == XnPropertyNames::action::trigger::name::KUp && + aHighLevelKey == XnPropertyNames::action::trigger::name::KRight ) + { + return ETrue; + } + + if ( *key == XnPropertyNames::action::trigger::name::KLeft && + aHighLevelKey == XnPropertyNames::action::trigger::name::KDown ) + { + return ETrue; + } + + if ( *key == XnPropertyNames::action::trigger::name::KRight && + aHighLevelKey == XnPropertyNames::action::trigger::name::KUp ) + { + return ETrue; + } + } + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// MatchActionForKeyEventL +// ----------------------------------------------------------------------------- +// +static TBool MatchActionForKeyEventL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnNode& aNode, + const TKeyEvent& aKeyEvent, TEventCode aType, + CXnDomNode& aActionNode ) + { + CXnDomList& children = aActionNode.ChildNodes(); + TInt count = children.Length(); + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* node = static_cast< CXnDomNode* >( children.Item( i ) ); + const TDesC8& type = node->Name(); + if ( type == XnPropertyNames::action::KTrigger ) + { + if ( node && ( IsTriggerRunnableL( *node ) || IsTriggerActiveL( *node ) ) ) + { + TBool match = MatchTriggerForKeyEventL( + aThis, aEngine, aNode, aKeyEvent, aType, aActionNode, *node ); + if ( match ) + { + return match; + } + } + } + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// IsTriggerActiveL +// ----------------------------------------------------------------------------- +// +static TBool IsTriggerActiveL( CXnDomNode& aNode ) + { + CXnDomList& propList = aNode.PropertyList(); + TInt count = propList.Length(); + for ( TInt j = 0; j < count; j++ ) + { + CXnDomProperty* prop = static_cast< CXnDomProperty* >( propList.Item( j ) ); + const TDesC8& propName = prop->Name(); + if ( propName == XnPropertyNames::style::common::KDisplay ) + { + CXnDomList& propValList = prop->PropertyValueList(); + TInt propValCount(propValList.Length()); + for ( TInt k = 0; k < propValCount; k++ ) + { + CXnDomPropertyValue* propVal = + static_cast< CXnDomPropertyValue* >( propValList.Item( k ) ); + CXnDomPropertyValue::TPrimitiveValueType type = + propVal->PrimitiveValueType(); + switch ( type ) + { + case CXnDomPropertyValue::EString: + case CXnDomPropertyValue::EIdent: + case CXnDomPropertyValue::EUri: + case CXnDomPropertyValue::EAttr: + case CXnDomPropertyValue::EUnknown: + { + const TDesC8& value = propVal->StringValueL(); + if ( value == XnPropertyNames::style::common::display::KNone ) + { + return EFalse; + } + else + { + return ETrue; + } + } + } + } + } + } + return ETrue; + } + +// ----------------------------------------------------------------------------- +// MatchActionForEventL +// ----------------------------------------------------------------------------- +// +static TBool MatchActionForEventL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnNode& aNode, + CXnNode& aEventData, + CXnDomNode& aActionNode, + TInt aSource ) + { + CXnDomList& children = aActionNode.ChildNodes(); + TInt count = children.Length(); + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* node = static_cast< CXnDomNode* >( children.Item( i ) ); + const TDesC8& type = node->Name(); + if ( type == XnPropertyNames::action::KTrigger && + node && IsTriggerRunnableL( *node ) ) + { + TBool match = MatchTriggerForEventL( + aThis, aEngine, aNode, aEventData, aActionNode, *node, aSource ); + if ( match ) + { + return match; + } + } + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// FindLoopedFocusableNodeL +// ----------------------------------------------------------------------------- +// +static CXnNode* FindLoopedFocusableNodeL( CXnNode& aNode, TBool aForward ) + { + if ( aNode.ViewNodeImpl() ) + { + return NULL; + } + CXnNode* nextNode = NULL; + CXnProperty* navLoopProperty = aNode.GetPropertyL( + XnPropertyNames::style::common::KS60NavLooping ); + if ( navLoopProperty ) + { + const TDesC8& loopValue = navLoopProperty->StringValue(); + if ( loopValue != KNullDesC8 && + loopValue == XnPropertyNames::grid::s60_focus_looping::KStop ) + { + return NULL; + } + } + if ( aForward ) + { + nextNode = ForwardLoopL( aNode ); + } + else + { + nextNode = BackwardLoopL( aNode ); + } + return nextNode; + } + +// ----------------------------------------------------------------------------- +// GetNavIndexL +// ----------------------------------------------------------------------------- +// +static CXnDomPropertyValue* GetNavIndexL( CXnNode& aNode ) + { + CXnProperty* navIndexProperty = aNode.NavIndexL(); + CXnDomPropertyValue* value = NULL; + if ( navIndexProperty ) + { + value = static_cast< CXnDomPropertyValue* >( + navIndexProperty->Property()->PropertyValueList().Item( 0 ) ); + } + return value; + } + +// ----------------------------------------------------------------------------- +// ForwardL +// ----------------------------------------------------------------------------- +// +static CXnNode* ForwardL( CXnNode& aNode ) + { + RPointerArray< CXnNode >& siblings = aNode.Parent()->Children(); + CXnNode* nextNode = NULL; + CXnDomPropertyValue* navIndexValue = GetNavIndexL( aNode ); + CXnDomPropertyValue* prevIndexValue = NULL; + CXnDomPropertyValue* tmpIndexValue = NULL; + TInt count = siblings.Count(); + TInt nodePosition = count; + TBool first = ETrue; + for ( TInt i = 0; i < count; ++i ) + { + CXnNode* tmpNode = siblings[i]; + if ( tmpNode == &aNode ) + { + nodePosition = i; + continue; + } + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + tmpIndexValue = GetNavIndexL( *tmpNode ); + if ( tmpIndexValue ) + { + if ( tmpIndexValue->IsNoneIdent() ) + { + // nav index set as none, skipping + continue; + } + } + if ( ( CompareNavIndexesL( tmpIndexValue, navIndexValue ) == 0 ) && + ( first || + ( CompareNavIndexesL( tmpIndexValue, prevIndexValue ) < 0 ) ) && + ( i > nodePosition ) ) + { + first = EFalse; + prevIndexValue = tmpIndexValue; + nextNode = tmpNode; + } + else if ( ( CompareNavIndexesL( tmpIndexValue, navIndexValue ) > 0 ) && + ( first || + ( CompareNavIndexesL( tmpIndexValue, prevIndexValue ) < 0 ) ) ) + { + first = EFalse; + prevIndexValue = tmpIndexValue; + nextNode = tmpNode; + } + } + return nextNode; + } + +// ----------------------------------------------------------------------------- +// ForwardLoopL +// ----------------------------------------------------------------------------- +// +static CXnNode* ForwardLoopL( CXnNode& aNode ) + { + RPointerArray< CXnNode >& siblings = aNode.Parent()->Children(); + CXnNode* nextNode = NULL; + CXnDomPropertyValue* navIndexValue = GetNavIndexL( aNode ); + CXnDomPropertyValue* tmpIndexValue = NULL; + CXnDomPropertyValue* prevIndexValue = NULL; + TInt count = siblings.Count(); + TInt nodePosition = count; + TBool first = ETrue; + for ( TInt i = 0; i < count; ++i ) + { + CXnNode* tmpNode = siblings[i]; + if ( tmpNode == &aNode ) + { + nodePosition = i; + continue; + } + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + tmpIndexValue = GetNavIndexL( *tmpNode ); + if ( tmpIndexValue ) + { + if ( tmpIndexValue->IsNoneIdent() ) + { + // nav index set as none, skipping + continue; + } + } + if ( ( CompareNavIndexesL( navIndexValue, tmpIndexValue ) == 0 ) && + ( first || + ( CompareNavIndexesL( tmpIndexValue, prevIndexValue ) < 0 ) ) && + ( i < nodePosition ) ) + { + first = EFalse; + prevIndexValue = tmpIndexValue; + nextNode = tmpNode; + } + else if ( ( CompareNavIndexesL( tmpIndexValue, navIndexValue ) < 0 ) && + ( first || + ( CompareNavIndexesL( tmpIndexValue, prevIndexValue ) < 0 ) ) ) + { + first = EFalse; + prevIndexValue = tmpIndexValue; + nextNode = tmpNode; + } + } + return nextNode; + } + +// ----------------------------------------------------------------------------- +// BackwardL +// ----------------------------------------------------------------------------- +// +static CXnNode* BackwardL( CXnNode& aNode ) + { + RPointerArray< CXnNode >& siblings = aNode.Parent()->Children(); + CXnNode* nextNode = NULL; + CXnDomPropertyValue* navIndexValue = GetNavIndexL( aNode ); + CXnDomPropertyValue* tmpIndexValue = NULL; + TInt count = siblings.Count(); + CXnDomPropertyValue* nextIndexValue = GetNavIndexL( *siblings[count - 1] ); + TInt nodePosition = 0; + TBool first = ETrue; + for ( TInt i = count - 1; i > -1; --i ) + { + CXnNode* tmpNode = siblings[i]; + if ( tmpNode == &aNode ) + { + nodePosition = i; + continue; + } + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + tmpIndexValue = GetNavIndexL( *tmpNode ); + if ( tmpIndexValue ) + { + if ( tmpIndexValue->IsNoneIdent() ) + { + // nav index set as none, skipping + continue; + } + } + if ( ( CompareNavIndexesL( navIndexValue, tmpIndexValue ) == 0 ) && + ( first || + ( CompareNavIndexesL( tmpIndexValue, nextIndexValue ) > 0 ) ) && + ( i < nodePosition ) ) + { + first = EFalse; + nextIndexValue = tmpIndexValue; + nextNode = tmpNode; + } + else if ( ( CompareNavIndexesL( tmpIndexValue, navIndexValue ) < 0 ) && + ( first || + ( CompareNavIndexesL( tmpIndexValue, nextIndexValue ) > 0 ) ) ) + { + first = EFalse; + nextIndexValue = tmpIndexValue; + nextNode = tmpNode; + } + } + return nextNode; + } + +// ----------------------------------------------------------------------------- +// BackwardLoopL +// ----------------------------------------------------------------------------- +// +static CXnNode* BackwardLoopL( CXnNode& aNode ) + { + RPointerArray& siblings = aNode.Parent()->Children(); + CXnNode* nextNode = NULL; + CXnDomPropertyValue* navIndexValue = GetNavIndexL( aNode ); + CXnDomPropertyValue* tmpIndexValue = NULL; + TInt count = siblings.Count(); + CXnDomPropertyValue* nextIndexValue = GetNavIndexL( *siblings[count - 1] ); + TInt nodePosition = 0; + TBool first = ETrue; + for ( TInt i = count - 1; i > -1; --i ) + { + CXnNode* tmpNode = siblings[i]; + if ( tmpNode == &aNode ) + { + nodePosition = i; + continue; + } + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + tmpIndexValue = GetNavIndexL( *tmpNode ); + if ( tmpIndexValue ) + { + if ( tmpIndexValue->IsNoneIdent() ) + { + // nav index set as none, skipping + continue; + } + } + if ( ( CompareNavIndexesL( tmpIndexValue, navIndexValue ) == 0 ) && + ( first || + ( CompareNavIndexesL( tmpIndexValue, nextIndexValue ) > 0 ) ) && + ( i > nodePosition ) ) + { + first = EFalse; + nextIndexValue = tmpIndexValue; + nextNode = tmpNode; + } + else if ( ( CompareNavIndexesL( tmpIndexValue, navIndexValue ) > 0 ) && + ( first || + ( CompareNavIndexesL( tmpIndexValue, nextIndexValue ) > 0 ) ) ) + { + first = EFalse; + nextIndexValue = tmpIndexValue; + nextNode = tmpNode; + } + } + return nextNode; + } + +// ----------------------------------------------------------------------------- +// CompareNavIndexesL +// ----------------------------------------------------------------------------- +// +static TInt CompareNavIndexesL( + CXnDomPropertyValue* aCurrentPropertyValue, + CXnDomPropertyValue* aNextPropertyValue ) + { + if ( !aCurrentPropertyValue && !aNextPropertyValue ) + { + return 0; + } + else if ( aCurrentPropertyValue && !aNextPropertyValue ) + { + if ( aCurrentPropertyValue->IsAutoIdent() ) + { + return 0; + } + return 1; + } + else if ( !aCurrentPropertyValue && aNextPropertyValue ) + { + if ( aNextPropertyValue->IsAutoIdent() ) + { + return 0; + } + return -1; + } + else if ( aCurrentPropertyValue->IsAutoIdent() && + aNextPropertyValue->IsAutoIdent() ) + { + return 0; + } + else if ( !aCurrentPropertyValue->IsAutoIdent() && + aNextPropertyValue->IsAutoIdent() ) + { + return 1; + } + else if ( aCurrentPropertyValue->IsAutoIdent() && + !aNextPropertyValue->IsAutoIdent() ) + { + return -1; + } + else + { + return + aCurrentPropertyValue->FloatValueL() < aNextPropertyValue->FloatValueL() ? + -1 : + aCurrentPropertyValue->FloatValueL() == aNextPropertyValue->FloatValueL() ? + 0 : + 1; + } + } + +// ----------------------------------------------------------------------------- +// FindNextFocusableNodeByNavIndexL +// ----------------------------------------------------------------------------- +// +static CXnNode* FindNextFocusableNodeByNavIndexL( CXnNode& aNode, TBool aForward ) + { + if ( aNode.ViewNodeImpl() ) + { + return NULL; + } + CXnNode* nextNode = NULL; + if ( aForward ) + { + nextNode = ForwardL( aNode ); + } + else + { + nextNode = BackwardL( aNode ); + } + return nextNode; + } + +// ----------------------------------------------------------------------------- +// FindNextFocusableNodeL +// ----------------------------------------------------------------------------- +// +TBool FindNextFocusableNodeL( CXnNode& aNode, TBool aForward ) + { + CXnNode* node( FindNextFocusableNodeByNavIndexL( aNode, aForward ) ); + + if ( !node ) + { + node = FindLoopedFocusableNodeL( aNode, aForward ); + } + + if ( node ) + { + node->SetStateL( XnPropertyNames::style::common::KFocus ); + if( node && node->ScrollableControl() ) + { + node->ScrollableControl()->ShowItem( *node ); + } + return ETrue; + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// FindNextNodeFromRightL +// ----------------------------------------------------------------------------- +// +static CXnNode* FindNextNodeFromRightL( + RPointerArray< CXnNode >& aArray, + CXnNode& aNode, + TBool stayInNamespace, + CXnUiEngine* aEngine ) + { + + CXnNode* nextNode = NULL; + TRect rect = aNode.PaddingRect(); + + for ( TInt i = 0; i < aArray.Count(); ++i ) + { + CXnNode* tmpNode = aArray[i]; + if ( tmpNode == &aNode ) + { + continue; + } + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + if ( tmpNode->FindViewNode() != tmpNode->UiEngine()->ActiveView() ) + { + // do not shift focus to another view + continue; + } + + const TDesC8& tmpNamespace = tmpNode->Impl()->Namespace(); + const TDesC8& nodeNamespace = aNode.Impl()->Namespace(); + + if ( stayInNamespace && tmpNamespace != nodeNamespace ) + { + // if staying in the same namespace is required, + // do not shift focus to a different namespace + continue; + } + + // TODO: only plugin widgets are available in edit mode + + TRect tmpRect = tmpNode->PaddingRect(); + + // temp node qualification: + // 1. left edge of temp node is to the right from focused's right edge + // 2. top edge of temp node is NOT below the bottom edge of focused node + // 3. bottom edge of temp node is NOT above the top edge of focused node + if ( rect.iBr.iX - 1 < tmpRect.iTl.iX && + rect.iBr.iY - 1 >= tmpRect.iTl.iY && + rect.iTl.iY <= tmpRect.iBr.iY - 1 ) + { + if ( !nextNode ) + { + nextNode = tmpNode; + } + else + { + // left edge of temp node is closer to focused than next node's + // left edge + if ( tmpRect.iTl.iX < nextNode->PaddingRect().iTl.iX ) + { + nextNode = tmpNode; + continue; + } + // left edge of temp and next are at the same level + else if ( tmpRect.iTl.iX == nextNode->PaddingRect().iTl.iX ) + { + // top edges are at the same level, choose this one + if ( tmpRect.iTl.iY == rect.iTl.iY ) + { + nextNode = tmpNode; + continue; + } + // top edges are not at the same level + else + { + if ( !AknLayoutUtils::LayoutMirrored() ) + { + // candidate's top edge is below focused's top edge + // and previous candidate's top edge is above + // focused's top edge + if ( nextNode->PaddingRect().iTl.iY < rect.iTl.iY && + tmpRect.iTl.iY > rect.iTl.iY ) + { + nextNode = tmpNode; + continue; + } + // previous candidate's top edge is below focused's + // top edge. Also, candidate's top edge is below + // focused's top edge. Select the highest one. + else if ( nextNode->PaddingRect().iTl.iY > rect.iTl.iY && + tmpRect.iTl.iY > rect.iTl.iY && + tmpRect.iTl.iY < nextNode->PaddingRect().iTl.iY ) + { + nextNode = tmpNode; + continue; + } + } + else // arabic/hebrew layout + { + // candidate's top edge is above focused's top edge + // and previous candidate's top edge is below + // focused's top edge + if ( nextNode->PaddingRect().iTl.iY > rect.iTl.iY && + tmpRect.iTl.iY < rect.iTl.iY ) + { + nextNode = tmpNode; + continue; + } + // candidate's and previous' top edge is below focused's + // top edge. Select the highest one. + else if ( nextNode->PaddingRect().iTl.iY > rect.iTl.iY && + tmpRect.iTl.iY > rect.iTl.iY && + tmpRect.iTl.iY < nextNode->PaddingRect().iTl.iY ) + { + nextNode = tmpNode; + continue; + } + } + } + } + else + { + continue; + } + } + } + } + + // find node below or above to the right + if ( !nextNode ) + { + if ( !stayInNamespace && aEngine && + aEngine->ViewManager()->ViewAmount() != KOneView ) + { + aEngine->ViewManager()->ActivateNextViewL(); + return nextNode; + } + CXnNode* candidateAbove = NULL; + CXnNode* candidateBelow = NULL; + + for ( TInt i = 0; i < aArray.Count(); ++i ) + { + CXnNode* tmpNode = aArray[i]; + if ( tmpNode == &aNode ) + { + continue; + } + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + if ( tmpNode->FindViewNode() != tmpNode->UiEngine()->ActiveView() ) + { + // do not shift focus to another view + continue; + } + + const TDesC8& tmpNamespace = tmpNode->Impl()->Namespace(); + const TDesC8& nodeNamespace = aNode.Impl()->Namespace(); + + if ( stayInNamespace && tmpNamespace != nodeNamespace ) + { + // if staying in the same namespace is required, + // do not shift focus to a different namespace + continue; + } + // TODO: only plugin widgets are available in edit mode + + TRect tmpRect = tmpNode->PaddingRect(); + + // temp node qualification: + // left edge of temp node is to the right from focused's right edge + if ( rect.iBr.iX - 1 < tmpRect.iTl.iX ) + { + // tmp is above the focused node + if ( tmpRect.iBr.iY - 1 < rect.iTl.iY ) + { + if ( candidateAbove == NULL ) + { + candidateAbove = tmpNode; + } + else + { + // use pythagorean theorem to determine the closest node + TInt xDistTmp = tmpRect.iTl.iX - rect.iBr.iX; + TInt yDistTmp = tmpRect.iBr.iY - rect.iTl.iY; + TReal tmpDist = Abs( ( xDistTmp * xDistTmp ) + ( yDistTmp * yDistTmp ) ); + + TInt xCand = candidateAbove->PaddingRect().iTl.iX - rect.iBr.iX; + TInt yCand = candidateAbove->PaddingRect().iBr.iY - rect.iTl.iY; + TReal cDist = Abs( ( xCand * xCand ) + ( yCand * yCand ) ); + + if ( tmpDist < cDist ) + { + candidateAbove = tmpNode; + } + } + } + else + { + if ( candidateBelow == NULL ) + { + candidateBelow = tmpNode; + } + else + { + // use pythagorean theorem to determine the closest node + TInt xDistTmp = tmpRect.iTl.iX - rect.iBr.iX; + TInt yDistTmp = tmpRect.iTl.iY - rect.iBr.iY; + TReal tmpDist = Abs( ( xDistTmp * xDistTmp ) + ( yDistTmp * yDistTmp ) ); + + TInt xCand = candidateBelow->PaddingRect().iTl.iX - rect.iBr.iX; + TInt yCand = candidateBelow->PaddingRect().iTl.iY - rect.iBr.iY; + TReal cDist = Abs( ( xCand * xCand ) + ( yCand * yCand ) ); + + if ( tmpDist < cDist ) + { + candidateBelow = tmpNode; + } + } + } + } + } + + if ( !AknLayoutUtils::LayoutMirrored() ) + { + if ( candidateBelow ) + { + nextNode = candidateBelow; + } + else + { + if ( candidateAbove ) + { + nextNode = candidateAbove; + } + } + } + else + { + if ( candidateAbove ) + { + nextNode = candidateAbove; + } + else + { + if ( candidateBelow ) + { + nextNode = candidateBelow; + } + } + } + } + + // loop to the right + if ( !nextNode ) + { + CXnNode* candidateAbove = NULL; + CXnNode* candidateBelow = NULL; + + for ( TInt i = 0; i < aArray.Count(); ++i ) + { + CXnNode* tmpNode = aArray[i]; + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + if ( tmpNode->FindViewNode() != tmpNode->UiEngine()->ActiveView() ) + { + // do not shift focus to another view + continue; + } + + const TDesC8& tmpNamespace = tmpNode->Impl()->Namespace(); + const TDesC8& nodeNamespace = aNode.Impl()->Namespace(); + + if ( stayInNamespace && tmpNamespace != nodeNamespace ) + { + // if staying in the same namespace is required, + // do not shift focus to a different namespace + continue; + } + + // TODO: only plugin widgets are available in edit mode + TRect tmpRect = tmpNode->PaddingRect(); + + // tmp is above the focused node + if ( tmpRect.iBr.iY <= rect.iTl.iY ) + { + if ( candidateAbove == NULL ) + { + candidateAbove = tmpNode; + } + else + { + // use pythagorean theorem to determine the closest node + TInt xDistTmp = tmpRect.iTl.iX; + TInt yDistTmp = tmpRect.iTl.iY - rect.iTl.iY; + TReal tmpDist = Abs( ( xDistTmp * xDistTmp ) + ( yDistTmp * yDistTmp ) ); + + TInt xCand = candidateAbove->PaddingRect().iTl.iX; + TInt yCand = candidateAbove->PaddingRect().iTl.iY - rect.iTl.iY; + TReal cDist = Abs( ( xCand * xCand ) + ( yCand * yCand ) ); + + if ( tmpDist < cDist ) + { + candidateAbove = tmpNode; + } + } + } + else + { + if ( candidateBelow == NULL ) + { + candidateBelow = tmpNode; + } + else + { + // use pythagorean theorem to determine the closest node + TInt xDistTmp = tmpRect.iTl.iX; + TInt yDistTmp = rect.iTl.iY - tmpRect.iTl.iY; + TReal tmpDist = Abs( ( xDistTmp * xDistTmp ) + ( yDistTmp * yDistTmp ) ); + + TInt xCand = candidateBelow->PaddingRect().iTl.iX; + TInt yCand = rect.iTl.iY - candidateBelow->PaddingRect().iTl.iY; + TReal cDist = Abs( ( xCand * xCand ) + ( yCand * yCand ) ); + + if ( tmpDist < cDist ) + { + candidateBelow = tmpNode; + } + } + } + } + + if ( candidateAbove && candidateBelow ) + { + CXnNode* pluginAbove = FindPluginNode( *candidateAbove ); + CXnNode* pluginBelow = FindPluginNode( *candidateBelow ); + + TReal aboveDist = 0; + TReal belowDist = 0; + + if ( pluginAbove ) + { + TInt xAbove = pluginAbove->PaddingRect().iTl.iX; + TInt yAbove = 0; + if ( !AknLayoutUtils::LayoutMirrored() ) + { + yAbove = rect.iTl.iY - pluginAbove->PaddingRect().iTl.iY; + } + else + { + yAbove = rect.iTl.iY - pluginAbove->PaddingRect().iBr.iY; + } + aboveDist = Abs( ( xAbove * xAbove ) + ( yAbove * yAbove ) ); + } + else + { + TInt xAbove = candidateAbove->PaddingRect().iTl.iX; + TInt yAbove = 0; + if ( !AknLayoutUtils::LayoutMirrored() ) + { + yAbove = rect.iTl.iY - candidateAbove->PaddingRect().iTl.iY; + } + else + { + yAbove = rect.iTl.iY - candidateAbove->PaddingRect().iBr.iY; + } + + aboveDist = Abs( ( xAbove * xAbove ) + ( yAbove * yAbove ) ); + } + + if ( pluginBelow ) + { + TInt xBelow = pluginBelow->PaddingRect().iTl.iX; + TInt yBelow = pluginBelow->PaddingRect().iTl.iY - rect.iTl.iY; + belowDist = Abs( ( xBelow * xBelow ) + ( yBelow * yBelow ) ); + } + else + { + TInt xBelow = candidateBelow->PaddingRect().iTl.iX; + TInt yBelow = candidateBelow->PaddingRect().iTl.iY - rect.iTl.iY; + belowDist = Abs( ( xBelow * xBelow ) + ( yBelow * yBelow ) ); + } + + if ( aboveDist < belowDist ) + { + nextNode = candidateAbove; + } + else if ( belowDist < aboveDist ) + { + nextNode = candidateBelow; + } + else + { + if ( !AknLayoutUtils::LayoutMirrored() ) + { + nextNode = candidateBelow; + } + else + { + nextNode = candidateAbove; + } + } + } + else if ( candidateAbove ) + { + nextNode = candidateAbove; + } + else if ( candidateBelow ) + { + nextNode = candidateBelow; + } + else + { + // do nothing + } + } + + if ( stayInNamespace && !nextNode ) + { + return &aNode; + } + + return nextNode; + } + +// ----------------------------------------------------------------------------- +// FindNextNodeFromLeftL +// ----------------------------------------------------------------------------- +// +static CXnNode* FindNextNodeFromLeftL( + RPointerArray< CXnNode >& aArray, + CXnNode& aNode, + TBool stayInNamespace, + CXnUiEngine* aEngine ) + { + CXnNode* nextNode = NULL; + TRect rect = aNode.PaddingRect(); + + for ( TInt i = 0; i < aArray.Count(); ++i ) + { + CXnNode* tmpNode = aArray[i]; + if ( tmpNode == &aNode ) + { + continue; + } + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + if ( tmpNode->FindViewNode() != tmpNode->UiEngine()->ActiveView() ) + { + // do not shift focus to another view + continue; + } + + const TDesC8& tmpNamespace = tmpNode->Impl()->Namespace(); + const TDesC8& nodeNamespace = aNode.Impl()->Namespace(); + + if ( stayInNamespace && tmpNamespace != nodeNamespace ) + { + // if staying in the same namespace is required, + // do not shift focus to a different namespace + continue; + } + + // TODO: only plugin widgets are available in edit mode + + TRect tmpRect = tmpNode->PaddingRect(); + + // temp node qualification: + // 1. right edge of temp node is to the left from focused's left edge + // 2. top edge of temp node is NOT below the bottom edge of focused node + // 3. bottom edge of temp node is NOT above the top edge of focused node + if ( rect.iTl.iX > tmpRect.iBr.iX - 1 && + rect.iBr.iY - 1 >= tmpRect.iTl.iY && + rect.iTl.iY <= tmpRect.iBr.iY - 1 ) + { + if ( !nextNode ) + { + nextNode = tmpNode; + } + else + { + // right edge of temp node is closer to focused than next node's + // right edge + if ( tmpRect.iBr.iX - 1 > nextNode->PaddingRect().iBr.iX - 1 ) + { + nextNode = tmpNode; + continue; + } + // left edge of temp and next are at the same level + else if ( tmpRect.iBr.iX - 1 == nextNode->PaddingRect().iBr.iX - 1 ) + { + // top edges are at the same level, choose this one + if ( tmpRect.iTl.iY == rect.iTl.iY ) + { + nextNode = tmpNode; + continue; + } + // top edges are not at the same level + else + { + if ( !AknLayoutUtils::LayoutMirrored() ) + { + // candidate's top edge is below focused's top edge + // and previous candidate's top edge is above focused's + // top edge + if ( nextNode->PaddingRect().iTl.iY > rect.iTl.iY && + tmpRect.iTl.iY < rect.iTl.iY ) + { + nextNode = tmpNode; + continue; + } + // candidate's and previous candidate's top edge is + // above focused's top edge. Select highest one. + else if ( nextNode->PaddingRect().iTl.iY < rect.iTl.iY && + tmpRect.iTl.iY < rect.iTl.iY && + tmpRect.iTl.iY < nextNode->PaddingRect().iTl.iY ) + { + nextNode = tmpNode; + continue; + } + } + else // arabic/hebrew layout + { + // candidate's top edge is below focused's top edge + // and previous candidate's top edge is above + // focused's top edge + if ( nextNode->PaddingRect().iTl.iY < rect.iTl.iY && + tmpRect.iTl.iY > rect.iTl.iY ) + { + nextNode = tmpNode; + continue; + } + // previous candidate's top edge is below focused's + // top edge. Also, candidate's top edge is below + // focused's top edge. Select the highest one. + else if ( nextNode->PaddingRect().iTl.iY > rect.iTl.iY && + tmpRect.iTl.iY > rect.iTl.iY && + tmpRect.iTl.iY < nextNode->PaddingRect().iTl.iY ) + { + nextNode = tmpNode; + continue; + } + } + } + } + else + { + continue; + } + } + } + } + + if ( !nextNode ) + { + if ( !stayInNamespace && aEngine && + aEngine->ViewManager()->ViewAmount() != KOneView ) + { + aEngine->ViewManager()->ActivatePreviousViewL(); + return nextNode; + } + CXnNode* candidateAbove = NULL; + CXnNode* candidateBelow = NULL; + + for ( TInt i = 0; i < aArray.Count(); ++i ) + { + CXnNode* tmpNode = aArray[i]; + if ( tmpNode == &aNode ) + { + continue; + } + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + if ( tmpNode->FindViewNode() != tmpNode->UiEngine()->ActiveView() ) + { + // do not shift focus to another view + continue; + } + + const TDesC8& tmpNamespace = tmpNode->Impl()->Namespace(); + const TDesC8& nodeNamespace = aNode.Impl()->Namespace(); + + if ( stayInNamespace && tmpNamespace != nodeNamespace ) + { + // if staying in the same namespace is required, + // do not shift focus to a different namespace + continue; + } + + // TODO: only plugin widgets are available in edit mode + TRect tmpRect = tmpNode->PaddingRect(); + + // temp node qualification: + // right edge of temp node is to the left from focused's left edge + if ( tmpRect.iBr.iX < rect.iTl.iX - 1 ) + { + // tmp is above the focused node + if ( tmpRect.iBr.iY < rect.iTl.iY ) + { + if ( candidateAbove == NULL ) + { + candidateAbove = tmpNode; + } + else + { + // use pythagorean theorem to determine the closest node + TInt xDistTmp = rect.iTl.iX - tmpRect.iBr.iX; + TInt yDistTmp = rect.iTl.iY - tmpRect.iBr.iY; + TReal tmpDist = Abs( ( xDistTmp * xDistTmp ) + ( yDistTmp * yDistTmp ) ); + + TInt xCand = rect.iTl.iX - candidateAbove->PaddingRect().iTl.iX; + TInt yCand = rect.iTl.iY - candidateAbove->PaddingRect().iBr.iY; + TReal cDist = Abs( ( xCand * xCand ) + ( yCand * yCand ) ); + + if ( tmpDist < cDist ) + { + candidateAbove = tmpNode; + } + } + } + else + { + if ( candidateBelow == NULL ) + { + candidateBelow = tmpNode; + } + else + { + // use pythagorean theorem to determine the closest node + TInt xDistTmp = rect.iTl.iX - tmpRect.iBr.iX; + TInt yDistTmp = rect.iBr.iY - tmpRect.iTl.iY; + TReal tmpDist = Abs( ( xDistTmp * xDistTmp ) + ( yDistTmp * yDistTmp ) ); + + TInt xCand = rect.iTl.iX - candidateBelow->PaddingRect().iBr.iX; + TInt yCand = rect.iBr.iY - candidateBelow->PaddingRect().iTl.iY; + TReal cDist = Abs( ( xCand * xCand ) + ( yCand * yCand ) ); + + if ( tmpDist < cDist ) + { + candidateBelow = tmpNode; + } + } + } + } + } + + if ( !AknLayoutUtils::LayoutMirrored() ) + { + if ( candidateAbove ) + { + nextNode = candidateAbove; + } + else + { + if ( candidateBelow ) + { + nextNode = candidateBelow; + } + } + } + else + { + if ( candidateBelow ) + { + nextNode = candidateBelow; + } + else + { + if ( candidateAbove ) + { + nextNode = candidateAbove; + } + } + } + } + + // get view width to get looping x point + TInt viewWidth = aNode.FindViewNode()->PaddingRect().Width(); + + // loop to the left + if ( !nextNode ) + { + CXnNode* candidateAbove = NULL; + CXnNode* candidateBelow = NULL; + + for ( TInt i = 0; i < aArray.Count(); ++i ) + { + CXnNode* tmpNode = aArray[i]; + /* + if ( tmpNode == &aNode ) + { + continue; + } + */ + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + if ( tmpNode->FindViewNode() != tmpNode->UiEngine()->ActiveView() ) + { + // do not shift focus to another view + continue; + } + + const TDesC8& tmpNamespace = tmpNode->Impl()->Namespace(); + const TDesC8& nodeNamespace = aNode.Impl()->Namespace(); + + if ( stayInNamespace && tmpNamespace != nodeNamespace ) + { + // if staying in the same namespace is required, + // do not shift focus to a different namespace + continue; + } + + + // TODO: only plugin widgets are available in edit mode + TRect tmpRect = tmpNode->PaddingRect(); + + // tmp is above the focused node + if ( tmpRect.iBr.iY <= rect.iTl.iY ) + { + if ( candidateAbove == NULL ) + { + candidateAbove = tmpNode; + } + else + { + // use pythagorean theorem to determine the closest node + TInt xDistTmp = viewWidth - tmpRect.iBr.iX; + TInt yDistTmp = rect.iTl.iY - tmpRect.iBr.iY; + TReal tmpDist = Abs( ( xDistTmp * xDistTmp ) + ( yDistTmp * yDistTmp ) ); + + TInt xCand = viewWidth - candidateAbove->PaddingRect().iBr.iX; + TInt yCand = rect.iTl.iY - candidateAbove->PaddingRect().iTl.iY; + TReal cDist = Abs( ( xCand * xCand ) + ( yCand * yCand ) ); + + if ( tmpDist < cDist ) + { + candidateAbove = tmpNode; + } + } + } + else + { + if ( candidateBelow == NULL ) + { + candidateBelow = tmpNode; + } + else + { + // use pythagorean theorem to determine the closest node + TInt xDistTmp = viewWidth - tmpRect.iBr.iX; + TInt yDistTmp = tmpRect.iTl.iY - rect.iTl.iY; + TReal tmpDist = Abs( ( xDistTmp * xDistTmp ) + ( yDistTmp * yDistTmp ) ); + + TInt xCand = viewWidth - candidateBelow->PaddingRect().iBr.iX; + TInt yCand = candidateBelow->PaddingRect().iTl.iY - rect.iTl.iY; + TReal cDist = Abs( ( xCand * xCand ) + ( yCand * yCand ) ); + + if ( tmpDist < cDist ) + { + candidateBelow = tmpNode; + } + } + } + } + + if ( candidateAbove && candidateBelow ) + { + CXnNode* pluginAbove = FindPluginNode( *candidateAbove ); + CXnNode* pluginBelow = FindPluginNode( *candidateBelow ); + + TReal aboveDist = 0; + TReal belowDist = 0; + + if ( pluginAbove ) + { + // compare to bottom right when looping to left + TInt xAbove = viewWidth - pluginAbove->PaddingRect().iBr.iX; + TInt yAbove = 0; + if ( !AknLayoutUtils::LayoutMirrored() ) + { + yAbove = rect.iTl.iY - pluginAbove->PaddingRect().iBr.iY; + } + else + { + yAbove = rect.iTl.iY - pluginAbove->PaddingRect().iTl.iY; + } + + aboveDist = Abs( (xAbove * xAbove) + (yAbove * yAbove) ); + } + else + { + TInt xAbove = viewWidth - candidateAbove->PaddingRect().iBr.iX; + TInt yAbove = 0; + if ( !AknLayoutUtils::LayoutMirrored() ) + { + yAbove = rect.iTl.iY - candidateAbove->PaddingRect().iBr.iY; + } + else + { + yAbove = rect.iTl.iY - candidateAbove->PaddingRect().iTl.iY; + } + aboveDist = Abs( ( xAbove * xAbove ) + ( yAbove * yAbove ) ); + } + + if ( pluginBelow ) + { + TInt xBelow = viewWidth - pluginBelow->PaddingRect().iBr.iX; + TInt yBelow = pluginBelow->PaddingRect().iTl.iY - rect.iTl.iY; + belowDist = Abs( ( xBelow * xBelow ) + ( yBelow * yBelow ) ); + } + else + { + TInt xBelow = viewWidth - candidateBelow->PaddingRect().iBr.iX; + TInt yBelow = candidateBelow->PaddingRect().iTl.iY - rect.iTl.iY; + belowDist = Abs( ( xBelow * xBelow ) + ( yBelow * yBelow ) ); + } + + if ( aboveDist < belowDist ) + { + nextNode = candidateAbove; + } + else if ( belowDist < aboveDist ) + { + nextNode = candidateBelow; + } + else + { + if ( !AknLayoutUtils::LayoutMirrored() ) + { + nextNode = candidateBelow; + } + else + { + nextNode = candidateAbove; + } + } + } + else if ( candidateAbove ) + { + nextNode = candidateAbove; + } + else if ( candidateBelow ) + { + nextNode = candidateBelow; + } + else + { + // do nothing + } + } + + if ( stayInNamespace && !nextNode ) + { + return &aNode; + } + + return nextNode; + } + +// ----------------------------------------------------------------------------- +// FindNextNodeFromBelowL +// ----------------------------------------------------------------------------- +// +static CXnNode* FindNextNodeFromBelowL( + RPointerArray< CXnNode >& aArray, + CXnNode& aNode, TBool stayInNamespace ) + { + CXnNode* nextNode = NULL; + TRect rect = aNode.PaddingRect(); + + for ( TInt i = 0; i < aArray.Count(); ++i ) + { + CXnNode* tmpNode = aArray[i]; + if ( tmpNode == &aNode ) + { + continue; + } + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + if ( tmpNode->FindViewNode() != tmpNode->UiEngine()->ActiveView() ) + { + // do not shift focus to another view + continue; + } + + const TDesC8& tmpNamespace = tmpNode->Impl()->Namespace(); + const TDesC8& nodeNamespace = aNode.Impl()->Namespace(); + + if ( stayInNamespace && tmpNamespace != nodeNamespace ) + { + // if staying in the same namespace is required, + // do not shift focus to a different namespace + continue; + } + + // TODO: only plugin widgets are available in edit mode + + TRect tmpRect = tmpNode->PaddingRect(); + + // temp node qualification: + // 1. top edge of the temp node is below bottom edge of focused node + // 2. temp node's right or left edge is between focused's left or right edge + if ( tmpRect.iTl.iY > rect.iBr.iY - 1 && + tmpRect.iBr.iX - 1 >= rect.iTl.iX && + tmpRect.iTl.iX <= rect.iBr.iX - 1 ) + { + if ( !nextNode ) + { + nextNode = tmpNode; + } + else + { + // temp node is closer than next node + if ( tmpRect.iTl.iY < nextNode->PaddingRect().iTl.iY ) + { + nextNode = tmpNode; + continue; + } + // top edge of temp node and next are at the same level + else if ( tmpRect.iTl.iY == nextNode->PaddingRect().iTl.iY ) + { + // western layout: take the leftmost one + if ( !AknLayoutUtils::LayoutMirrored() && + tmpRect.iBr.iX - 1 < nextNode->PaddingRect().iBr.iX - 1 ) + { + nextNode = tmpNode; + continue; + } + // arabic/hebrew layout: take the rightmost one + if ( AknLayoutUtils::LayoutMirrored() && + tmpRect.iBr.iX - 1 > nextNode->PaddingRect().iBr.iX - 1 ) + { + nextNode = tmpNode; + continue; + } + } + else + { + continue; + } + } + } + } + + // no nodes found on the right, try looping + if ( !nextNode ) + { + for ( TInt i = 0; i < aArray.Count(); ++i ) + { + CXnNode* tmpNode = aArray[i]; + TRect tmpRect = tmpNode->PaddingRect(); + if ( tmpNode == &aNode ) + { + continue; + } + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + if ( tmpRect.Intersects( rect ) ) + { + continue; + } + if ( tmpNode->FindViewNode() != tmpNode->UiEngine()->ActiveView() ) + { + // do not shift focus to another view + continue; + } + + const TDesC8& tmpNamespace = tmpNode->Impl()->Namespace(); + const TDesC8& nodeNamespace = aNode.Impl()->Namespace(); + + if ( stayInNamespace && tmpNamespace != nodeNamespace ) + { + // if staying in the same namespace is required, + // do not shift focus to a different namespace + continue; + } + + // TODO: only plugin widgets are available in edit mode + + // temp node's right or left edge must be between focused's left or + // right edge + if ( tmpRect.iBr.iX - 1 >= rect.iTl.iX && + tmpRect.iTl.iX <= rect.iBr.iX - 1 ) + { + if ( !nextNode ) + { + nextNode = tmpNode; + } + else + { + // temp node is closer than next node + if ( tmpRect.iTl.iY < nextNode->PaddingRect().iTl.iY ) + { + nextNode = tmpNode; + continue; + } + // top edge of temp node and next are at the same level + else if ( tmpRect.iTl.iY == nextNode->PaddingRect().iTl.iY ) + { + // western layout: take the leftmost one + if ( !AknLayoutUtils::LayoutMirrored() && + tmpRect.iBr.iX - 1 < nextNode->PaddingRect().iBr.iX - 1 ) + { + nextNode = tmpNode; + continue; + } + // arabic/hebrew layout: take the rightmost one + if ( AknLayoutUtils::LayoutMirrored() && + tmpRect.iBr.iX - 1 > nextNode->PaddingRect().iBr.iX - 1 ) + { + nextNode = tmpNode; + continue; + } + } + else + { + continue; + } + } + } + } + } + + if ( stayInNamespace && !nextNode ) + { + return &aNode; + } + + return nextNode; + } + +// ----------------------------------------------------------------------------- +// FindNextNodeFromAboveL +// ----------------------------------------------------------------------------- +// +static CXnNode* FindNextNodeFromAboveL( + RPointerArray< CXnNode >& aArray, + CXnNode& aNode, TBool stayInNamespace ) + { + CXnNode* nextNode = NULL; + TRect rect = aNode.PaddingRect(); + + for ( TInt i = 0; i < aArray.Count(); ++i ) + { + CXnNode* tmpNode = aArray[i]; + if ( tmpNode == &aNode ) + { + continue; + } + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + if ( tmpNode->FindViewNode() != tmpNode->UiEngine()->ActiveView() ) + { + // do not shift focus to another view + continue; + } + + const TDesC8& tmpNamespace = tmpNode->Impl()->Namespace(); + const TDesC8& nodeNamespace = aNode.Impl()->Namespace(); + + if ( stayInNamespace && tmpNamespace != nodeNamespace ) + { + // if staying in the same namespace is required, + // do not shift focus to a different namespace + continue; + } + + // TODO: only plugin widgets are available in edit mode + TRect tmpRect = tmpNode->PaddingRect(); + + // temp node qualification: + // 1. bottom edge of the temp node is above the top edge of focused node + // 2. temp node's right or left edge is between focused's left or right edge + if ( tmpRect.iBr.iY - 1 < rect.iTl.iY && + tmpRect.iBr.iX - 1 >= rect.iTl.iX && + tmpRect.iTl.iX <= rect.iBr.iX - 1 ) + { + if ( !nextNode ) + { + nextNode = tmpNode; + } + else + { + // temp node is closer than next node + if ( tmpRect.iBr.iY - 1 > nextNode->PaddingRect().iBr.iY - 1 ) + { + nextNode = tmpNode; + continue; + } + // bottom edge of temp and next node are at the same level + else if ( tmpRect.iBr.iY - 1 == nextNode->PaddingRect().iBr.iY - 1 ) + { + // western layout: take the leftmost one + if ( !AknLayoutUtils::LayoutMirrored() && + tmpRect.iBr.iX - 1 < nextNode->PaddingRect().iBr.iX - 1 ) + { + nextNode = tmpNode; + continue; + } + // arabic/hebrew layout: take the rightmost one + if ( AknLayoutUtils::LayoutMirrored() && + tmpRect.iBr.iX - 1 > nextNode->PaddingRect().iBr.iX - 1 ) + { + nextNode = tmpNode; + continue; + } + } + else + { + continue; + } + } + } + } + + // no nodes found on the right, try looping + if ( !nextNode ) + { + for ( TInt i = 0; i < aArray.Count(); ++i ) + { + CXnNode* tmpNode = aArray[i]; + TRect tmpRect = tmpNode->PaddingRect(); + if ( tmpNode == &aNode ) + { + continue; + } + if ( !IsNodeNavigableL( *tmpNode ) ) + { + continue; + } + if ( tmpRect.Intersects( rect ) ) + { + continue; + } + if ( tmpNode->FindViewNode() != tmpNode->UiEngine()->ActiveView() ) + { + // do not shift focus to another view + continue; + } + + const TDesC8& tmpNamespace = tmpNode->Impl()->Namespace(); + const TDesC8& nodeNamespace = aNode.Impl()->Namespace(); + + if ( stayInNamespace && tmpNamespace != nodeNamespace ) + { + // if staying in the same namespace is required, + // do not shift focus to a different namespace + continue; + } + + // TODO: only plugin widgets are available in edit mode + + // temp node's right or left edge must be between focused's left or + // right edge + if ( tmpRect.iBr.iX - 1 >= rect.iTl.iX && + tmpRect.iTl.iX <= rect.iBr.iX - 1 ) + { + if ( !nextNode ) + { + nextNode = tmpNode; + } + else + { + // temp node is closer than next node + if ( tmpRect.iBr.iY - 1 > nextNode->PaddingRect().iBr.iY - 1 ) + { + nextNode = tmpNode; + continue; + } + // bottom edge of temp and next node are at the same level + else if ( tmpRect.iBr.iY - 1 == nextNode->PaddingRect().iBr.iY - 1 ) + { + // western layout: take the leftmost one + if ( !AknLayoutUtils::LayoutMirrored() && + tmpRect.iBr.iX - 1 < nextNode->PaddingRect().iBr.iX - 1 ) + { + nextNode = tmpNode; + continue; + } + // arabic/hebrew layout: take the rightmost one + if ( AknLayoutUtils::LayoutMirrored() && + tmpRect.iBr.iX - 1 > nextNode->PaddingRect().iBr.iX - 1 ) + { + nextNode = tmpNode; + continue; + } + } + else + { + continue; + } + } + } + } + } + + if ( stayInNamespace && !nextNode ) + { + return &aNode; + } + + return nextNode; + } + +// ----------------------------------------------------------------------------- +// FindPluginNode +// ----------------------------------------------------------------------------- +// +static CXnNode* FindPluginNode( CXnNode& aNode ) + { + _LIT8( KPlugin, "plugin" ); + + CXnNode* pluginNode = NULL; + CXnNode* tmp = &aNode; + + while( tmp->Parent() ) + { + tmp = tmp->Parent(); + const TDesC8& nodeType = tmp->DomNode()->Name(); + + if ( nodeType == KPlugin ) + { + pluginNode = tmp; + break; + } + } + + return pluginNode; + } + +// ----------------------------------------------------------------------------- +// DoInternalFocusChangeL +// ----------------------------------------------------------------------------- +// +static TBool DoInternalFocusChangeL( CXnUiEngine& aEngine, + CXnNode& aNode, const TKeyEvent& aKeyEvent, TEventCode aType ) + { + if ( aNode.ViewNodeImpl() ) + { + return EFalse; + } + if ( aType != 1 ) + { + return EFalse; + } + if ( aKeyEvent.iScanCode != EStdKeyLeftArrow && + aKeyEvent.iScanCode != EStdKeyRightArrow && + aKeyEvent.iScanCode != EStdKeyDownArrow && + aKeyEvent.iScanCode != EStdKeyUpArrow ) + { + return EFalse; + } + CXnNode* parent = aNode.Parent(); + if ( !parent ) + { + return EFalse; + } + + // Handle 'appearance' navigation first, if the current node has + // "nav-index: appearance"... + CXnProperty* navind = aNode.NavIndexL(); + if ( navind && navind->StringValue() == XnPropertyNames::style::common::KAppearance ) + { + + CXnAppUiAdapter& appui = static_cast< CXnAppUiAdapter& >( *iAvkonAppUi ); + CXnPluginData& plugin( + appui.ViewManager().ActiveViewData().Plugin( &aNode ) ); + + // find if node is in a widget that contatins some opened popup window + + TBool containsPopUp = plugin.IsDisplayingPopup(); + + CXnNode* nextNode( NULL ); + RPointerArray< CXnNode >& array = aEngine.ViewManager()->AppearanceNodes(); + if ( aKeyEvent.iScanCode == EStdKeyDownArrow ) + { + nextNode = FindNextNodeFromBelowL( array, aNode, containsPopUp ); + } + else if ( aKeyEvent.iScanCode == EStdKeyUpArrow ) + { + nextNode = FindNextNodeFromAboveL( array, aNode, containsPopUp ); + } + else if ( aKeyEvent.iScanCode == EStdKeyRightArrow ) + { + nextNode = FindNextNodeFromRightL( array, aNode, containsPopUp, &aEngine ); + } + else if ( aKeyEvent.iScanCode == EStdKeyLeftArrow ) + { + nextNode = FindNextNodeFromLeftL( array, aNode, containsPopUp, &aEngine ); + } + if ( nextNode ) + { + if( nextNode && nextNode->ScrollableControl() ) + { + nextNode->ScrollableControl()->ShowItem( *nextNode ); + } + nextNode->SetStateL( XnPropertyNames::style::common::KFocus ); + return ETrue; + } + } + else + { + const TDesC8* direction( &XnPropertyNames::style::common::direction::KLTR ); + const TDesC8* orientation( &XnPropertyNames::style::common::block_progression::KTB ); + + CXnProperty* directionProperty( parent->DirectionL() ); + + if ( directionProperty ) + { + direction = &directionProperty->StringValue(); + } + + CXnProperty* orientationProperty( parent->BlockProgressionL() ); + + if ( orientationProperty ) + { + orientation = &orientationProperty->StringValue(); + } + + TBool match = EFalse; + + if ( *direction == XnPropertyNames::style::common::direction::KLTR && + ( *orientation == XnPropertyNames::style::common::block_progression::KLR || + *orientation == XnPropertyNames::style::common::block_progression::KRL ) ) + { + if ( aKeyEvent.iScanCode == EStdKeyLeftArrow ) + { + match = FindNextFocusableNodeL( aNode, EFalse ); + } + if ( aKeyEvent.iScanCode == EStdKeyRightArrow ) + { + match = FindNextFocusableNodeL( aNode, ETrue ); + } + } + else if ( *direction == XnPropertyNames::style::common::direction::KRTL && + ( *orientation == XnPropertyNames::style::common::block_progression::KLR || + *orientation == XnPropertyNames::style::common::block_progression::KRL ) ) + { + if ( aKeyEvent.iScanCode == EStdKeyRightArrow ) + { + match = FindNextFocusableNodeL( aNode, EFalse ); + } + if ( aKeyEvent.iScanCode == EStdKeyLeftArrow ) + { + match = FindNextFocusableNodeL( aNode, ETrue ); + } + } + else if ( *direction == XnPropertyNames::style::common::direction::KLTR && + *orientation == XnPropertyNames::style::common::block_progression::KTB ) + { + if ( aKeyEvent.iScanCode == EStdKeyUpArrow ) + { + match = FindNextFocusableNodeL( aNode, EFalse ); + } + if ( aKeyEvent.iScanCode == EStdKeyDownArrow ) + { + match = FindNextFocusableNodeL( aNode, ETrue ); + } + } + else if ( *direction == XnPropertyNames::style::common::direction::KRTL && + *orientation == XnPropertyNames::style::common::block_progression::KTB ) + { + if ( aKeyEvent.iScanCode == EStdKeyDownArrow ) + { + match = FindNextFocusableNodeL( aNode, EFalse ); + } + if ( aKeyEvent.iScanCode == EStdKeyUpArrow ) + { + match = FindNextFocusableNodeL( aNode, ETrue ); + } + } + return match; + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// DoTriggerKeyEventL +// ----------------------------------------------------------------------------- +// +static TBool DoTriggerKeyEventL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnNode& aNode, + const TKeyEvent& aKeyEvent, + TEventCode aType ) + { + CXnDomNode* domNode = aNode.DomNode(); + CXnDomList& children = domNode->ChildNodes(); + TInt count = children.Length(); + TBool returnValue = EFalse; + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* node = static_cast< CXnDomNode* >( children.Item( i ) ); + const TDesC8& type = node->Name(); + if ( type == XnPropertyNames::action::KActions ) + { + CXnDomList& actionChildren = node->ChildNodes(); + TInt actionCount = actionChildren.Length(); + for ( TInt j = 0; j < actionCount; ++j ) + { + CXnDomNode* actionNode = + static_cast< CXnDomNode* >( actionChildren.Item( j ) ); + const TDesC8& actionType = actionNode->Name(); + if ( actionType == XnPropertyNames::action::KAction ) + { + TBool match = MatchActionForKeyEventL( + aThis, aEngine, aNode, aKeyEvent, aType, *actionNode ); + if ( match ) + { + returnValue = ETrue; + } + } + } + } + } + + if ( returnValue ) + { + // Return is removed from here to enable auto navigation altough the + // action is alreadytriggered. This enables simpler theme definitions + // especially in AI2 case. If regression is observed then return should + // be restored here. Task ou1s60ui#3386. + //return returnValue; + } + + DoCompoundNodeScrollingL( aNode, aKeyEvent, aType ); + + returnValue = DoInternalFocusChangeL( aEngine, aNode, aKeyEvent, aType ); + + if ( returnValue ) + { + aEngine.RenderUIL(); + } + + return returnValue; + } + +// ----------------------------------------------------------------------------- +// DoTriggerEventL +// ----------------------------------------------------------------------------- +// +static void DoTriggerEventL( + CXnNodeImpl* aThis, + CXnUiEngine& aEngine, + CXnNode& aNode, + CXnNode& aActionsParent, + CXnNode& aEventData, + TInt aSource ) + { + CXnDomList& children( aActionsParent.DomNode()->ChildNodes() ); + + TInt count( children.Length() ); + + for ( TInt i = 0; i < count; ++i ) + { + CXnDomNode* node = static_cast< CXnDomNode* >( children.Item( i ) ); + const TDesC8& type = node->Name(); + if ( type == XnPropertyNames::action::KActions ) + { + CXnDomList& actionChildren = node->ChildNodes(); + TInt actionCount = actionChildren.Length(); + for ( TInt j = 0; j < actionCount; ++j ) + { + CXnDomNode* actionNode = + static_cast< CXnDomNode* >( actionChildren.Item( j ) ); + const TDesC8& actionType = actionNode->Name(); + if ( actionType == XnPropertyNames::action::KAction ) + { + TBool match = MatchActionForEventL( + aThis, aEngine, aNode, aEventData, *actionNode, aSource ); + } + } + } + } + } + +// ----------------------------------------------------------------------------- +// DoReceiveFocusL +// ----------------------------------------------------------------------------- +// +static TBool DoReceiveFocusL( CXnNode& aNode, CXnUiEngine& /*aEngine*/ ) + { + CXnProperty* focusable = aNode.GetPropertyL( + XnPropertyNames::common::KFocusable ); + CXnProperty* disabled = aNode.GetPropertyL( + XnPropertyNames::common::KDisabled ); + if ( focusable ) + { + const TDesC8& focusValue = focusable->StringValue(); + if ( focusValue != KNullDesC8 ) + { + if ( focusValue != XnPropertyNames::KTrue ) + { + return EFalse; + } + } + } + else + { + return EFalse; + } + if ( disabled ) + { + const TDesC8& disabledValue = disabled->StringValue(); + if ( disabledValue != KNullDesC8 ) + { + if ( disabledValue == XnPropertyNames::KTrue ) + { + return EFalse; + } + } + } + if ( !IsNodeNavigableL( aNode ) ) + { + return EFalse; + } + + return ETrue; + } + +// ----------------------------------------------------------------------------- +// DoSetActiveL +// ----------------------------------------------------------------------------- +// +static void DoSetActiveL( CXnNode& aNode, CXnUiEngine& aUiEngine ) + { + CXnNode* activate = BuildActivateTriggerNodeL( aUiEngine ); + activate->SetUiEngine( aUiEngine ); + CleanupStack::PushL( activate ); + aNode.ReportXuikonEventL( *activate ); + CleanupStack::PopAndDestroy( activate ); + } + +// ----------------------------------------------------------------------------- +// Informs the component about the property change. +// ----------------------------------------------------------------------------- +// +static void InformPropertyChangeL( CXnNode& aNode, CXnProperty* aProperty ) + { + //Inform the component about the property change. + CXnNode* parent( aNode.Parent() ); + + if ( parent ) + { + if ( parent->Type()->Type() == KMenuBar ) + { + CXnMenuAdapter* adapter = + static_cast< CXnMenuAdapter* >( parent->Control() ); + + if ( adapter ) + { + adapter->HandleMenuPropertyChangeL( &aNode.PluginIfL(), aProperty ); + } + } + else if ( aNode.IsLayoutCapable() ) + { + CXnControlAdapter* adapter( aNode.Control() ); + + if ( adapter ) + { + adapter->HandlePropertyChangeL( aProperty ); + } + } + } + } + +// ----------------------------------------------------------------------------- +// Informs parent and its children about the property change. +// ----------------------------------------------------------------------------- +// +static void InformChildrenPropertyChangeL( + CXnNode& aParent, + CXnProperty* aProperty, + TBool aInformParent = ETrue ) + { + RPointerArray< CXnNode >& children( aParent.Children() ); + if ( aInformParent ) + { + InformPropertyChangeL( aParent, aProperty ); + } + TInt count( children.Count() ); + for ( TInt i = 0 ; i < count; i++ ) + { + InformChildrenPropertyChangeL( *children[i], aProperty, ETrue ); + } + } + +// ----------------------------------------------------------------------------- +// DisplayValueMatchL +// ----------------------------------------------------------------------------- +// +static TBool DisplayValueMatchL( + CXnNode& aNode, + const TDesC8& aDisplayValue ) + { + CXnProperty* display = aNode.GetPropertyL( KDisplay ); + if ( display ) + { + const TDesC8& value = display->StringValue(); + if ( value.Compare( aDisplayValue ) == KErrNone ) + { + return ETrue; + } + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// SetFloatPropertyToNodeL +// Set float property to a node +// ----------------------------------------------------------------------------- +// +static void SetFloatPropertyToNodeL( + CXnDomStringPool& aStringPool, CXnNode& aNode, + const TDesC8& aPropertyName, TReal aPropertyValue, + CXnDomPropertyValue::TPrimitiveValueType aValueType ) + { + // create property + CXnProperty* prop = CXnProperty::NewL( + aPropertyName, aPropertyValue, aValueType, aStringPool ); + + CleanupStack::PushL( prop ); + aNode.SetPropertyL( prop ); + CleanupStack::Pop( prop ); + } + +// ----------------------------------------------------------------------------- +// SetStringPropertyToNodeL +// Set string property to a node +// ----------------------------------------------------------------------------- +// +static void SetStringPropertyToNodeL( + CXnDomStringPool& aStringPool, + CXnNode& aNode, + const TDesC8& aPropertyName, + const TDesC8& aPropertyValue ) + { + // create property + CXnProperty* prop = CXnProperty::NewL( + aPropertyName, aPropertyValue, CXnDomPropertyValue::EString, aStringPool ); + + CleanupStack::PushL( prop ); + aNode.SetPropertyL( prop ); + CleanupStack::Pop( prop ); + } + +// ----------------------------------------------------------------------------- +// FindYoungestSiblingWithDisplayL +// Seek youngest sibling node with given display value +// ----------------------------------------------------------------------------- +// +static CXnNode* FindYoungestSiblingWithDisplayL( + RPointerArray< CXnNode >& aSiblingArray, + const TDesC8& aDisplayValue, + TInt& aIndex ) + { + aIndex = KErrNotFound; + CXnNode* node = NULL; + TInt siblingCount( aSiblingArray.Count() ); + //Find youngest sibling with display block + for ( TInt i = siblingCount; i > 0; ) + { + node = aSiblingArray[--i]; + if ( DisplayValueMatchL( *node, aDisplayValue ) ) + { + aIndex = i; + return node; + } + } + return NULL; + } + +// ----------------------------------------------------------------------------- +// FindOldestSiblingWithDisplayL +// Seek oldest sibling node with given display value +// ----------------------------------------------------------------------------- +// +static CXnNode* FindOldestSiblingWithDisplayL( + RPointerArray< CXnNode >& aSiblingArray, + const TDesC8& aDisplayValue, + TInt& aIndex ) + { + aIndex = KErrNotFound; + CXnNode* node = NULL; + TInt siblingCount( aSiblingArray.Count() ); + //Find oldest sibling with display block + for ( TInt i = 0; i < siblingCount; i++ ) + { + node = aSiblingArray[i]; + if ( DisplayValueMatchL( *node, aDisplayValue ) ) + { + aIndex = i; + return node; + } + } + return NULL; + } + +// ----------------------------------------------------------------------------- +// ScrollBoxToBeginningL +// Show the oldest siblings that fit into the compound box. +// ----------------------------------------------------------------------------- +// +static void ScrollBoxToBeginningL( RPointerArray< CXnNode >& aSiblingArray ) + { + CXnNode* node = NULL; + TInt toBeDisplayed(0); + TInt siblingCount( aSiblingArray.Count() ); + for ( TInt i = 0; i < siblingCount; i++ ) + { + node = aSiblingArray[i]; + if ( DisplayValueMatchL( *node, KBlock ) ) + { + CXnDomStringPool& sp = node->DomNode()->StringPool(); + //Switch the display to 'none' to visible siblings. + SetStringPropertyToNodeL( sp, *node, KDisplay, KNone ); + node = aSiblingArray[toBeDisplayed]; + toBeDisplayed++; + //Switch the display to 'block' to hidden siblings. + SetStringPropertyToNodeL( sp, *node, KDisplay, KBlock ); + } + } + } + +// ----------------------------------------------------------------------------- +// ScrollBoxToEndL +// Show the youngest siblings that fit into the compound box. +// ----------------------------------------------------------------------------- +// +static void ScrollBoxToEndL( RPointerArray< CXnNode >& aSiblingArray ) + { + CXnNode* node = NULL; + TInt siblingCount( aSiblingArray.Count() ); + TInt toBeDisplayed( siblingCount - 1 ); + for ( TInt i = siblingCount; i > 0; ) + { + node = aSiblingArray[--i]; + if ( DisplayValueMatchL( *node, KBlock ) ) + { + CXnDomStringPool& sp = node->DomNode()->StringPool(); + //Switch the display to 'none' to visible siblings. + SetStringPropertyToNodeL( sp, *node, KDisplay, KNone ); + node = aSiblingArray[toBeDisplayed]; + toBeDisplayed--; + //Switch the display to 'block' to hidden siblings. + SetStringPropertyToNodeL( sp, *node, KDisplay, KBlock ); + } + } + } + +// ----------------------------------------------------------------------------- +// IsCompoundNodeL +// Checks whether the node is coumound node. +// ----------------------------------------------------------------------------- +// +static TBool IsCompoundNodeL( CXnNode* aNode ) + { + if ( !aNode ) + { + return EFalse; + } + CXnProperty* compoundProperty = aNode->GetPropertyL( KCompound ); + if ( compoundProperty ) + { + const TDesC8& value = compoundProperty->StringValue(); + if ( !value.Compare( KTrue ) ) + { + return ETrue; + } + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// IsLoopingSetL +// Checks whether the node is set to loop. +// ----------------------------------------------------------------------------- +// +static TBool IsLoopingNodeL( CXnNode* aNode ) + { + if ( !aNode ) + { + return EFalse; + } + CXnProperty* navLoopProperty = aNode->GetPropertyL( + XnPropertyNames::style::common::KS60NavLooping ); + if ( navLoopProperty ) + { + const TDesC8& loopValue = navLoopProperty->StringValue(); + if ( loopValue == XnPropertyNames::grid::s60_focus_looping::KStop ) + { + return EFalse; + } + } + return ETrue; + } + +// ----------------------------------------------------------------------------- +// NotifyScrollNodeL +// Notify scroll node i.e compound box first and last siblings that there is +// nothing more to scroll +// ----------------------------------------------------------------------------- +// +static void NotifyScrollNodeL( CXnNode* aNode, TBool aBegin, TBool aGainEnd ) + { + RPointerArray< CXnNode >& siblings = aNode->Parent()->Children(); + // Last sibling is assumend to be an end scrolling node + CXnNode* scrollNode = siblings[0]; + if ( !aBegin ) + { + scrollNode = siblings[siblings.Count() - 1]; + } + CXnNode* triggerNode = + BuildTriggerNodeL( *scrollNode->UiEngine(), aGainEnd?KGainEnd:KLoseEnd ); + triggerNode->SetUiEngine( *scrollNode->UiEngine() ); + CleanupStack::PushL( triggerNode ); + scrollNode->ReportXuikonEventL( *triggerNode ); + CleanupStack::PopAndDestroy( triggerNode ); + } + +// ----------------------------------------------------------------------------- +// DoCompoundNodeBeginKeyL +// If key towards begin of list was pressed scroll to that direction +// ----------------------------------------------------------------------------- +// +static void DoCompoundNodeBeginKeyL( + RPointerArray< CXnNode >& aChildren, + CXnNode* aFocusedNode ) + { + TInt oldestIndex( 0 ); + // Notify scrollNode if aFocusedNode is node end of the list + CXnNode* lastItem = aChildren[aChildren.Count() - 1]; + if ( aFocusedNode == lastItem && !IsLoopingNodeL( lastItem ) ) + { + NotifyScrollNodeL( aChildren[0]->Parent(), EFalse, EFalse ); + } + CXnNode* node = FindOldestSiblingWithDisplayL( aChildren, KBlock, oldestIndex ); + // Set next node's display to block + if ( node && node == aFocusedNode ) + { + if ( oldestIndex - 1 >= 0 ) + { + node = aChildren[oldestIndex - 1]; + CXnDomStringPool& sp = node->DomNode()->StringPool(); + SetStringPropertyToNodeL( sp, *node, KDisplay, KBlock ); + // find youngest sibling with display block + TInt index( 0 ); + node = FindYoungestSiblingWithDisplayL( aChildren, KBlock, index ); + if ( node ) + { + SetStringPropertyToNodeL( sp, *node, KDisplay, KNone ); + } + } + else + { + if ( IsLoopingNodeL( node ) ) + { + ScrollBoxToEndL( aChildren ); + } + else + { + NotifyScrollNodeL( aChildren[0]->Parent(), ETrue, ETrue ); + } + } + } + } + +// ----------------------------------------------------------------------------- +// DoCompoundNodeEndKeyL +// If key towards end of list was pressed scroll to that direction +// ----------------------------------------------------------------------------- +// +static void DoCompoundNodeEndKeyL( + RPointerArray< CXnNode >& aChildren, + CXnNode* aFocusedNode ) + { + TInt index( 0 ); + TInt siblingCount( aChildren.Count() ); + // Notify scrollNode if aFocusedNode is first node of the list + CXnNode* firstItem = aChildren[0]; + if ( aFocusedNode == firstItem && !IsLoopingNodeL( firstItem ) ) + { + NotifyScrollNodeL( aChildren[0]->Parent(), ETrue, EFalse ); + } + CXnNode* node = FindYoungestSiblingWithDisplayL( aChildren, KBlock, index ); + // Set next node's display to block + if ( node && node == aFocusedNode ) + { + if ( index < siblingCount - 1 ) + { + node = aChildren[index + 1]; + CXnDomStringPool& sp = node->DomNode()->StringPool(); + SetStringPropertyToNodeL( sp , *node, KDisplay, KBlock ); + // find oldest sibling with display block + TInt oldestIndex( 0 ); + node = FindOldestSiblingWithDisplayL( aChildren, KBlock, oldestIndex ); + if ( node ) + { + SetStringPropertyToNodeL( sp, *node, KDisplay, KNone ); + } + } + else // we are end of list + { + if ( IsLoopingNodeL( node ) ) + { + ScrollBoxToBeginningL( aChildren ); + } + else + { + NotifyScrollNodeL( aChildren[0]->Parent(), EFalse, ETrue ); + } + } + } + } + +// ----------------------------------------------------------------------------- +// DoCompoundNodeScrollingL +// Process compound node key events +// ----------------------------------------------------------------------------- +// +static void DoCompoundNodeScrollingL( + CXnNode& aFocusedNode, + const TKeyEvent& aKeyEvent, + TEventCode aType ) + { + if ( aType != EEventKey ) + { + return; + } + CXnNode* compoundNode = aFocusedNode.Parent(); + if ( IsCompoundNodeL( compoundNode ) ) + { + RPointerArray< CXnNode >& children = compoundNode->Children(); + + if ( aKeyEvent.iScanCode != EStdKeyLeftArrow && + aKeyEvent.iScanCode != EStdKeyRightArrow && + aKeyEvent.iScanCode != EStdKeyDownArrow && + aKeyEvent.iScanCode != EStdKeyUpArrow ) + { + return; + } + CXnNode* parent = aFocusedNode.Parent(); + if ( !parent ) + { + return; + } + else + { + const TDesC8* direction( + &XnPropertyNames::style::common::direction::KLTR ); + const TDesC8* orientation( + &XnPropertyNames::style::common::block_progression::KTB ); + + CXnProperty* directionProperty( parent->DirectionL() ); + + if ( directionProperty ) + { + direction = &directionProperty->StringValue(); + } + + CXnProperty* orientationProperty( parent->BlockProgressionL() ); + + if ( orientationProperty ) + { + orientation = &orientationProperty->StringValue(); + } + + if ( *direction == XnPropertyNames::style::common::direction::KLTR && + ( *orientation == XnPropertyNames::style::common::block_progression::KLR || + *orientation == XnPropertyNames::style::common::block_progression::KRL ) ) + { + if ( aKeyEvent.iScanCode == EStdKeyLeftArrow ) + { + DoCompoundNodeBeginKeyL( children, &aFocusedNode ); + } + if ( aKeyEvent.iScanCode == EStdKeyRightArrow ) + { + DoCompoundNodeEndKeyL( children, &aFocusedNode ); + } + } + else if ( *direction == XnPropertyNames::style::common::direction::KRTL && + ( *orientation == XnPropertyNames::style::common::block_progression::KLR || + *orientation == XnPropertyNames::style::common::block_progression::KRL ) ) + { + if ( aKeyEvent.iScanCode == EStdKeyLeftArrow ) + { + DoCompoundNodeEndKeyL( children, &aFocusedNode ); + } + if ( aKeyEvent.iScanCode == EStdKeyRightArrow ) + { + DoCompoundNodeBeginKeyL( children, &aFocusedNode ); + } + } + else if ( *direction == XnPropertyNames::style::common::direction::KLTR && + *orientation == XnPropertyNames::style::common::block_progression::KTB ) + { + if ( aKeyEvent.iScanCode == EStdKeyUpArrow ) + { + DoCompoundNodeBeginKeyL( children, &aFocusedNode ); + } + else if ( aKeyEvent.iScanCode == EStdKeyDownArrow ) + { + DoCompoundNodeEndKeyL( children, &aFocusedNode ); + } + } + else if ( *direction == XnPropertyNames::style::common::direction::KRTL && + *orientation == XnPropertyNames::style::common::block_progression::KTB ) + { + if ( aKeyEvent.iScanCode == EStdKeyDownArrow ) + { + DoCompoundNodeBeginKeyL( children, &aFocusedNode ); + } + else if ( aKeyEvent.iScanCode == EStdKeyUpArrow ) + { + DoCompoundNodeEndKeyL( children, &aFocusedNode ); + } + } + } + } + } + +// ----------------------------------------------------------------------------- +// BuildTriggerNodeL +// Builds a trigger node +// ----------------------------------------------------------------------------- +// +static CXnNode* BuildTriggerNodeL( + CXnUiEngine& aUiEngine, + const TDesC8& aTriggerName ) + { + CXnNode* node = CXnNode::NewL(); + CleanupStack::PushL( node ); + CXnType* type = CXnType::NewL( XnPropertyNames::action::KTrigger ); + CleanupStack::PushL( type ); + CXnNodeImpl* impl = CXnNodeImpl::NewL( type ); + CleanupStack::Pop( type ); + node->SetImpl( impl ); + node->SetUiEngine( aUiEngine ); + CXnDomPropertyValue* nameValue = + CXnDomPropertyValue::NewL( aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::PushL( nameValue ); + nameValue->SetStringValueL( CXnDomPropertyValue::EString, aTriggerName ); + CXnProperty* name = CXnProperty::NewL( + XnPropertyNames::action::trigger::KName, + nameValue, + aUiEngine.ODT()->DomDocument().StringPool() ); + CleanupStack::Pop( nameValue ); + CleanupStack::PushL( name ); + node->SetPropertyL( name ); + CleanupStack::Pop( name ); + CleanupStack::Pop( node ); + return node; + } + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::NewL() +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CXnNodeImpl* CXnNodeImpl::NewL( CXnType* aType ) + { + CXnNodeImpl* self = new ( ELeave ) CXnNodeImpl; + + CleanupStack::PushL( self ); + self->ConstructL( aType ); + CleanupStack::Pop(); + + return self; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::ConstructL() +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::ConstructL( CXnType* aType ) + { + iType = aType; + iPropertyList = CXnPropertyList::NewL(); + iLayoutCapable = ETrue; + iHandleTooltip = ETrue; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::CXnNodeImpl() +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CXnNodeImpl::CXnNodeImpl() + : iDropped( 0 ), iChildren( 1 ), iAdaptive( 0 ) + { + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::~CXnNodeImpl() +// C++ default destructor. +// ----------------------------------------------------------------------------- +// +CXnNodeImpl::~CXnNodeImpl() + { + delete iPropertyList; + delete iType; + iPropertyPseudoClasses.Reset(); + iStates.Reset(); + iChildren.ResetAndDestroy(); + delete iGridPropertyCache; + delete iLayoutPropertyCache; + DeletePeriodic(); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetNode +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetNode( CXnNode& aNode ) + { + iNode = &aNode; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::Node +// ----------------------------------------------------------------------------- +// +CXnNode* CXnNodeImpl::Node() + { + return iNode; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetRect +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetRect( const TRect& aRect ) + { + iRect = aRect; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::Rect +// ----------------------------------------------------------------------------- +// +TRect CXnNodeImpl::Rect() + { + return AdjustRectIfNeeded(iRect); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetBorderRect +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetBorderRect( const TRect& aRect ) + { + iBorderRect = aRect; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BorderRect +// ----------------------------------------------------------------------------- +// +TRect CXnNodeImpl::BorderRect() + { + return AdjustRectIfNeeded(iBorderRect); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetNormalFlowBorderRect +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetNormalFlowBorderRect( const TRect& aRect ) + { + iNormalFlowBorderRect = aRect; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::NormalFlowBorderRect +// ----------------------------------------------------------------------------- +// +TRect CXnNodeImpl::NormalFlowBorderRect() + { + return AdjustRectIfNeeded(iNormalFlowBorderRect); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetMarginRect +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetMarginRect( const TRect& aRect ) + { + iMarginRect = aRect; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::MarginRect +// ----------------------------------------------------------------------------- +// +TRect CXnNodeImpl::MarginRect() + { + return AdjustRectIfNeeded(iMarginRect); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetPaddingRect +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetPaddingRect( const TRect& aRect ) + { + iPaddingRect = aRect; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::PaddingRect +// ----------------------------------------------------------------------------- +// +TRect CXnNodeImpl::PaddingRect() + { + return AdjustRectIfNeeded(iPaddingRect); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::Type() +// Returns control type. +// ----------------------------------------------------------------------------- +// +CXnType* CXnNodeImpl::Type() + { + return iType; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::Parent +// Get component parent +// ----------------------------------------------------------------------------- +// +CXnNode* CXnNodeImpl::Parent() const + { + return iParent; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetParent +// Set component parent +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetParent( CXnNode& aParent ) + { + iParent = &aParent; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::AddChildL +// Adds a child to this container. +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::AddChildL( CXnNode* aChild ) + { + TInt err = iChildren.Append( aChild ); + if ( err != KErrNone ) + { + User::Leave( KXnErrAddChildToAreaFailed ); + } + aChild->SetParent( *iNode ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::Children +// ----------------------------------------------------------------------------- +// +RPointerArray< CXnNode >& CXnNodeImpl::Children() + { + return iChildren; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetPCDataL +// Set a property. +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetPCDataL( const TDesC8& aData ) + { + iDomNode->SetPCDataL( aData ); + + SetDirtyL( XnDirtyLevel::ERender ); + + CXnDomStringPool& sp( iDomNode->StringPool() ); + + CXnDomPropertyValue* newValue = CXnDomPropertyValue::NewL( sp ); + CleanupStack::PushL( newValue ); + newValue->SetStringValueL( CXnDomPropertyValue::EString, KNullDesC8 ); + // create property + CXnProperty* prop = CXnProperty::NewL( + XnPropertyNames::common::KPCData, newValue, sp ); + CleanupStack::Pop( newValue ); + CleanupStack::PushL( prop ); + + InformPropertyChangeL( *iNode, prop ); + + CleanupStack::PopAndDestroy( prop ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::GetPCData +// Set a property. +// ----------------------------------------------------------------------------- +// +const TDesC8& CXnNodeImpl::GetPCData() + { + if ( iRef ) + { + CXnNode* refNode( NULL ); + TRAP_IGNORE( refNode = RefNodeL( this, iRef, iUiEngine ) ); + + if ( refNode ) + { + return refNode->GetPCData(); + } + } + + return iDomNode->PCData(); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetHandleTooltip() +// Sets wheter to handle tooltips +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetHandleTooltip( TBool aFlag ) + { + iHandleTooltip = aFlag; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::ShowPopupsL() +// Searchs and shoes tooltips +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::ShowPopupsL( TRect aRect, TInt aSource ) + { + if ( iHandleTooltip ) + { + for ( TInt i = 0; i < iChildren.Count(); i++ ) + { + CXnNode* node( iChildren[i] ); + + if ( node->Type()->Type() == KToolTip ) + { + CXnNodeAppIf& tooltipNode( node->AppIfL() ); + CXnPopup* popup( NULL ); + + XnComponentInterface::MakeInterfaceL( popup, tooltipNode ); + + if ( popup ) + { + if ( aSource == XnEventSource::EStylus ) + { + const TTimeIntervalMicroSeconds32 delay( 0 ); + const TTimeIntervalMicroSeconds32 display( 1000 * 1000 * 6 ); + + popup->ShowPopupL( aRect, delay, display ); + } + else + { + popup->ShowPopupL( aRect ); + } + } + } + } + } + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::HidePopupsL() +// Searchs and hides tooltips +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::HidePopupsL() + { + if ( iHandleTooltip ) + { + for ( TInt i = 0; i < iChildren.Count(); i++ ) + { + CXnNode* node( iChildren[i] ); + + if ( node->Type()->Type() == KToolTip ) + { + CXnNodeAppIf& tooltipNode( node->AppIfL() ); + CXnPopup* popup( NULL ); + + XnComponentInterface::MakeInterfaceL( popup, tooltipNode ); + + if ( popup ) + { + popup->HidePopupL(); + } + } + } + } + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetPropertyL +// Sets a property, informs property change and builds trigger. +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetPropertyL( CXnProperty* aProperty, TBool aNotify ) + { + TInt level( DoSetPropertyL( aProperty ) ); + + if ( !aNotify || level == XnDirtyLevel::ENone ) + { + // all done + return; + } + + InformPropertyChangeL( *iNode, aProperty ); + + if ( iLayoutCapable && iNode->Parent() ) + { + const TDesC8* value( NULL ); + const TDesC8& name( aProperty->Property()->Name() ); + TBool informChildren( EFalse ); + + if ( name == XnPropertyNames::style::common::KDisplay ) + { + value = &XnPropertyNames::style::common::display::KNone; + informChildren = ETrue; + } + else if ( name == XnPropertyNames::style::common::KVisibility ) + { + value = &XnPropertyNames::style::common::visibility::KHidden; + informChildren = ETrue; + } + + if ( value ) + { + if ( *value == aProperty->StringValue() ) + { + CXnNode* loseVisualisation( + BuildTriggerNodeL( + *iUiEngine, + XnPropertyNames::action::trigger::name::KLoseVisualisation ) ); + + CleanupStack::PushL( loseVisualisation ); + + CXnNode* focused( iUiEngine->FocusedNode() ); + + for ( CXnNode* node = focused; node; node = node->Parent() ) + { + if ( node == iNode ) + { + // Focus is either in this node or + // somewhere in this node's childrens + focused->UnsetStateL( + XnPropertyNames::style::common::KFocus ); + + focused->UnsetStateL( + XnPropertyNames::style::common::KHold ); + + focused->UnsetStateL( + XnPropertyNames::style::common::KActive ); + + // Report losevisualisation to focused node if the node + // is 'visualisationaware' + CXnProperty* visaware = GetPropertyL( + XnPropertyNames::common::KVisualisationAware ); + + if ( visaware && visaware->StringValue() == + XnPropertyNames::KTrue ) + { + focused->ReportXuikonEventL( *loseVisualisation ); + } + + break; + } + } + + if ( focused != iNode ) + { + // Report losevisualisation to this node if the node + // is 'visualisationaware' + CXnProperty* visaware = GetPropertyL( + XnPropertyNames::common::KVisualisationAware ); + if ( visaware && visaware->StringValue() == + XnPropertyNames::KTrue ) + { + iNode->ReportXuikonEventL( *loseVisualisation ); + } + } + + CleanupStack::PopAndDestroy( loseVisualisation ); + } + else + { + if ( !iUiEngine->FocusedNode() ) + { + CXnNode* node( IsNodeNavigableL( Node() ) ); + + if ( node ) + { + // This node can be focused + iUiEngine->AddFocusCandidateL( node ); + } + } + } + } + + if ( informChildren && ( iNode->Children().Count() > 0 ) ) + { + //we have already done inform for the parent, so EFalse + InformChildrenPropertyChangeL( *iNode, aProperty, EFalse ); + } + } + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetPropertyWithoutNotificationL +// Sets a property. +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetPropertyWithoutNotificationL( CXnProperty* aProperty ) + { + SetPropertyL( aProperty, EFalse ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetPropertyArrayL +// Sets an array of properties and after all the properties are set informs +// property change. +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetPropertyArrayL( + RPointerArray< CXnProperty >& aPropertyArray ) + { + TBool informPropertyChange( EFalse ); + + TInt count( aPropertyArray.Count() ); + + iUiEngine->DisableRenderUiLC(); + + for ( TInt i = 0; i < count; i++ ) + { + CXnProperty* aProp( aPropertyArray[i] ); + + const TDesC8& name( aProp->Property()->Name() ); + + if ( name == XnPropertyNames::style::common::KDisplay || + name == XnPropertyNames::style::common::KVisibility ) + { + SetPropertyL( aProp ); + } + else + { + SetPropertyL( aProp, EFalse ); + informPropertyChange = ETrue; + } + } + + if ( informPropertyChange ) + { + InformPropertyChangeL( *iNode, NULL ); + } + + CleanupStack::PopAndDestroy(); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::DoSetPropertyL +// Does the actual property update +// ----------------------------------------------------------------------------- +// +TInt CXnNodeImpl::DoSetPropertyL( CXnProperty* aProperty ) + { + TInt level( XnDirtyLevel::ENone ); + + const TDesC8* refid( CheckRefAttributeL( iRef ) ); + + if ( refid && aProperty->Property()->Name() != XnPropertyNames::common::KId ) + { + delete aProperty; + + return level; + } + + const TDesC8& name( aProperty->Property()->Name() ); + + CXnProperty* prop( GetPropertyL( name ) ); + + if ( prop && prop->EqualsL( *aProperty ) ) + { + // No change in the property value + delete aProperty; + + return level; + } + + level = DirtyLevelFromPropertyL( *iNode, name ); + + // Save the displayed state, before setting the property + TBool isDisplayed( IsNodeDisplayedL( *iNode ) ); + + CXnDomProperty::TPseudoClass pseudoClass( aProperty->Property()->PseudoClass() ); + + if ( pseudoClass != CXnDomProperty::ENone ) + { + InsertPropertyPseudoClassL( pseudoClass, iPropertyPseudoClasses ); + + if ( IsStateSet( PseudoClassName( pseudoClass ) ) ) + { + SetCachedProperty( + aProperty, + iLayoutPropertyCache, + iRef, + iName, + iValue, + iLabel, + iInitialFocus, + iClass, + iId, + iPath, + iMaskPath, + iGridPropertyCache, + EFalse, + EFalse ); + } + } + else + { + SetCachedProperty( + aProperty, + iLayoutPropertyCache, + iRef, + iName, + iValue, + iLabel, + iInitialFocus, + iClass, + iId, + iPath, + iMaskPath, + iGridPropertyCache, + EFalse, + EFalse ); + } + + iPropertyList->SetPropertyL( aProperty ); + + TBool isDisplayedNow( IsNodeDisplayedL( *iNode ) ); + + level = ( iAdaptive & XnAdaptive::EIgnoreDirty ) ? XnDirtyLevel::ENone : level; + + // This is from layout calculation point of view + TBool displayed( ETrue ); + + if ( isDisplayed && !isDisplayedNow ) + { + // Node loses its visualisation (either display: none, or + // visibility: hidden) Make sure control is hidden + CCoeControl* ctrl( iNode->Control() ); + + if ( ctrl ) + { + ctrl->MakeVisible( EFalse ); + } + } + else if ( !isDisplayed && isDisplayedNow ) + { + // Node gains its visualisation (both display: block, and + // visibility: visible) + // Run gainvisualisation trigger, if node is 'visualisationaware' + CXnProperty* visaware( + GetPropertyL( XnPropertyNames::common::KVisualisationAware ) ); + + if ( visaware && visaware->StringValue() == XnPropertyNames::KTrue ) + { + CXnNode* gainVisualisation( BuildTriggerNodeL( *iUiEngine, + XnPropertyNames::action::trigger::name::KGainVisualisation ) ); + CleanupStack::PushL( gainVisualisation ); + iNode->ReportXuikonEventL( *gainVisualisation ); + CleanupStack::PopAndDestroy( gainVisualisation ); + } + } + else if ( !isDisplayed && !isDisplayedNow ) + { + // No change + displayed = EFalse; + } + + SetDirtyL( level, displayed ); + + return level; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::InitializePropertyL +// Set a property. +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::InitializePropertyL( CXnProperty* aProperty ) + { + const TDesC8* refid( CheckRefAttributeL( iRef ) ); + + if ( refid && aProperty->Property()->Name() != XnPropertyNames::common::KId ) + { + delete aProperty; + + return; + } + + if ( aProperty->Property()->PseudoClass() != CXnDomProperty::ENone ) + { + InsertPropertyPseudoClassL( + aProperty->Property()->PseudoClass(), iPropertyPseudoClasses ); + + SetCachedProperty( + aProperty, + iLayoutPropertyCache, + iRef, + iName, + iValue, + iLabel, + iInitialFocus, + iClass, + iId, + iPath, + iMaskPath, + iGridPropertyCache, + ETrue, + ETrue ); + } + else + { + SetCachedProperty( + aProperty, + iLayoutPropertyCache, + iRef, + iName, + iValue, + iLabel, + iInitialFocus, + iClass, + iId, + iPath, + iMaskPath, + iGridPropertyCache, + ETrue, + EFalse ); + } + + iPropertyList->SetPropertyL( aProperty ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::GetPropertyL +// Gets a property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::GetPropertyL( const TDesC8& aKey ) + { + CXnNode* refNode( RefNodeL( this, iRef, iUiEngine ) ) ; + + if ( refNode && aKey != KRef && aKey != KId ) + { + return refNode->GetPropertyL( aKey ); + } + + CXnDomProperty* attribute = NULL; + CXnProperty* property = iPropertyList->GetProperty( aKey ); + + if ( property ) + { + attribute = property->Property(); + CXnDomList& list = attribute->PropertyValueList(); + + if ( list.Length() == 0 ) + { + return NULL; + } + + CXnDomPropertyValue* attributeValue = + static_cast< CXnDomPropertyValue* >( list.Item( 0 ) ); + + if ( !attributeValue ) + { + return NULL; + } + + if ( attributeValue->IsInheritIdent() && iParent ) + { + // inherited values are queried from the parent + property = iParent->GetPropertyL( aKey ); + } + + // otherwise just return the value + return property; + } + + // if not found, return NULL + return NULL; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetStateL +// Set a pseudoclass +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetStateL( const TDesC8& aState, TInt aSource ) + { + if ( IsStateSet( aState ) ) + { + return; + } + + TBool focusReceived( EFalse ); + TBool activated( EFalse ); + TBool stateChanged( EFalse ); + + if ( aState == XnPropertyNames::action::trigger::name::KFocus ) + { + if ( !iUiEngine->AppUiAdapter().FocusShown() ) + { + return; + } + + focusReceived = DoReceiveFocusL( *iNode, *iUiEngine ); + + if ( focusReceived ) + { + // focused + HidePopupsL(); + ShowPopupsL( iNode->Rect(), aSource ); + + if ( IsStateSet( XnPropertyNames::action::trigger::name::KPassiveFocus ) ) + { + iUiEngine->RemovePassiveFocusedNodeL( iNode ); + } + + stateChanged = focusReceived = iPropertyList->SetStateL( aState ); + } + } + else if ( aState == XnPropertyNames::style::common::KPressedDown ) + { + if ( IsStateSet( XnPropertyNames::action::trigger::name::KFocus ) ) + { + iPropertyList->SetStateL( + XnPropertyNames::style::common::KPressedDown ); + iNode->SetDirtyL( XnDirtyLevel::ERender ); + } + } + else if ( aState == XnPropertyNames::style::common::KActive ) + { + activated = ETrue; + } + else if ( aState == XnPropertyNames::action::trigger::name::KPassiveFocus ) + { + // is focusable node + if ( DoReceiveFocusL( *iNode, *iUiEngine ) ) + { + // focused + stateChanged = iPropertyList->SetStateL( aState ); + } + } + else + { + stateChanged = iPropertyList->SetStateL( aState ); + } + + if ( stateChanged ) + { + CXnDomProperty::TPseudoClass pseudoClass( PseudoClassFromName( aState ) ); + + if ( pseudoClass != CXnDomProperty::ENone ) + { + iStates.Append( pseudoClass ); + + // Ensure that pseudo class is defined + InsertPropertyPseudoClassL( pseudoClass, iPropertyPseudoClasses ); + + if ( IsPropertyPseudoClass( pseudoClass, iPropertyPseudoClasses ) ) + { + EnableStatePropertiesL( *iNode, pseudoClass, iLayoutPropertyCache ); + + InformPropertyChangeL( *iNode ); + } + } + + if ( aState == XnPropertyNames::style::common::KPressedDown ) + { + iNode->SetDirtyL( XnDirtyLevel::ERender ); + } + } + + if ( focusReceived && aState == XnPropertyNames::action::trigger::name::KFocus ) + { + iUiEngine->SetFocusedNodeL( iNode, aSource ); + } + + if ( activated ) + { + DoSetActiveL( *iNode, *iUiEngine ); + } + + if ( stateChanged ) + { + iUiEngine->RenderUIL(); + } + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::IsStateSet +// Check whether a state is set or not +// ----------------------------------------------------------------------------- +// +TBool CXnNodeImpl::IsStateSet( const TDesC8& aState ) + { + return iPropertyList->IsStateSet( aState ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetStateWithoutNotificationL +// Set a pseudoclass +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetStateWithoutNotificationL( const TDesC8& aState ) + { + if ( IsStateSet( aState ) ) + { + return; + } + + TBool setState( ETrue ); + + if ( aState == XnPropertyNames::action::trigger::name::KFocus ) + { + if ( !iUiEngine->AppUiAdapter().FocusShown() ) + { + return; + } + + setState = DoReceiveFocusL( *iNode, *iUiEngine ); + } + + if ( setState && iPropertyList->SetStateL( aState ) ) + { + CXnDomProperty::TPseudoClass pseudoClass( PseudoClassFromName( aState ) ); + + if ( pseudoClass != CXnDomProperty::ENone ) + { + iStates.Append( pseudoClass ); + + // Ensure that pseudo class is defined + InsertPropertyPseudoClassL( pseudoClass, iPropertyPseudoClasses ); + + if ( IsPropertyPseudoClass( pseudoClass, iPropertyPseudoClasses ) ) + { + EnableStatePropertiesL( *iNode, pseudoClass, iLayoutPropertyCache ); + } + } + + if ( aState == XnPropertyNames::action::trigger::name::KFocus ) + { + iUiEngine->SetFocusedNodeL( iNode ); + + HidePopupsL(); + } + + iUiEngine->RenderUIL(); + } + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::UnsetStateL +// Unset a pseudoclass +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::UnsetStateL( const TDesC8& aState ) + { + if ( !IsStateSet( aState ) ) + { + return; + } + + if ( aState == XnPropertyNames::action::trigger::name::KFocus ) + { + HidePopupsL(); + + iPropertyList->UnsetState( + XnPropertyNames::style::common::KPressedDown ); + + if ( iUiEngine->FocusedNode() == iNode ) + { + iUiEngine->SetFocusedNodeL( NULL ); + } + } + + TBool stateChanged( iPropertyList->UnsetState( aState ) ); + + if ( stateChanged ) + { + CXnDomProperty::TPseudoClass pseudoClass( PseudoClassFromName( aState ) ); + + if ( IsPropertyPseudoClass( pseudoClass, iPropertyPseudoClasses ) ) + { + DisableStatePropertiesL( + *iNode, pseudoClass, iStates, iLayoutPropertyCache ); + + InformPropertyChangeL( *iNode ); + } + + for ( TInt i = iStates.Count() - 1; i >= 0; --i ) + { + if ( iStates[i] == pseudoClass ) + { + iStates.Remove( i ); + } + } + + if ( aState == XnPropertyNames::style::common::KPressedDown ) + { + iNode->SetDirtyL( XnDirtyLevel::ERender ); + } + + iUiEngine->RenderUIL(); + } + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetUiEngine +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetUiEngine( CXnUiEngine& aEngine ) + { + iUiEngine = &aEngine; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::UiEngine +// ----------------------------------------------------------------------------- +// +CXnUiEngine* CXnNodeImpl::UiEngine() + { + return iUiEngine; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::ReportXuikonEventL +// ----------------------------------------------------------------------------- +// +TBool CXnNodeImpl::ReportXuikonEventL( CXnNode& aEventData, TInt aSource ) + { + CXnProperty* prop( GetPropertyL( KActionsHandler ) ); + + CXnNode* handler( NULL ); + + iUiEngine->DisableRenderUiLC(); + + if ( prop ) + { + const TDesC8& value( prop->StringValue() ); + + handler = iUiEngine->FindNodeByIdL( value, Namespace() ); + } + + if ( handler && handler->Type()->Type() == KActionsHandler ) + { + // Let node to handle actions + DoTriggerEventL( this, *iUiEngine, *iNode, + *handler, aEventData, aSource ); + } + else + { + // Let this node to handle actions + DoTriggerEventL( this, *iUiEngine, *iNode, + *iNode, aEventData, aSource ); + } + + CleanupStack::PopAndDestroy(); // DisableRenderUiLC + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::OfferKeyEventL +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::OfferKeyEventL( const TKeyEvent& aKeyEvent, TEventCode aType ) + { + DoTriggerKeyEventL( this, *iUiEngine, *iNode, aKeyEvent, aType ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetDropped +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetDropped( const TInt aDropped ) + { + if ( Type()->Type() != KToolTip ) + { + iDropped = aDropped; + + TInt count( iChildren.Count() ); + + for ( TInt i = 0; i < count; i++ ) + { + iChildren[i]->SetDropped( aDropped ); + } + } + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::IsDropped +// ----------------------------------------------------------------------------- +// +TInt CXnNodeImpl::IsDropped() const + { + return iDropped; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetLayoutCapable +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetLayoutCapable( const TBool aLayoutCapable ) + { + iLayoutCapable = aLayoutCapable; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::IsLayoutCapable +// ----------------------------------------------------------------------------- +// +TBool CXnNodeImpl::IsLayoutCapable() const + { + return iLayoutCapable; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetRenderedL +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetRenderedL() + { + if ( !iLayoutCapable ) + { + return; + } + + CXnControlAdapter* control = + static_cast< CXnControlAdapter* >( iNode->Control() ); + + if ( control ) + { + TBool displayed( IsNodeDisplayedL( *iNode, ETrue, EFalse ) ); + + control->SetBlank( EFalse ); + + if ( iDropped || !displayed ) + { + // Need to check blank here + CXnProperty* prop( VisibilityL() ); + + if ( prop && prop->StringValue() == + XnPropertyNames::style::common::visibility::KBlank ) + { + control->SetBlank( ETrue ); + control->MakeVisible( EFalse ); + control->SetComponentsToInheritVisibility( EFalse ); + control->MakeVisible( ETrue ); + control->SetComponentsToInheritVisibility( ETrue ); + } + else + { + if ( control->IsVisible() ) + { + control->MakeVisible( EFalse ); + } + } + } + else + { + CCoeControl* parent( control->Parent() ); + + TBool parentVisible( ETrue ); + + if ( parent && !parent->IsVisible() ) + { + parentVisible = EFalse; + } + + if ( !control->IsVisible() && parentVisible ) + { + TBool found( EFalse ); + + for ( CXnNode* node = iNode; !found && node; node = node->Parent() ) + { + if ( node->Type()->Type() == KToolTip ) + { + // Tooltip control handles its visibility internally + found = ETrue; + } + } + + if ( !found ) + { + control->MakeVisible( ETrue ); + } + } + } + } + + iRendered = ETrue; + + for ( TInt i = 0; i < iChildren.Count(); i++ ) + { + iChildren[i]->SetRenderedL(); + } + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetLaidOutL +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetLaidOutL() + { + if ( !iLayoutCapable ) + { + return; + } + + if ( iDropped || !IsNodeDisplayedL( *iNode ) ) + { + return; + } + + iLaidOut = ETrue; + + for ( TInt i = 0; i < iChildren.Count(); i++ ) + { + iChildren[i]->SetLaidOutL(); + } + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::IsLaidOut +// ----------------------------------------------------------------------------- +// +TBool CXnNodeImpl::IsLaidOut() const + { + return iLaidOut; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::ClearRenderedAndLaidOut +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::ClearRenderedAndLaidOut() + { + if ( !iRendered && !iLaidOut ) + { + return; + } + + TRect empty; + + SetRect( empty ); + SetPaddingRect( empty ); + SetBorderRect( empty ); + SetNormalFlowBorderRect( empty ); + SetMarginRect( empty ); + + iRendered = EFalse; + iLaidOut = EFalse; + + if ( iLayoutCapable ) + { + for ( TInt i = 0; i < iChildren.Count(); i++ ) + { + iChildren[i]->ClearRenderedAndLaidOut(); + } + } + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::MakeInterfaceL +// Create a component interface according to the given type. +// ----------------------------------------------------------------------------- +// +XnComponentInterface::MXnComponentInterface* CXnNodeImpl::MakeInterfaceL( + const TDesC8& /*aType*/ ) + { + return NULL; + } + +// ----------------------------------------------------------------------------- +// PropertyL +// Returns a property. +// ----------------------------------------------------------------------------- +// +static CXnProperty* PropertyL( CXnNodeImpl* aThis, CXnProperty* aProperty, + CXnProperty* ( CXnNode::* aFunc )(), CXnUiEngine* aUiEngine, + TAny* aLayoutPropertyCache, CXnNode* aParent, CXnProperty* aRef ) + { + CXnNode* refNode( RefNodeL( aThis, aRef, aUiEngine ) ) ; + + if ( refNode ) + { + return ( refNode->*aFunc )(); + } + + if ( aLayoutPropertyCache && aProperty ) + { + CXnDomProperty* attribute = aProperty->Property(); + CXnDomList& list = attribute->PropertyValueList(); + + if ( list.Length() == 0 ) + { + return NULL; + } + + CXnDomPropertyValue* attributeValue = + static_cast< CXnDomPropertyValue* >( list.Item( 0 ) ); + + if ( !attributeValue ) + { + return NULL; + } + + if ( attributeValue->IsInheritIdent() && aParent ) + { + // inherited values are queried from the parent + return ( aParent->*aFunc )(); + } + + // otherwise just return the value + return aProperty; + } + + return NULL; + } + +// ----------------------------------------------------------------------------- +// ReferredPropertyL +// Returns a referred property. +// ----------------------------------------------------------------------------- +// +static CXnProperty* ReferredPropertyL( + RPointerArray< CXnProperty >* aPropertyArray, + RArray< CXnDomProperty::TPseudoClass >& aStates ) + { + if ( !aPropertyArray ) + { + return NULL; + } + for ( TInt i = aPropertyArray->Count() - 1; i >= 0; --i ) + { + CXnProperty* tmp = ( *aPropertyArray )[i]; + for ( TInt j = aStates.Count() - 1; j >= 0; --j ) + { + if ( aStates[j] == tmp->Property()->PseudoClass() ) + { + return tmp; + } + } + for ( TInt j = aStates.Count() - 1; j >= 0; --j ) + { + if ( tmp->Property()->PseudoClass() == CXnDomProperty::ENone ) + { + return tmp; + } + } + } + for ( TInt i = aPropertyArray->Count() - 1; i >= 0; --i ) + { + CXnProperty* tmp = ( *aPropertyArray )[i]; + if ( tmp->Property()->PseudoClass() == CXnDomProperty::ENone ) + { + return tmp; + } + } + return NULL; + } + +// ----------------------------------------------------------------------------- +// RefNodeL +// Returns referred node. +// ----------------------------------------------------------------------------- +// +static CXnNode* RefNodeL( + CXnNodeImpl* aThis, + CXnProperty* aRef, + CXnUiEngine* aUiEngine ) + { + const TDesC8* refid( CheckRefAttributeL( aRef ) ); + + if ( refid ) + { + CXnNode* node( aUiEngine->FindNodeByIdL( *refid, aThis->Namespace() ) ); + + if ( node ) + { + return node; + } + } + + return NULL; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::WidthL +// Returns width property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::WidthL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iWidths ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iWidth : NULL; + return PropertyL( this, property, &CXnNode::WidthL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::HeightL +// Returns height property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::HeightL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if (refNode) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iHeights ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iHeight : NULL; + return PropertyL( this, property, &CXnNode::HeightL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::MarginLeftL +// Returns margin-left property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::MarginLeftL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iMarginLefts ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? + iLayoutPropertyCache->iMarginLeft : + NULL; + return PropertyL( this, property, &CXnNode::MarginLeftL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::MarginRightL +// Returns margin-right property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::MarginRightL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iMarginRights ) : + NULL; + return ReferredPropertyL(propertyArray, iStates); + } + CXnProperty* property = + iLayoutPropertyCache ? + iLayoutPropertyCache->iMarginRight : + NULL; + return PropertyL( this, property, &CXnNode::MarginRightL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BorderLeftL +// Returns border-left property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BorderLeftL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBorderLefts ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = iLayoutPropertyCache ? + iLayoutPropertyCache->iBorderLeft : + NULL; + return PropertyL( this, property, &CXnNode::BorderLeftL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BorderRightL +// Returns border-right property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BorderRightL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBorderRights ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? + iLayoutPropertyCache->iBorderRight : + NULL; + return PropertyL( this, property, &CXnNode::BorderRightL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::PaddingLeftL +// Returns padding-left property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::PaddingLeftL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iPaddingLefts ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? + iLayoutPropertyCache->iPaddingLeft : + NULL; + return PropertyL( this, property, &CXnNode::PaddingLeftL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::PaddingRightL +// Returns PaddingRightL property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::PaddingRightL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iPaddingRights ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iPaddingRight : NULL; + return PropertyL( this, property, &CXnNode::PaddingRightL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::MarginTopL +// Returns margin-top property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::MarginTopL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iMarginTops ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iMarginTop : NULL; + return PropertyL( this, property, &CXnNode::MarginTopL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::MarginBottomL +// Returns margin-bottom property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::MarginBottomL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iMarginBottoms ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iMarginBottom : NULL; + return PropertyL( this, property, &CXnNode::MarginBottomL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BorderTopL +// Returns border-top property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BorderTopL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBorderTops ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iBorderTop : NULL; + return PropertyL( this, property, &CXnNode::BorderTopL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BorderBottomL +// Returns border-bottom property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BorderBottomL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBorderBottoms ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iBorderBottom : NULL; + return PropertyL( this, property, &CXnNode::BorderBottomL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::PaddingTopL +// Returns padding-top property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::PaddingTopL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iPaddingTops ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iPaddingTop : NULL; + return PropertyL( this, property, &CXnNode::PaddingTopL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::PaddingBottomL +// Returns padding-bottom property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::PaddingBottomL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iPaddingBottoms ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iPaddingBottom : NULL; + return PropertyL( this, property, &CXnNode::PaddingBottomL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BorderWidthL +// Returns border-width property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BorderWidthL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBorderWidths ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iBorderWidth : NULL; + return PropertyL( this, property, &CXnNode::BorderWidthL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BlockProgressionL +// Returns block-progression property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BlockProgressionL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBlockProgressions ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iBlockProgression : NULL; + return PropertyL( this, property, &CXnNode::BlockProgressionL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::DirectionL +// Returns direction property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::DirectionL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iDirections ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iDirection : NULL; + return PropertyL( this, property, &CXnNode::DirectionL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::PositionL +// Returns position property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::PositionL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iPositions ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iPosition : NULL; + return PropertyL( this, property, &CXnNode::PositionL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::MaxHeightL +// Returns max-height property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::MaxHeightL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iMaxHeights ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iMaxHeight : NULL; + return PropertyL( this, property, &CXnNode::MaxHeightL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::MinHeightL +// Returns min-height property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::MinHeightL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iMinHeights ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iMinHeight : NULL; + return PropertyL( this, property, &CXnNode::MinHeightL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::MaxWidthL +// Returns max-width property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::MaxWidthL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iMaxWidths ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iMaxWidth : NULL; + return PropertyL( this, property, &CXnNode::MaxWidthL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::MinWidthL +// Returns min-width property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::MinWidthL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iMinWidths ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iMinWidth : NULL; + return PropertyL( this, property, &CXnNode::MinWidthL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::DisplayL +// Returns display property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::DisplayL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iDisplays ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iDisplay : NULL; + return PropertyL( this, property, &CXnNode::DisplayL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::LeftL +// Returns left property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::LeftL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iLefts ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iLeft : NULL; + return PropertyL( this, property, &CXnNode::LeftL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::RightL +// Returns right property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::RightL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iRights ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iRight : NULL; + return PropertyL( this, property, &CXnNode::RightL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::TopL +// Returns top property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::TopL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iTops ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iTop : NULL; + return PropertyL( this, property, &CXnNode::TopL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BottomL +// Returns bottom property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BottomL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBottoms ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iBottom : NULL; + return PropertyL( this, property, &CXnNode::BottomL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BorderLeftStyleL +// Returns border-left-style property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BorderLeftStyleL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBorderLeftStyles ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iBorderLeftStyle : NULL; + return PropertyL( this, property, &CXnNode::BorderLeftStyleL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BorderRightStyleL +// Returns border-right-style property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BorderRightStyleL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBorderRightStyles ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iBorderRightStyle : NULL; + return PropertyL( this, property, &CXnNode::BorderRightStyleL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BorderTopStyleL +// Returns border-top-style property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BorderTopStyleL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBorderTopStyles ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iBorderTopStyle : NULL; + return PropertyL( this, property, &CXnNode::BorderTopStyleL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BorderBottomStyleL +// Returns border-bottom-style property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BorderBottomStyleL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBorderBottomStyles ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iBorderBottomStyle : NULL; + return PropertyL( this, property, &CXnNode::BorderBottomStyleL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BorderStyleL +// Returns border-style property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BorderStyleL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBorderStyles ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iBorderStyle : NULL; + return PropertyL( this, property, &CXnNode::BorderStyleL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BorderImageL +// Returns border-image property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BorderImageL() + { + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iBorderImage : NULL; + return PropertyL( this, property, &CXnNode::BorderImageL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::DisplayPriorityL +// Returns display-priority property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::DisplayPriorityL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iDisplayPriorities ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iDisplayPriority : NULL; + return PropertyL( this, property, &CXnNode::DisplayPriorityL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::NameL +// Returns name property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::NameL() + { + return PropertyL( this, iName, &CXnNode::NameL, + iUiEngine, this, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::ValueL +// Returns value property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::ValueL() + { + return PropertyL( this, iValue, &CXnNode::ValueL, + iUiEngine, this, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::VisibilityL +// Returns visibility property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::VisibilityL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iVisibilities ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iVisibility : NULL; + return PropertyL( this, property, &CXnNode::VisibilityL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::LabelL +// Returns label property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::LabelL() + { + return PropertyL( this, iLabel, &CXnNode::LabelL, + iUiEngine, this, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::InitialFocusL +// Returns initial-focus property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::InitialFocusL() + { + return PropertyL( this, iInitialFocus, &CXnNode::InitialFocusL, + iUiEngine, this, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::ClassL +// Returns class property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::ClassL() + { + return PropertyL( this, iClass, &CXnNode::ClassL, + iUiEngine, this, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::IdL +// Returns id property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::IdL() + { + if ( iId ) + { + CXnDomProperty* attribute = iId->Property(); + CXnDomList& list = attribute->PropertyValueList(); + if ( list.Length() == 0 ) + { + return NULL; + } + CXnDomPropertyValue* attributeValue = + static_cast< CXnDomPropertyValue* >( list.Item( 0 ) ); + if ( !attributeValue ) + { + return NULL; + } + if ( attributeValue->IsInheritIdent() + && iParent ) + { + // inherited values are queried from the parent + return iParent->IdL(); + } + // otherwise just return the value + return iId; + } + // if not found, return NULL + return NULL; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::PathL +// Returns path property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::PathL() + { + return PropertyL( this, iPath, &CXnNode::PathL, + iUiEngine, this, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::MaskPathL +// Returns maskpath property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::MaskPathL() + { + return PropertyL( this, iMaskPath, &CXnNode::MaskPathL, + iUiEngine, this, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::NavIndexL +// Returns nav-index property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::NavIndexL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iNavIndexes ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iNavIndex : NULL; + return PropertyL( this, property, &CXnNode::NavIndexL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::VisibleRowsL +// Returns visible-rows property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::VisibleRowsL() + { + CXnProperty* property = + iGridPropertyCache ? iGridPropertyCache->iVisibleRows : NULL; + return PropertyL( this, property, &CXnNode::VisibleRowsL, + iUiEngine, iGridPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::GridColumnsL +// Returns grid-columns property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::GridColumnsL() + { + CXnProperty* property = + iGridPropertyCache ? iGridPropertyCache->iGridColumns : NULL; + return PropertyL( this, property, &CXnNode::GridColumnsL, + iUiEngine, iGridPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::GridOrientationL +// Returns grid-orientation property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::GridOrientationL() + { + CXnProperty* property = + iGridPropertyCache ? iGridPropertyCache->iGridOrientation : NULL; + return PropertyL( this, property, &CXnNode::GridOrientationL, + iUiEngine, iGridPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::GridVerDirectionL +// Returns grid-ver-direction property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::GridVerDirectionL() + { + CXnProperty* property = + iGridPropertyCache ? iGridPropertyCache->iGridVerDirection : NULL; + return PropertyL( this, property, &CXnNode::GridVerDirectionL, + iUiEngine, iGridPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::GridHorDirectionL +// Returns grid-hor-direction property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::GridHorDirectionL() + { + CXnProperty* property = + iGridPropertyCache ? iGridPropertyCache->iGridHorDirection : NULL; + return PropertyL( this, property, &CXnNode::GridHorDirectionL, + iUiEngine, iGridPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::FocusHorLoopingL +// Returns focus-hor-looping property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::FocusHorLoopingL() + { + CXnProperty* property = + iGridPropertyCache ? iGridPropertyCache->iFocusHorLooping : NULL; + return PropertyL( this, property, &CXnNode::FocusHorLoopingL, + iUiEngine, iGridPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::FocusVerLoopingL +// Returns focus-ver-looping property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::FocusVerLoopingL() + { + CXnProperty* property = + iGridPropertyCache ? iGridPropertyCache->iFocusVerLooping : NULL; + return PropertyL( this, property, &CXnNode::FocusVerLoopingL, + iUiEngine, iGridPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::ZIndexL +// Returns z-index property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::ZIndexL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iZIndexes ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iZIndex : NULL; + return PropertyL( this, property, &CXnNode::ZIndexL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BackgroundColorL +// Returns background-color property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BackgroundColorL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBackgroundColors ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iBackgroundColor : NULL; + return PropertyL( this, property, &CXnNode::BackgroundColorL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::BackgroundImageL +// Returns background-image property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::BackgroundImageL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iBackgroundImages ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iBackgroundImage : NULL; + return PropertyL( this, property, &CXnNode::BackgroundImageL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::FocusBackgroundL +// Returns focus-background property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::FocusBackgroundL() + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + + if ( refNode ) + { + RPointerArray< CXnProperty >* propertyArray = + refNode->Impl()->iLayoutPropertyCache ? + &( refNode->Impl()->iLayoutPropertyCache->iFocusBackgrounds ) : + NULL; + return ReferredPropertyL( propertyArray, iStates ); + } + + CXnProperty* property = + iLayoutPropertyCache ? iLayoutPropertyCache->iFocusBackground : NULL; + + return PropertyL( this, property, &CXnNode::FocusBackgroundL, + iUiEngine, iLayoutPropertyCache, + iParent, iRef ); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::RefL +// Returns ref property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::RefL() + { + return iRef; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::GridScrollBarWidthL +// Returns grid-scrollbar-width property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::GridScrollBarWidthL() + { + CXnProperty* property = NULL; + + if ( iGridPropertyCache && iGridPropertyCache->iGridScrollBarWidth) + { + property = PropertyL( + this, + iGridPropertyCache->iGridScrollBarWidth, + &CXnNode::GridScrollBarWidthL, + iUiEngine, iGridPropertyCache, + iParent, + iRef ); + } + + if ( !property && iRef ) + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + + if ( refNode ) + { + property = refNode->GridScrollBarWidthL(); + } + } + + if ( !property ) + { + TReal sbWidth( KS60ScrollbarDefaultWidth ); + // Set default value + CXnDomDocument& doc = iUiEngine->ODT()->DomDocument(); + CXnDomProperty* domProperty = CXnDomProperty::NewL( + XnPropertyNames::grid::KS60GridScrollbarWidth, doc.StringPool() ); + CleanupStack::PushL( domProperty ); + CXnDomPropertyValue* propertyValue = CXnDomPropertyValue::NewL( + doc.StringPool() ); + CleanupStack::PushL( propertyValue ); + if ( AknLayoutUtils::PenEnabled() ) + { + sbWidth = KS60ScrollbarDefaultWidthPenEnabled; + } + propertyValue->SetFloatValueL( CXnDomPropertyValue::EUnitValue, sbWidth ); + domProperty->PropertyValueList().AddItemL( propertyValue ); + CleanupStack::Pop( propertyValue ); + + property = CXnProperty::NewL( domProperty ); + CleanupStack::Pop( domProperty ); + CleanupStack::PushL( property ); + + // If this is a reference node, set property to the referred node, not this. + CXnNode* node = RefNodeL( this, iRef, iUiEngine ); + if ( node ) + { + node->SetPropertyL( property ); + } + else + { + this->SetPropertyL( property ); // deletes existing one + } + + CleanupStack::Pop( property ); + } + + return property; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::GridScrollBarMarginL +// Returns grid-scrollbar-margin property. +// ----------------------------------------------------------------------------- +// +CXnProperty* CXnNodeImpl::GridScrollBarMarginL() + { + CXnProperty* property = NULL; + if ( iGridPropertyCache && iGridPropertyCache->iGridScrollBarMargin ) + { + property = PropertyL( + this, + iGridPropertyCache->iGridScrollBarMargin, + &CXnNode::GridScrollBarMarginL, + iUiEngine, iGridPropertyCache, + iParent, + iRef ); + } + + if ( !property && iRef ) + { + CXnNode* refNode = RefNodeL( this, iRef, iUiEngine ); + + if ( refNode ) + { + property = refNode->GridScrollBarMarginL(); + } + } + + if ( !property ) + { + TReal sbMarginWidth( KS60ScrollbarDefaultMargin ); + // Set default value + CXnDomDocument& doc = iUiEngine->ODT()->DomDocument(); + CXnDomProperty* domProperty = + CXnDomProperty::NewL( + XnPropertyNames::grid::KS60GridScrollbarMargin, + doc.StringPool() ); + CleanupStack::PushL( domProperty ); + CXnDomPropertyValue* propertyValue = CXnDomPropertyValue::NewL( + doc.StringPool() ); + CleanupStack::PushL( propertyValue ); + if ( AknLayoutUtils::PenEnabled() ) + { + sbMarginWidth = KS60ScrollbarDefaultMarginPenEnabled; + } + propertyValue->SetFloatValueL( + CXnDomPropertyValue::EUnitValue, sbMarginWidth ); + domProperty->PropertyValueList().AddItemL( propertyValue ); + CleanupStack::Pop( propertyValue ); + + property = CXnProperty::NewL( domProperty ); + CleanupStack::Pop( domProperty ); + CleanupStack::PushL( property ); + + // If this is a reference node, set property to the referred node, not this. + CXnNode* node = RefNodeL( this, iRef, iUiEngine ); + if ( node ) + { + node->SetPropertyL( property ); + } + else + { + this->SetPropertyL( property ); // deletes existing one + } + + CleanupStack::Pop(property); + } + return property; + } + +// ---------------------------------------------------------------------------- +// CXnNodeImpl::SetDomNode +// Sets DOM node +// ---------------------------------------------------------------------------- +// +void CXnNodeImpl::SetDomNode( CXnDomNode* aDomNode ) + { + iDomNode = aDomNode; + } + +// ---------------------------------------------------------------------------- +// CXnNodeImpl::DomNode +// Returns the DOM node pointer +// ---------------------------------------------------------------------------- +// +CXnDomNode* CXnNodeImpl::DomNode() + { + return iDomNode; + } + +// ---------------------------------------------------------------------------- +// CXnNodeImpl::MeasureAdaptiveContentL +// Measures the adaptive content dimensions. +// ---------------------------------------------------------------------------- +// +TSize CXnNodeImpl::MeasureAdaptiveContentL( const TSize& aAvailableSize ) + { + TSize empty; + + TInt adaptive( IsAdaptive() ); + + if ( aAvailableSize.iWidth <= 0 && ( adaptive & XnAdaptive::EWidth ) || + aAvailableSize.iHeight <= 0 && ( adaptive & XnAdaptive::EHeight ) ) + { + // No available size, don't even try to measure + return empty; + } + + // node is displayed as default + TBool displayed( ETrue ); + + CXnProperty* displayProp( DisplayL() ); + + if ( displayProp ) + { + const TDesC8& value( displayProp->StringValue() ); + + if ( value != XnPropertyNames::style::common::display::KBlock ) + { + // Not displayed + displayed = EFalse; + } + } + + if ( adaptive && iLayoutCapable && !iDropped && displayed ) + { + CXnControlAdapter* adapter( iNode->Control() ); + + // What is my size? + if ( adapter ) + { + TInt width( 0 ); + TInt height( 0 ); + + TSize size = adapter->MeasureAdaptiveContentL( aAvailableSize ); + + if ( adaptive & XnAdaptive::EWidth ) + { + width = size.iWidth; + } + + if ( adaptive & XnAdaptive::EHeight ) + { + height = size.iHeight; + } + + return TSize( width, height ); + } + } + + return empty; + } + +// ---------------------------------------------------------------------------- +// CXnNodeImpl::IsAdaptive +// Checks if the node have adaptive content +// ---------------------------------------------------------------------------- +// +TInt CXnNodeImpl::IsAdaptive( TBool aIgnoreSizeFixed ) const + { + if ( !iAdaptive ) + { + return XnAdaptive::ENone; + } + + TInt adaptive( iAdaptive ); + + if ( ( adaptive & XnAdaptive::ESizeFixed ) && !aIgnoreSizeFixed ) + { + // When size is fixed, pretend non-adaptive + return XnAdaptive::ENone; + } + + // Remove measure control flags + adaptive &= ~XnAdaptive::EMeasure; + adaptive &= ~XnAdaptive::ESizeFixed; + + return adaptive; + } + +// ---------------------------------------------------------------------------- +// CXnNodeImpl::SetAdaptiveL +// Marks the node to have adaptive content +// ---------------------------------------------------------------------------- +// +void CXnNodeImpl::SetAdaptiveL( const TInt aAdaptive ) + { + TInt adaptive( aAdaptive ); + + // Force adaptive nodes to be auto + if ( adaptive & XnAdaptive::EMeasure ) + { + if ( iAdaptive & XnAdaptive::EMeasure ) + { + // Measure already pending + return; + } + + if ( iAdaptive & XnAdaptive::EWidth ) + { + adaptive |= XnAdaptive::EWidth; + } + + if ( iAdaptive & XnAdaptive::EHeight ) + { + adaptive |= XnAdaptive::EHeight; + } + + // Reset + iAdaptive = XnAdaptive::ENone; + } + + if ( ( adaptive & XnAdaptive::EWidth ) && + !( iAdaptive & XnAdaptive::EWidth ) ) + { + iAdaptive |= XnAdaptive::EIgnoreDirty; + + SetStringPropertyToNodeL( + DomNode()->StringPool(), *Node(), + XnPropertyNames::style::common::KWidth, + XnPropertyNames::style::common::KAuto ); + + // Width is adaptive + iAdaptive |= XnAdaptive::EWidth; + + iAdaptive &= ~XnAdaptive::EIgnoreDirty; + } + + if ( ( adaptive & XnAdaptive::EHeight ) && + !( iAdaptive & XnAdaptive::EHeight ) ) + { + iAdaptive |= XnAdaptive::EIgnoreDirty; + + SetStringPropertyToNodeL( + DomNode()->StringPool(), *Node(), + XnPropertyNames::style::common::KHeight, + XnPropertyNames::style::common::KAuto ); + + // Height is adaptive + iAdaptive |= XnAdaptive::EHeight; + + iAdaptive &= ~XnAdaptive::EIgnoreDirty; + } + + // Size is no more fixed + iAdaptive &= ~XnAdaptive::ESizeFixed; + + // and it needs to be measured + iAdaptive |= XnAdaptive::EMeasure; + } + +// ---------------------------------------------------------------------------- +// CXnNodeImpl::FixAdaptiveSize +// Fixes the adaptive node's size +// ---------------------------------------------------------------------------- +// +void CXnNodeImpl::FixAdaptiveSizeL( const TSize& aFixedSize ) + { + // Is there measure pending + if ( iAdaptive & XnAdaptive::EMeasure ) + { + if ( iAdaptive & XnAdaptive::EWidth ) + { + iAdaptive |= XnAdaptive::EIgnoreDirty; + + SetFloatPropertyToNodeL( + DomNode()->StringPool(), *Node(), + XnPropertyNames::style::common::KWidth, + aFixedSize.iWidth, CXnDomPropertyValue::EPx ); + + iAdaptive &= ~XnAdaptive::EIgnoreDirty; + } + + if ( iAdaptive & XnAdaptive::EHeight ) + { + iAdaptive |= XnAdaptive::EIgnoreDirty; + + SetFloatPropertyToNodeL( + DomNode()->StringPool(), *Node(), + XnPropertyNames::style::common::KHeight, + aFixedSize.iHeight, CXnDomPropertyValue::EPx ); + + iAdaptive &= ~XnAdaptive::EIgnoreDirty; + } + + // Measure done + iAdaptive &= ~XnAdaptive::EMeasure; + // Size is now fixed + iAdaptive |= XnAdaptive::ESizeFixed; + } + } + +// ---------------------------------------------------------------------------- +// CXnNodeImpl::PeriodicEventL +// ---------------------------------------------------------------------------- +// +TInt CXnNodeImpl::PeriodicEventL( TAny* aPtr ) + { + TXnTimedTrigger* params = static_cast< TXnTimedTrigger* >( aPtr ); + CXnNodeImpl* impl = params->iNodeImpl; + CXnUiEngine* engine = params->iEngine; + CXnNode* node = params->iNode; + CXnNode* eventData = params->iEventData; + CXnDomNode* actionNode = params->iActionNode; + CXnDomNode* triggerNode = params->iTriggerNode; + RunEventsL( impl, *engine, *node, *actionNode, *triggerNode, *eventData ); + delete params; + impl->DeletePeriodic(); + return EFalse; + } + +// ---------------------------------------------------------------------------- +// CXnNodeImpl::PeriodicTimer +// ---------------------------------------------------------------------------- +// +CPeriodic* CXnNodeImpl::PeriodicTimer() + { + return iPeriodicTimer; + } + +// ---------------------------------------------------------------------------- +// CXnNodeImpl::CreatePeriodicL +// ---------------------------------------------------------------------------- +// +void CXnNodeImpl::CreatePeriodicL() + { + iPeriodicTimer = CPeriodic::NewL( CActive::EPriorityIdle ); + } + +// --------------------------------------------------------- +// CXnNodeImpl::DeletePeriodic +// --------------------------------------------------------- +// +void CXnNodeImpl::DeletePeriodic() + { + if ( iPeriodicTimer ) + { + iPeriodicTimer->Cancel(); + delete iPeriodicTimer; + iPeriodicTimer = NULL; + } + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetDirtyL +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetDirtyL( TInt aLevel, TBool aDisplayedState ) + { + if( !aDisplayedState ) + { + // check if node isn't displayed indeed (def. param. = EFalse) + aDisplayedState = IsNodeDisplayedL( *iNode ); + } + if ( iLayoutCapable ) + { + if ( aLevel == XnDirtyLevel::ENone ) + { + // nothing to do + return; + } + + if ( aLevel == XnDirtyLevel::ELayoutAndRenderSiblings ) + { + if ( iParent ) + { + // Siblings needs to be laid out also + RPointerArray< CXnNode >& siblings( iParent->Children() ); + + for ( TInt i = 0; i < siblings.Count(); i++ ) + { + CXnNode* sibling( siblings[i] ); + + if ( sibling == iNode ) + { + sibling->SetDirtyL( XnDirtyLevel::ELayoutAndRender, + aDisplayedState ); + } + else + { + sibling->SetDirtyL( XnDirtyLevel::ELayoutAndRender ); + } + } + } + } + else + { + if ( ( iParent || iNode == iUiEngine->RootNode() ) && + iNode != iUiEngine->ActiveView() ) + { + // Full redraw (without layout) can be done by setting rootnode + // level to ERender + if ( aLevel == XnDirtyLevel::ERender && !iLaidOut && + iNode != iUiEngine->RootNode() ) + { + aLevel = XnDirtyLevel::ELayoutAndRender; + } + + if ( aDisplayedState ) + { + iUiEngine->AddDirtyNodeL( iNode, aLevel ); + } + else + { + ClearRenderedAndLaidOut(); + } + } + } + } + else if ( iParent && iParent->Type()->Type() == KMenuBar ) + { + // Mark menu to be refreshed + iUiEngine->AddDirtyNodeL( iParent, XnDirtyLevel::ERender ); + } + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::RunFocusChangeL +// ----------------------------------------------------------------------------- +// +TBool CXnNodeImpl::RunFocusChangeL( RPointerArray< CXnNode >& aFocusCandidates ) + { + for ( TInt i = 0; i < aFocusCandidates.Count(); i++ ) + { + CXnNode* node( aFocusCandidates[i] ); + + if ( IsNodeNavigableL( *node ) ) + { + if( node->ScrollableControl() ) + { + node->ScrollableControl()->ShowItem( *node ); + } + + node->SetStateWithoutNotificationL( + XnPropertyNames::style::common::KFocus ); + + // All done + return ETrue; + } + } + + // Focus change failed + CXnNode* focused( iUiEngine->FocusedNode() ); + + if ( focused ) + { + // Is the currently focused node still navigable + if ( !IsNodeNavigableL( *focused ) ) + { + // No, remove focus + focused->UnsetStateL( XnPropertyNames::style::common::KFocus ); + } + } + + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::ReorderNodesL +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::ReorderNodesL( CXnNode* aSource, CXnNode* aTarget ) + { + TInt target = -1; + TInt source = -1; + TInt childCount = iChildren.Count(); + RPointerArray< CXnNode > lockedNodes; + CleanupClosePushL( lockedNodes ); + RArray< TInt > lockedNodeIndex; + CleanupClosePushL( lockedNodeIndex ); + + for ( TInt i = 0; i < childCount; i++ ) + { + CXnNode* tmpNode = iChildren[i]; + CXnProperty* editable = tmpNode->GetPropertyL( + XnPropertyNames::style::common::edit::KEditable ); + if ( editable && editable->StringValue() == XnPropertyNames::KFalse ) + { + lockedNodes.AppendL( tmpNode ); + lockedNodeIndex.AppendL( i ); + continue; + } + + if ( tmpNode == aSource ) + { + source = i; + } + if ( tmpNode == aTarget ) + { + target = i; + } + } + if ( source != -1 && target != -1 ) + { + if ( target < source ) + { + iChildren.InsertL( aSource, target ); + iChildren.Remove( source + 1 ); + } + else if ( source < target ) + { + iChildren.Remove( source ); + iChildren.InsertL( aSource, target ); + } + + // put the locked nodes to the original places + TInt lockedNodeCount = lockedNodes.Count(); + TInt lockedIndexCount = lockedNodeIndex.Count(); + if ( lockedNodeCount != lockedIndexCount ) + { + return; + } + // First remove all the locked nodes + for ( TInt j = 0; j < lockedNodeCount; j++ ) + { + CXnNode* tmpLockedNode = lockedNodes[j]; + TInt ind = iChildren.FindL( tmpLockedNode ); + if ( KErrNotFound != ind ) + { + iChildren.Remove( ind ); + } + } + + //And then put them again to the original places + for ( TInt j = 0; j < lockedNodeCount; j++ ) + { + CXnNode* tmpLockedNode = lockedNodes[j]; + iChildren.InsertL( tmpLockedNode, lockedNodeIndex[j] ); + } + } + + lockedNodes.Reset(); + lockedNodeIndex.Reset(); + CleanupStack::PopAndDestroy( 2 ); // lockedNodes, lockedNodeIndex + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::FindNextNodeL +// ----------------------------------------------------------------------------- +// +CXnNode* CXnNodeImpl::FindNextNodeL( + RPointerArray< CXnNode >& aArray, + CXnNode& aNode, + TInt aDirection ) + { + CXnNode* node = NULL; + if ( aDirection == EStdKeyRightArrow ) + { + node = FindNextNodeFromRightL( aArray, aNode ); + } + else if ( aDirection == EStdKeyLeftArrow ) + { + node = FindNextNodeFromLeftL( aArray, aNode ); + } + else if ( aDirection == EStdKeyUpArrow ) + { + node = FindNextNodeFromAboveL( aArray, aNode ); + } + else if ( aDirection == EStdKeyDownArrow ) + { + node = FindNextNodeFromBelowL( aArray, aNode ); + } + return node; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::Namespace +// ----------------------------------------------------------------------------- +// +const TDesC8& CXnNodeImpl::Namespace() + { + return DomNode()->Namespace(); + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::SetScrollableControl() +// ----------------------------------------------------------------------------- +// +void CXnNodeImpl::SetScrollableControl( CXnScrollableControlAdapter* aScrollableControl ) + { + iScrollableControl = aScrollableControl; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::ScrollableControl() +// ----------------------------------------------------------------------------- +// +CXnScrollableControlAdapter* CXnNodeImpl::ScrollableControl() + { + return iScrollableControl; + } + +// ----------------------------------------------------------------------------- +// CXnNodeImpl::AdjustRectIfNeeded +// ----------------------------------------------------------------------------- +// +TRect CXnNodeImpl::AdjustRectIfNeeded( TRect aRect ) + { + if(iScrollableControl) + { + aRect.Move( iScrollableControl->DeltaPosition() ); + } + return aRect; + } +