31 #include "xnodt.h" |
31 #include "xnodt.h" |
32 #include "xndomlist.h" |
32 #include "xndomlist.h" |
33 #include "xndompropertyvalue.h" |
33 #include "xndompropertyvalue.h" |
34 #include "xnmenuadapter.h" |
34 #include "xnmenuadapter.h" |
35 #include "xnpopupcontroladapter.h" |
35 #include "xnpopupcontroladapter.h" |
|
36 #include "xnviewcontroladapter.h" |
36 #include "xnviewdata.h" |
37 #include "xnviewdata.h" |
|
38 #include "xnrootdata.h" |
37 #include "xnnodebreadthfirstiterator.h" |
39 #include "xnnodebreadthfirstiterator.h" |
38 #include "xntype.h" |
40 #include "xntype.h" |
39 #include "xnnodepluginif.h" |
41 #include "xnnodepluginif.h" |
40 #include "xncomponentnodeimpl.h" |
42 #include "xncomponentnodeimpl.h" |
41 #include "xnproperty.h" |
43 #include "xnproperty.h" |
79 _LIT8( KWidgetNodeName, "widget" ); |
80 _LIT8( KWidgetNodeName, "widget" ); |
80 _LIT8( KWidgetExtensionNodeName, "widgetextension" ); |
81 _LIT8( KWidgetExtensionNodeName, "widgetextension" ); |
81 _LIT8( KScrollableBoxNodeName, "scrollablebox" ); |
82 _LIT8( KScrollableBoxNodeName, "scrollablebox" ); |
82 _LIT8( KMenuBar, "menubar" ); |
83 _LIT8( KMenuBar, "menubar" ); |
83 _LIT8( KPopUpNodeName, "popup" ); |
84 _LIT8( KPopUpNodeName, "popup" ); |
|
85 _LIT8( KEditorNodeName, "texteditor" ); |
84 |
86 |
85 _LIT8( KPlugin, "plugin" ); |
87 _LIT8( KPlugin, "plugin" ); |
86 |
88 |
87 // LOCAL CONSTANTS AND MACROS |
89 // LOCAL CONSTANTS AND MACROS |
88 static const TReal KIntConversionConstant = 0.5; |
90 static const TReal KIntConversionConstant = 0.5; |
8462 // |
8485 // |
8463 CXnPointerArray* CXnUiEngineImpl::FindNodeByClassL( |
8486 CXnPointerArray* CXnUiEngineImpl::FindNodeByClassL( |
8464 const TDesC8& aClassId, const TDesC8& aNamespace ) |
8487 const TDesC8& aClassId, const TDesC8& aNamespace ) |
8465 { |
8488 { |
8466 // Find the namespace where to start node class look-up |
8489 // Find the namespace where to start node class look-up |
8467 CXnPluginData* pluginData( |
8490 CXnViewData& active( iViewManager.ActiveViewData() ); |
8468 iViewManager.ActiveViewData().Plugin( aNamespace ) ); |
8491 |
8469 |
8492 CXnPluginData* pluginData( active.Plugin( aNamespace ) ); |
|
8493 |
|
8494 if ( aNamespace != KNullDesC8 && !pluginData ) |
|
8495 { |
|
8496 RPointerArray< CXnPluginData >& views( |
|
8497 iViewManager.ActiveAppData().PluginData() ); |
|
8498 |
|
8499 for ( TInt i = 0; i < views.Count(); i++ ) |
|
8500 { |
|
8501 CXnViewData* view = static_cast< CXnViewData* >( views[i] ); |
|
8502 |
|
8503 if ( view != &active ) |
|
8504 { |
|
8505 pluginData = view->Plugin( aNamespace ); |
|
8506 |
|
8507 if ( pluginData ) |
|
8508 { |
|
8509 break; |
|
8510 } |
|
8511 } |
|
8512 } |
|
8513 } |
|
8514 |
8470 CXnPointerArray* array = CXnPointerArray::NewL(); |
8515 CXnPointerArray* array = CXnPointerArray::NewL(); |
8471 CleanupStack::PushL( array ); |
8516 CleanupStack::PushL( array ); |
8472 |
8517 |
8473 if ( pluginData ) |
8518 if ( pluginData ) |
8474 { |
8519 { |
8479 CleanupStack::Pop( array ); |
8524 CleanupStack::Pop( array ); |
8480 |
8525 |
8481 return array; |
8526 return array; |
8482 } |
8527 } |
8483 |
8528 |
|
8529 // ----------------------------------------------------------------------------- |
|
8530 // CXnUiEngineImpl::FindContentSourceNodesL() |
|
8531 // ----------------------------------------------------------------------------- |
|
8532 // |
|
8533 CXnPointerArray* CXnUiEngineImpl::FindContentSourceNodesL( |
|
8534 const TDesC8& aNamespace ) |
|
8535 { |
|
8536 CXnViewData& active( iViewManager.ActiveViewData() ); |
|
8537 |
|
8538 CXnPluginData* pluginData( active.Plugin( aNamespace ) ); |
|
8539 |
|
8540 if ( aNamespace != KNullDesC8 && !pluginData ) |
|
8541 { |
|
8542 RPointerArray< CXnPluginData >& views( |
|
8543 iViewManager.ActiveAppData().PluginData() ); |
|
8544 |
|
8545 for ( TInt i = 0; i < views.Count(); i++ ) |
|
8546 { |
|
8547 CXnViewData* view = static_cast< CXnViewData* >( views[i] ); |
|
8548 |
|
8549 if ( view != &active ) |
|
8550 { |
|
8551 pluginData = view->Plugin( aNamespace ); |
|
8552 |
|
8553 if ( pluginData ) |
|
8554 { |
|
8555 break; |
|
8556 } |
|
8557 } |
|
8558 } |
|
8559 } |
|
8560 |
|
8561 CXnPointerArray* array = CXnPointerArray::NewL(); |
|
8562 CleanupStack::PushL( array ); |
|
8563 |
|
8564 if ( pluginData ) |
|
8565 { |
|
8566 RPointerArray< CXnNode > list; |
|
8567 CleanupClosePushL( list ); |
|
8568 |
|
8569 pluginData->ContentSourceNodesL( list ); |
|
8570 |
|
8571 const TInt count( list.Count() ); |
|
8572 |
|
8573 array->Container().ReserveL( count ); |
|
8574 |
|
8575 for ( TInt i = 0; i < count; i++ ) |
|
8576 { |
|
8577 array->Container().Append( list[i] ); |
|
8578 } |
|
8579 |
|
8580 CleanupStack::PopAndDestroy( &list ); |
|
8581 } |
|
8582 |
|
8583 CleanupStack::Pop( array ); |
|
8584 |
|
8585 return array; |
|
8586 } |
|
8587 |
8484 // ----------------------------------------------------------------------------- |
8588 // ----------------------------------------------------------------------------- |
8485 // CXnUiEngineImpl::Resources() |
8589 // CXnUiEngineImpl::Resources() |
8486 // ----------------------------------------------------------------------------- |
8590 // ----------------------------------------------------------------------------- |
8487 // |
8591 // |
8488 CArrayPtrSeg< CXnResource >& CXnUiEngineImpl::Resources() |
8592 CArrayPtrSeg< CXnResource >& CXnUiEngineImpl::Resources() |
8881 // Handles a change to the control's resources of type aType |
8985 // Handles a change to the control's resources of type aType |
8882 // ----------------------------------------------------------------------------- |
8986 // ----------------------------------------------------------------------------- |
8883 // |
8987 // |
8884 void CXnUiEngineImpl::HandleResourceChangeL( TInt aType ) |
8988 void CXnUiEngineImpl::HandleResourceChangeL( TInt aType ) |
8885 { |
8989 { |
8886 |
|
8887 if ( aType == KAknSplitInputEnabled ) |
|
8888 { |
|
8889 if(!iSplitScreenState.isPartialScreenEnabled ) |
|
8890 { |
|
8891 DisableRenderUiLC(); |
|
8892 HandlePartialTouchInputL( aType ); |
|
8893 RootNode()->SetDirtyL(); |
|
8894 ForceRenderUIL(); |
|
8895 CleanupStack::PopAndDestroy(); |
|
8896 } |
|
8897 } |
|
8898 |
|
8899 if ( aType == KAknSplitInputDisabled ) |
|
8900 { |
|
8901 if( iSplitScreenState.isPartialScreenEnabled ) |
|
8902 { |
|
8903 DisableRenderUiLC(); |
|
8904 HandlePartialTouchInputL( aType ); |
|
8905 RootNode()->SetDirtyL(); |
|
8906 ForceRenderUIL(); |
|
8907 CleanupStack::PopAndDestroy(); |
|
8908 } |
|
8909 } |
|
8910 |
|
8911 if ( iMenuNode ) |
8990 if ( iMenuNode ) |
8912 { |
8991 { |
8913 CXnControlAdapter* adapter( iMenuNode->Control() ); |
8992 CXnControlAdapter* adapter( iMenuNode->Control() ); |
8914 |
8993 |
8915 if ( adapter ) |
8994 if ( adapter ) |
8918 } |
8997 } |
8919 } |
8998 } |
8920 |
8999 |
8921 if ( aType == KEikDynamicLayoutVariantSwitch ) |
9000 if ( aType == KEikDynamicLayoutVariantSwitch ) |
8922 { |
9001 { |
8923 // Must return here if there is no current view or |
9002 HandleDynamicLayoutVariantSwitchL(); |
8924 // controladapterlist. This may occur when the phone |
9003 } |
8925 // is booted for the first time and the location/date |
9004 else if ( aType == KAknsMessageSkinChange ) |
8926 // query is visible. |
9005 { |
8927 if ( !ActiveView() ) |
9006 HandleSkinChangeL(); |
8928 { |
9007 } |
8929 return; |
9008 else if( iCurrentViewControlAdapter ) |
8930 } |
9009 { |
8931 |
9010 iCurrentViewControlAdapter->HandleResourceChange( aType ); |
8932 // Update client rect |
9011 } |
8933 SetClientRectL( iAppUiAdapter.ClientRect(), EFalse ); |
9012 } |
8934 |
9013 |
8935 // Update background rect |
9014 // ----------------------------------------------------------------------------- |
8936 // Bg rect is always screen size. |
9015 // CXnUiEngineImpl::HandleSkinChangeL |
8937 TRect bgRect; |
9016 // Handles a skin change to the controls |
8938 AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, bgRect ); |
9017 // ----------------------------------------------------------------------------- |
8939 iAppUiAdapter.ViewAdapter().BgManager().SetRect( bgRect ); |
9018 // |
8940 |
9019 void CXnUiEngineImpl::HandleSkinChangeL() |
8941 iEditMode->HandleScreenDeviceChangedL(); |
9020 { |
|
9021 // Force relayout |
|
9022 DisableRenderUiLC(); |
|
9023 |
|
9024 RootNode()->SetDirtyL(); |
|
9025 |
|
9026 for ( TInt i = 0; i < iControlAdapterList->Count(); i++ ) |
|
9027 { |
|
9028 CXnControlAdapter* adapter( ( *iControlAdapterList )[i] ); |
|
9029 adapter->SkinChanged(); |
|
9030 } |
|
9031 |
|
9032 ForceRenderUIL(); |
|
9033 |
|
9034 CleanupStack::PopAndDestroy(); |
|
9035 |
|
9036 // Handle inactive views |
|
9037 RPointerArray< CXnPluginData >& views( |
|
9038 iAppUiAdapter.ViewManager().ActiveAppData().PluginData() ); |
|
9039 |
|
9040 for ( TInt i = 0; i < views.Count(); i++ ) |
|
9041 { |
|
9042 CXnViewData* view = static_cast< CXnViewData* >( views[i] ); |
|
9043 if ( view && !view->Active() ) |
|
9044 { |
|
9045 RPointerArray< CXnControlAdapter > controls; |
|
9046 CleanupClosePushL( controls ); |
|
9047 view->ControlsL( controls ); |
|
9048 for ( TInt j = 0; j < controls.Count(); j++ ) |
|
9049 { |
|
9050 controls[j]->SkinChanged(); |
|
9051 } |
|
9052 CleanupStack::PopAndDestroy( &controls ); |
|
9053 } |
|
9054 } |
|
9055 } |
|
9056 |
|
9057 // ----------------------------------------------------------------------------- |
|
9058 // CXnUiEngineImpl::HandleDynamicLayoutVariantSwitchL |
|
9059 // Handles a KEikDynamicLayoutVariantSwitch resource change |
|
9060 // ----------------------------------------------------------------------------- |
|
9061 // |
|
9062 void CXnUiEngineImpl::HandleDynamicLayoutVariantSwitchL() |
|
9063 { |
|
9064 // Must return here if there is no current view or |
|
9065 // controladapterlist. This may occur when the phone |
|
9066 // is booted for the first time and the location/date |
|
9067 // query is visible. |
|
9068 if ( !ActiveView() ) |
|
9069 { |
|
9070 return; |
|
9071 } |
|
9072 |
|
9073 // Update client rect |
|
9074 SetClientRectL( iAppUiAdapter.ClientRect(), EFalse ); |
|
9075 |
|
9076 // Update background rect |
|
9077 // Bg rect is always screen size. |
|
9078 TRect bgRect; |
|
9079 AknLayoutUtils::LayoutMetricsRect( AknLayoutUtils::EScreen, bgRect ); |
|
9080 iAppUiAdapter.ViewAdapter().BgManager().SetRect( bgRect ); |
|
9081 |
|
9082 iEditMode->HandleScreenDeviceChangedL(); |
|
9083 |
|
9084 // Force relayout |
|
9085 DisableRenderUiLC(); |
|
9086 |
|
9087 RootNode()->SetDirtyL(); |
|
9088 |
|
9089 ReportScreenDeviceChangeL(); |
|
9090 |
|
9091 for ( TInt i = 0; i < iControlAdapterList->Count(); i++ ) |
|
9092 { |
|
9093 CXnControlAdapter* adapter( ( *iControlAdapterList )[i] ); |
8942 |
9094 |
8943 // Force relayout |
9095 adapter->HandleScreenDeviceChangedL(); |
8944 DisableRenderUiLC(); |
9096 } |
8945 |
9097 |
8946 RootNode()->SetDirtyL(); |
9098 ForceRenderUIL(); |
8947 |
9099 |
8948 ReportScreenDeviceChangeL(); |
9100 CleanupStack::PopAndDestroy(); |
8949 |
|
8950 for ( TInt i = 0; i < iControlAdapterList->Count(); i++ ) |
|
8951 { |
|
8952 CXnControlAdapter* adapter( ( *iControlAdapterList )[i] ); |
|
8953 |
|
8954 adapter->HandleScreenDeviceChangedL(); |
|
8955 } |
|
8956 |
|
8957 ForceRenderUIL(); |
|
8958 |
|
8959 CleanupStack::PopAndDestroy(); |
|
8960 } |
|
8961 else if ( aType == KAknsMessageSkinChange ) |
|
8962 { |
|
8963 // Force relayout |
|
8964 DisableRenderUiLC(); |
|
8965 |
|
8966 RootNode()->SetDirtyL(); |
|
8967 |
|
8968 for ( TInt i = 0; i < iControlAdapterList->Count(); i++ ) |
|
8969 { |
|
8970 CXnControlAdapter* adapter( ( *iControlAdapterList )[i] ); |
|
8971 adapter->SkinChanged(); |
|
8972 } |
|
8973 |
|
8974 ForceRenderUIL(); |
|
8975 |
|
8976 CleanupStack::PopAndDestroy(); |
|
8977 } |
|
8978 } |
9101 } |
8979 |
9102 |
8980 // ----------------------------------------------------------------------------- |
9103 // ----------------------------------------------------------------------------- |
8981 // CXnUiEngineImpl::IsMenuDisplaying |
9104 // CXnUiEngineImpl::IsMenuDisplaying |
8982 // Checks whether the menu is displaying or not. |
9105 // Checks whether the menu is displaying or not. |
9719 } |
9844 } |
9720 |
9845 |
9721 // ----------------------------------------------------------------------------- |
9846 // ----------------------------------------------------------------------------- |
9722 // CXnUiEngineImpl::HandlePartialTouchInputL() |
9847 // CXnUiEngineImpl::HandlePartialTouchInputL() |
9723 // ----------------------------------------------------------------------------- |
9848 // ----------------------------------------------------------------------------- |
9724 void CXnUiEngineImpl::HandlePartialTouchInputL( TInt aType ) |
9849 void CXnUiEngineImpl::HandlePartialTouchInputL( CXnNode& aNode, TBool aEnable ) |
9725 { |
9850 { |
9726 if( !iSplitScreenState.iPartialScreenEditorNode ) |
9851 DisableRenderUiLC(); |
9727 { |
9852 CXnNode* editorplugin = FindPlugin( aNode ); |
9728 return; |
9853 |
9729 } |
9854 if ( aEnable ) |
9730 if ( aType == KAknSplitInputEnabled ) |
9855 |
9731 { |
9856 { |
|
9857 iSplitScreenState.iPartialScreenOpen = ETrue; |
|
9858 iSplitScreenState.iPartialScreenEditorNode = &aNode; |
|
9859 |
9732 // make sure that we always get up event |
9860 // make sure that we always get up event |
9733 CCoeControl& bg( iAppUiAdapter.ViewAdapter().BgControl() ); |
9861 CXnViewControlAdapter* control = static_cast< CXnViewControlAdapter* >( |
9734 static_cast<CXnBgControl*>(&bg)->ResetGrabbingL(); |
9862 iViewManager.ActiveViewData().ViewNode()->Control() ); |
9735 |
9863 |
9736 // don't remove input from stack if split input is enabled |
9864 control->ResetGrabbing(); |
9737 XnTextEditorInterface::MXnTextEditorInterface* editorControl = NULL; |
9865 |
9738 XnComponentInterface::MakeInterfaceL( editorControl, |
9866 // Hide all plugins except the one that contains given editor node |
9739 iSplitScreenState.iPartialScreenEditorNode->AppIfL() ); |
9867 RPointerArray< CXnNode >& plugins( *Plugins() ); |
9740 if( editorControl ) |
9868 for( TInt i=0; i<plugins.Count(); i++ ) |
9741 { |
|
9742 editorControl->HandleEditorEvent(CXnTextEditor::KKeepSplitInputInStack); |
|
9743 } |
|
9744 |
|
9745 RPointerArray<CXnNode> plugins = *Plugins(); |
|
9746 |
|
9747 for( TInt i=0; i<plugins.Count(); i++ ) |
|
9748 { |
9869 { |
9749 CXnNode* pluginNode = plugins[i]; |
9870 CXnNode* pluginNode = plugins[i]; |
9750 CXnNode* editorplugin = FindPlugin( *iSplitScreenState.iPartialScreenEditorNode ); |
|
9751 |
|
9752 if ( pluginNode != editorplugin ) |
9871 if ( pluginNode != editorplugin ) |
9753 { |
9872 { |
9754 SetNodeVisibleL(pluginNode, EFalse); |
9873 SetNodeVisibleL(pluginNode, EFalse); |
9755 } |
9874 } |
9756 } |
9875 } |
9757 |
9876 |
|
9877 // Block progression must be bottom-to-top when partial screen is open |
|
9878 // Previous value needs to be stored first |
9758 StorePartialScreenBlockProgressionL(); |
9879 StorePartialScreenBlockProgressionL(); |
9759 |
9880 |
9760 iSplitScreenState.isPartialScreenEnabled = ETrue; |
|
9761 SetPartialScreenBlockProgressionL( |
9881 SetPartialScreenBlockProgressionL( |
9762 XnPropertyNames::style::common::block_progression::KBT ); |
9882 XnPropertyNames::style::common::block_progression::KBT ); |
|
9883 |
|
9884 // Hide statuspane |
9763 iAppUiAdapter.StatusPane()->MakeVisible( EFalse ); |
9885 iAppUiAdapter.StatusPane()->MakeVisible( EFalse ); |
9764 } |
9886 } |
9765 |
9887 |
9766 if ( aType == KAknSplitInputDisabled ) |
9888 else |
9767 { |
9889 { |
9768 |
9890 // Show plugin nodes again |
9769 // set remove stack true if disable event does not come from widget controls |
9891 RPointerArray< CXnNode >& plugins( *Plugins() ); |
9770 if(iSplitScreenState.isPartialScreenOpen) |
9892 |
9771 { |
9893 for( TInt i=0; i<plugins.Count(); i++ ) |
9772 XnTextEditorInterface::MXnTextEditorInterface* editorControl = NULL; |
9894 { |
9773 XnComponentInterface::MakeInterfaceL( editorControl, |
9895 CXnNode* pluginNode = plugins[i]; |
9774 iSplitScreenState.iPartialScreenEditorNode->AppIfL() ); |
9896 |
9775 if( editorControl ) |
9897 if ( pluginNode != editorplugin ) |
9776 { |
9898 { |
9777 editorControl->HandleEditorEvent(CXnTextEditor::KRemoveSplitInputFromStack); |
9899 SetNodeVisibleL(pluginNode, ETrue); |
9778 } |
9900 } |
9779 } |
9901 } |
9780 |
|
9781 RPointerArray<CXnNode> plugins = *Plugins(); |
|
9782 |
|
9783 for( TInt i=0; i<plugins.Count(); i++ ) |
|
9784 { |
|
9785 CXnNode* pluginNode = plugins[i]; |
|
9786 |
|
9787 if ( pluginNode != iSplitScreenState.iPartialScreenEditorNode ) |
|
9788 { |
|
9789 SetNodeVisibleL(pluginNode, ETrue); |
|
9790 } |
|
9791 } |
|
9792 |
9902 |
9793 if( iSplitScreenState.iPartialScreenBlock == NULL ) |
9903 if( iSplitScreenState.iPartialScreenBlock == NULL ) |
9794 { |
9904 { |
9795 SetPartialScreenBlockProgressionL( |
9905 SetPartialScreenBlockProgressionL( |
9796 XnPropertyNames::style::common::block_progression::KTB ); |
9906 XnPropertyNames::style::common::block_progression::KTB ); |
9797 } |
9907 } |
9798 else |
9908 else |
9799 { |
9909 { |
9800 SetPartialScreenBlockProgressionL(iSplitScreenState.iPartialScreenBlock->Des()); |
9910 SetPartialScreenBlockProgressionL(iSplitScreenState.iPartialScreenBlock->Des()); |
|
9911 delete iSplitScreenState.iPartialScreenBlock; |
|
9912 iSplitScreenState.iPartialScreenBlock = NULL; |
9801 } |
9913 } |
9802 |
9914 |
9803 iSplitScreenState.isPartialScreenEnabled = EFalse; |
9915 iSplitScreenState.iPartialScreenEditorNode = NULL; |
9804 iAppUiAdapter.StatusPane()->MakeVisible(ETrue); |
9916 iSplitScreenState.iPartialScreenOpen = EFalse; |
9805 } |
9917 |
|
9918 // Show statuspane again |
|
9919 iAppUiAdapter.StatusPane()->MakeVisible(ETrue); |
|
9920 } |
|
9921 |
|
9922 RootNode()->SetDirtyL(); |
|
9923 ForceRenderUIL(); |
|
9924 CleanupStack::PopAndDestroy(); |
9806 } |
9925 } |
9807 |
9926 |
9808 // ----------------------------------------------------------------------------- |
9927 // ----------------------------------------------------------------------------- |
9809 // ----------------------------------------------------------------------------- |
9928 // ----------------------------------------------------------------------------- |
9810 CCoeControl* CXnUiEngineImpl::WindowOwningControl( CXnNode& aNode ) |
9929 CCoeControl* CXnUiEngineImpl::WindowOwningControl( CXnNode& aNode ) |
9899 |
10018 |
9900 // ----------------------------------------------------------------------------- |
10019 // ----------------------------------------------------------------------------- |
9901 // EnablePartialTouchInput |
10020 // EnablePartialTouchInput |
9902 // ----------------------------------------------------------------------------- |
10021 // ----------------------------------------------------------------------------- |
9903 void CXnUiEngineImpl::EnablePartialTouchInput( CXnNode& aNode, TBool aEnable ) |
10022 void CXnUiEngineImpl::EnablePartialTouchInput( CXnNode& aNode, TBool aEnable ) |
9904 { |
10023 { |
9905 iSplitScreenState.iPartialScreenEditorNode = &aNode; |
10024 if( aEnable && !iSplitScreenState.iPartialScreenOpen || |
9906 iSplitScreenState.isPartialScreenOpen = aEnable; |
10025 !aEnable && iSplitScreenState.iPartialScreenOpen ) |
|
10026 { |
|
10027 TRAP_IGNORE( HandlePartialTouchInputL( aNode, aEnable ) ); |
|
10028 } |
9907 } |
10029 } |
9908 |
10030 |
9909 // ----------------------------------------------------------------------------- |
10031 // ----------------------------------------------------------------------------- |
9910 // SetNodeVisibleL |
10032 // SetNodeVisibleL |
9911 // ----------------------------------------------------------------------------- |
10033 // ----------------------------------------------------------------------------- |