diff options
Diffstat (limited to 'framework')
24 files changed, 13815 insertions, 3253 deletions
diff --git a/framework/inc/services.h b/framework/inc/services.h index 9c19f8b6251e..bdd6221eff9c 100644 --- a/framework/inc/services.h +++ b/framework/inc/services.h @@ -125,6 +125,8 @@ namespace framework{ #define SERVICENAME_TABWINDOWSERVICE DECLARE_ASCII("com.sun.star.ui.dialogs.TabContainerWindow" ) #define SERVICENAME_WINDOWCONTENTFACTORYMANAGER DECLARE_ASCII("com.sun.star.ui.WindowContentFactoryManager" ) #define SERVICENAME_DISPLAYACCESS DECLARE_ASCII("com.sun.star.awt.DisplayAccess" ) +#define SERVICENAME_PANELFACTORY DECLARE_ASCII("com.sun.star.ui.PanelFactory" ) +#define SERVICENAME_MODELWINSERVICE DECLARE_ASCII("com.sun.star.ui.ModelWinService" ) //_________________________________________________________________________________________________________________ // used implementationnames by framework @@ -211,6 +213,8 @@ namespace framework{ #define IMPLEMENTATIONNAME_IMAGEMANAGER DECLARE_ASCII("com.sun.star.comp.framework.ImageManager" ) #define IMPLEMENTATIONNAME_TABWINDOWSERVICE DECLARE_ASCII("com.sun.star.comp.framework.TabWindowService" ) #define IMPLEMENTATIONNAME_WINDOWCONTENTFACTORYMANAGER DECLARE_ASCII("com.sun.star.comp.framework.WindowContentFactoryManager" ) +#define IMPLEMENTATIONNAME_PANELFACTORY DECLARE_ASCII("com.sun.star.comp.framework.PanelFactory" ) +#define IMPLEMENTATIONNAME_MODELWINSERVICE DECLARE_ASCII("com.sun.star.comp.framework.ModelWinService" ) } // namespace framework diff --git a/framework/inc/services/layoutmanager.hxx b/framework/inc/services/layoutmanager.hxx index 2ccba9e7ffde..898d1c240b2b 100644 --- a/framework/inc/services/layoutmanager.hxx +++ b/framework/inc/services/layoutmanager.hxx @@ -6,6 +6,9 @@ * * OpenOffice.org - a multi-platform office productivity suite * + * $RCSfile: layoutmanager.hxx,v $ + * $Revision: 1.34 $ + * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -50,6 +53,8 @@ #include <uielement/menubarmanager.hxx> #include <uiconfiguration/windowstateconfiguration.hxx> #include <classes/addonsoptions.hxx> +#include <uielement/panelwindow.hxx> +#include <uielement/uielement.hxx> //_________________________________________________________________________________________________________________ // interface includes @@ -87,6 +92,8 @@ class MenuBar; namespace framework { + class ToolbarLayoutManager; + class PanelManager; class GlobalSettings; typedef ::cppu::WeakImplHelper9 < ::com::sun::star::lang::XServiceInfo , ::com::sun::star::frame::XLayoutManager @@ -233,101 +240,19 @@ namespace framework sal_Int16 m_nLines; sal_Bool m_bIsHorizontal; }; - struct SingleRowColumnWindowData - { - SingleRowColumnWindowData() : nVarSize( 0 ), nStaticSize( 0 ), nSpace( 0 ) {} - - std::vector< rtl::OUString > aUIElementNames; - std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > > aRowColumnWindows; - std::vector< ::com::sun::star::awt::Rectangle > aRowColumnWindowSizes; - std::vector< sal_Int32 > aRowColumnSpace; - ::com::sun::star::awt::Rectangle aRowColumnRect; - sal_Int32 nVarSize; - sal_Int32 nStaticSize; - sal_Int32 nSpace; - sal_Int32 nRowColumn; - }; protected: DECL_LINK( AsyncLayoutHdl, Timer * ); private: - enum DockingOperation - { - DOCKOP_BEFORE_COLROW, - DOCKOP_ON_COLROW, - DOCKOP_AFTER_COLROW - }; - struct UIElement - { - UIElement() : m_bFloating( sal_False ), - m_bVisible( sal_True ), - m_bUserActive( sal_False ), - m_bCreateNewRowCol0( sal_False ), - m_bDeactiveHide( sal_False ), - m_bMasterHide( sal_False ), - m_bContextSensitive( sal_False ), - m_bContextActive( sal_True ), - m_bNoClose( sal_False ), - m_bSoftClose( sal_False ), - m_bStateRead( sal_False ), - m_nStyle( BUTTON_SYMBOL ) - {} - - UIElement( const rtl::OUString& rName, - const rtl::OUString& rType, - const com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement >& rUIElement, - sal_Bool bFloating = sal_False - ) : m_aType( rType ), - m_aName( rName ), - m_xUIElement( rUIElement ), - m_bFloating( bFloating ), - m_bVisible( sal_True ), - m_bUserActive( sal_False ), - m_bCreateNewRowCol0( sal_False ), - m_bDeactiveHide( sal_False ), - m_bMasterHide( sal_False ), - m_bContextSensitive( sal_False ), - m_bContextActive( sal_True ), - m_bNoClose( sal_False ), - m_bSoftClose( sal_False ), - m_bStateRead( sal_False ), - m_nStyle( BUTTON_SYMBOL ) {} - - bool operator< ( const UIElement& aUIElement ) const; - UIElement& operator=( const UIElement& rUIElement ); - - rtl::OUString m_aType; - rtl::OUString m_aName; - rtl::OUString m_aUIName; - com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement > m_xUIElement; - sal_Bool m_bFloating, - m_bVisible, - m_bUserActive, - m_bCreateNewRowCol0, - m_bDeactiveHide, - m_bMasterHide, - m_bContextSensitive, - m_bContextActive; - sal_Bool m_bNoClose, - m_bSoftClose, - m_bStateRead; - sal_Int16 m_nStyle; - DockedData m_aDockedData; - FloatingData m_aFloatingData; - }; - typedef std::vector< UIElement > UIElementVector; //--------------------------------------------------------------------------------------------------------- // helper //--------------------------------------------------------------------------------------------------------- - - //--------------------------------------------------------------------------------------------------------- - // helper - //--------------------------------------------------------------------------------------------------------- void impl_clearUpMenuBar(); void implts_reset( sal_Bool bAttach ); + void implts_setMenuBarCloser(sal_Bool bCloserState); void implts_updateMenuBarClose(); sal_Bool implts_resetMenuBar(); @@ -347,60 +272,25 @@ namespace framework void implts_setElementData( UIElement& rUIElement, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDockableWindow >& rDockWindow ); void implts_sortUIElements(); void implts_destroyElements(); - void implts_destroyDockingAreaWindows(); - void implts_createAddonsToolBars(); - void implts_createCustomToolBars(); - void implts_createNonContextSensitiveToolBars(); - void implts_createCustomToolBars( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >& aCustomTbxSeq ); - void implts_createCustomToolBar( const rtl::OUString& aTbxResName, const rtl::OUString& aTitle ); void implts_toggleFloatingUIElementsVisibility( sal_Bool bActive ); void implts_reparentChildWindows(); + ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement > implts_createDockingWindow( const ::rtl::OUString& aElementName ); sal_Bool implts_isEmbeddedLayoutManager() const; sal_Int16 implts_getCurrentSymbolsSize(); sal_Int16 implts_getCurrentSymbolsStyle(); - ::com::sun::star::uno::Reference< com::sun::star::awt::XWindowPeer > implts_createToolkitWindow( const ::com::sun::star::uno::Reference< com::sun::star::awt::XWindowPeer >& rParent ); ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement > implts_createElement( const rtl::OUString& aName ); - rtl::OUString implts_generateGenericAddonToolbarTitle( sal_Int32 nNumber ) const; - - // docking methods - ::Rectangle implts_calcHotZoneRect( const ::Rectangle& rRect, sal_Int32 nHotZoneOffset ); - void implts_calcDockingPosSize( UIElement& aUIElement, DockingOperation& eDockOperation, ::Rectangle& rTrackingRect, const Point& rMousePos ); - DockingOperation implts_determineDockingOperation( ::com::sun::star::ui::DockingArea DockingArea, const ::Rectangle& rRowColRect, const Point& rMousePos ); - ::Rectangle implts_getWindowRectFromRowColumn( ::com::sun::star::ui::DockingArea DockingArea, const SingleRowColumnWindowData& rRowColumnWindowData, const ::Point& rMousePos, const rtl::OUString& rExcludeElementName ); - ::Rectangle implts_determineFrontDockingRect( ::com::sun::star::ui::DockingArea eDockingArea, - sal_Int32 nRowCol, - const ::Rectangle& rDockedElementRect, - const ::rtl::OUString& rMovedElementName, - const ::Rectangle& rMovedElementRect ); - void implts_calcWindowPosSizeOnSingleRowColumn( sal_Int32 nDockingArea, - sal_Int32 nOffset, - SingleRowColumnWindowData& rRowColumnWindowData, - const ::Size& rContainerSize ); - ::Rectangle implts_calcTrackingAndElementRect( ::com::sun::star::ui::DockingArea eDockingArea, - sal_Int32 nRowCol, - UIElement& rUIElement, - const ::Rectangle& rTrackingRect, - const ::Rectangle& rRowColumnRect, - const ::Size& rContainerWinSize ); - void implts_renumberRowColumnData( ::com::sun::star::ui::DockingArea eDockingArea, DockingOperation eDockingOperation, const UIElement& rUIElement ); // layouting methods sal_Bool implts_compareRectangles( const ::com::sun::star::awt::Rectangle& rRect1, const ::com::sun::star::awt::Rectangle& rRect2 ); sal_Bool implts_resizeContainerWindow( const ::com::sun::star::awt::Size& rContainerSize, const ::com::sun::star::awt::Point& rComponentPos ); ::Size implts_getTopBottomDockingAreaSizes(); ::Size implts_getContainerWindowOutputSize(); - ::com::sun::star::awt::Rectangle implts_getDockingAreaWindowSizes(); - void implts_getDockingAreaElementInfos( ::com::sun::star::ui::DockingArea DockingArea, std::vector< SingleRowColumnWindowData >& rRowColumnsWindowData ); - void implts_getDockingAreaElementInfoOnSingleRowCol( ::com::sun::star::ui::DockingArea, - sal_Int32 nRowCol, - SingleRowColumnWindowData& rRowColumnWindowData ); - ::Point implts_findNextCascadeFloatingPos(); - void implts_findNextDockingPos( ::com::sun::star::ui::DockingArea DockingArea, const ::Size& aUIElementSize, ::Point& rVirtualPos, ::Point& rPixelPos ); + + void implts_setDockingAreaWindowSizes( const css::awt::Rectangle& rBorderSpace ); ::com::sun::star::awt::Rectangle implts_calcDockingAreaSizes(); - void implts_setDockingAreaWindowSizes( const com::sun::star::awt::Rectangle& rBorderSpace ); sal_Bool implts_doLayout( sal_Bool bForceRequestBorderSpace, sal_Bool bOuterResize ); - void implts_doLayout_notify( sal_Bool bOuterResize ); + void implts_doLayout_notify( sal_Bool bOuterResize ); // internal methods to control status/progress bar ::Size implts_getStatusBarSize(); @@ -425,8 +315,6 @@ namespace framework void implts_setVisibleState( sal_Bool bShow ); void implts_updateUIElementsVisibleState( sal_Bool bShow ); void implts_setCurrentUIVisibility( sal_Bool bShow ); - sal_Bool impl_parseResourceURL( const rtl::OUString aResourceURL, rtl::OUString& aElementType, rtl::OUString& aElementName ); - void implts_notifyListeners( short nEvent, ::com::sun::star::uno::Any aInfoParam ); #ifdef DBG_UTIL void implts_checkElementContainer(); @@ -476,7 +364,6 @@ namespace framework bool m_bHideCurrentUI; bool m_bGlobalSettings; bool m_bPreserveContentSize; - DockingOperation m_eDockOperation; UIElement m_aDockUIElement; css::awt::Rectangle m_aDockingArea; css::uno::Reference< ::com::sun::star::ui::XDockingAreaAcceptor > m_xDockingAreaAcceptor; @@ -515,6 +402,9 @@ namespace framework sal_Int16 m_eSymbolsStyle; Timer m_aAsyncLayoutTimer; ::cppu::OMultiTypeInterfaceContainerHelper m_aListenerContainer; // container for ALL Listener + PanelManager* m_pPanelManager; + ToolbarLayoutManager* m_pToolbarManager; + css::uno::Reference< ::com::sun::star::awt::XDockableWindowListener > m_xToolbarManager; }; } // namespace framework diff --git a/framework/inc/services/modelwinservice.hxx b/framework/inc/services/modelwinservice.hxx new file mode 100755 index 000000000000..7e07fcb0cd37 --- /dev/null +++ b/framework/inc/services/modelwinservice.hxx @@ -0,0 +1,122 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: urltransformer.hxx,v $ + * $Revision: 1.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_SERVICES_MODELWINSERVICE_HXX_ +#define __FRAMEWORK_SERVICES_MODELWINSERVICE_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/threadhelpbase.hxx> +#include <macros/generic.hxx> +#include <macros/debug.hxx> +#include <macros/xinterface.hxx> +#include <macros/xtypeprovider.hxx> +#include <macros/xserviceinfo.hxx> +#include <general.h> +#include <stdtypes.h> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/awt/XControlModel.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <cppuhelper/weak.hxx> +#include <vcl/window.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +class IModelWin +{ + public: + virtual void registerModelForXWindow( const css::uno::Reference< css::awt::XWindow >& rWindow, const css::uno::Reference< css::awt::XControlModel >& rModel ) = 0; + virtual void deregisterModelForXWindow( const css::uno::Reference< css::awt::XWindow >& rWindow ) = 0; +}; + +class ModelWinService : public css::lang::XTypeProvider + , public css::lang::XServiceInfo + , public css::container::XNameAccess + , public IModelWin + , public ::cppu::OWeakObject +{ + public: + ModelWinService(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager ); + virtual ~ModelWinService(); + + //--------------------------------------------------------------------------------------------------------- + // XInterface, XTypeProvider, XServiceInfo + //--------------------------------------------------------------------------------------------------------- + + FWK_DECLARE_XINTERFACE + FWK_DECLARE_XTYPEPROVIDER + DECLARE_XSERVICEINFO + + //--------------------------------------------------------------------------------------------------------- + // IModelWin + //--------------------------------------------------------------------------------------------------------- + virtual void registerModelForXWindow( const css::uno::Reference< css::awt::XWindow >& rWindow, const css::uno::Reference< css::awt::XControlModel >& rModel ); + virtual void deregisterModelForXWindow( const css::uno::Reference< css::awt::XWindow >& rWindow ); + + //--------------------------------------------------------------------------------------------------------- + // XNameAccess + //--------------------------------------------------------------------------------------------------------- + virtual css::uno::Any SAL_CALL getByName( const ::rtl::OUString& sName ) throw( css::container::NoSuchElementException , + css::lang::WrappedTargetException , + css::uno::RuntimeException ); + virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames() throw( css::uno::RuntimeException ); + virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& sName ) throw( css::uno::RuntimeException ); + + //--------------------------------------------------------------------------------------------------------- + // XElementAccess + //--------------------------------------------------------------------------------------------------------- + virtual css::uno::Type SAL_CALL getElementType() throw( css::uno::RuntimeException ); + virtual sal_Bool SAL_CALL hasElements() throw( css::uno::RuntimeException ); + + private: + css::uno::Reference< css::lang::XMultiServiceFactory > m_xServiceManager; +}; + +} + +#endif // __FRAMEWORK_SERVICES_MODELWINSERVICE_HXX_ diff --git a/framework/inc/uielement/panelwindow.hxx b/framework/inc/uielement/panelwindow.hxx new file mode 100755 index 000000000000..e1b8ae2abcc7 --- /dev/null +++ b/framework/inc/uielement/panelwindow.hxx @@ -0,0 +1,81 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutmanager.hxx,v $ + * $Revision: 1.34 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_LAYOUTMANAGER_PANELWINDOW_HXX_ +#define __FRAMEWORK_LAYOUTMANAGER_PANELWINDOW_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <vcl/dockwin.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework +{ + +class PanelWindow : public DockingWindow +{ + public: + PanelWindow( Window* pParent, WinBits nWinBits =0); + virtual ~PanelWindow(); + + const ::rtl::OUString& getResourceURL() const; + void setResourceURL(const ::rtl::OUString& rResourceURL); + Window* getContentWindow() const; + void setContentWindow( Window* pContentWindow ); + + virtual void Command ( const CommandEvent& rCEvt ); + virtual void StateChanged( StateChangedType nType ); + virtual void DataChanged( const DataChangedEvent& rDCEvt ); + virtual void Resize(); + + // Provide additional handlers to support external implementations + void SetCommandHdl( const Link& aLink ) { m_aCommandHandler = aLink; } + const Link& GetCommandHdl() const { return m_aCommandHandler; } + void SetStateChangedHdl( const Link& aLink ) { m_aStateChangedHandler = aLink; } + const Link& GetStateChangedHdl() const { return m_aStateChangedHandler; } + void SetDataChangedHdl( const Link& aLink ) { m_aDataChangedHandler = aLink; } + const Link& GetDataChangedHdl() { return m_aDataChangedHandler; } + + private: + ::rtl::OUString m_aResourceURL; + Link m_aCommandHandler; + Link m_aStateChangedHandler; + Link m_aDataChangedHandler; + Window* m_pContentWindow; +}; + +} + +#endif // __FRAMEWORK_UIELEMENT_PANELWINDOW_HXX_ diff --git a/framework/inc/uielement/panelwrapper.hxx b/framework/inc/uielement/panelwrapper.hxx new file mode 100755 index 000000000000..c3f72140ad59 --- /dev/null +++ b/framework/inc/uielement/panelwrapper.hxx @@ -0,0 +1,70 @@ + + +#ifndef __FRAMEWORK_UIELEMENT_PANELWRAPPER_HXX_ +#define __FRAMEWORK_UIELEMENT_PANELWRAPPER_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <helper/uielementwrapperbase.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +namespace framework +{ + +class PanelWrapper : public UIElementWrapperBase +{ + public: + PanelWrapper( const com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory >& xServiceManager ); + virtual ~PanelWrapper(); + + // XInterface + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw( ::com::sun::star::uno::RuntimeException ); + + // XComponent + virtual void SAL_CALL dispose() throw (::com::sun::star::uno::RuntimeException); + + // XInitialization + virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException); + + // XUIElement + virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getRealInterface() throw (::com::sun::star::uno::RuntimeException); + + // XUpdatable + virtual void SAL_CALL update() throw (::com::sun::star::uno::RuntimeException); + + // XEventListener + using cppu::OPropertySetHelper::disposing; + virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& aEvent ) throw (::com::sun::star::uno::RuntimeException); + + ::rtl::OUString getResourceURL() { return m_aResourceURL; } + + //------------------------------------------------------------------------------------------------------------- + // protected methods + //------------------------------------------------------------------------------------------------------------- + protected: + virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const com::sun::star::uno::Any& aValue ) throw( com::sun::star::uno::Exception ); + + private: + com::sun::star::uno::Reference< com::sun::star::lang::XMultiServiceFactory > m_xServiceManager; + com::sun::star::uno::Reference< com::sun::star::awt::XWindow > m_xPanelWindow; + bool m_bNoClose; +}; + +} + +#endif // __FRAMEWORK_UIELEMENT_PANELWRAPPER_HXX_ diff --git a/framework/inc/uielement/uielement.hxx b/framework/inc/uielement/uielement.hxx new file mode 100755 index 000000000000..98e65d5c5a93 --- /dev/null +++ b/framework/inc/uielement/uielement.hxx @@ -0,0 +1,146 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutmanager.hxx,v $ + * $Revision: 1.34 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_LAYOUTMANAGER_UIELEMENT_HXX_ +#define __FRAMEWORK_LAYOUTMANAGER_UIELEMENT_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/ui/XUIElement.hpp> +#include <com/sun/star/ui/DockingArea.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <rtl/ustring.hxx> +#include <vcl/toolbox.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework +{ + +struct DockedData +{ + DockedData() : m_aPos( LONG_MAX, LONG_MAX ), + m_nDockedArea( ::com::sun::star::ui::DockingArea_DOCKINGAREA_TOP ), + m_bLocked( sal_False ) {} + + Point m_aPos; + Size m_aSize; + sal_Int16 m_nDockedArea; + sal_Bool m_bLocked; +}; + +struct FloatingData +{ + FloatingData() : m_aPos( LONG_MAX, LONG_MAX ), + m_nLines( 1 ), + m_bIsHorizontal( sal_True ) {} + + Point m_aPos; + Size m_aSize; + sal_Int16 m_nLines; + sal_Bool m_bIsHorizontal; +}; + +struct UIElement +{ + UIElement() : m_bFloating( sal_False ), + m_bVisible( sal_True ), + m_bUserActive( sal_False ), + m_bCreateNewRowCol0( sal_False ), + m_bDeactiveHide( sal_False ), + m_bMasterHide( sal_False ), + m_bContextSensitive( sal_False ), + m_bContextActive( sal_True ), + m_bNoClose( sal_False ), + m_bSoftClose( sal_False ), + m_bStateRead( sal_False ), + m_nStyle( BUTTON_SYMBOL ) + {} + + UIElement( const rtl::OUString& rName, + const rtl::OUString& rType, + const com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement >& rUIElement, + sal_Bool bFloating = sal_False + ) : m_aType( rType ), + m_aName( rName ), + m_xUIElement( rUIElement ), + m_bFloating( bFloating ), + m_bVisible( sal_True ), + m_bUserActive( sal_False ), + m_bCreateNewRowCol0( sal_False ), + m_bDeactiveHide( sal_False ), + m_bMasterHide( sal_False ), + m_bContextSensitive( sal_False ), + m_bContextActive( sal_True ), + m_bNoClose( sal_False ), + m_bSoftClose( sal_False ), + m_bStateRead( sal_False ), + m_nStyle( BUTTON_SYMBOL ) {} + + bool operator< ( const UIElement& aUIElement ) const; + UIElement& operator=( const UIElement& rUIElement ); + + rtl::OUString m_aType; + rtl::OUString m_aName; + rtl::OUString m_aUIName; + com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement > m_xUIElement; + sal_Bool m_bFloating, + m_bVisible, + m_bUserActive, + m_bCreateNewRowCol0, + m_bDeactiveHide, + m_bMasterHide, + m_bContextSensitive, + m_bContextActive; + sal_Bool m_bNoClose, + m_bSoftClose, + m_bStateRead; + sal_Int16 m_nStyle; + DockedData m_aDockedData; + FloatingData m_aFloatingData; +}; + +typedef std::vector< UIElement > UIElementVector; + +} // namespace framework + +#endif // __FRAMEWORK_LAYOUTMANAGER_UIELEMENT_HXX_ diff --git a/framework/source/layoutmanager/helpers.cxx b/framework/source/layoutmanager/helpers.cxx new file mode 100755 index 000000000000..bfa20e9324cd --- /dev/null +++ b/framework/source/layoutmanager/helpers.cxx @@ -0,0 +1,304 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutmanager.hxx,v $ + * $Revision: 1.34 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include "helpers.hxx" +#include <threadhelp/resetableguard.hxx> +#include <services.h> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/ui/DockingArea.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> +#include <com/sun/star/frame/XDispatchHelper.hpp> +#include <com/sun/star/awt/XDockableWindow.hpp> +#include <com/sun/star/awt/XDockableWindowListener.hpp> +#include <com/sun/star/awt/XWindowListener.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <comphelper/mediadescriptor.hxx> +#include <vcl/svapp.hxx> +#include <vcl/toolbox.hxx> +#include <vos/mutex.hxx> +#include <toolkit/unohlp.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +using namespace com::sun::star; + +namespace framework +{ + +// ATTENTION! +// This value is directly copied from the sfx2 project. +// You have to change BOTH values, see sfx2/inc/sfx2/sfxsids.hrc (SID_DOCKWIN_START) +static const sal_Int32 DOCKWIN_ID_BASE = 9800; + +bool lcl_checkUIElement(const uno::Reference< ui::XUIElement >& xUIElement, awt::Rectangle& _rPosSize, uno::Reference< awt::XWindow >& _xWindow) +{ + bool bRet = xUIElement.is(); + if ( bRet ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + _xWindow.set( xUIElement->getRealInterface(), uno::UNO_QUERY ); + _rPosSize = _xWindow->getPosSize(); + + Window* pWindow = VCLUnoHelper::GetWindow( _xWindow ); + if ( pWindow->GetType() == WINDOW_TOOLBOX ) + { + ::Size aSize = ((ToolBox*)pWindow)->CalcWindowSizePixel( 1 ); + _rPosSize.Width = aSize.Width(); + _rPosSize.Height = aSize.Height(); + } + } // if ( xUIElement.is() ) + return bRet; +} + +uno::Reference< awt::XWindowPeer > createToolkitWindow( const uno::Reference< lang::XMultiServiceFactory >& rFactory, const uno::Reference< awt::XWindowPeer >& rParent, const char* pService ) +{ + const rtl::OUString aAWTToolkit( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.Toolkit" )); + + uno::Reference< awt::XWindowPeer > xPeer; + if ( rFactory.is() ) + { + uno::Reference< awt::XToolkit > xToolkit( rFactory->createInstance( aAWTToolkit ), uno::UNO_QUERY_THROW ); + if ( xToolkit.is() ) + { + // describe window properties. + css::awt::WindowDescriptor aDescriptor; + aDescriptor.Type = awt::WindowClass_SIMPLE ; + aDescriptor.WindowServiceName = DECLARE_ASCII(pService) ; + aDescriptor.ParentIndex = -1 ; + aDescriptor.Parent = uno::Reference< awt::XWindowPeer >( rParent, uno::UNO_QUERY ) ; + aDescriptor.Bounds = awt::Rectangle(0,0,0,0) ; + aDescriptor.WindowAttributes = 0 ; + + // create a awt window + xPeer = xToolkit->createWindow( aDescriptor ); + } + } + + return xPeer; +} + +// convert alignment constant to vcl's WindowAlign type +WindowAlign ImplConvertAlignment( sal_Int16 aAlignment ) +{ + if ( aAlignment == ui::DockingArea_DOCKINGAREA_LEFT ) + return WINDOWALIGN_LEFT; + else if ( aAlignment == ui::DockingArea_DOCKINGAREA_RIGHT ) + return WINDOWALIGN_RIGHT; + else if ( aAlignment == ui::DockingArea_DOCKINGAREA_TOP ) + return WINDOWALIGN_TOP; + else + return WINDOWALIGN_BOTTOM; +} + +bool impl_parseResourceURL( const rtl::OUString aResourceURL, rtl::OUString& aElementType, rtl::OUString& aElementName ) +{ + sal_Int32 nIndex = 0; + + ::rtl::OUString aUIResourceURL( UIRESOURCE_URL ); + if ( aResourceURL.indexOf( aUIResourceURL ) == 0 ) + { + ::rtl::OUString aPathPart = aResourceURL.copy( aUIResourceURL.getLength() ); + ::rtl::OUString aUIResource = aPathPart.getToken( 0, (sal_Unicode)'/', nIndex ); + + aElementType = aPathPart.getToken( 0, (sal_Unicode)'/', nIndex ); + aElementName = aPathPart.getToken( 0, (sal_Unicode)'/', nIndex ); + return true; + } + + return false; +} + +css::awt::Rectangle impl_convertRectangleToAWT( const ::Rectangle& rRect ) +{ + css::awt::Rectangle aRect; + aRect.X = rRect.Left(); + aRect.Y = rRect.Top(); + aRect.Width = rRect.GetWidth(); + aRect.Height = rRect.GetHeight(); + return aRect; +} + +::Rectangle impl_convertAWTToRectangle( const ::com::sun::star::awt::Rectangle& rRect ) +{ + ::Rectangle aRect; + aRect.Left() = rRect.X; + aRect.Top() = rRect.Y; + aRect.Right() = rRect.X + rRect.Width; + aRect.Bottom() = rRect.Y + rRect.Height; + + return aRect; +} + +uno::Reference< frame::XModel > impl_getModelFromFrame( const uno::Reference< frame::XFrame >& rFrame ) +{ + // Query for the model to get check the context information + uno::Reference< frame::XModel > xModel; + if ( rFrame.is() ) + { + uno::Reference< frame::XController > xController( rFrame->getController(), uno::UNO_QUERY ); + if ( xController.is() ) + xModel = xController->getModel(); + } + + return xModel; +} + +sal_Bool implts_isPreviewModel( const uno::Reference< frame::XModel >& xModel ) +{ + if ( xModel.is() ) + { + ::comphelper::MediaDescriptor aDesc( xModel->getArgs() ); + return aDesc.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_PREVIEW(), (sal_Bool)sal_False); + } + else + return sal_False; +} + +sal_Bool implts_isFrameOrWindowTop( const uno::Reference< frame::XFrame >& xFrame ) +{ + if (xFrame->isTop()) + return sal_True; + + uno::Reference< awt::XTopWindow > xWindowCheck(xFrame->getContainerWindow(), uno::UNO_QUERY); // dont use _THROW here ... its a check only + if (xWindowCheck.is()) + { + // --> PB 2007-06-18 #i76867# top and system window is required. + ::vos::OGuard aSolarLock(&Application::GetSolarMutex()); + uno::Reference< awt::XWindow > xWindow( xWindowCheck, uno::UNO_QUERY ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + return ( pWindow && pWindow->IsSystemWindow() ); + // <-- + } + + return sal_False; +} + +void impl_setDockingWindowVisibility( const css::uno::Reference< css::lang::XMultiServiceFactory>& rSMGR, const css::uno::Reference< css::frame::XFrame >& rFrame, const ::rtl::OUString& rDockingWindowName, bool bVisible ) +{ + const ::rtl::OUString aDockWinPrefixCommand( RTL_CONSTASCII_USTRINGPARAM( "DockingWindow" )); + css::uno::WeakReference< css::frame::XDispatchHelper > xDispatchHelper; + + sal_Int32 nID = rDockingWindowName.toInt32(); + sal_Int32 nIndex = nID - DOCKWIN_ID_BASE; + + css::uno::Reference< css::frame::XDispatchProvider > xProvider(rFrame, css::uno::UNO_QUERY); + if ( nIndex >= 0 && xProvider.is() ) + { + ::rtl::OUString aDockWinCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:" )); + ::rtl::OUString aDockWinArgName( aDockWinPrefixCommand ); + + aDockWinArgName += ::rtl::OUString::valueOf( nIndex ); + + css::uno::Sequence< css::beans::PropertyValue > aArgs(1); + aArgs[0].Name = aDockWinArgName; + aArgs[0].Value = css::uno::makeAny( bVisible ); + + css::uno::Reference< css::frame::XDispatchHelper > xDispatcher( xDispatchHelper ); + if ( !xDispatcher.is()) + { + xDispatcher = css::uno::Reference< css::frame::XDispatchHelper >( + rSMGR->createInstance(SERVICENAME_DISPATCHHELPER), css::uno::UNO_QUERY_THROW); + } + + aDockWinCommand = aDockWinCommand + aDockWinArgName; + xDispatcher->executeDispatch( + xProvider, + aDockWinCommand, + ::rtl::OUString::createFromAscii("_self"), + 0, + aArgs); + } +} + +void impl_addWindowListeners( + const css::uno::Reference< css::uno::XInterface >& xThis, + const css::uno::Reference< css::ui::XUIElement >& xUIElement ) +{ + css::uno::Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), css::uno::UNO_QUERY ); + css::uno::Reference< css::awt::XDockableWindow > xDockWindow( xUIElement->getRealInterface(), css::uno::UNO_QUERY ); + if ( xDockWindow.is() && xWindow.is() ) + { + try + { + xDockWindow->addDockableWindowListener( + css::uno::Reference< css::awt::XDockableWindowListener >( + xThis, css::uno::UNO_QUERY )); + xWindow->addWindowListener( + css::uno::Reference< css::awt::XWindowListener >( + xThis, css::uno::UNO_QUERY )); + xDockWindow->enableDocking( sal_True ); + } + catch ( css::uno::Exception& ) + { + } + } +} + +css::uno::Reference< css::awt::XWindowPeer > implts_createToolkitWindow( + const css::uno::Reference< css::awt::XToolkit >& rToolkit, + const css::uno::Reference< css::awt::XWindowPeer >& rParent ) +{ + css::uno::Reference< css::awt::XWindowPeer > xPeer; + if ( rToolkit.is() ) + { + // describe window properties. + css::awt::WindowDescriptor aDescriptor; + aDescriptor.Type = css::awt::WindowClass_SIMPLE; + aDescriptor.WindowServiceName = DECLARE_ASCII("dockingarea"); + aDescriptor.ParentIndex = -1; + aDescriptor.Parent = css::uno::Reference< css::awt::XWindowPeer >( rParent, css::uno::UNO_QUERY ); + aDescriptor.Bounds = css::awt::Rectangle(0,0,0,0); + aDescriptor.WindowAttributes = 0; + + // create a docking area window + xPeer = rToolkit->createWindow( aDescriptor ); + } + + return xPeer; +} + +} // namespace framework diff --git a/framework/source/layoutmanager/helpers.hxx b/framework/source/layoutmanager/helpers.hxx new file mode 100755 index 000000000000..71eb623df6ff --- /dev/null +++ b/framework/source/layoutmanager/helpers.hxx @@ -0,0 +1,85 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutmanager.hxx,v $ + * $Revision: 1.34 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_LAYOUTMANAGER_HELPERS_HXX_ +#define __FRAMEWORK_LAYOUTMANAGER_HELPERS_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <macros/generic.hxx> +#include <stdtypes.h> +#include <properties.h> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/awt/XWindowPeer.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/ui/XUIElement.hpp> +#include <com/sun/star/awt/Rectangle.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <vcl/window.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +#define UIRESOURCE_PROTOCO_ASCII "private:" +#define UIRESOURCE_RESOURCE_ASCII "resource" +#define UIRESOURCE_URL_ASCII "private:resource" +#define UIRESOURCE_URL rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( UIRESOURCE_URL_ASCII )) + +namespace framework +{ + +bool lcl_checkUIElement(const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement >& xUIElement,::com::sun::star::awt::Rectangle& _rPosSize, ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow >& _xWindow); +::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > createToolkitWindow( const css::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rFactory, const css::uno::Reference< ::com::sun::star::awt::XWindowPeer >& rParent, const char* pService ); +WindowAlign ImplConvertAlignment( sal_Int16 aAlignment ); +bool impl_parseResourceURL( const rtl::OUString aResourceURL, rtl::OUString& aElementType, rtl::OUString& aElementName ); +::com::sun::star::awt::Rectangle impl_convertRectangleToAWT( const ::Rectangle& rRect ); +::Rectangle impl_convertAWTToRectangle( const ::com::sun::star::awt::Rectangle& rRect ); +::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > impl_getModelFromFrame( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame ); +sal_Bool implts_isPreviewModel( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel ); +sal_Bool implts_isFrameOrWindowTop( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame ); +void impl_setDockingWindowVisibility( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory>& rSMGR, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame, const ::rtl::OUString& rDockingWindowName, bool bVisible ); +void impl_addWindowListeners( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xThis, const ::com::sun::star::uno::Reference< css::ui::XUIElement >& xUIElement ); +::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer > implts_createToolkitWindow( const css::uno::Reference< ::com::sun::star::awt::XToolkit >& rToolkit, const css::uno::Reference< ::com::sun::star::awt::XWindowPeer >& rParent ); + +} + +#endif // __FRAMEWORK_LAYOUTMANAGER_HELPERS_HXX_ diff --git a/framework/source/layoutmanager/layoutmanager.cxx b/framework/source/layoutmanager/layoutmanager.cxx index 458368bd6581..4eb3d76a8f08 100644 --- a/framework/source/layoutmanager/layoutmanager.cxx +++ b/framework/source/layoutmanager/layoutmanager.cxx @@ -6,6 +6,9 @@ * * OpenOffice.org - a multi-platform office productivity suite * + * $RCSfile: layoutmanager.cxx,v $ + * $Revision: 1.72 $ + * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -32,26 +35,21 @@ // my own includes //_________________________________________________________________________________________________________________ -// #include <math.h> - -#ifndef _FRAMEWORK_SERVICES_LAYOUTMANAGER_HXX_ #include <services/layoutmanager.hxx> -#endif +#include <helpers.hxx> +#include <panelmanager.hxx> #include <threadhelp/resetableguard.hxx> #include <services.h> - #include <classes/sfxhelperfunctions.hxx> #include <uielement/menubarwrapper.hxx> #include <classes/addonsoptions.hxx> #include <uiconfiguration/windowstateconfiguration.hxx> #include <classes/fwkresid.hxx> - -#ifndef __FRAMEWORK_CLASSES_RESOURCE_HRC_ #include <classes/resource.hrc> -#endif #include <toolkit/helper/convert.hxx> #include <uielement/progressbarwrapper.hxx> #include <uiconfiguration/globalsettings.hxx> +#include <toolbarlayoutmanager.hxx> //_________________________________________________________________________________________________________________ // interface includes @@ -115,49 +113,12 @@ using namespace ::com::sun::star::ui; using namespace com::sun::star::frame; using namespace ::com::sun::star::frame; -#define UIRESOURCE_PROTOCO_ASCII "private:" -#define UIRESOURCE_RESOURCE_ASCII "resource" -#define UIRESOURCE_URL_ASCII "private:resource" -#define UIRESOURCE_URL rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( UIRESOURCE_URL_ASCII )) // ATTENTION! // This value is directly copied from the sfx2 project. // You have to change BOTH values, see sfx2/inc/sfx2/sfxsids.hrc (SID_DOCKWIN_START) static const sal_Int32 DOCKWIN_ID_BASE = 9800; -bool lcl_checkUIElement(const Reference< XUIElement >& xUIElement,css::awt::Rectangle& _rPosSize,Reference< css::awt::XWindow >& _xWindow) -{ - bool bRet = xUIElement.is(); - if ( bRet ) - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - _xWindow.set( xUIElement->getRealInterface(), UNO_QUERY ); - _rPosSize = _xWindow->getPosSize(); - - Window* pWindow = VCLUnoHelper::GetWindow( _xWindow ); - if ( pWindow->GetType() == WINDOW_TOOLBOX ) - { - ::Size aSize = ((ToolBox*)pWindow)->CalcWindowSizePixel( 1 ); - _rPosSize.Width = aSize.Width(); - _rPosSize.Height = aSize.Height(); - } - } // if ( xUIElement.is() ) - return bRet; -} - -// convert alignment constant to vcl's WindowAlign type -static WindowAlign ImplConvertAlignment( sal_Int16 aAlignment ) -{ - if ( aAlignment == DockingArea_DOCKINGAREA_LEFT ) - return WINDOWALIGN_LEFT; - else if ( aAlignment == DockingArea_DOCKINGAREA_RIGHT ) - return WINDOWALIGN_RIGHT; - else if ( aAlignment == DockingArea_DOCKINGAREA_TOP ) - return WINDOWALIGN_TOP; - else - return WINDOWALIGN_BOTTOM; -} - //_________________________________________________________________________________________________________________ // Namespace //_________________________________________________________________________________________________________________ @@ -172,179 +133,6 @@ struct UIElementVisibility bool bVisible; }; -bool LayoutManager::UIElement::operator< ( const LayoutManager::UIElement& aUIElement ) const -{ - if ( !m_xUIElement.is() && aUIElement.m_xUIElement.is() ) - return false; - else if ( m_xUIElement.is() && !aUIElement.m_xUIElement.is() ) - return true; - else if ( !m_bVisible && aUIElement.m_bVisible ) - return false; - else if ( m_bVisible && !aUIElement.m_bVisible ) - return true; - else if ( !m_bFloating && aUIElement.m_bFloating ) - return true; - else if ( m_bFloating && !aUIElement.m_bFloating ) - return false; - else - { - if ( m_bFloating ) - { - bool bEqual = ( m_aFloatingData.m_aPos.Y() == aUIElement.m_aFloatingData.m_aPos.Y() ); - if ( bEqual ) - return ( m_aFloatingData.m_aPos.X() < aUIElement.m_aFloatingData.m_aPos.X() ); - else - return ( m_aFloatingData.m_aPos.Y() < aUIElement.m_aFloatingData.m_aPos.Y() ); - } - else - { - if ( m_aDockedData.m_nDockedArea < aUIElement.m_aDockedData.m_nDockedArea ) - return true; - else if ( m_aDockedData.m_nDockedArea > aUIElement.m_aDockedData.m_nDockedArea ) - return false; - else - { - if ( m_aDockedData.m_nDockedArea == DockingArea_DOCKINGAREA_TOP || - m_aDockedData.m_nDockedArea == DockingArea_DOCKINGAREA_BOTTOM ) - { - if ( !( m_aDockedData.m_aPos.Y() == aUIElement.m_aDockedData.m_aPos.Y() ) ) - return ( m_aDockedData.m_aPos.Y() < aUIElement.m_aDockedData.m_aPos.Y() ); - else - { - bool bEqual = ( m_aDockedData.m_aPos.X() == aUIElement.m_aDockedData.m_aPos.X() ); - if ( bEqual ) - { - return m_bUserActive && !aUIElement.m_bUserActive; - } - else - return ( m_aDockedData.m_aPos.X() < aUIElement.m_aDockedData.m_aPos.X() ); - } - } - else - { - if ( !( m_aDockedData.m_aPos.X() == aUIElement.m_aDockedData.m_aPos.X() ) ) - return ( m_aDockedData.m_aPos.X() < aUIElement.m_aDockedData.m_aPos.X() ); - else - { - bool bEqual = ( m_aDockedData.m_aPos.Y() == aUIElement.m_aDockedData.m_aPos.Y() ); - if ( bEqual ) - { - return m_bUserActive && !aUIElement.m_bUserActive; - } - else - return ( m_aDockedData.m_aPos.Y() < aUIElement.m_aDockedData.m_aPos.Y() ); - } - } - } - } - } -} - -LayoutManager::UIElement& LayoutManager::UIElement::operator= ( const LayoutManager::UIElement& rUIElement ) -{ - if (this == &rUIElement) { return *this; } - m_aType = rUIElement.m_aType; - m_aName = rUIElement.m_aName; - m_aUIName = rUIElement.m_aUIName; - m_xUIElement = rUIElement.m_xUIElement; - m_bFloating = rUIElement.m_bFloating; - m_bVisible = rUIElement.m_bVisible; - m_bUserActive = rUIElement.m_bUserActive; - m_bCreateNewRowCol0 = rUIElement.m_bCreateNewRowCol0; - m_bDeactiveHide = rUIElement.m_bDeactiveHide; - m_bMasterHide = rUIElement.m_bMasterHide; - m_bContextSensitive = rUIElement.m_bContextSensitive; - m_bContextActive = rUIElement.m_bContextActive; - m_bNoClose = rUIElement.m_bNoClose; - m_bSoftClose = rUIElement.m_bSoftClose; - m_bStateRead = rUIElement.m_bStateRead; - m_nStyle = rUIElement.m_nStyle; - m_aDockedData = rUIElement.m_aDockedData; - m_aFloatingData = rUIElement.m_aFloatingData; - return *this; -} - -static Reference< XModel > impl_getModelFromFrame( const Reference< XFrame >& rFrame ) -{ - // Query for the model to get check the context information - Reference< XModel > xModel; - if ( rFrame.is() ) - { - Reference< XController > xController( rFrame->getController(), UNO_QUERY ); - if ( xController.is() ) - xModel = xController->getModel(); - } - - return xModel; -} - -static sal_Bool implts_isPreviewModel( const Reference< XModel >& xModel ) -{ - if ( xModel.is() ) - { - ::comphelper::MediaDescriptor aDesc( xModel->getArgs() ); - return aDesc.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_PREVIEW(), (sal_Bool)sal_False); - } - else - return sal_False; -} - -static sal_Bool implts_isFrameOrWindowTop( const css::uno::Reference< css::frame::XFrame >& xFrame ) -{ - if (xFrame->isTop()) - return sal_True; - - css::uno::Reference< css::awt::XTopWindow > xWindowCheck(xFrame->getContainerWindow(), css::uno::UNO_QUERY); // dont use _THROW here ... its a check only - if (xWindowCheck.is()) - { - // --> PB 2007-06-18 #i76867# top and system window is required. - ::vos::OGuard aSolarLock(&Application::GetSolarMutex()); - css::uno::Reference< css::awt::XWindow > xWindow( xWindowCheck, UNO_QUERY ); - Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); - return ( pWindow && pWindow->IsSystemWindow() ); - // <-- - } - - return sal_False; -} - -static void impl_setDockingWindowVisibility( const css::uno::Reference< css::lang::XMultiServiceFactory>& rSMGR, const css::uno::Reference< css::frame::XFrame >& rFrame, const ::rtl::OUString& rDockingWindowName, bool bVisible ) -{ - const ::rtl::OUString aDockWinPrefixCommand( RTL_CONSTASCII_USTRINGPARAM( "DockingWindow" )); - css::uno::WeakReference< css::frame::XDispatchHelper > xDispatchHelper; - - sal_Int32 nID = rDockingWindowName.toInt32(); - sal_Int32 nIndex = nID - DOCKWIN_ID_BASE; - - css::uno::Reference< css::frame::XDispatchProvider > xProvider(rFrame, css::uno::UNO_QUERY); - if ( nIndex >= 0 && xProvider.is() ) - { - ::rtl::OUString aDockWinCommand( RTL_CONSTASCII_USTRINGPARAM( ".uno:" )); - ::rtl::OUString aDockWinArgName( aDockWinPrefixCommand ); - - aDockWinArgName += ::rtl::OUString::valueOf( nIndex ); - - css::uno::Sequence< css::beans::PropertyValue > aArgs(1); - aArgs[0].Name = aDockWinArgName; - aArgs[0].Value = css::uno::makeAny( bVisible ); - - css::uno::Reference< css::frame::XDispatchHelper > xDispatcher( xDispatchHelper ); - if ( !xDispatcher.is()) - { - xDispatcher = css::uno::Reference< css::frame::XDispatchHelper >( - rSMGR->createInstance(SERVICENAME_DISPATCHHELPER), css::uno::UNO_QUERY_THROW); - } - - aDockWinCommand = aDockWinCommand + aDockWinArgName; - xDispatcher->executeDispatch( - xProvider, - aDockWinCommand, - ::rtl::OUString::createFromAscii("_self"), - 0, - aArgs); - } -} - //***************************************************************************************************************** // XInterface, XTypeProvider, XServiceInfo //***************************************************************************************************************** @@ -383,7 +171,6 @@ LayoutManager::LayoutManager( const Reference< XMultiServiceFactory >& xServiceM , m_bHideCurrentUI( false ) , m_bGlobalSettings( sal_False ) , m_bPreserveContentSize( false ) - , m_eDockOperation( DOCKOP_ON_COLROW ) , m_pInplaceMenuBar( NULL ) , m_xModuleManager( Reference< XModuleManager >( xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY )) @@ -410,12 +197,16 @@ LayoutManager::LayoutManager( const Reference< XMultiServiceFactory >& xServiceM , m_aCustomizeCmd( RTL_CONSTASCII_USTRINGPARAM( "ConfigureDialog" )) , m_pAddonOptions( 0 ) , m_aListenerContainer( m_aLock.getShareableOslMutex() ) + , m_pPanelManager( 0 ) + , m_pToolbarManager( 0 ) { // Initialize statusbar member m_aStatusBarElement.m_aType = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "statusbar" )); m_aStatusBarElement.m_aName = m_aStatusBarAlias; - m_pMiscOptions = new SvtMiscOptions(); + m_pMiscOptions = new SvtMiscOptions(); + m_pToolbarManager = new ToolbarLayoutManager( xServiceManager, m_xUIElementFactoryManager ); + m_xToolbarManager = uno::Reference< awt::XDockableWindowListener >( static_cast< OWeakObject* >( m_pToolbarManager ), uno::UNO_QUERY ); m_pMiscOptions->AddListenerLink( LINK( this, LayoutManager, OptionsChanged ) ); Application::AddEventListener( LINK( this, LayoutManager, SettingsChanged ) ); @@ -425,7 +216,6 @@ LayoutManager::LayoutManager( const Reference< XMultiServiceFactory >& xServiceM m_aAsyncLayoutTimer.SetTimeout( 50 ); m_aAsyncLayoutTimer.SetTimeoutHdl( LINK( this, LayoutManager, AsyncLayoutHdl ) ); - registerProperty( LAYOUTMANAGER_PROPNAME_AUTOMATICTOOLBARS, LAYOUTMANAGER_PROPHANDLE_AUTOMATICTOOLBARS, css::beans::PropertyAttribute::TRANSIENT, &m_bAutomaticToolbars, ::getCppuType( &m_bAutomaticToolbars ) ); registerProperty( LAYOUTMANAGER_PROPNAME_HIDECURRENTUI, LAYOUTMANAGER_PROPHANDLE_HIDECURRENTUI, css::beans::PropertyAttribute::TRANSIENT, &m_bHideCurrentUI, ::getCppuType( &m_bHideCurrentUI ) ); registerProperty( LAYOUTMANAGER_PROPNAME_LOCKCOUNT, LAYOUTMANAGER_PROPHANDLE_LOCKCOUNT, css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY, &m_nLockCount, getCppuType( &m_nLockCount ) ); @@ -511,27 +301,6 @@ void LayoutManager::impl_clearUpMenuBar() implts_unlock(); } -sal_Bool LayoutManager::impl_parseResourceURL( const rtl::OUString aResourceURL, rtl::OUString& aElementType, rtl::OUString& aElementName ) -{ - URL aURL; - sal_Int32 nIndex = 0; - - aURL.Complete = aResourceURL; - m_xURLTransformer->parseStrict( aURL ); - - ::rtl::OUString aUIResource = aURL.Path.getToken( 0, (sal_Unicode)'/', nIndex ); - - if (( aURL.Protocol.equalsIgnoreAsciiCaseAscii( UIRESOURCE_PROTOCO_ASCII )) && - ( aUIResource.equalsIgnoreAsciiCaseAscii( UIRESOURCE_RESOURCE_ASCII ))) - { - aElementType = aURL.Path.getToken( 0, (sal_Unicode)'/', nIndex ); - aElementName = aURL.Path.getToken( 0, (sal_Unicode)'/', nIndex ); - return sal_True; - } - - return sal_False; -} - void LayoutManager::implts_lock() { /* SAFE AREA ----------------------------------------------------------------------------------------------- */ @@ -697,14 +466,17 @@ void LayoutManager::implts_reset( sal_Bool bAttached ) aModuleIdentifier = ::rtl::OUString(); } + Reference< XUIConfigurationManager > xModCfgMgr( xModuleCfgMgr, UNO_QUERY ); + Reference< XUIConfigurationManager > xDokCfgMgr( xDocCfgMgr, UNO_QUERY ); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ WriteGuard aWriteLock( m_aLock ); m_xModel = xModel; m_aDockingArea = css::awt::Rectangle(); m_bComponentAttached = bAttached; m_aModuleIdentifier = aModuleIdentifier; - m_xModuleCfgMgr = Reference< XUIConfigurationManager >( xModuleCfgMgr, UNO_QUERY ); - m_xDocCfgMgr = Reference< XUIConfigurationManager >( xDocCfgMgr, UNO_QUERY ); + m_xModuleCfgMgr = xModCfgMgr; + m_xDocCfgMgr = xDokCfgMgr; m_xPersistentWindowState = xPersistentWindowState; m_aStatusBarElement.m_bStateRead = sal_False; // reset state to read data again! aWriteLock.unlock(); @@ -712,32 +484,15 @@ void LayoutManager::implts_reset( sal_Bool bAttached ) if ( bAttached ) { - // reset docking area windows back to zero size - try - { - if ( xTopDockingWindow.is() ) - xTopDockingWindow->setPosSize( 0, 0, 0, 0, css::awt::PosSize::POSSIZE ); - if ( xLeftDockingWindow.is() ) - xLeftDockingWindow->setPosSize( 0, 0, 0, 0, css::awt::PosSize::POSSIZE ); - if ( xRightDockingWindow.is() ) - xRightDockingWindow->setPosSize( 0, 0, 0, 0, css::awt::PosSize::POSSIZE ); - if ( xBottomDockingWindow.is() ) - xBottomDockingWindow->setPosSize( 0, 0, 0, 0, css::awt::PosSize::POSSIZE ); - } - catch ( Exception& ) - { - } - - if ( bAutomaticToolbars ) - { - implts_createCustomToolBars(); - implts_createAddonsToolBars(); - implts_createNonContextSensitiveToolBars(); - } - implts_sortUIElements(); + m_pToolbarManager->attach( xFrame, xModCfgMgr, xDokCfgMgr, xPersistentWindowState ); + css::uno::Reference< css::awt::XWindowPeer > xParent( xContainerWindow, UNO_QUERY ); + m_pToolbarManager->setParentWindow( xParent ); } else + { + m_pToolbarManager->reset(); implts_destroyElements(); + } } implts_unlock(); @@ -784,333 +539,6 @@ void LayoutManager::implts_destroyElements() aWriteLock.unlock(); } -void LayoutManager::implts_destroyDockingAreaWindows() -{ - std::vector< Reference< css::awt::XWindow > > oldDockingAreaWindows; - - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - WriteGuard aWriteLock( m_aLock ); - oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP] ); - oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM] ); - oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT] ); - oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT] ); - - m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP].clear(); - m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM].clear(); - m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT].clear(); - m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT].clear(); - aWriteLock.unlock(); - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - - const sal_uInt32 nCount = oldDockingAreaWindows.size(); - for ( sal_uInt32 i=0; i < nCount; i++ ) - { - if ( oldDockingAreaWindows[i].is() ) - { - try - { - oldDockingAreaWindows[i]->dispose(); - } - catch ( Exception& ) - { - } - } - } -} - -void LayoutManager::implts_createCustomToolBar( const rtl::OUString& aTbxResName, const rtl::OUString& aTitle ) -{ - if ( aTbxResName.getLength() > 0 ) - { - createElement( aTbxResName ); - if ( aTitle ) - { - Reference< XUIElement > xUIElement = getElement( aTbxResName ); - if ( xUIElement.is() ) - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - - Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); - Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); - if ( pWindow ) - pWindow->SetText( aTitle ); - } - } - } -} - -void LayoutManager::implts_createCustomToolBars( - const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >& aTbxSeqSeq ) -{ - const Sequence< PropertyValue >* pTbxSeq = aTbxSeqSeq.getConstArray(); - for ( sal_Int32 i = 0; i < aTbxSeqSeq.getLength(); i++ ) - { - const Sequence< PropertyValue >& rTbxSeq = pTbxSeq[i]; - ::rtl::OUString aTbxResName; - ::rtl::OUString aTbxTitle; - for ( sal_Int32 j = 0; j < rTbxSeq.getLength(); j++ ) - { - if ( rTbxSeq[j].Name.equalsAscii( "ResourceURL" )) - rTbxSeq[j].Value >>= aTbxResName; - else if ( rTbxSeq[j].Name.equalsAscii( "UIName" )) - rTbxSeq[j].Value >>= aTbxTitle; - } - - // Only create custom toolbars. Their name have to start with "custom_"! - if ( aTbxResName.getLength() > 0 && aTbxResName.indexOf( m_aCustomTbxPrefix ) != -1 ) - implts_createCustomToolBar( aTbxResName, aTbxTitle ); - } -} - -void LayoutManager::implts_createCustomToolBars() -{ - ReadGuard aReadLock( m_aLock ); - if ( !m_bComponentAttached ) - return; - - Reference< XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager ); - Reference< XFrame > xFrame( m_xFrame ); - Reference< XModel > xModel; - Reference< XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr, UNO_QUERY ); - Reference< XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr, UNO_QUERY ); - aReadLock.unlock(); - - if ( xFrame.is() ) - { - xModel = impl_getModelFromFrame( xFrame ); - if ( implts_isPreviewModel( xModel )) - return; // no custom toolbars for preview frame! - - Sequence< Sequence< PropertyValue > > aTbxSeq; - if ( xDocCfgMgr.is() ) - { - aTbxSeq = xDocCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR ); - implts_createCustomToolBars( aTbxSeq ); // first create all document based toolbars - } - if ( xModuleCfgMgr.is() ) - { - aTbxSeq = xModuleCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR ); - implts_createCustomToolBars( aTbxSeq ); // second create module based toolbars - } - } -} - -rtl::OUString LayoutManager::implts_generateGenericAddonToolbarTitle( sal_Int32 nNumber ) const -{ - String aAddonGenericTitle; - - aAddonGenericTitle = String( FwkResId( STR_TOOLBAR_TITLE_ADDON )); - const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper(); - - String aNumStr = rI18nHelper.GetNum( nNumber, 0, FALSE, FALSE ); - aAddonGenericTitle.SearchAndReplaceAscii( "%num%", aNumStr ); - - return rtl::OUString( aAddonGenericTitle ); -} - -void LayoutManager::implts_createAddonsToolBars() -{ - WriteGuard aWriteLock( m_aLock ); - if ( !m_bComponentAttached ) - return; - - Reference< XModel > xModel; - Reference< XFrame > xFrame( m_xFrame ); - if ( !xFrame.is() ) - return; - - if ( !m_pAddonOptions ) - m_pAddonOptions = new AddonsOptions; - - Reference< XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager ); - aWriteLock.unlock(); - - xModel = impl_getModelFromFrame( xFrame ); - if ( implts_isPreviewModel( xModel )) - return; // no addon toolbars for preview frame! - - UIElementVector aUIElementVector; - Sequence< Sequence< PropertyValue > > aAddonToolBarData; - Reference< XUIElement > xUIElement; - - sal_uInt32 nCount = m_pAddonOptions->GetAddonsToolBarCount(); - ::rtl::OUString aAddonsToolBarStaticName( m_aFullAddonTbxPrefix ); - ::rtl::OUString aElementType( RTL_CONSTASCII_USTRINGPARAM( "toolbar" )); - - Sequence< PropertyValue > aPropSeq( 2 ); - aPropSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); - aPropSeq[0].Value <<= xFrame; - aPropSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationData" )); - for ( sal_uInt32 i = 0; i < nCount; i++ ) - { - ::rtl::OUString aAddonToolBarName( aAddonsToolBarStaticName + m_pAddonOptions->GetAddonsToolbarResourceName(i) ); - aAddonToolBarData = m_pAddonOptions->GetAddonsToolBarPart( i ); - aPropSeq[1].Value <<= aAddonToolBarData; - - aWriteLock.lock(); - UIElement aElement = impl_findElement( aAddonToolBarName ); - aWriteLock.unlock(); - - // #i79828 - // It's now possible that we are called more than once. Be sure to not create - // add-on toolbars more than once! - if ( aElement.m_xUIElement.is() ) - continue; - - try - { - xUIElement = xUIElementFactory->createUIElement( aAddonToolBarName, aPropSeq ); - if ( xUIElement.is() ) - { - Reference< css::awt::XDockableWindow > xDockWindow( xUIElement->getRealInterface(), UNO_QUERY ); - if ( xDockWindow.is() ) - { - try - { - xDockWindow->addDockableWindowListener( Reference< css::awt::XDockableWindowListener >( static_cast< OWeakObject * >( this ), UNO_QUERY )); - xDockWindow->enableDocking( sal_True ); - Reference< css::awt::XWindow > xWindow( xDockWindow, UNO_QUERY ); - if ( xWindow.is() ) - xWindow->addWindowListener( Reference< css::awt::XWindowListener >( static_cast< OWeakObject * >( this ), UNO_QUERY )); - } - catch ( Exception& ) - { - } - } - - ::rtl::OUString aGenericAddonTitle = implts_generateGenericAddonToolbarTitle( i+1 ); - - if ( aElement.m_aName.getLength() > 0 ) - { - // Reuse a local entry so we are able to use the latest - // UI changes for this document. - implts_setElementData( aElement, xDockWindow ); - aElement.m_xUIElement = xUIElement; - if ( aElement.m_aUIName.getLength() == 0 ) - { - aElement.m_aUIName = aGenericAddonTitle; - implts_writeWindowStateData( aElement.m_aName, aElement ); - } - } - else - { - // Create new UI element and try to read its state data - UIElement aNewToolbar( aAddonToolBarName, aElementType, xUIElement ); - aNewToolbar.m_bFloating = sal_True; - implts_readWindowStateData( aAddonToolBarName, aNewToolbar ); - implts_setElementData( aNewToolbar, xDockWindow ); - if ( aNewToolbar.m_aUIName.getLength() == 0 ) - { - aNewToolbar.m_aUIName = aGenericAddonTitle; - implts_writeWindowStateData( aNewToolbar.m_aName, aNewToolbar ); - } - implts_insertUIElement( aNewToolbar ); - } - - Reference< css::awt::XWindow > xWindow( xDockWindow, UNO_QUERY ); - if ( xWindow.is() ) - { - // Set generic title for add-on toolbar - vos::OGuard aGuard( Application::GetSolarMutex() ); - Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); - if ( pWindow->GetText().Len() == 0 ) - pWindow->SetText( aGenericAddonTitle ); - if ( pWindow->GetType() == WINDOW_TOOLBOX ) - { - ToolBox* pToolbar = (ToolBox *)pWindow; - pToolbar->SetMenuType(); - } - } - } - } - catch ( NoSuchElementException& ) - { - } - catch ( IllegalArgumentException& ) - { - } - } -} - -void LayoutManager::implts_createNonContextSensitiveToolBars() -{ - ReadGuard aReadLock( m_aLock ); - - if ( !m_xPersistentWindowState.is() || - !m_xFrame.is() || - !m_bComponentAttached ) - return; - - Reference< XFrame > xFrame( m_xFrame ); - - Reference< XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager ); - Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); - aReadLock.unlock(); - - if ( implts_isPreviewModel( impl_getModelFromFrame( xFrame ))) - return; - - std::vector< rtl::OUString > aMakeVisibleToolbars; - - try - { - Sequence< rtl::OUString > aToolbarNames = xPersistentWindowState->getElementNames(); - - if ( aToolbarNames.getLength() > 0 ) - { - rtl::OUString aElementType; - rtl::OUString aElementName; - rtl::OUString aName; - - Reference< ::com::sun::star::ui::XUIElement > xUIElement; - aMakeVisibleToolbars.reserve(aToolbarNames.getLength()); - WriteGuard aWriteLock( m_aLock ); - - const rtl::OUString* pTbNames = aToolbarNames.getConstArray(); - for ( sal_Int32 i = 0; i < aToolbarNames.getLength(); i++ ) - { - aName = pTbNames[i]; - if ( impl_parseResourceURL( aName, aElementType, aElementName )) - { - // Check that we only create: - // - Toolbars (the statusbar is also member of the persistent window state) - // - Not custom toolbars, there are created with their own method (implts_createCustomToolbars) - if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" ) && - aElementName.indexOf( m_aCustomTbxPrefix ) == -1 ) - { - UIElement aNewToolbar( aName, aElementType, xUIElement ); - bool bFound = implts_findElement( aName, aNewToolbar ); - if ( !bFound ) - implts_readWindowStateData( aName, aNewToolbar ); - - if ( aNewToolbar.m_bVisible && - !aNewToolbar.m_bContextSensitive ) - { - if ( !bFound ) - implts_insertUIElement( aNewToolbar ); - aMakeVisibleToolbars.push_back( aName ); - } - } - } - } - } - } - catch ( RuntimeException& e ) - { - throw e; - } - catch ( Exception& ) - { - } - - if ( !aMakeVisibleToolbars.empty() ) - { - implts_lock(); - ::std::for_each( aMakeVisibleToolbars.begin(), aMakeVisibleToolbars.end(),::boost::bind( &LayoutManager::requestElement, this,_1 )); - implts_unlock(); - } -} - void LayoutManager::implts_toggleFloatingUIElementsVisibility( sal_Bool bActive ) { WriteGuard aWriteLock( m_aLock ); @@ -1241,7 +669,7 @@ sal_Bool LayoutManager::implts_findElement( const rtl::OUString& aName, UIElemen return sal_False; } -LayoutManager::UIElement& LayoutManager::impl_findElement( const rtl::OUString& aName ) +UIElement& LayoutManager::impl_findElement( const rtl::OUString& aName ) { static UIElement aEmptyElement; @@ -1578,12 +1006,12 @@ void LayoutManager::implts_writeWindowStateData( const rtl::OUString& aName, con if ( xPersistentWindowState->hasByName( aName )) { - Reference< XNameReplace > xReplace( xPersistentWindowState, UNO_QUERY ); + Reference< XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY ); xReplace->replaceByName( aName, makeAny( aWindowState )); } else { - Reference< XNameContainer > xInsert( xPersistentWindowState, UNO_QUERY ); + Reference< XNameContainer > xInsert( xPersistentWindowState, uno::UNO_QUERY ); xInsert->insertByName( aName, makeAny( aWindowState )); } } @@ -1598,360 +1026,6 @@ void LayoutManager::implts_writeWindowStateData( const rtl::OUString& aName, con aWriteLock.unlock(); } -void LayoutManager::implts_setElementData( UIElement& rElement, const Reference< css::awt::XDockableWindow >& rDockWindow ) -{ - ReadGuard aReadLock( m_aLock ); - sal_Bool bShowElement( rElement.m_bVisible && !rElement.m_bMasterHide && m_bParentWindowVisible ); - aReadLock.unlock(); - - Reference< css::awt::XDockableWindow > xDockWindow( rDockWindow ); - Reference< css::awt::XWindow2 > xWindow( xDockWindow, UNO_QUERY ); - - Window* pWindow( 0 ); - ToolBox* pToolBox( 0 ); - - if ( xDockWindow.is() && xWindow.is() ) - { - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - pWindow = VCLUnoHelper::GetWindow( xWindow ); - if ( pWindow ) - { - String aText = pWindow->GetText(); - if ( aText.Len() == 0 ) - pWindow->SetText( rElement.m_aUIName ); - if ( rElement.m_bNoClose ) - pWindow->SetStyle( pWindow->GetStyle() & ~WB_CLOSEABLE ); - if ( pWindow->GetType() == WINDOW_TOOLBOX ) - pToolBox = (ToolBox *)pWindow; - } - if ( pToolBox ) - { - if (( rElement.m_nStyle < 0 ) || - ( rElement.m_nStyle > BUTTON_SYMBOLTEXT )) - rElement.m_nStyle = BUTTON_SYMBOL; - pToolBox->SetButtonType( (ButtonType)rElement.m_nStyle ); - if ( rElement.m_bNoClose ) - pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() & ~WB_CLOSEABLE ); - } - } - - if ( rElement.m_bFloating ) - { - if ( pWindow ) - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - String aText = pWindow->GetText(); - if ( aText.Len() == 0 ) - pWindow->SetText( rElement.m_aUIName ); - } - - ::Point aPos( rElement.m_aFloatingData.m_aPos.X(), - rElement.m_aFloatingData.m_aPos.Y() ); - sal_Bool bWriteData( sal_False ); - sal_Bool bUndefPos = ( rElement.m_aFloatingData.m_aPos.X() == SAL_MAX_INT32 || - rElement.m_aFloatingData.m_aPos.Y() == SAL_MAX_INT32 ); - sal_Bool bSetSize = ( rElement.m_aFloatingData.m_aSize.Width() != 0 && - rElement.m_aFloatingData.m_aSize.Height() != 0 ); - xDockWindow->setFloatingMode( sal_True ); - if ( bUndefPos ) - { - aPos = implts_findNextCascadeFloatingPos(); - rElement.m_aFloatingData.m_aPos = aPos; // set new cascaded position - bWriteData = sal_True; - } - - if( bSetSize ) - xWindow->setOutputSize( AWTSize( rElement.m_aFloatingData.m_aSize ) ); - else - { - if( pToolBox ) - { - // set an optimal initial floating size - vos::OGuard aGuard( Application::GetSolarMutex() ); - ::Size aSize( pToolBox->CalcFloatingWindowSizePixel() ); - pToolBox->SetOutputSizePixel( aSize ); - } - } - - // #i60882# IMPORTANT: Set position after size as it is - // possible that we position some part of the toolbar - // outside of the desktop. A default constructed toolbar - // always has one line. Now VCL automatically - // position the toolbar back into the desktop. Therefore - // we resize the toolbar with the new (wrong) position. - // To fix this problem we have to set the size BEFORE the - // position. - xWindow->setPosSize( aPos.X(), aPos.Y(), 0, 0, - css::awt::PosSize::POS ); - - if ( bWriteData ) - implts_writeWindowStateData( rElement.m_aName, rElement ); - if ( bShowElement && pWindow ) - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); - } - } - else - { - ::Point aDockPos; - ::Point aPixelPos; - sal_Bool bSetSize( sal_False ); - ::Size aSize; - - if ( pToolBox ) - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - pToolBox->SetAlign( ImplConvertAlignment(rElement.m_aDockedData.m_nDockedArea ) ); - pToolBox->SetLineCount( 1 ); - if ( rElement.m_aDockedData.m_bLocked ) - xDockWindow->lock(); - aSize = pToolBox->CalcWindowSizePixel(); - bSetSize = sal_True; - - if (( rElement.m_aDockedData.m_aPos.X() == SAL_MAX_INT32 ) && - ( rElement.m_aDockedData.m_aPos.Y() == SAL_MAX_INT32 )) - { - implts_findNextDockingPos( (DockingArea)rElement.m_aDockedData.m_nDockedArea, - aSize, - aDockPos, - aPixelPos ); - rElement.m_aDockedData.m_aPos = aDockPos; - } - } - - xWindow->setPosSize( aPixelPos.X(), - aPixelPos.Y(), - 0, 0, - css::awt::PosSize::POS ); - if( bSetSize ) - xWindow->setOutputSize( AWTSize( aSize) ); - - if ( bShowElement && pWindow ) - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - pWindow->Show( sal_True ); - } - } - } -} - -::Point LayoutManager::implts_findNextCascadeFloatingPos() -{ - const sal_Int32 nHotZoneX = 50; - const sal_Int32 nHotZoneY = 50; - const sal_Int32 nCascadeIndentX = 15; - const sal_Int32 nCascadeIndentY = 15; - - ReadGuard aReadLock( m_aLock ); - Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow; - Reference< css::awt::XWindow > xTopDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP]; - Reference< css::awt::XWindow > xLeftDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT]; - aReadLock.unlock(); - - ::Point aStartPos( nCascadeIndentX, nCascadeIndentY ); - ::Point aCurrPos( aStartPos ); - css::awt::Rectangle aRect; - - Window* pContainerWindow( 0 ); - if ( xContainerWindow.is() ) - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); - if ( pContainerWindow ) - aStartPos = pContainerWindow->OutputToScreenPixel( aStartPos ); - } - - // Determine size of top and left docking area - css::awt::Rectangle aTopRect = xTopDockingWindow->getPosSize(); - css::awt::Rectangle aLeftRect = xLeftDockingWindow->getPosSize(); - - aStartPos.X() += aLeftRect.Width + nCascadeIndentX; - aStartPos.Y() += aTopRect.Height + nCascadeIndentY; - aCurrPos = aStartPos; - - // Try to find a cascaded position for the new floating window - UIElementVector::const_iterator pIter; - for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) - { - if ( pIter->m_xUIElement.is() ) - { - Reference< css::awt::XDockableWindow > xDockWindow( pIter->m_xUIElement->getRealInterface(), UNO_QUERY ); - Reference< css::awt::XWindow > xWindow( xDockWindow, UNO_QUERY ); - if ( xDockWindow.is() && xDockWindow->isFloating() ) - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); - if ( pWindow && pWindow->IsVisible() ) - { - css::awt::Rectangle aFloatRect = xWindow->getPosSize(); - if ((( aFloatRect.X - nHotZoneX ) <= aCurrPos.X() ) && - ( aFloatRect.X >= aCurrPos.X() ) && - (( aFloatRect.Y - nHotZoneY ) <= aCurrPos.Y() ) && - ( aFloatRect.Y >= aCurrPos.Y() )) - { - aCurrPos.X() = aFloatRect.X + nCascadeIndentX; - aCurrPos.Y() = aFloatRect.Y + nCascadeIndentY; - } - } - } - } - } - - return aCurrPos; -} - -void LayoutManager::implts_findNextDockingPos( DockingArea DockingArea, const ::Size& aUIElementSize, ::Point& rVirtualPos, ::Point& rPixelPos ) -{ - ReadGuard aReadLock( m_aLock ); - Reference< css::awt::XWindow > xDockingWindow = m_xDockAreaWindows[DockingArea]; - ::Size aDockingWinSize; - Window* pDockingWindow( 0 ); - aReadLock.unlock(); - - if (( DockingArea < DockingArea_DOCKINGAREA_TOP ) || - ( DockingArea > DockingArea_DOCKINGAREA_RIGHT )) - DockingArea = DockingArea_DOCKINGAREA_TOP; - - { - // Retrieve output size from container Window - vos::OGuard aGuard( Application::GetSolarMutex() ); - pDockingWindow = VCLUnoHelper::GetWindow( xDockingWindow ); - if ( pDockingWindow ) - aDockingWinSize = pDockingWindow->GetOutputSizePixel(); - } - - sal_Int32 nFreeRowColPixelPos( 0 ); - sal_Int32 nMaxSpace( 0 ); - sal_Int32 nNeededSpace( 0 ); - sal_Int32 nTopDockingAreaSize( 0 ); - - if (( DockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( DockingArea == DockingArea_DOCKINGAREA_BOTTOM )) - { - nMaxSpace = aDockingWinSize.Width(); - nNeededSpace = aUIElementSize.Width(); - } - else - { - nMaxSpace = aDockingWinSize.Height(); - nNeededSpace = aUIElementSize.Height(); - nTopDockingAreaSize = implts_getTopBottomDockingAreaSizes().Width(); - } - - std::vector< SingleRowColumnWindowData > aRowColumnsWindowData; - - implts_getDockingAreaElementInfos( DockingArea, aRowColumnsWindowData ); - sal_Int32 nPixelPos( 0 ); - const sal_uInt32 nCount = aRowColumnsWindowData.size(); - for ( sal_uInt32 i = 0; i < nCount; i++ ) - { - SingleRowColumnWindowData& rRowColumnWindowData = aRowColumnsWindowData[i]; - - if (( DockingArea == DockingArea_DOCKINGAREA_BOTTOM ) || - ( DockingArea == DockingArea_DOCKINGAREA_RIGHT )) - nPixelPos += rRowColumnWindowData.nStaticSize; - - if ((( nMaxSpace - rRowColumnWindowData.nVarSize ) >= nNeededSpace ) || - ( rRowColumnWindowData.nSpace >= nNeededSpace )) - { - // Check current row where we can find the needed space - sal_Int32 nCurrPos( 0 ); - const sal_uInt32 nWindowSizesCount = rRowColumnWindowData.aRowColumnWindowSizes.size(); - for ( sal_uInt32 j = 0; j < nWindowSizesCount; j++ ) - { - css::awt::Rectangle rRect = rRowColumnWindowData.aRowColumnWindowSizes[j]; - sal_Int32& rSpace = rRowColumnWindowData.aRowColumnSpace[j]; - if (( DockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( DockingArea == DockingArea_DOCKINGAREA_BOTTOM )) - { - if ( rSpace >= nNeededSpace ) - { - rVirtualPos = ::Point( nCurrPos, rRowColumnWindowData.nRowColumn ); - if ( DockingArea == DockingArea_DOCKINGAREA_TOP ) - rPixelPos = ::Point( nCurrPos, nPixelPos ); - else - rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos ); - return; - } - nCurrPos = rRect.X + rRect.Width; - } - else - { - if ( rSpace >= nNeededSpace ) - { - rVirtualPos = ::Point( rRowColumnWindowData.nRowColumn, nCurrPos ); - if ( DockingArea == DockingArea_DOCKINGAREA_LEFT ) - rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos ); - else - rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos ); - return; - } - nCurrPos = rRect.Y + rRect.Height; - } - } - - if (( nCurrPos + nNeededSpace ) <= nMaxSpace ) - { - if (( DockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( DockingArea == DockingArea_DOCKINGAREA_BOTTOM )) - { - rVirtualPos = ::Point( nCurrPos, rRowColumnWindowData.nRowColumn ); - if ( DockingArea == DockingArea_DOCKINGAREA_TOP ) - rPixelPos = ::Point( nCurrPos, nPixelPos ); - else - rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos ); - return; - } - else - { - rVirtualPos = ::Point( rRowColumnWindowData.nRowColumn, nCurrPos ); - if ( DockingArea == DockingArea_DOCKINGAREA_LEFT ) - rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos ); - else - rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos ); - return; - } - } - } - - if (( DockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( DockingArea == DockingArea_DOCKINGAREA_LEFT )) - nPixelPos += rRowColumnWindowData.nStaticSize; - } - - sal_Int32 nNextFreeRowCol( 0 ); - sal_Int32 nRowColumnsCount = aRowColumnsWindowData.size(); - if ( nRowColumnsCount > 0 ) - nNextFreeRowCol = aRowColumnsWindowData[nRowColumnsCount-1].nRowColumn+1; - else - nNextFreeRowCol = 0; - - if ( nNextFreeRowCol == 0 ) - { - if ( DockingArea == DockingArea_DOCKINGAREA_BOTTOM ) - nFreeRowColPixelPos = aDockingWinSize.Height() - aUIElementSize.Height(); - else if ( DockingArea == DockingArea_DOCKINGAREA_RIGHT ) - nFreeRowColPixelPos = aDockingWinSize.Width() - aUIElementSize.Width(); - } - - if (( DockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( DockingArea == DockingArea_DOCKINGAREA_BOTTOM )) - { - rVirtualPos = ::Point( 0, nNextFreeRowCol ); - if ( DockingArea == DockingArea_DOCKINGAREA_TOP ) - rPixelPos = ::Point( 0, nFreeRowColPixelPos ); - else - rPixelPos = ::Point( 0, aDockingWinSize.Height() - nFreeRowColPixelPos ); - } - else - { - rVirtualPos = ::Point( nNextFreeRowCol, 0 ); - rPixelPos = ::Point( aDockingWinSize.Width() - nFreeRowColPixelPos, 0 ); - } -} - ::Size LayoutManager::implts_getContainerWindowOutputSize() { ReadGuard aReadLock( m_aLock ); @@ -1992,1053 +1066,6 @@ void LayoutManager::implts_sortUIElements() aWriteLock.unlock(); } -void LayoutManager::implts_getDockingAreaElementInfos( DockingArea eDockingArea, std::vector< SingleRowColumnWindowData >& rRowColumnsWindowData ) -{ - std::vector< UIElement > aWindowVector; - - if (( eDockingArea < DockingArea_DOCKINGAREA_TOP ) || - ( eDockingArea > DockingArea_DOCKINGAREA_RIGHT )) - eDockingArea = DockingArea_DOCKINGAREA_TOP; - - Reference< css::awt::XWindow > xDockAreaWindow; - - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - ReadGuard aReadLock( m_aLock ); - aWindowVector.reserve(m_aUIElements.size()); - xDockAreaWindow = m_xDockAreaWindows[eDockingArea]; - UIElementVector::iterator pIter; - for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) - { - if ( pIter->m_aDockedData.m_nDockedArea == eDockingArea && pIter->m_bVisible && !pIter->m_bFloating ) - { - Reference< XUIElement > xUIElement( pIter->m_xUIElement ); - if ( xUIElement.is() ) - { - Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); - Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); - if ( xDockWindow.is() ) - { - // docked windows - aWindowVector.push_back( *pIter ); - } - } - } - } - aReadLock.unlock(); - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - - rRowColumnsWindowData.clear(); - - // Collect data from windows that are on the same row/column - sal_Int32 j; - sal_Int32 nIndex( 0 ); - sal_Int32 nLastPos( 0 ); - sal_Int32 nCurrPos( -1 ); - sal_Int32 nLastRowColPixelPos( 0 ); - css::awt::Rectangle aDockAreaRect; - - if ( xDockAreaWindow.is() ) - aDockAreaRect = xDockAreaWindow->getPosSize(); - - if ( eDockingArea == DockingArea_DOCKINGAREA_TOP ) - nLastRowColPixelPos = 0; - else if ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM ) - nLastRowColPixelPos = aDockAreaRect.Height; - else if ( eDockingArea == DockingArea_DOCKINGAREA_LEFT ) - nLastRowColPixelPos = 0; - else - nLastRowColPixelPos = aDockAreaRect.Width; - - const sal_uInt32 nCount = aWindowVector.size(); - for ( j = 0; j < sal_Int32( nCount); j++ ) - { - const UIElement& rElement = aWindowVector[j]; - Reference< css::awt::XWindow > xWindow; - Reference< XUIElement > xUIElement( rElement.m_xUIElement ); - css::awt::Rectangle aPosSize; - if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) ) - continue; - if (( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )) - { - if ( nCurrPos == -1 ) - { - nCurrPos = rElement.m_aDockedData.m_aPos.Y(); - nLastPos = 0; - - SingleRowColumnWindowData aRowColumnWindowData; - aRowColumnWindowData.nRowColumn = nCurrPos; - rRowColumnsWindowData.push_back( aRowColumnWindowData ); - } - - sal_Int32 nSpace( 0 ); - if ( rElement.m_aDockedData.m_aPos.Y() != nCurrPos ) - { - if ( eDockingArea == DockingArea_DOCKINGAREA_TOP ) - nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize; - else - nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize; - ++nIndex; - nLastPos = 0; - nCurrPos = rElement.m_aDockedData.m_aPos.Y(); - SingleRowColumnWindowData aRowColumnWindowData; - aRowColumnWindowData.nRowColumn = nCurrPos; - rRowColumnsWindowData.push_back( aRowColumnWindowData ); - } - - // Calc space before an element and store it - nSpace = ( rElement.m_aDockedData.m_aPos.X() - nLastPos ); - if ( rElement.m_aDockedData.m_aPos.X() >= nLastPos ) - { - rRowColumnsWindowData[nIndex].nSpace += nSpace; - nLastPos = rElement.m_aDockedData.m_aPos.X() + aPosSize.Width; - } - else - { - nSpace = 0; - nLastPos += aPosSize.Width; - } - rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace ); - - rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow ); - rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName ); - rRowColumnsWindowData[nIndex].aRowColumnWindowSizes.push_back( - css::awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), - rElement.m_aDockedData.m_aPos.Y(), - aPosSize.Width, - aPosSize.Height )); - if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Height ) - rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Height; - if ( eDockingArea == DockingArea_DOCKINGAREA_TOP ) - rRowColumnsWindowData[nIndex].aRowColumnRect = css::awt::Rectangle( 0, nLastRowColPixelPos, - aDockAreaRect.Width, aPosSize.Height ); - else - rRowColumnsWindowData[nIndex].aRowColumnRect = css::awt::Rectangle( 0, ( nLastRowColPixelPos - aPosSize.Height ), - aDockAreaRect.Width, aPosSize.Height ); - rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Width + nSpace; - } - else - { - if ( nCurrPos == -1 ) - { - nCurrPos = rElement.m_aDockedData.m_aPos.X(); - nLastPos = 0; - - SingleRowColumnWindowData aRowColumnWindowData; - aRowColumnWindowData.nRowColumn = nCurrPos; - rRowColumnsWindowData.push_back( aRowColumnWindowData ); - } - - sal_Int32 nSpace( 0 ); - if ( rElement.m_aDockedData.m_aPos.X() != nCurrPos ) - { - if ( eDockingArea == DockingArea_DOCKINGAREA_LEFT ) - nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize; - else - nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize; - ++nIndex; - nLastPos = 0; - nCurrPos = rElement.m_aDockedData.m_aPos.X(); - SingleRowColumnWindowData aRowColumnWindowData; - aRowColumnWindowData.nRowColumn = nCurrPos; - rRowColumnsWindowData.push_back( aRowColumnWindowData ); - } - - // Calc space before an element and store it - nSpace = ( rElement.m_aDockedData.m_aPos.Y() - nLastPos ); - if ( rElement.m_aDockedData.m_aPos.Y() > nLastPos ) - { - rRowColumnsWindowData[nIndex].nSpace += nSpace; - nLastPos = rElement.m_aDockedData.m_aPos.Y() + aPosSize.Height; - } - else - { - nSpace = 0; - nLastPos += aPosSize.Height; - } - rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace ); - - rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow ); - rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName ); - rRowColumnsWindowData[nIndex].aRowColumnWindowSizes.push_back( - css::awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), - rElement.m_aDockedData.m_aPos.Y(), - aPosSize.Width, - aPosSize.Height )); - if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Width ) - rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Width; - if ( eDockingArea == DockingArea_DOCKINGAREA_LEFT ) - rRowColumnsWindowData[nIndex].aRowColumnRect = css::awt::Rectangle( nLastRowColPixelPos, 0, - aPosSize.Width, aDockAreaRect.Height ); - else - rRowColumnsWindowData[nIndex].aRowColumnRect = css::awt::Rectangle( ( nLastRowColPixelPos - aPosSize.Width ), 0, - aPosSize.Width, aDockAreaRect.Height ); - rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Height + nSpace; - } - } -} - -void LayoutManager::implts_getDockingAreaElementInfoOnSingleRowCol( DockingArea eDockingArea, sal_Int32 nRowCol, SingleRowColumnWindowData& rRowColumnWindowData ) -{ - std::vector< UIElement > aWindowVector; - - if (( eDockingArea < DockingArea_DOCKINGAREA_TOP ) || - ( eDockingArea > DockingArea_DOCKINGAREA_RIGHT )) - eDockingArea = DockingArea_DOCKINGAREA_TOP; - - sal_Bool bHorzDockArea = (( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )); - - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - ReadGuard aReadLock( m_aLock ); - UIElementVector::iterator pIter; - UIElementVector::iterator pEnd = m_aUIElements.end(); - for ( pIter = m_aUIElements.begin(); pIter != pEnd; pIter++ ) - { - if ( pIter->m_aDockedData.m_nDockedArea == eDockingArea ) - { - sal_Bool bSameRowCol = bHorzDockArea ? - ( pIter->m_aDockedData.m_aPos.Y() == nRowCol ) : - ( pIter->m_aDockedData.m_aPos.X() == nRowCol ); - Reference< XUIElement > xUIElement( pIter->m_xUIElement ); - - if ( bSameRowCol && xUIElement.is() ) - { - Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); - if ( xWindow.is() ) - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); - Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); - if ( pWindow && pIter->m_bVisible && xDockWindow.is() && !pIter->m_bFloating ) - { - // docked windows - aWindowVector.push_back( *pIter ); - } - } - } - } - } - aReadLock.unlock(); - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - - // Initialize structure - rRowColumnWindowData.aUIElementNames.clear(); - rRowColumnWindowData.aRowColumnWindows.clear(); - rRowColumnWindowData.aRowColumnWindowSizes.clear(); - rRowColumnWindowData.aRowColumnSpace.clear(); - rRowColumnWindowData.nVarSize = 0; - rRowColumnWindowData.nStaticSize = 0; - rRowColumnWindowData.nSpace = 0; - rRowColumnWindowData.nRowColumn = nRowCol; - - // Collect data from windows that are on the same row/column - sal_Int32 j; - sal_Int32 nLastPos( 0 ); - - const sal_uInt32 nCount = aWindowVector.size(); - for ( j = 0; j < sal_Int32( nCount); j++ ) - { - const UIElement& rElement = aWindowVector[j]; - Reference< css::awt::XWindow > xWindow; - Reference< XUIElement > xUIElement( rElement.m_xUIElement ); - css::awt::Rectangle aPosSize; - if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) ) - continue; - - sal_Int32 nSpace; - if (( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )) - { - nSpace = ( rElement.m_aDockedData.m_aPos.X() - nLastPos ); - - // Calc space before an element and store it - if ( rElement.m_aDockedData.m_aPos.X() > nLastPos ) - rRowColumnWindowData.nSpace += nSpace; - else - nSpace = 0; - - nLastPos = rElement.m_aDockedData.m_aPos.X() + aPosSize.Width; - - - rRowColumnWindowData.aRowColumnWindowSizes.push_back( - css::awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), - rElement.m_aDockedData.m_aPos.Y(), - aPosSize.Width, - aPosSize.Height )); - if ( rRowColumnWindowData.nStaticSize < aPosSize.Height ) - rRowColumnWindowData.nStaticSize = aPosSize.Height; - rRowColumnWindowData.nVarSize += aPosSize.Width; - } - else - { - // Calc space before an element and store it - nSpace = ( rElement.m_aDockedData.m_aPos.Y() - nLastPos ); - if ( rElement.m_aDockedData.m_aPos.Y() > nLastPos ) - rRowColumnWindowData.nSpace += nSpace; - else - nSpace = 0; - - nLastPos = rElement.m_aDockedData.m_aPos.Y() + aPosSize.Height; - - rRowColumnWindowData.aRowColumnWindowSizes.push_back( - css::awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), - rElement.m_aDockedData.m_aPos.Y(), - aPosSize.Width, - aPosSize.Height )); - if ( rRowColumnWindowData.nStaticSize < aPosSize.Width ) - rRowColumnWindowData.nStaticSize = aPosSize.Width; - rRowColumnWindowData.nVarSize += aPosSize.Height; - } - - rRowColumnWindowData.aUIElementNames.push_back( rElement.m_aName ); - rRowColumnWindowData.aRowColumnWindows.push_back( xWindow ); - rRowColumnWindowData.aRowColumnSpace.push_back( nSpace ); - rRowColumnWindowData.nVarSize += nSpace; - } -} - -::Rectangle LayoutManager::implts_determineFrontDockingRect( - DockingArea eDockingArea, - sal_Int32 nRowCol, - const ::Rectangle& rDockedElementRect, - const ::rtl::OUString& rMovedElementName, - const ::Rectangle& rMovedElementRect ) -{ - SingleRowColumnWindowData aRowColumnWindowData; - - sal_Bool bHorzDockArea = (( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )); - - implts_getDockingAreaElementInfoOnSingleRowCol( eDockingArea, nRowCol, aRowColumnWindowData ); - if ( aRowColumnWindowData.aRowColumnWindows.empty() ) - return rMovedElementRect; - else - { - sal_Int32 nSpace( 0 ); - ::Rectangle aFrontDockingRect( rMovedElementRect ); - const sal_uInt32 nCount = aRowColumnWindowData.aRowColumnWindows.size(); - for ( sal_uInt32 i = 0; i < nCount; i++ ) - { - if ( bHorzDockArea ) - { - if ( aRowColumnWindowData.aRowColumnWindowSizes[i].X >= rDockedElementRect.Left() ) - { - nSpace += aRowColumnWindowData.aRowColumnSpace[i]; - break; - } - else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName ) - nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Width + - aRowColumnWindowData.aRowColumnSpace[i]; - else - nSpace = 0; - } - else - { - if ( aRowColumnWindowData.aRowColumnWindowSizes[i].Y >= rDockedElementRect.Top() ) - { - nSpace += aRowColumnWindowData.aRowColumnSpace[i]; - break; - } - else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName ) - nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Height + - aRowColumnWindowData.aRowColumnSpace[i]; - else - nSpace = 0; - } - } - - if ( nSpace > 0 ) - { - sal_Int32 nMove = std::min( nSpace, static_cast<sal_Int32>(aFrontDockingRect.getWidth()) ); - if ( bHorzDockArea ) - aFrontDockingRect.Move( -nMove, 0 ); - else - aFrontDockingRect.Move( 0, -nMove ); - } - - return aFrontDockingRect; - } -} - -::Rectangle LayoutManager::implts_getWindowRectFromRowColumn( - ::com::sun::star::ui::DockingArea DockingArea, - const SingleRowColumnWindowData& rRowColumnWindowData, - const ::Point& rMousePos, - const rtl::OUString& rExcludeElementName ) -{ - ::Rectangle aWinRect; - - if (( DockingArea < DockingArea_DOCKINGAREA_TOP ) || - ( DockingArea > DockingArea_DOCKINGAREA_RIGHT )) - DockingArea = DockingArea_DOCKINGAREA_TOP; - - if ( rRowColumnWindowData.aRowColumnWindows.empty() ) - return aWinRect; - else - { - ReadGuard aReadLock( m_aLock ); - Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow; - Reference< css::awt::XWindow > xDockingAreaWindow = m_xDockAreaWindows[DockingArea]; - aReadLock.unlock(); - - // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect - vos::OGuard aGuard( Application::GetSolarMutex() ); - - // Retrieve output size from container Window - Window* pContainerWindow( VCLUnoHelper::GetWindow( xContainerWindow )); - Window* pDockingAreaWindow( VCLUnoHelper::GetWindow( xDockingAreaWindow )); - if ( pDockingAreaWindow && pContainerWindow ) - { - const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindows.size(); - for ( sal_uInt32 i = 0; i < nCount; i++ ) - { - css::awt::Rectangle aWindowRect = rRowColumnWindowData.aRowColumnWindows[i]->getPosSize(); - ::Rectangle aRect( aWindowRect.X, aWindowRect.Y, aWindowRect.X+aWindowRect.Width, aWindowRect.Y+aWindowRect.Height ); - aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() ))); - if ( aRect.IsInside( rMousePos )) - { - // Check if we have found the excluded element. If yes, we have to provide an empty rectangle. - // We prevent that a toolbar cannot be moved when the mouse pointer is inside its own rectangle! - if ( rExcludeElementName != rRowColumnWindowData.aUIElementNames[i] ) - return aRect; - else - break; - } - } - } - } - - return aWinRect; -} - -framework::LayoutManager::DockingOperation -LayoutManager::implts_determineDockingOperation( - ::com::sun::star::ui::DockingArea DockingArea, - const ::Rectangle& rRowColRect, - const Point& rMousePos ) -{ - const sal_Int32 nHorzVerticalRegionSize = 6; - const sal_Int32 nHorzVerticalMoveRegion = 4; - - if ( rRowColRect.IsInside( rMousePos )) - { - if (( DockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( DockingArea == DockingArea_DOCKINGAREA_BOTTOM )) - { - sal_Int32 nRegion = rRowColRect.getHeight() / nHorzVerticalRegionSize; - sal_Int32 nPosY = rRowColRect.Top() + nRegion; - - if ( rMousePos.Y() < nPosY ) - return ( DockingArea == DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW; - else if ( rMousePos.Y() < ( nPosY + nRegion*nHorzVerticalMoveRegion )) - return DOCKOP_ON_COLROW; - else - return ( DockingArea == DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW; - } - else - { - sal_Int32 nRegion = rRowColRect.getWidth() / nHorzVerticalRegionSize; - sal_Int32 nPosX = rRowColRect.Left() + nRegion; - - if ( rMousePos.X() < nPosX ) - return ( DockingArea == DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW; - else if ( rMousePos.X() < ( nPosX + nRegion*nHorzVerticalMoveRegion )) - return DOCKOP_ON_COLROW; - else - return ( DockingArea == DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW; - } - } - else - return DOCKOP_ON_COLROW; -} - -::Rectangle LayoutManager::implts_calcTrackingAndElementRect( - ::com::sun::star::ui::DockingArea eDockingArea, - sal_Int32 nRowCol, - UIElement& rUIElement, - const ::Rectangle& rTrackingRect, - const ::Rectangle& rRowColumnRect, - const ::Size& rContainerWinSize ) -{ - sal_Bool bHorizontalDockArea( ( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )); - - sal_Int32 nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() ); - sal_Int32 nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() ); - - ::Size aStatusBarSize( implts_getStatusBarSize() ); - sal_Int32 nMaxLeftRightDockAreaSize = rContainerWinSize.Height() - - nTopDockingAreaSize - - nBottomDockingAreaSize - - aStatusBarSize.Height(); - - ::Rectangle aTrackingRect( rTrackingRect ); - if ( bHorizontalDockArea ) - { - sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 ))); - if (( nPosX + rTrackingRect.getWidth()) > rContainerWinSize.Width() ) - nPosX = std::min( nPosX, - std::max( sal_Int32( rContainerWinSize.Width() - rTrackingRect.getWidth() ), - sal_Int32( 0 ))); - - sal_Int32 nSize = std::min( rContainerWinSize.Width(), rTrackingRect.getWidth() ); - - aTrackingRect.SetPos( ::Point( nPosX, rRowColumnRect.Top() )); - aTrackingRect.setWidth( nSize ); - aTrackingRect.setHeight( rRowColumnRect.getHeight() ); - - // Set virtual position - rUIElement.m_aDockedData.m_aPos.X() = nPosX; - rUIElement.m_aDockedData.m_aPos.Y() = nRowCol; - } - else - { - sal_Int32 nMaxDockingAreaHeight = std::max( sal_Int32( 0 ), - sal_Int32( nMaxLeftRightDockAreaSize )); - - sal_Int32 nPosY( std::max( sal_Int32( aTrackingRect.Top()), sal_Int32( nTopDockingAreaSize ))); - if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight )) - nPosY = std::min( nPosY, - std::max( sal_Int32( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() )), - sal_Int32( nTopDockingAreaSize ))); - - sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) ); - - aTrackingRect.SetPos( ::Point( rRowColumnRect.Left(), nPosY )); - aTrackingRect.setWidth( rRowColumnRect.getWidth() ); - aTrackingRect.setHeight( nSize ); - - ReadGuard aReadLock( m_aLock ); - Reference< css::awt::XWindow > xDockingAreaWindow = m_xDockAreaWindows[eDockingArea]; - Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow; - aReadLock.unlock(); - - sal_Int32 nDockPosY( 0 ); - Window* pDockingAreaWindow( 0 ); - Window* pContainerWindow( 0 ); - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow ); - pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); - nDockPosY = pDockingAreaWindow->ScreenToOutputPixel( - pContainerWindow->OutputToScreenPixel( ::Point( 0, nPosY ))).Y(); - } - - // Set virtual position - rUIElement.m_aDockedData.m_aPos.X() = nRowCol; - rUIElement.m_aDockedData.m_aPos.Y() = nDockPosY; - } - - return aTrackingRect; -} - -void implts_setTrackingRect( DockingArea eDockingArea, const Point& rMousePos, ::Rectangle& rTrackingRect ) -{ - sal_Bool bHorizontalDockArea( ( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )); - - ::Point aPoint = rTrackingRect.TopLeft(); - if ( bHorizontalDockArea ) - aPoint.X() = rMousePos.X(); - else - aPoint.Y() = rMousePos.Y(); - rTrackingRect.SetPos( aPoint ); -} - -void LayoutManager::implts_calcDockingPosSize( - UIElement& rUIElement, - DockingOperation& rDockingOperation, - ::Rectangle& rTrackingRect, - const Point& rMousePos ) -{ - ReadGuard aReadLock( m_aLock ); - Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow; - ::Size aContainerWinSize; - Window* pContainerWindow( 0 ); - aReadLock.unlock(); - - { - // Retrieve output size from container Window - vos::OGuard aGuard( Application::GetSolarMutex() ); - pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); - aContainerWinSize = pContainerWindow->GetOutputSizePixel(); - } - - if ( !rUIElement.m_xUIElement.is() ) - { - rTrackingRect = ::Rectangle(); - return; - } - - Window* pDockWindow( 0 ); - Window* pDockingAreaWindow( 0 ); - ToolBox* pToolBox( 0 ); - Reference< css::awt::XWindow > xWindow( rUIElement.m_xUIElement->getRealInterface(), UNO_QUERY ); - Reference< css::awt::XWindow > xDockingAreaWindow; - ::Rectangle aTrackingRect( rTrackingRect ); - ::com::sun::star::ui::DockingArea eDockedArea( (::com::sun::star::ui::DockingArea)rUIElement.m_aDockedData.m_nDockedArea ); - sal_Int32 nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() ); - sal_Int32 nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() ); - sal_Bool bHorizontalDockArea( ( eDockedArea == DockingArea_DOCKINGAREA_TOP ) || - ( eDockedArea == DockingArea_DOCKINGAREA_BOTTOM )); - ::Size aStatusBarSize( implts_getStatusBarSize() ); - sal_Int32 nMaxLeftRightDockAreaSize = aContainerWinSize.Height() - - nTopDockingAreaSize - - nBottomDockingAreaSize - - aStatusBarSize.Height(); - ::Rectangle aDockingAreaRect; - - aReadLock.lock(); - xDockingAreaWindow = m_xDockAreaWindows[eDockedArea]; - aReadLock.unlock(); - - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow ); - pDockWindow = VCLUnoHelper::GetWindow( xWindow ); - if ( pDockWindow && pDockWindow->GetType() == WINDOW_TOOLBOX ) - pToolBox = (ToolBox *)pDockWindow; - - aDockingAreaRect = ::Rectangle( pDockingAreaWindow->GetPosPixel(), pDockingAreaWindow->GetSizePixel() ); - if ( pToolBox ) - { - // docked toolbars always have one line - ::Size aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( sal_Int16( eDockedArea )) ); - aTrackingRect.SetSize( ::Size( aSize.Width(), aSize.Height() )); - } - } - - // default docking operation, dock on the given row/column - sal_Bool bOpOutsideOfDockingArea( !aDockingAreaRect.IsInside( rMousePos )); - std::vector< SingleRowColumnWindowData > aRowColumnsWindowData; - - rDockingOperation = DOCKOP_ON_COLROW; - implts_getDockingAreaElementInfos( eDockedArea, aRowColumnsWindowData ); - - // determine current first row/column and last row/column - sal_Int32 nMaxRowCol( -1 ); - sal_Int32 nMinRowCol( SAL_MAX_INT32 ); - const sal_uInt32 nCount = aRowColumnsWindowData.size(); - for ( sal_uInt32 i = 0; i < nCount; i++ ) - { - if ( aRowColumnsWindowData[i].nRowColumn > nMaxRowCol ) - nMaxRowCol = aRowColumnsWindowData[i].nRowColumn; - if ( aRowColumnsWindowData[i].nRowColumn < nMinRowCol ) - nMinRowCol = aRowColumnsWindowData[i].nRowColumn; - } - - if ( !bOpOutsideOfDockingArea ) - { - // docking inside our docking area - sal_Int32 nIndex( -1 ); - sal_Int32 nRowCol( -1 ); - ::Rectangle aWindowRect; - ::Rectangle aRowColumnRect; - - const sal_uInt32 nWindowDataCount = aRowColumnsWindowData.size(); - for ( sal_uInt32 i = 0; i < nWindowDataCount; i++ ) - { - ::Rectangle aRect( aRowColumnsWindowData[i].aRowColumnRect.X, - aRowColumnsWindowData[i].aRowColumnRect.Y, - aRowColumnsWindowData[i].aRowColumnRect.X + aRowColumnsWindowData[i].aRowColumnRect.Width, - aRowColumnsWindowData[i].aRowColumnRect.Y + aRowColumnsWindowData[i].aRowColumnRect.Height ); - - { - // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect - vos::OGuard aGuard( Application::GetSolarMutex() ); - aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() ))); - } - - sal_Bool bIsInsideRowCol( aRect.IsInside( rMousePos ) ); - if ( bIsInsideRowCol ) - { - nIndex = i; - nRowCol = aRowColumnsWindowData[i].nRowColumn; - rDockingOperation = implts_determineDockingOperation( eDockedArea, aRect, rMousePos ); - aWindowRect = implts_getWindowRectFromRowColumn( eDockedArea, aRowColumnsWindowData[i], rMousePos, rUIElement.m_aName ); - aRowColumnRect = aRect; - break; - } - } - - OSL_ENSURE( ( nIndex >= 0 ) && ( nRowCol >= 0 ), "Impossible case - no row/column found but mouse pointer is inside our docking area" ); - if (( nIndex >= 0 ) && ( nRowCol >= 0 )) - { - if ( rDockingOperation == DOCKOP_ON_COLROW ) - { - if ( !aWindowRect.IsEmpty()) - { - // Tracking rect is on a row/column and mouse is over a docked toolbar. - // Determine if the tracking rect must be located before/after the docked toolbar. - - ::Rectangle aUIElementRect( aWindowRect ); - sal_Int32 nMiddle( bHorizontalDockArea ? ( aWindowRect.Left() + aWindowRect.getWidth() / 2 ) : - ( aWindowRect.Top() + aWindowRect.getHeight() / 2 )); - sal_Bool bInsertBefore( bHorizontalDockArea ? ( rMousePos.X() < nMiddle ) : ( rMousePos.Y() < nMiddle )); - if ( bInsertBefore ) - { - if ( bHorizontalDockArea ) - { - sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( aContainerWinSize.Width() - aWindowRect.Left() ), - sal_Int32( aTrackingRect.getWidth() ))); - if ( nSize == 0 ) - nSize = aWindowRect.getWidth(); - - aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() )); - aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect,rUIElement.m_aName, aUIElementRect ); - - // Set virtual position - rUIElement.m_aDockedData.m_aPos.X() = aWindowRect.Left(); - rUIElement.m_aDockedData.m_aPos.Y() = nRowCol; - } - else - { - sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( - nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Top() ), - sal_Int32( aTrackingRect.getHeight() ))); - if ( nSize == 0 ) - nSize = aWindowRect.getHeight(); - - aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize )); - aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect, rUIElement.m_aName, aUIElementRect ); - - // Set virtual position - sal_Int32 nPosY = pDockingAreaWindow->ScreenToOutputPixel( - pContainerWindow->OutputToScreenPixel( aWindowRect.TopLeft() )).Y(); - rUIElement.m_aDockedData.m_aPos.X() = nRowCol; - rUIElement.m_aDockedData.m_aPos.Y() = nPosY; - } - - rTrackingRect = aWindowRect; - return; - } - else - { - if ( bHorizontalDockArea ) - { - sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32(( aContainerWinSize.Width() ) - aWindowRect.Right() ), - sal_Int32( aTrackingRect.getWidth() ))); - if ( nSize == 0 ) - { - aUIElementRect.SetPos( ::Point( aContainerWinSize.Width() - aTrackingRect.getWidth(), aWindowRect.Top() )); - aUIElementRect.SetSize( ::Size( aTrackingRect.getWidth(), aWindowRect.getHeight() )); - rUIElement.m_aDockedData.m_aPos.X() = aUIElementRect.Left(); - } - else - { - aUIElementRect.SetPos( ::Point( aWindowRect.Right(), aWindowRect.Top() )); - aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() )); - rUIElement.m_aDockedData.m_aPos.X() = aWindowRect.Right(); - } - - // Set virtual position - rUIElement.m_aDockedData.m_aPos.Y() = nRowCol; - } - else - { - sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Bottom() ), - sal_Int32( aTrackingRect.getHeight() ))); - aUIElementRect.SetPos( ::Point( aWindowRect.Left(), aWindowRect.Bottom() )); - aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize )); - - // Set virtual position - sal_Int32 nPosY( 0 ); - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - nPosY = pDockingAreaWindow->ScreenToOutputPixel( - pContainerWindow->OutputToScreenPixel( aWindowRect.BottomRight() )).Y(); - } - rUIElement.m_aDockedData.m_aPos.X() = nRowCol; - rUIElement.m_aDockedData.m_aPos.Y() = nPosY; - } - - rTrackingRect = aUIElementRect; - return; - } - } - else - { - implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect ); - rTrackingRect = implts_calcTrackingAndElementRect( - eDockedArea, nRowCol, rUIElement, - aTrackingRect, aRowColumnRect, aContainerWinSize ); - return; - } - } - else - { - if ((( nRowCol == nMinRowCol ) && ( rDockingOperation == DOCKOP_BEFORE_COLROW )) || - (( nRowCol == nMaxRowCol ) && ( rDockingOperation == DOCKOP_AFTER_COLROW ))) - bOpOutsideOfDockingArea = sal_True; - else - { - // handle docking before/after a row - implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect ); - rTrackingRect = implts_calcTrackingAndElementRect( - eDockedArea, nRowCol, rUIElement, - aTrackingRect, aRowColumnRect, aContainerWinSize ); - - sal_Int32 nOffsetX( 0 ); - sal_Int32 nOffsetY( 0 ); - if ( bHorizontalDockArea ) - nOffsetY = sal_Int32( floor( aRowColumnRect.getHeight() / 2 + 0.5 )); - else - nOffsetX = sal_Int32( floor( aRowColumnRect.getWidth() / 2 + 0.5 )); - - if ( rDockingOperation == DOCKOP_BEFORE_COLROW ) - { - if (( eDockedArea == DockingArea_DOCKINGAREA_TOP ) || - ( eDockedArea == DockingArea_DOCKINGAREA_LEFT )) - { - // Docking before/after means move track rectangle half column/row. - // As left and top are ordered 0...n instead of right and bottom - // which uses n...0, we have to use negative values for top/left. - nOffsetX *= -1; - nOffsetY *= -1; - } - } - else - { - if (( eDockedArea == DockingArea_DOCKINGAREA_BOTTOM ) || - ( eDockedArea == DockingArea_DOCKINGAREA_RIGHT )) - { - // Docking before/after means move track rectangle half column/row. - // As left and top are ordered 0...n instead of right and bottom - // which uses n...0, we have to use negative values for top/left. - nOffsetX *= -1; - nOffsetY *= -1; - } - nRowCol++; - } - - if ( bHorizontalDockArea ) - rUIElement.m_aDockedData.m_aPos.Y() = nRowCol; - else - rUIElement.m_aDockedData.m_aPos.X() = nRowCol; - - rTrackingRect.Move( nOffsetX, nOffsetY ); - rTrackingRect.SetSize( aTrackingRect.GetSize() ); - } - } - } - } - - // Docking outside of our docking window area => - // Users want to dock before/after first/last docked element or to an empty docking area - if ( bOpOutsideOfDockingArea ) - { - // set correct size for docking - implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect ); - rTrackingRect = aTrackingRect; - - if ( bHorizontalDockArea ) - { - sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 ))); - if (( nPosX + rTrackingRect.getWidth()) > aContainerWinSize.Width() ) - nPosX = std::min( nPosX, - std::max( sal_Int32( aContainerWinSize.Width() - rTrackingRect.getWidth() ), - sal_Int32( 0 ))); - - sal_Int32 nSize = std::min( aContainerWinSize.Width(), rTrackingRect.getWidth() ); - sal_Int32 nDockHeight = std::max( static_cast<sal_Int32>(aDockingAreaRect.getHeight()), sal_Int32( 0 )); - if ( nDockHeight == 0 ) - { - sal_Int32 nPosY( std::max( aDockingAreaRect.Top(), aDockingAreaRect.Bottom() )); - if ( eDockedArea == DockingArea_DOCKINGAREA_BOTTOM ) - nPosY -= rTrackingRect.getHeight(); - rTrackingRect.SetPos( Point( nPosX, nPosY )); - rUIElement.m_aDockedData.m_aPos.Y() = 0; - } - else if ( rMousePos.Y() < ( aDockingAreaRect.Top() + ( nDockHeight / 2 ))) - { - rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Top() - rTrackingRect.getHeight() )); - if ( eDockedArea == DockingArea_DOCKINGAREA_TOP ) - rUIElement.m_aDockedData.m_aPos.Y() = 0; - else - rUIElement.m_aDockedData.m_aPos.Y() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; - rDockingOperation = DOCKOP_BEFORE_COLROW; - } - else - { - rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Bottom() )); - if ( eDockedArea == DockingArea_DOCKINGAREA_TOP ) - rUIElement.m_aDockedData.m_aPos.Y() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; - else - rUIElement.m_aDockedData.m_aPos.Y() = 0; - rDockingOperation = DOCKOP_AFTER_COLROW; - } - rTrackingRect.setWidth( nSize ); - - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - nPosX = pDockingAreaWindow->ScreenToOutputPixel( - pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).X(); - } - rUIElement.m_aDockedData.m_aPos.X() = nPosX; - } - else - { - sal_Int32 nMaxDockingAreaHeight = std::max( sal_Int32( 0 ), - sal_Int32( nMaxLeftRightDockAreaSize )); - - sal_Int32 nPosY( std::max( sal_Int32( aTrackingRect.Top()), sal_Int32( nTopDockingAreaSize ))); - if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight )) - nPosY = std::min( nPosY, - std::max( sal_Int32( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() )), - sal_Int32( nTopDockingAreaSize ))); - - sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) ); - sal_Int32 nDockWidth = std::max( static_cast<sal_Int32>(aDockingAreaRect.getWidth()), sal_Int32( 0 )); - if ( nDockWidth == 0 ) - { - sal_Int32 nPosX( std::max( aDockingAreaRect.Left(), aDockingAreaRect.Right() )); - if ( eDockedArea == DockingArea_DOCKINGAREA_RIGHT ) - nPosX -= rTrackingRect.getWidth(); - rTrackingRect.SetPos( Point( nPosX, nPosY )); - rUIElement.m_aDockedData.m_aPos.X() = 0; - } - else if ( rMousePos.X() < ( aDockingAreaRect.Left() + ( nDockWidth / 2 ))) - { - rTrackingRect.SetPos( Point( aDockingAreaRect.Left() - rTrackingRect.getWidth(), nPosY )); - if ( eDockedArea == DockingArea_DOCKINGAREA_LEFT ) - rUIElement.m_aDockedData.m_aPos.X() = 0; - else - rUIElement.m_aDockedData.m_aPos.X() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; - rDockingOperation = DOCKOP_BEFORE_COLROW; - } - else - { - rTrackingRect.SetPos( Point( aDockingAreaRect.Right(), nPosY )); - if ( eDockedArea == DockingArea_DOCKINGAREA_LEFT ) - rUIElement.m_aDockedData.m_aPos.X() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; - else - rUIElement.m_aDockedData.m_aPos.X() = 0; - rDockingOperation = DOCKOP_AFTER_COLROW; - } - rTrackingRect.setHeight( nSize ); - - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - nPosY = pDockingAreaWindow->ScreenToOutputPixel( - pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).Y(); - } - rUIElement.m_aDockedData.m_aPos.Y() = nPosY; - } - } -} - -void LayoutManager::implts_renumberRowColumnData( - ::com::sun::star::ui::DockingArea eDockingArea, - DockingOperation /*eDockingOperation*/, - const UIElement& rUIElement ) -{ - ReadGuard aReadLock( m_aLock ); - Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); - aReadLock.unlock(); - - sal_Bool bHorzDockingArea(( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )); - sal_Int32 nRowCol( bHorzDockingArea ? rUIElement.m_aDockedData.m_aPos.Y() : - rUIElement.m_aDockedData.m_aPos.X() ); - - WriteGuard aWriteLock( m_aLock ); - UIElementVector::iterator pIter; - for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) - { - if (( pIter->m_aDockedData.m_nDockedArea == sal_Int16( eDockingArea )) && - ( pIter->m_aName != rUIElement.m_aName )) - { - // Don't change toolbars without a valid docking position! - if (( pIter->m_aDockedData.m_aPos.X() == SAL_MAX_INT32 ) && - ( pIter->m_aDockedData.m_aPos.Y() == SAL_MAX_INT32 )) - continue; - - sal_Int32 nWindowRowCol = ( bHorzDockingArea ) ? - pIter->m_aDockedData.m_aPos.Y() : pIter->m_aDockedData.m_aPos.X(); - if ( nWindowRowCol >= nRowCol ) - { - if ( bHorzDockingArea ) - pIter->m_aDockedData.m_aPos.Y() += 1; - else - pIter->m_aDockedData.m_aPos.X() += 1; - } - } - } - aWriteLock.unlock(); - - // We have to change the persistent window state part - if ( xPersistentWindowState.is() ) - { - try - { - Sequence< rtl::OUString > aWindowElements = xPersistentWindowState->getElementNames(); - for ( sal_Int32 i = 0; i < aWindowElements.getLength(); i++ ) - { - if ( rUIElement.m_aName != aWindowElements[i] ) - { - try - { - Sequence< PropertyValue > aPropValueSeq; - css::awt::Point aDockedPos; - DockingArea nDockedArea( DockingArea_DOCKINGAREA_DEFAULT ); - - xPersistentWindowState->getByName( aWindowElements[i] ) >>= aPropValueSeq; - for ( sal_Int32 j = 0; j < aPropValueSeq.getLength(); j++ ) - { - if ( aPropValueSeq[j].Name == m_aPropDockingArea ) - aPropValueSeq[j].Value >>= nDockedArea; - else if ( aPropValueSeq[j].Name == m_aPropDockPos ) - aPropValueSeq[j].Value >>= aDockedPos; - } - - // Don't change toolbars without a valid docking position! - if (( aDockedPos.X == SAL_MAX_INT32 ) && ( aDockedPos.Y == SAL_MAX_INT32 )) - continue; - - sal_Int32 nWindowRowCol = ( bHorzDockingArea ) ? aDockedPos.Y : aDockedPos.X; - if (( nDockedArea == eDockingArea ) && ( nWindowRowCol >= nRowCol )) - { - if ( bHorzDockingArea ) - aDockedPos.Y += 1; - else - aDockedPos.X += 1; - - Reference< XNameReplace > xReplace( xPersistentWindowState, UNO_QUERY ); - xReplace->replaceByName( aWindowElements[i], makeAny( aPropValueSeq )); - } - } - catch ( Exception& ) - { - } - } - } - } - catch ( Exception& ) - { - } - } -} - -::Size LayoutManager::implts_getTopBottomDockingAreaSizes() -{ - ::Size aSize; - Reference< css::awt::XWindow > xTopDockingAreaWindow; - Reference< css::awt::XWindow > xBottomDockingAreaWindow; - - ReadGuard aReadLock( m_aLock ); - xTopDockingAreaWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP]; - xBottomDockingAreaWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM]; - aReadLock.unlock(); - - if ( xTopDockingAreaWindow.is() ) - aSize.Width() = xTopDockingAreaWindow->getPosSize().Height; - if ( xBottomDockingAreaWindow.is() ) - aSize.Height() = xBottomDockingAreaWindow->getPosSize().Height; - - return aSize; -} - Reference< XUIElement > LayoutManager::implts_createElement( const rtl::OUString& aName ) { Reference< ::com::sun::star::ui::XUIElement > xUIElement; @@ -3064,28 +1091,6 @@ Reference< XUIElement > LayoutManager::implts_createElement( const rtl::OUString return xUIElement; } -Reference< css::awt::XWindowPeer > LayoutManager::implts_createToolkitWindow( const Reference< css::awt::XWindowPeer >& rParent ) -{ - Reference< css::awt::XWindowPeer > xPeer; - css::uno::Reference< css::awt::XToolkit > xToolkit( m_xSMGR->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY ); - if ( xToolkit.is() ) - { - // describe window properties. - css::awt::WindowDescriptor aDescriptor; - aDescriptor.Type = css::awt::WindowClass_SIMPLE ; - aDescriptor.WindowServiceName = DECLARE_ASCII("dockingarea") ; - aDescriptor.ParentIndex = -1 ; - aDescriptor.Parent = css::uno::Reference< css::awt::XWindowPeer >( rParent, UNO_QUERY ) ; - aDescriptor.Bounds = css::awt::Rectangle(0,0,0,0) ; - aDescriptor.WindowAttributes = 0 ; - - // create a docking area window - xPeer = xToolkit->createWindow( aDescriptor ); - } - - return xPeer; -} - void LayoutManager::implts_setVisibleState( sal_Bool bShow ) { /* SAFE AREA ----------------------------------------------------------------------------------------------- */ @@ -3210,7 +1215,7 @@ void LayoutManager::implts_updateUIElementsVisibleState( sal_Bool bSetVisible ) if ( bSetVisible ) { - implts_createNonContextSensitiveToolBars(); + m_pToolbarManager->implts_createNonContextSensitiveToolBars(); implts_doLayout_notify( sal_False ); } else @@ -3771,28 +1776,17 @@ throw ( RuntimeException ) if ( xWindow.is() && ( m_xFrame->getContainerWindow() != m_xContainerWindow || !xDockingAreaAcceptor.is() ) ) xWindow->removeWindowListener( Reference< css::awt::XWindowListener >( static_cast< OWeakObject * >( this ), UNO_QUERY )); - oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP] ); - oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM] ); - oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT] ); - oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT] ); - - m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP].clear(); - m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM].clear(); - m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT].clear(); - m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT].clear(); m_aDockingArea = css::awt::Rectangle(); + m_pToolbarManager->reset(); Window* pContainerWindow = VCLUnoHelper::GetWindow( xWindow ); if ( pContainerWindow ) pContainerWindow->RemoveChildEventListener( LINK( this, LayoutManager, WindowEventListener ) ); - } - // Set new docking area acceptor and add ourself as window listener on the container window. - // Create our docking area windows which are parents for all docked windows. - css::uno::Reference< css::awt::XWindow > xTopDockWindow; - css::uno::Reference< css::awt::XWindow > xBottomDockWindow; - css::uno::Reference< css::awt::XWindow > xLeftDockWindow; - css::uno::Reference< css::awt::XWindow > xRightDockWindow; + // destroy panel manager + delete m_pPanelManager; + m_pPanelManager = NULL; + } Reference< ::com::sun::star::ui::XDockingAreaAcceptor > xOldDockingAreaAcceptor( m_xDockingAreaAcceptor ); m_xDockingAreaAcceptor = xDockingAreaAcceptor; @@ -3817,14 +1811,11 @@ throw ( RuntimeException ) } css::uno::Reference< css::awt::XWindowPeer > xParent( m_xContainerWindow, UNO_QUERY ); - xTopDockWindow = Reference< css::awt::XWindow >( implts_createToolkitWindow( xParent ), UNO_QUERY ); - xBottomDockWindow = Reference< css::awt::XWindow >( implts_createToolkitWindow( xParent ), UNO_QUERY ); - xLeftDockWindow = Reference< css::awt::XWindow >( implts_createToolkitWindow( xParent ), UNO_QUERY ); - xRightDockWindow = Reference< css::awt::XWindow >( implts_createToolkitWindow( xParent ), UNO_QUERY ); - m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP] = xTopDockWindow; - m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM] = xBottomDockWindow; - m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT] = xLeftDockWindow; - m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT] = xRightDockWindow; + m_pToolbarManager->setParentWindow( xParent ); + + // create new panel manager + m_pPanelManager = new PanelManager( m_xSMGR, m_xFrame ); + m_pPanelManager->createPanels(); } aWriteLock.unlock(); @@ -3833,15 +1824,6 @@ throw ( RuntimeException ) if ( xDockingAreaAcceptor.is() ) { vos::OGuard aGuard( Application::GetSolarMutex() ); - ::DockingAreaWindow* pWindow; - pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xTopDockWindow ) ); - if( pWindow ) pWindow->SetAlign( WINDOWALIGN_TOP ); - pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xBottomDockWindow ) ); - if( pWindow ) pWindow->SetAlign( WINDOWALIGN_BOTTOM ); - pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xLeftDockWindow ) ); - if( pWindow ) pWindow->SetAlign( WINDOWALIGN_LEFT ); - pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xRightDockWindow ) ); - if( pWindow ) pWindow->SetAlign( WINDOWALIGN_RIGHT ); // Add layout manager as listener to get notifications about toolbar button activties Window* pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); @@ -3856,21 +1838,6 @@ throw ( RuntimeException ) if ( !oldDockingAreaWindows.empty() ) { - const sal_uInt32 nCount = oldDockingAreaWindows.size(); - for ( sal_uInt32 i = 0; i < nCount; ++i ) - { - if ( oldDockingAreaWindows[i].is() ) - { - try - { - oldDockingAreaWindows[i]->dispose(); - } - catch ( Exception& ) - { - } - } - } - // Reset docking area size for our old docking area acceptor css::awt::Rectangle aEmptyRect; xOldDockingAreaAcceptor->setDockingAreaSpace( aEmptyRect ); @@ -3879,11 +1846,7 @@ throw ( RuntimeException ) if ( xDockingAreaAcceptor.is() ) { if ( bAutomaticToolbars ) - { - implts_createAddonsToolBars(); // create addon toolbars - implts_createCustomToolBars(); // create custom toolbars - implts_createNonContextSensitiveToolBars(); - } + m_pToolbarManager->createToolbars(); implts_sortUIElements(); implts_doLayout( sal_True, sal_False ); } @@ -3988,6 +1951,12 @@ void LayoutManager::implts_reparentChildWindows() } } +uno::Reference< ui::XUIElement > LayoutManager::implts_createDockingWindow( const ::rtl::OUString& aElementName ) +{ + Reference< XUIElement > xUIElement = implts_createElement( aElementName ); + return xUIElement; +} + IMPL_LINK( LayoutManager, WindowEventListener, VclSimpleEvent*, pEvent ) { // To enable toolbar controllers to change their image when a sub-toolbar function @@ -4098,84 +2067,22 @@ throw (RuntimeException) /* SAFE AREA ----------------------------------------------------------------------------------------------- */ WriteGuard aWriteLock( m_aLock ); - sal_Bool bFound( sal_False ); - sal_Bool bNotify( sal_False ); - ::rtl::OUString aElementType; - ::rtl::OUString aElementName; - Reference< ::com::sun::star::ui::XUIElement > xUIElement; - - implts_findElement( aName, aElementType, aElementName, xUIElement ); - bFound = xUIElement.is(); + bool bMustBeLayouted( false ); + bool bNotify( false ); - if ( /*xFrame.is() && */m_xContainerWindow.is() && !implts_isPreviewModel( xModel ) ) // no bars on preview mode + if ( m_xContainerWindow.is() && !implts_isPreviewModel( xModel ) ) // no UI elements on preview frames { + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + impl_parseResourceURL( aName, aElementType, aElementName ); + if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" )) { - if ( !bFound ) + if ( m_pToolbarManager != NULL ) { - SvtCommandOptions aCmdOptions; - - xUIElement = implts_createElement( aName ); - sal_Bool bVisible( sal_False ); - if ( xUIElement.is() ) - { - Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); - Reference< css::awt::XDockableWindow > xDockWindow( xUIElement->getRealInterface(), UNO_QUERY ); - if ( xDockWindow.is() && xWindow.is() ) - { - try - { - xDockWindow->addDockableWindowListener( Reference< css::awt::XDockableWindowListener >( - static_cast< OWeakObject * >( this ), UNO_QUERY )); - xWindow->addWindowListener( Reference< css::awt::XWindowListener >( - static_cast< OWeakObject * >( this ), UNO_QUERY )); - xDockWindow->enableDocking( sal_True ); - } - catch ( Exception& ) - { - } - } - - UIElement& rElement = impl_findElement( aName ); - if ( rElement.m_aName.getLength() > 0 ) - { - // Reuse a local entry so we are able to use the latest - // UI changes for this document. - implts_setElementData( rElement, xDockWindow ); - rElement.m_xUIElement = xUIElement; - bVisible = rElement.m_bVisible; - } - else - { - // Create new UI element and try to read its state data - UIElement aNewToolbar( aName, aElementType, xUIElement ); - implts_readWindowStateData( aName, aNewToolbar ); - implts_setElementData( aNewToolbar, xDockWindow ); - implts_insertUIElement( aNewToolbar ); - bVisible = aNewToolbar.m_bVisible; - } - - // set toolbar menu style according to customize command state - Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); - if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) - { - ToolBox* pToolbar = (ToolBox *)pWindow; - USHORT nMenuType = pToolbar->GetMenuType(); - if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, m_aCustomizeCmd )) - pToolbar->SetMenuType( nMenuType & ~TOOLBOX_MENUTYPE_CUSTOMIZE ); - else - pToolbar->SetMenuType( nMenuType | TOOLBOX_MENUTYPE_CUSTOMIZE ); - } - } - aWriteLock.unlock(); - - implts_sortUIElements(); - - if ( bVisible ) - { - doLayout(); - bNotify = sal_True; - } + bNotify = m_pToolbarManager->createToolbar( aName ); + bMustBeLayouted = m_pToolbarManager->isLayoutDirty(); } } else if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" )) @@ -4250,13 +2157,24 @@ throw (RuntimeException) } else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" )) { - aWriteLock.unlock(); + // Add layout manager as listener for docking and other window events + uno::Reference< uno::XInterface > xThis( static_cast< OWeakObject* >(this), css::uno::UNO_QUERY ); + uno::Reference< ui::XUIElement > xUIElement( implts_createDockingWindow( aName )); + + if ( xUIElement.is() ) + { + impl_addWindowListeners( xThis, xUIElement ); + m_pPanelManager->addDockingWindow( aName, xUIElement ); + } // The docking window is created by a factory method located in the sfx2 library. - CreateDockingWindow( xFrame, aElementName ); +// CreateDockingWindow( xFrame, aElementName ); } } + if ( bMustBeLayouted ) + implts_doLayout_notify( sal_True ); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ if ( bNotify ) { @@ -4834,96 +2752,13 @@ throw (RuntimeException) sal_Bool SAL_CALL LayoutManager::dockWindow( const ::rtl::OUString& aName, DockingArea DockingArea, const css::awt::Point& Pos ) throw (RuntimeException) { - UIElement aUIElement; + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; - if ( implts_findElement( aName, aUIElement ) && aUIElement.m_xUIElement.is() ) + if ( impl_parseResourceURL( aName, aElementType, aElementName )) { - try - { - Reference< css::awt::XWindow > xWindow( aUIElement.m_xUIElement->getRealInterface(), UNO_QUERY ); - Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); - if ( xDockWindow.is() ) - { - if ( DockingArea != DockingArea_DOCKINGAREA_DEFAULT ) - aUIElement.m_aDockedData.m_nDockedArea = sal_Int16( DockingArea ); - - if (( Pos.X != SAL_MAX_INT32 ) && ( Pos.Y != SAL_MAX_INT32 )) - aUIElement.m_aDockedData.m_aPos = ::Point( Pos.X, Pos.Y ); - - if ( !xDockWindow->isFloating() ) - { - Window* pWindow( 0 ); - ToolBox* pToolBox( 0 ); - - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - pWindow = VCLUnoHelper::GetWindow( xWindow ); - if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) - { - pToolBox = (ToolBox *)pWindow; - - // We have to set the alignment of the toolbox. It's possible that the toolbox is moved from a - // horizontal to a vertical docking area! - pToolBox->SetAlign( ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea )); - } - } - - if (( aUIElement.m_aDockedData.m_aPos.X() == SAL_MAX_INT32 ) || - ( aUIElement.m_aDockedData.m_aPos.Y() == SAL_MAX_INT32 )) - { - // Docking on its default position without a preset position - - // we have to find a good place for it. - ::Size aSize; - - vos::OGuard aGuard( Application::GetSolarMutex() ); - { - if ( pToolBox ) - aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea ) ); - else - aSize = pWindow->GetSizePixel(); - } - - ::Point aPixelPos; - ::Point aDockPos; - implts_findNextDockingPos( (::com::sun::star::ui::DockingArea)aUIElement.m_aDockedData.m_nDockedArea, - aSize, - aDockPos, - aPixelPos ); - aUIElement.m_aDockedData.m_aPos = aDockPos; - } - } - - WriteGuard aWriteLock( m_aLock ); - UIElement& rUIElement = LayoutManager::impl_findElement( aUIElement.m_aName ); - if ( rUIElement.m_aName == aName ) - { - rUIElement.m_aDockedData.m_nDockedArea = aUIElement.m_aDockedData.m_nDockedArea; - rUIElement.m_aDockedData.m_aPos = aUIElement.m_aDockedData.m_aPos; - } - aWriteLock.unlock(); - - if ( xDockWindow->isFloating() ) - { - // Will call toggle floating mode which will do the rest! - xWindow->setVisible( sal_False ); - xDockWindow->setFloatingMode( sal_False ); - xWindow->setVisible( sal_True ); - } - else - { - implts_writeWindowStateData( aName, aUIElement ); - implts_sortUIElements(); - - if ( aUIElement.m_bVisible ) - doLayout(); - } - - return sal_True; - } - } - catch ( DisposedException& ) - { - } + if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" )) + m_pToolbarManager->dockToolbar( aName, DockingArea, Pos ); } return sal_False; @@ -5569,28 +3404,14 @@ sal_Bool LayoutManager::implts_doLayout( sal_Bool bForceRequestBorderSpace, sal_ aStatusBarSize = implts_getStatusBarSize(); aBorderSpace.Height -= aStatusBarSize.Height(); - implts_setDockingAreaWindowSizes( aBorderSpace ); + m_pToolbarManager->setDockingArea( aBorderSpace ); // Subtract status bar size from our container output size. Docking area windows // don't contain the status bar! aContainerSize = implts_getContainerWindowOutputSize(); aContainerSize.Height() -= aStatusBarSize.Height(); - // Retrieve row/column dependent data from all docked user-interface elements - for ( sal_Int32 i = 0; i < DOCKINGAREAS_COUNT; i++ ) - { - std::vector< SingleRowColumnWindowData > aRowColumnsWindowData; - - implts_getDockingAreaElementInfos( (DockingArea)i, aRowColumnsWindowData ); - - sal_Int32 nOffset( 0 ); - const sal_uInt32 nCount = aRowColumnsWindowData.size(); - for ( sal_uInt32 j = 0; j < nCount; ++j ) - { - implts_calcWindowPosSizeOnSingleRowColumn( i, nOffset, aRowColumnsWindowData[j], aContainerSize ); - nOffset += aRowColumnsWindowData[j].nStaticSize; - } - } + m_pToolbarManager->doLayout(aContainerSize); // Position the status bar if ( aStatusBarSize.Height() > 0 ) @@ -5686,208 +3507,6 @@ throw (::com::sun::star::uno::RuntimeException) return m_bVisible; } -void LayoutManager::implts_calcWindowPosSizeOnSingleRowColumn( sal_Int32 nDockingArea, - sal_Int32 nOffset, - SingleRowColumnWindowData& rRowColumnWindowData, - const ::Size& rContainerSize ) -{ - sal_Int32 nDiff( 0 ); - sal_Int32 nRCSpace( rRowColumnWindowData.nSpace ); - sal_Int32 nTopDockingAreaSize; - sal_Int32 nBottomDockingAreaSize; - sal_Int32 nContainerClientSize; - - if ( rRowColumnWindowData.aRowColumnWindows.empty() ) - return; - - if (( nDockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( nDockingArea == DockingArea_DOCKINGAREA_BOTTOM )) - { - nContainerClientSize = rContainerSize.Width(); - nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize; - } - else - { - nTopDockingAreaSize = implts_getTopBottomDockingAreaSizes().Width(); - nBottomDockingAreaSize = implts_getTopBottomDockingAreaSizes().Height(); - nContainerClientSize = ( rContainerSize.Height() - nTopDockingAreaSize - nBottomDockingAreaSize ); - nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize; - } - - const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindowSizes.size(); - if (( nDiff < 0 ) && ( nRCSpace > 0 )) - { - // First we try to reduce the size of blank space before/behind docked windows - sal_Int32 i = nCount - 1; - while ( i >= 0 ) - { - sal_Int32 nSpace = rRowColumnWindowData.aRowColumnSpace[i]; - if ( nSpace >= -nDiff ) - { - - if (( nDockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( nDockingArea == DockingArea_DOCKINGAREA_BOTTOM )) - { - // Try to move this and all user elements behind with the calculated difference - for ( sal_uInt32 j = i; j < nCount ; j++ ) - rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff; - } - else - { - // Try to move this and all user elements behind with the calculated difference - for ( sal_uInt32 j = i; j < nCount ; j++ ) - rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff; - } - nDiff = 0; - - break; - } - else if ( nSpace > 0 ) - { - if (( nDockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( nDockingArea == DockingArea_DOCKINGAREA_BOTTOM )) - { - // Try to move this and all user elements behind with the calculated difference - for ( sal_uInt32 j = i; j < nCount; j++ ) - rRowColumnWindowData.aRowColumnWindowSizes[j].X -= nSpace; - } - else - { - // Try to move this and all user elements behind with the calculated difference - for ( sal_uInt32 j = i; j < nCount; j++ ) - rRowColumnWindowData.aRowColumnWindowSizes[j].Y -= nSpace; - } - nDiff += nSpace; - } - --i; - } - } - - // Check if we have to reduce further - if ( nDiff < 0 ) - { - // Now we have to reduce the size of certain docked windows - sal_Int32 i = sal_Int32( nCount - 1 ); - while ( i >= 0 ) - { - css::awt::Rectangle& rWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i]; - ::Size aMinSize; - - vos::OGuard aGuard( Application::GetSolarMutex() ); - { - Reference< css::awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i]; - Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); - if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) - aMinSize = ((ToolBox *)pWindow)->CalcMinimumWindowSizePixel(); - } - - if (( aMinSize.Width() > 0 ) && ( aMinSize.Height() > 0 )) - { - if (( nDockingArea == DockingArea_DOCKINGAREA_TOP ) || - ( nDockingArea == DockingArea_DOCKINGAREA_BOTTOM )) - { - sal_Int32 nMaxReducation = ( rWinRect.Width - aMinSize.Width() ); - if ( nMaxReducation >= -nDiff ) - { - rWinRect.Width = rWinRect.Width + nDiff; - nDiff = 0; - } - else - { - rWinRect.Width = aMinSize.Width(); - nDiff += nMaxReducation; - } - - // Try to move this and all user elements behind with the calculated difference - for ( sal_uInt32 j = i; j < nCount; j++ ) - rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff; - } - else - { - sal_Int32 nMaxReducation = ( rWinRect.Height - aMinSize.Height() ); - if ( nMaxReducation >= -nDiff ) - { - rWinRect.Height = rWinRect.Height + nDiff; - nDiff = 0; - } - else - { - rWinRect.Height = aMinSize.Height(); - nDiff += nMaxReducation; - } - - // Try to move this and all user elements behind with the calculated difference - for ( sal_uInt32 j = i; j < nCount; j++ ) - rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff; - } - } - - if ( nDiff >= 0 ) - break; - - --i; - } - } - - /* SAFE AREA ----------------------------------------------------------------------------------------------- */ - ReadGuard aReadLock( m_aLock ); - Window* pDockAreaWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[nDockingArea] ); - aReadLock.unlock(); - - sal_Int32 nCurrPos( 0 ); - sal_Int32 nStartOffset( 0 ); - - if ( nDockingArea == DockingArea_DOCKINGAREA_RIGHT ) - nStartOffset = pDockAreaWindow->GetSizePixel().Width() - rRowColumnWindowData.nStaticSize; - else if ( nDockingArea == DockingArea_DOCKINGAREA_BOTTOM ) - nStartOffset = pDockAreaWindow->GetSizePixel().Height() - rRowColumnWindowData.nStaticSize; - - vos::OGuard aGuard( Application::GetSolarMutex() ); - for ( sal_uInt32 i = 0; i < nCount; i++ ) - { - Reference< css::awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i]; - Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); - Window* pOldParentWindow = pWindow->GetParent(); - - if ( pDockAreaWindow != pOldParentWindow ) - pWindow->SetParent( pDockAreaWindow ); - - css::awt::Rectangle aWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i]; - if ( nDockingArea == DockingArea_DOCKINGAREA_TOP ) - { - if ( aWinRect.X < nCurrPos ) - aWinRect.X = nCurrPos; - pWindow->SetPosSizePixel( ::Point( aWinRect.X, nOffset ), - ::Size( aWinRect.Width, rRowColumnWindowData.nStaticSize )); - nCurrPos += ( aWinRect.X - nCurrPos ) + aWinRect.Width; - } - else if ( nDockingArea == DockingArea_DOCKINGAREA_BOTTOM ) - { - if ( aWinRect.X < nCurrPos ) - aWinRect.X = nCurrPos; - pWindow->SetPosSizePixel( ::Point( aWinRect.X, nStartOffset - nOffset ), - ::Size( aWinRect.Width, rRowColumnWindowData.nStaticSize )); - nCurrPos += ( aWinRect.X - nCurrPos ) + aWinRect.Width; - } - else if ( nDockingArea == DockingArea_DOCKINGAREA_LEFT ) - { - if ( aWinRect.Y < nCurrPos ) - aWinRect.Y = nCurrPos; - pWindow->SetPosSizePixel( ::Point( nOffset, aWinRect.Y ), - ::Size( rRowColumnWindowData.nStaticSize, aWinRect.Height )); - nCurrPos += ( aWinRect.Y - nCurrPos ) + aWinRect.Height; - } - else if ( nDockingArea == DockingArea_DOCKINGAREA_RIGHT ) - { - if ( aWinRect.Y < nCurrPos ) - aWinRect.Y = nCurrPos; - pWindow->SetPosSizePixel( ::Point( nStartOffset - nOffset, aWinRect.Y ), - ::Size( rRowColumnWindowData.nStaticSize, aWinRect.Height )); - nCurrPos += ( aWinRect.Y - nCurrPos ) + aWinRect.Height; - } - } -} - ::Size LayoutManager::implts_getStatusBarSize() { ReadGuard aReadLock( m_aLock ); @@ -5925,107 +3544,19 @@ css::awt::Rectangle LayoutManager::implts_calcDockingAreaSizes() ReadGuard aReadLock( m_aLock ); xContainerWindow = m_xContainerWindow; xDockingAreaAcceptor = m_xDockingAreaAcceptor; - UIElementVector aWindowVector( m_aUIElements ); aReadLock.unlock(); css::awt::Rectangle aBorderSpace; if ( xDockingAreaAcceptor.is() && xContainerWindow.is() ) - { - sal_Int32 nCurrRowColumn( 0 ); - sal_Int32 nCurrPos( 0 ); - sal_Int32 nCurrDockingArea( DockingArea_DOCKINGAREA_TOP ); - std::vector< sal_Int32 > aRowColumnSizes[DOCKINGAREAS_COUNT]; - UIElementVector::const_iterator pConstIter; - - aRowColumnSizes[nCurrDockingArea].clear(); - aRowColumnSizes[nCurrDockingArea].push_back( 0 ); - - for ( pConstIter = aWindowVector.begin(); pConstIter != aWindowVector.end(); pConstIter++ ) - { - Reference< XUIElement > xUIElement( pConstIter->m_xUIElement, UNO_QUERY ); - if ( xUIElement.is() ) - { - Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); - Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); - if ( xWindow.is() && xDockWindow.is() ) - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - - Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); - if ( pWindow && pWindow->IsVisible() && !xDockWindow->isFloating() ) - { - css::awt::Rectangle aPosSize = xWindow->getPosSize(); - if ( pConstIter->m_aDockedData.m_nDockedArea != nCurrDockingArea ) - { - nCurrDockingArea = pConstIter->m_aDockedData.m_nDockedArea; - nCurrRowColumn = 0; - nCurrPos = 0; - aRowColumnSizes[nCurrDockingArea].clear(); - aRowColumnSizes[nCurrDockingArea].push_back( 0 ); - } - - if ( pConstIter->m_aDockedData.m_nDockedArea == nCurrDockingArea ) - { - if (( pConstIter->m_aDockedData.m_nDockedArea == DockingArea_DOCKINGAREA_TOP ) || - ( pConstIter->m_aDockedData.m_nDockedArea == DockingArea_DOCKINGAREA_BOTTOM )) - { - if ( pConstIter->m_aDockedData.m_aPos.Y() > nCurrPos ) - { - ++nCurrRowColumn; - nCurrPos = pConstIter->m_aDockedData.m_aPos.Y(); - aRowColumnSizes[nCurrDockingArea].push_back( 0 ); - } - - if ( aPosSize.Height > aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] ) - aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] = aPosSize.Height; - } - else - { - if ( pConstIter->m_aDockedData.m_aPos.X() > nCurrPos ) - { - ++nCurrRowColumn; - nCurrPos = pConstIter->m_aDockedData.m_aPos.X(); - aRowColumnSizes[nCurrDockingArea].push_back( 0 ); - } - - if ( aPosSize.Width > aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] ) - aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] = aPosSize.Width; - } - } - } - } - } - } + aBorderSpace = m_pToolbarManager->getDockingArea(); - // Sum up max heights from every row/column - if ( !aWindowVector.empty() ) - { - for ( sal_Int32 i = 0; i <= DockingArea_DOCKINGAREA_RIGHT; i++ ) - { - sal_Int32 nSize( 0 ); - const sal_uInt32 nCount = aRowColumnSizes[i].size(); - for ( sal_uInt32 j = 0; j < nCount; j++ ) - nSize += aRowColumnSizes[i][j]; - - if ( i == DockingArea_DOCKINGAREA_TOP ) - aBorderSpace.Y = nSize; - else if ( i == DockingArea_DOCKINGAREA_BOTTOM ) - aBorderSpace.Height = nSize; - else if ( i == DockingArea_DOCKINGAREA_LEFT ) - aBorderSpace.X = nSize; - else - aBorderSpace.Width = nSize; - } - } - - // We have to add the height of a possible status bar - aBorderSpace.Height += implts_getStatusBarSize().Height(); - } + // We have to add the height of a possible status bar + aBorderSpace.Height += implts_getStatusBarSize().Height(); return aBorderSpace; } -void LayoutManager::implts_setDockingAreaWindowSizes( const css::awt::Rectangle& rBorderSpace ) +void LayoutManager::implts_setDockingAreaWindowSizes( const css::awt::Rectangle& /*rBorderSpace*/ ) { Reference< css::awt::XWindow > xContainerWindow; @@ -6041,64 +3572,6 @@ void LayoutManager::implts_setDockingAreaWindowSizes( const css::awt::Rectangle& aRectangle.Height - aInfo.TopInset - aInfo.BottomInset ); ::Size aStatusBarSize = implts_getStatusBarSize(); - sal_Int32 nLeftRightDockingAreaHeight( aContainerClientSize.Height ); - if ( rBorderSpace.Y >= 0 ) - { - // Top docking area window - aReadLock.lock(); - Reference< css::awt::XWindow > xDockAreaWindow( m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP] ); - aReadLock.unlock(); - - xDockAreaWindow->setPosSize( 0, 0, aContainerClientSize.Width, rBorderSpace.Y, css::awt::PosSize::POSSIZE ); - xDockAreaWindow->setVisible( sal_True ); - nLeftRightDockingAreaHeight -= rBorderSpace.Y; - } - - if ( rBorderSpace.Height >= 0 ) - { - // Bottom docking area window - sal_Int32 nBottomPos = std::max( sal_Int32( aContainerClientSize.Height - rBorderSpace.Height - aStatusBarSize.Height() ), sal_Int32( 0 )); - sal_Int32 nHeight = ( nBottomPos == 0 ) ? 0 : rBorderSpace.Height; - - aReadLock.lock(); - Reference< css::awt::XWindow > xDockAreaWindow( m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM] ); - aReadLock.unlock(); - - xDockAreaWindow->setPosSize( 0, nBottomPos, aContainerClientSize.Width, nHeight, css::awt::PosSize::POSSIZE ); - xDockAreaWindow->setVisible( sal_True ); - nLeftRightDockingAreaHeight -= nHeight; - } - - nLeftRightDockingAreaHeight -= aStatusBarSize.Height(); - if ( rBorderSpace.X >= 0 || nLeftRightDockingAreaHeight > 0 ) - { - // Left docking area window - aReadLock.lock(); - Reference< css::awt::XWindow > xDockAreaWindow( m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT] ); - aReadLock.unlock(); - - // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority! - sal_Int32 nHeight = std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight )); - - xDockAreaWindow->setPosSize( 0, rBorderSpace.Y, rBorderSpace.X, nHeight, css::awt::PosSize::POSSIZE ); - xDockAreaWindow->setVisible( sal_True ); - } - if ( rBorderSpace.Width >= 0 || nLeftRightDockingAreaHeight > 0 ) - { - // Right docking area window - aReadLock.lock(); - Reference< css::awt::XWindow > xDockAreaWindow( m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT] ); - aReadLock.unlock(); - - // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority! - sal_Int32 nLeftPos = std::max( sal_Int32( 0 ), sal_Int32( aContainerClientSize.Width - rBorderSpace.Width )); - sal_Int32 nHeight = std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight )); - sal_Int32 nWidth = ( nLeftPos == 0 ) ? 0 : rBorderSpace.Width; - - xDockAreaWindow->setPosSize( nLeftPos, rBorderSpace.Y, nWidth, nHeight, css::awt::PosSize::POSSIZE ); - xDockAreaWindow->setVisible( sal_True ); - } - // Position the status bar if ( aStatusBarSize.Height() > 0 ) { @@ -6182,6 +3655,16 @@ sal_Bool LayoutManager::implts_resetMenuBar() return sal_False; } +void LayoutManager::implts_setMenuBarCloser(sal_Bool bCloserState) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_bMenuBarCloser = bCloserState; + aWriteLock.unlock(); + + implts_updateMenuBarClose(); +} + sal_Int16 LayoutManager::implts_getCurrentSymbolsSize() { sal_Int16 eOptSymbolsSize( 0 ); @@ -6289,263 +3772,32 @@ IMPL_LINK( LayoutManager, SettingsChanged, void*, EMPTYARG ) //--------------------------------------------------------------------------------------------------------- void SAL_CALL LayoutManager::startDocking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException) { - sal_Bool bWinFound( sal_False ); - UIElement aUIElement; + Reference< css::awt::XWindow > xWindow( e.Source, UNO_QUERY ); - ReadGuard aReadGuard( m_aLock ); - Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow ); - Reference< css::awt::XWindow2 > xWindow( e.Source, UNO_QUERY ); - aReadGuard.unlock(); - - Window* pContainerWindow( 0 ); - Window* pWindow( 0 ); - ::Point aMousePos; - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); - aMousePos = pContainerWindow->ScreenToOutputPixel( ::Point( e.MousePos.X, e.MousePos.Y )); - } - - bWinFound = implts_findElement( e.Source, aUIElement ); - - if ( bWinFound && xWindow.is() ) - { - css::awt::Rectangle aRect; - Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); - if ( xDockWindow->isFloating() ) - { - css::awt::Rectangle aPos = xWindow->getPosSize(); - css::awt::Size aSize = xWindow->getOutputSize(); - - aUIElement.m_aFloatingData.m_aPos = ::Point( aPos.X, aPos.Y ); - aUIElement.m_aFloatingData.m_aSize = ::Size( aSize.Width, aSize.Height ); - - vos::OGuard aGuard( Application::GetSolarMutex() ); - pWindow = VCLUnoHelper::GetWindow( xWindow ); - if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) - { - ToolBox* pToolBox = (ToolBox *)pWindow; - aUIElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines(); - aUIElement.m_aFloatingData.m_bIsHorizontal = (( pToolBox->GetAlign() == WINDOWALIGN_TOP ) || - ( pToolBox->GetAlign() == WINDOWALIGN_BOTTOM )); - } - } - } - - WriteGuard aWriteLock( m_aLock ); - m_bDockingInProgress = bWinFound; - m_aDockUIElement = aUIElement; - m_aDockUIElement.m_bUserActive = sal_True; - m_aStartDockMousePos = aMousePos; - aWriteLock.unlock(); -} - -::Rectangle LayoutManager::implts_calcHotZoneRect( const ::Rectangle& rRect, sal_Int32 nHotZoneOffset ) -{ - ::Rectangle aRect( rRect ); - - aRect.Left() -= nHotZoneOffset; - aRect.Top() -= nHotZoneOffset; - aRect.Right() += nHotZoneOffset; - aRect.Bottom() += nHotZoneOffset; - return aRect; + // Determine if we have a toolbar and forward request to toolbar manager + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + ToolBox* pToolBox = 0; + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + m_pToolbarManager->startDocking(e); } css::awt::DockingData SAL_CALL LayoutManager::docking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException) { - const sal_Int32 MAGNETIC_DISTANCE_UNDOCK = 25; - const sal_Int32 MAGNETIC_DISTANCE_DOCK = 20; - - css::awt::DockingData aDockingData; - Reference< css::awt::XDockableWindow > xDockWindow( e.Source, UNO_QUERY ); - Reference< css::awt::XWindow > xWindow( e.Source, UNO_QUERY ); - Reference< css::awt::XWindow > xTopDockingWindow; - Reference< css::awt::XWindow > xLeftDockingWindow; - Reference< css::awt::XWindow > xRightDockingWindow; - Reference< css::awt::XWindow > xBottomDockingWindow; - Reference< css::awt::XWindow > xContainerWindow; - UIElement aUIDockingElement; - DockingOperation eDockingOperation( DOCKOP_ON_COLROW ); - ::Size aStatusBarSize; - - aDockingData.TrackingRectangle = e.TrackingRectangle; - sal_Bool bDockingInProgress; - - { - ReadGuard aReadLock( m_aLock ); - bDockingInProgress = m_bDockingInProgress; - if ( bDockingInProgress ) - { - xContainerWindow = m_xContainerWindow; - xTopDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP]; - xLeftDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT]; - xRightDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT]; - xBottomDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM]; - aUIDockingElement = m_aDockUIElement; - aStatusBarSize = implts_getStatusBarSize(); - } - } - - if ( bDockingInProgress && - xDockWindow.is() && - xWindow.is() ) - { - try - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - - sal_Int16 eDockingArea( -1 ); // none - sal_Int32 nMagneticZone( aUIDockingElement.m_bFloating ? MAGNETIC_DISTANCE_DOCK : MAGNETIC_DISTANCE_UNDOCK ); - css::awt::Rectangle aNewTrackingRect; - ::Rectangle aTrackingRect( e.TrackingRectangle.X, - e.TrackingRectangle.Y, - ( e.TrackingRectangle.X + e.TrackingRectangle.Width ), - ( e.TrackingRectangle.Y + e.TrackingRectangle.Height )); - - css::awt::Rectangle aTmpRect = xTopDockingWindow->getPosSize(); - ::Rectangle aTopDockRect( aTmpRect.X, aTmpRect.Y, aTmpRect.Width, aTmpRect.Height ); - ::Rectangle aHotZoneTopDockRect( implts_calcHotZoneRect( aTopDockRect, nMagneticZone )); - - aTmpRect = xBottomDockingWindow->getPosSize(); - ::Rectangle aBottomDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width), ( aTmpRect.Y + aTmpRect.Height )); - ::Rectangle aHotZoneBottomDockRect( implts_calcHotZoneRect( aBottomDockRect, nMagneticZone )); - - aTmpRect = xLeftDockingWindow->getPosSize(); - ::Rectangle aLeftDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height )); - ::Rectangle aHotZoneLeftDockRect( implts_calcHotZoneRect( aLeftDockRect, nMagneticZone )); - - aTmpRect = xRightDockingWindow->getPosSize(); - ::Rectangle aRightDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height )); - ::Rectangle aHotZoneRightDockRect( implts_calcHotZoneRect( aRightDockRect, nMagneticZone )); - - Window* pContainerWindow( VCLUnoHelper::GetWindow( xContainerWindow ) ); - Window* pDockingAreaWindow( 0 ); - ::Point aMousePos( pContainerWindow->ScreenToOutputPixel( ::Point( e.MousePos.X, e.MousePos.Y ))); - - if ( aHotZoneTopDockRect.IsInside( aMousePos )) - eDockingArea = DockingArea_DOCKINGAREA_TOP; - else if ( aHotZoneBottomDockRect.IsInside( aMousePos )) - eDockingArea = DockingArea_DOCKINGAREA_BOTTOM; - else if ( aHotZoneLeftDockRect.IsInside( aMousePos )) - eDockingArea = DockingArea_DOCKINGAREA_LEFT; - else if ( aHotZoneRightDockRect.IsInside( aMousePos )) - eDockingArea = DockingArea_DOCKINGAREA_RIGHT; - - // Higher priority for movements inside the real docking area - if ( aTopDockRect.IsInside( aMousePos )) - eDockingArea = DockingArea_DOCKINGAREA_TOP; - else if ( aBottomDockRect.IsInside( aMousePos )) - eDockingArea = DockingArea_DOCKINGAREA_BOTTOM; - else if ( aLeftDockRect.IsInside( aMousePos )) - eDockingArea = DockingArea_DOCKINGAREA_LEFT; - else if ( aRightDockRect.IsInside( aMousePos )) - eDockingArea = DockingArea_DOCKINGAREA_RIGHT; - - // Determine if we have a toolbar and set alignment according to the docking area! - Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); - ToolBox* pToolBox = 0; - if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) - pToolBox = (ToolBox *)pWindow; - - if ( eDockingArea != -1 ) - { - if ( eDockingArea == DockingArea_DOCKINGAREA_TOP ) - { - aUIDockingElement.m_aDockedData.m_nDockedArea = DockingArea_DOCKINGAREA_TOP; - aUIDockingElement.m_bFloating = sal_False; - pDockingAreaWindow = VCLUnoHelper::GetWindow( xTopDockingWindow ); - } - else if ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM ) - { - aUIDockingElement.m_aDockedData.m_nDockedArea = DockingArea_DOCKINGAREA_BOTTOM; - aUIDockingElement.m_bFloating = sal_False; - pDockingAreaWindow = VCLUnoHelper::GetWindow( xBottomDockingWindow ); - } - else if ( eDockingArea == DockingArea_DOCKINGAREA_LEFT ) - { - aUIDockingElement.m_aDockedData.m_nDockedArea = DockingArea_DOCKINGAREA_LEFT; - aUIDockingElement.m_bFloating = sal_False; - pDockingAreaWindow = VCLUnoHelper::GetWindow( xLeftDockingWindow ); - } - else if ( eDockingArea == DockingArea_DOCKINGAREA_RIGHT ) - { - aUIDockingElement.m_aDockedData.m_nDockedArea = DockingArea_DOCKINGAREA_RIGHT; - aUIDockingElement.m_bFloating = sal_False; - pDockingAreaWindow = VCLUnoHelper::GetWindow( xRightDockingWindow ); - } - - ::Point aOutputPos = pContainerWindow->ScreenToOutputPixel( aTrackingRect.TopLeft() ); - aTrackingRect.SetPos( aOutputPos ); - - ::Rectangle aNewDockingRect( aTrackingRect ); - implts_calcDockingPosSize( aUIDockingElement, eDockingOperation, aNewDockingRect, aMousePos ); - - ::Point aScreenPos = pContainerWindow->OutputToScreenPixel( aNewDockingRect.TopLeft() ); - aNewTrackingRect = css::awt::Rectangle( aScreenPos.X(), - aScreenPos.Y(), - aNewDockingRect.getWidth(), - aNewDockingRect.getHeight() ); - aDockingData.TrackingRectangle = aNewTrackingRect; - } - else if ( pToolBox && bDockingInProgress ) - { - sal_Bool bIsHorizontal = (( pToolBox->GetAlign() == WINDOWALIGN_TOP ) || - ( pToolBox->GetAlign() == WINDOWALIGN_BOTTOM )); - ::Size aFloatSize = aUIDockingElement.m_aFloatingData.m_aSize; - if ( aFloatSize.Width() > 0 && aFloatSize.Height() > 0 ) - { - aUIDockingElement.m_aFloatingData.m_aPos = pContainerWindow->ScreenToOutputPixel( - ::Point( e.MousePos.X, e.MousePos.Y )); - aDockingData.TrackingRectangle.Height = aFloatSize.Height(); - aDockingData.TrackingRectangle.Width = aFloatSize.Width(); - } - else - { - aFloatSize = pToolBox->CalcWindowSizePixel(); - if ( !bIsHorizontal ) - { - // Floating toolbars are always horizontal aligned! We have to swap - // width/height if we have a vertical aligned toolbar. - sal_Int32 nTemp = aFloatSize.Height(); - aFloatSize.Height() = aFloatSize.Width(); - aFloatSize.Width() = nTemp; - } + Reference< css::awt::XWindow > xWindow( e.Source, UNO_QUERY ); - aDockingData.TrackingRectangle.Height = aFloatSize.Height(); - aDockingData.TrackingRectangle.Width = aFloatSize.Width(); - - // For the first time we don't have any data about the floating size of a toolbar. - // We calculate it and store it for later use. - aUIDockingElement.m_aFloatingData.m_aPos = pContainerWindow->ScreenToOutputPixel( - ::Point( e.MousePos.X, e.MousePos.Y )); - aUIDockingElement.m_aFloatingData.m_aSize = aFloatSize; - aUIDockingElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines(); - aUIDockingElement.m_aFloatingData.m_bIsHorizontal = (( pToolBox->GetAlign() == WINDOWALIGN_TOP ) || - ( pToolBox->GetAlign() == WINDOWALIGN_BOTTOM )); - } - aDockingData.TrackingRectangle.X = e.MousePos.X; - aDockingData.TrackingRectangle.Y = e.MousePos.Y; - } + // Determine if we have a toolbar and forward request to toolbar manager + css::awt::DockingData aDockingData; - aDockingData.bFloating = ( eDockingArea == -1 ); + // copy current tracking rectangle from docking event + aDockingData.TrackingRectangle = e.TrackingRectangle; - // Write current data to the member docking progress data - WriteGuard aWriteLock( m_aLock ); - m_aDockUIElement.m_bFloating = aDockingData.bFloating; - if ( !aDockingData.bFloating ) - { - m_aDockUIElement.m_aDockedData = aUIDockingElement.m_aDockedData; - m_eDockOperation = eDockingOperation; - } - else - m_aDockUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData; - aWriteLock.unlock(); - } - catch ( Exception& ) - { - } - } + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + ToolBox* pToolBox = 0; + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + aDockingData = m_pToolbarManager->docking(e); return aDockingData; } @@ -6553,287 +3805,49 @@ throw (::com::sun::star::uno::RuntimeException) void SAL_CALL LayoutManager::endDocking( const ::com::sun::star::awt::EndDockingEvent& e ) throw (::com::sun::star::uno::RuntimeException) { - sal_Bool bDockingInProgress( sal_False ); - sal_Bool bStartDockFloated( sal_False ); - sal_Bool bFloating( sal_False ); - UIElement aUIDockingElement; + Reference< css::awt::XWindow > xWindow( e.Source, UNO_QUERY ); - WriteGuard aWriteLock( m_aLock ); - bDockingInProgress = m_bDockingInProgress; - aUIDockingElement = m_aDockUIElement; - bFloating = aUIDockingElement.m_bFloating; - - UIElement& rUIElement = impl_findElement( aUIDockingElement.m_aName ); - if ( rUIElement.m_aName == aUIDockingElement.m_aName ) - { - if ( aUIDockingElement.m_bFloating ) - { - // Write last position into position data - Reference< css::awt::XWindow > xWindow( aUIDockingElement.m_xUIElement->getRealInterface(), UNO_QUERY ); - rUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData; - css::awt::Rectangle aTmpRect = xWindow->getPosSize(); - rUIElement.m_aFloatingData.m_aPos = ::Point( aTmpRect.X, aTmpRect.Y ); - // make changes also for our local data as we use it to make data persistent - aUIDockingElement.m_aFloatingData = rUIElement.m_aFloatingData; - } - else - { - rUIElement.m_aDockedData = aUIDockingElement.m_aDockedData; - rUIElement.m_aFloatingData.m_aSize = aUIDockingElement.m_aFloatingData.m_aSize; - - if ( m_eDockOperation != DOCKOP_ON_COLROW ) - { - // we have to renumber our row/column data to insert a new row/column - implts_renumberRowColumnData( (::com::sun::star::ui::DockingArea)aUIDockingElement.m_aDockedData.m_nDockedArea, - m_eDockOperation, - aUIDockingElement ); - } - } - - bStartDockFloated = rUIElement.m_bFloating; - rUIElement.m_bFloating = m_aDockUIElement.m_bFloating; - rUIElement.m_bUserActive = sal_True; - } - - // reset member for next docking operation - m_aDockUIElement.m_xUIElement.clear(); - m_eDockOperation = DOCKOP_ON_COLROW; - aWriteLock.unlock(); - - implts_writeWindowStateData( aUIDockingElement.m_aName, aUIDockingElement ); - - if ( bDockingInProgress ) - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - Window* pWindow = VCLUnoHelper::GetWindow( Reference< css::awt::XWindow >( e.Source, UNO_QUERY )); - ToolBox* pToolBox = 0; - if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) - pToolBox = (ToolBox *)pWindow; - - if ( pToolBox ) - { - if( e.bFloating ) - { - if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal ) - pToolBox->SetAlign( WINDOWALIGN_TOP ); - else - pToolBox->SetAlign( WINDOWALIGN_LEFT ); - } - else - { - ::Size aSize; - - pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) ); - - // Docked toolbars have always one line - aSize = pToolBox->CalcWindowSizePixel( 1 ); - - // Lock layouting updates as our listener would be called due to SetSizePixel - pToolBox->SetOutputSizePixel( aSize ); - } - } - } - - aWriteLock.lock(); - m_bDockingInProgress = sal_False; - aWriteLock.unlock(); - - implts_sortUIElements(); - if ( !bStartDockFloated || !bFloating ) + // Determine if we have a toolbar and forward request to toolbar manager + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + ToolBox* pToolBox = 0; + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) { - // Optimization: Don't layout if we started floating and now floating again. - // This would not change anything for the docked user-interface elements. - doLayout(); + m_pToolbarManager->endDocking(e); + if ( m_pToolbarManager->isLayoutDirty()) + implts_doLayout_notify( sal_True ); } } sal_Bool SAL_CALL LayoutManager::prepareToggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException) { - sal_Bool bDockingInProgress( sal_False ); - - ReadGuard aReadLock( m_aLock ); - bDockingInProgress = m_bDockingInProgress; - aReadLock.unlock(); - - UIElement aUIDockingElement; - sal_Bool bWinFound( implts_findElement( e.Source, aUIDockingElement ) ); - Reference< css::awt::XWindow > xWindow( e.Source, UNO_QUERY ); - - if ( bWinFound && xWindow.is() ) - { - if ( !bDockingInProgress ) - { - css::awt::Rectangle aRect; - Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); - if ( xDockWindow->isFloating() ) - { - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); - if ( pWindow ) - { - if ( pWindow->GetType() == WINDOW_TOOLBOX ) - { - ToolBox* pToolBox = (ToolBox *)pWindow; - aUIDockingElement.m_aFloatingData.m_aPos = pToolBox->GetPosPixel(); - aUIDockingElement.m_aFloatingData.m_aSize = pToolBox->GetOutputSizePixel(); - aUIDockingElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines(); - aUIDockingElement.m_aFloatingData.m_bIsHorizontal = (( pToolBox->GetAlign() == WINDOWALIGN_TOP ) || - ( pToolBox->GetAlign() == WINDOWALIGN_BOTTOM )); - } - } - } + Reference< css::awt::XWindow > xWindow( e.Source, UNO_QUERY ); - WriteGuard aWriteLock( m_aLock ); - UIElement& rUIElement = LayoutManager::impl_findElement( aUIDockingElement.m_aName ); - if ( rUIElement.m_aName == aUIDockingElement.m_aName ) - rUIElement = aUIDockingElement; - aWriteLock.unlock(); - } - } - } - - return sal_True; + // Determine if we have a toolbar and forward request to toolbar manager + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + ToolBox* pToolBox = 0; + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + return m_pToolbarManager->prepareToggleFloatingMode(e); + else + return sal_False; } void SAL_CALL LayoutManager::toggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException) { - sal_Bool bDockingInProgress( sal_False ); - UIElement aUIDockingElement; - - ReadGuard aReadLock( m_aLock ); - bDockingInProgress = m_bDockingInProgress; - if ( bDockingInProgress ) - aUIDockingElement = m_aDockUIElement; - aReadLock.unlock(); + Reference< css::awt::XWindow > xWindow( e.Source, UNO_QUERY ); - Window* pWindow( 0 ); - ToolBox* pToolBox( 0 ); - Reference< css::awt::XWindow2 > xWindow; - - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - xWindow = Reference< css::awt::XWindow2 >( e.Source, UNO_QUERY ); - pWindow = VCLUnoHelper::GetWindow( xWindow ); - - if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) - pToolBox = (ToolBox *)pWindow; - } - - if ( !bDockingInProgress ) - { - sal_Bool bWinFound( implts_findElement( e.Source, aUIDockingElement ) ); - if ( bWinFound && xWindow.is() ) - { - aUIDockingElement.m_bFloating = !aUIDockingElement.m_bFloating; - aUIDockingElement.m_bUserActive = sal_True; - - WriteGuard aWriteLock( m_aLock ); - m_bDoLayout = sal_True; - aWriteLock.unlock(); - - if ( aUIDockingElement.m_bFloating ) - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( pToolBox ) - { - pToolBox->SetLineCount( aUIDockingElement.m_aFloatingData.m_nLines ); - if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal ) - pToolBox->SetAlign( WINDOWALIGN_TOP ); - else - pToolBox->SetAlign( WINDOWALIGN_LEFT ); - } - - sal_Bool bUndefPos = ( aUIDockingElement.m_aFloatingData.m_aPos.X() == SAL_MAX_INT32 || - aUIDockingElement.m_aFloatingData.m_aPos.Y() == SAL_MAX_INT32 ); - sal_Bool bSetSize = ( aUIDockingElement.m_aFloatingData.m_aSize.Width() != 0 && - aUIDockingElement.m_aFloatingData.m_aSize.Height() != 0 ); - - if ( bUndefPos ) - aUIDockingElement.m_aFloatingData.m_aPos = implts_findNextCascadeFloatingPos(); - - if ( !bSetSize ) - { - if ( pToolBox ) - aUIDockingElement.m_aFloatingData.m_aSize = pToolBox->CalcFloatingWindowSizePixel(); - else - aUIDockingElement.m_aFloatingData.m_aSize = pWindow->GetOutputSizePixel(); - } - - xWindow->setPosSize( aUIDockingElement.m_aFloatingData.m_aPos.X(), - aUIDockingElement.m_aFloatingData.m_aPos.Y(), - 0, 0, css::awt::PosSize::POS ); - xWindow->setOutputSize( AWTSize( aUIDockingElement.m_aFloatingData.m_aSize ) ); - } - else - { - if (( aUIDockingElement.m_aDockedData.m_aPos.X() == SAL_MAX_INT32 ) && - ( aUIDockingElement.m_aDockedData.m_aPos.Y() == SAL_MAX_INT32 )) - { - // Docking on its default position without a preset position - - // we have to find a good place for it. - ::Point aPixelPos; - ::Point aDockPos; - ::Size aSize; - - { - vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( pToolBox ) - aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea ) ); - else - aSize = pWindow->GetSizePixel(); - } - - implts_findNextDockingPos( (::com::sun::star::ui::DockingArea)aUIDockingElement.m_aDockedData.m_nDockedArea, - aSize, - aDockPos, - aPixelPos ); - aUIDockingElement.m_aDockedData.m_aPos = aDockPos; - } - - vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( pToolBox ) - { - pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) ); - ::Size aSize = pToolBox->CalcWindowSizePixel( 1 ); - css::awt::Rectangle aRect = xWindow->getPosSize(); - xWindow->setPosSize( aRect.X, aRect.Y, 0, 0, css::awt::PosSize::POS ); - xWindow->setOutputSize( AWTSize( aSize ) ); - } - } - - aWriteLock.lock(); - m_bDoLayout = sal_False; - UIElement& rUIElement = LayoutManager::impl_findElement( aUIDockingElement.m_aName ); - if ( rUIElement.m_aName == aUIDockingElement.m_aName ) - rUIElement = aUIDockingElement; - aWriteLock.unlock(); - - implts_writeWindowStateData( aUIDockingElement.m_aName, aUIDockingElement ); - - implts_sortUIElements(); - doLayout(); - } - } - else + // Determine if we have a toolbar and forward request to toolbar manager + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + ToolBox* pToolBox = 0; + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) { - vos::OGuard aGuard( Application::GetSolarMutex() ); - if ( pToolBox ) - { - if ( aUIDockingElement.m_bFloating ) - { - if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal ) - pToolBox->SetAlign( WINDOWALIGN_TOP ); - else - pToolBox->SetAlign( WINDOWALIGN_LEFT ); - } - else - { - pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) ); - } - } + m_pToolbarManager->toggleFloatingMode(e); + if ( m_pToolbarManager->isLayoutDirty()) + implts_doLayout_notify( sal_True ); } } @@ -6880,7 +3894,6 @@ throw (::com::sun::star::uno::RuntimeException) void SAL_CALL LayoutManager::endPopupMode( const ::com::sun::star::awt::EndPopupModeEvent& ) throw (::com::sun::star::uno::RuntimeException) { - } //--------------------------------------------------------------------------------------------------------- @@ -7201,7 +4214,10 @@ throw( RuntimeException ) m_xInplaceMenuBar.clear(); m_xContainerWindow.clear(); m_xContainerTopWindow.clear(); - implts_destroyDockingAreaWindows(); + + // forward disposing call to toolbar manager + if ( m_pToolbarManager != NULL ) + m_pToolbarManager->disposing(rEvent); if ( m_xModuleCfgMgr.is() ) { @@ -7552,4 +4568,3 @@ com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CA } } // namespace framework - diff --git a/framework/source/layoutmanager/layoutmanager.cxx.bak b/framework/source/layoutmanager/layoutmanager.cxx.bak new file mode 100755 index 000000000000..82fc4e1a8d71 --- /dev/null +++ b/framework/source/layoutmanager/layoutmanager.cxx.bak @@ -0,0 +1,7388 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutmanager.cxx,v $ + * $Revision: 1.72 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <services/layoutmanager.hxx> +#include <helpers.hxx> +#include <panelmanager.hxx> +#include <threadhelp/resetableguard.hxx> +#include <services.h> +#include <classes/sfxhelperfunctions.hxx> +#include <uielement/menubarwrapper.hxx> +#include <classes/addonsoptions.hxx> +#include <uiconfiguration/windowstateconfiguration.hxx> +#include <classes/fwkresid.hxx> +#include <classes/resource.hrc> +#include <toolkit/helper/convert.hxx> +#include <uielement/progressbarwrapper.hxx> +#include <uiconfiguration/globalsettings.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/frame/FrameAction.hpp> +#include <com/sun/star/frame/XUIControllerRegistration.hpp> +#include <com/sun/star/lang/XMultiComponentFactory.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> +#include <com/sun/star/awt/XSystemDependentMenuPeer.hpp> +#include <com/sun/star/lang/SystemDependent.hpp> +#include <com/sun/star/awt/VclWindowPeerAttribute.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/XDevice.hpp> +#include <com/sun/star/awt/XSystemDependentWindowPeer.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> +#include <com/sun/star/ui/XModuleUIConfigurationManagerSupplier.hpp> +#include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp> +#include <com/sun/star/ui/UIElementType.hpp> +#include <com/sun/star/container/XNameReplace.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/ui/XUIFunctionListener.hpp> +#include <com/sun/star/frame/LayoutManagerEvents.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/frame/XDispatchHelper.hpp> +#include <com/sun/star/lang/DisposedException.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <svtools/imgdef.hxx> +#include <tools/diagnose_ex.h> +#include <vcl/window.hxx> +#include <vcl/wrkwin.hxx> +#include <vcl/dockingarea.hxx> +#include <vcl/svapp.hxx> +#include <vcl/i18nhelp.hxx> +#include <vcl/wall.hxx> +#include <toolkit/unohlp.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <toolkit/awt/vclxmenu.hxx> +#include <comphelper/mediadescriptor.hxx> +#include <comphelper/uno3.hxx> +#include <rtl/logfile.hxx> +#include <unotools/cmdoptions.hxx> + +#include <algorithm> +#include <boost/bind.hpp> +// ______________________________________________ +// using namespace + +using namespace ::com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::util; +using namespace com::sun::star::lang; +using namespace com::sun::star::container; +using namespace ::com::sun::star::ui; +using namespace com::sun::star::frame; +using namespace ::com::sun::star::frame; + +#define UIRESOURCE_PROTOCO_ASCII "private:" +#define UIRESOURCE_RESOURCE_ASCII "resource" +#define UIRESOURCE_URL_ASCII "private:resource" +#define UIRESOURCE_URL rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( UIRESOURCE_URL_ASCII )) + +// ATTENTION! +// This value is directly copied from the sfx2 project. +// You have to change BOTH values, see sfx2/inc/sfx2/sfxsids.hrc (SID_DOCKWIN_START) +static const sal_Int32 DOCKWIN_ID_BASE = 9800; + +//_________________________________________________________________________________________________________________ +// Namespace +//_________________________________________________________________________________________________________________ +// + +namespace framework +{ + +struct UIElementVisibility +{ + rtl::OUString aName; + bool bVisible; +}; + +//***************************************************************************************************************** +// XInterface, XTypeProvider, XServiceInfo +//***************************************************************************************************************** +IMPLEMENT_FORWARD_XTYPEPROVIDER2( LayoutManager, LayoutManager_Base, LayoutManager_PBase ) +IMPLEMENT_FORWARD_XINTERFACE2( LayoutManager, LayoutManager_Base, LayoutManager_PBase ) + +DEFINE_XSERVICEINFO_MULTISERVICE ( LayoutManager , + ::cppu::OWeakObject , + SERVICENAME_LAYOUTMANAGER , + IMPLEMENTATIONNAME_LAYOUTMANAGER + ) + +DEFINE_INIT_SERVICE ( LayoutManager, {} ) + + +LayoutManager::LayoutManager( const Reference< XMultiServiceFactory >& xServiceManager ) + : LayoutManager_Base ( ) + , ThreadHelpBase ( &Application::GetSolarMutex() ) + , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() ) + , LayoutManager_PBase ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) ) + , m_xSMGR( xServiceManager ) + , m_xURLTransformer( xServiceManager->createInstance( SERVICENAME_URLTRANSFORMER ), UNO_QUERY ) + , m_xDisplayAccess( xServiceManager->createInstance( SERVICENAME_DISPLAYACCESS ), UNO_QUERY ) + , m_nLockCount( 0 ) + , m_bActive( sal_False ) + , m_bInplaceMenuSet( sal_False ) + , m_bDockingInProgress( sal_False ) + , m_bMenuVisible( sal_True ) + , m_bComponentAttached( sal_False ) + , m_bDoLayout( sal_False ) + , m_bVisible( sal_True ) + , m_bParentWindowVisible( sal_False ) + , m_bMustDoLayout( sal_True ) + , m_bAutomaticToolbars( sal_True ) + , m_bStoreWindowState( sal_False ) + , m_bHideCurrentUI( false ) + , m_bGlobalSettings( sal_False ) + , m_bPreserveContentSize( false ) + , m_eDockOperation( DOCKOP_ON_COLROW ) + , m_pInplaceMenuBar( NULL ) + , m_xModuleManager( Reference< XModuleManager >( + xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY )) + , m_xUIElementFactoryManager( Reference< ::com::sun::star::ui::XUIElementFactory >( + xServiceManager->createInstance( SERVICENAME_UIELEMENTFACTORYMANAGER ), UNO_QUERY )) + , m_bMenuBarCloser( sal_False ) + , m_xPersistentWindowStateSupplier( Reference< XNameAccess >( + xServiceManager->createInstance( SERVICENAME_WINDOWSTATECONFIGURATION ), UNO_QUERY )) + , m_pGlobalSettings( 0 ) + , m_aCustomTbxPrefix( RTL_CONSTASCII_USTRINGPARAM( "custom_" )) + , m_aFullCustomTbxPrefix( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/custom_" )) + , m_aFullAddonTbxPrefix( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/addon_" )) + , m_aStatusBarAlias( RTL_CONSTASCII_USTRINGPARAM( "private:resource/statusbar/statusbar" )) + , m_aProgressBarAlias( RTL_CONSTASCII_USTRINGPARAM( "private:resource/progressbar/progressbar" )) + , m_aPropDocked( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_DOCKED )) + , m_aPropVisible( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_VISIBLE )) + , m_aPropDockingArea( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_DOCKINGAREA )) + , m_aPropDockPos( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_DOCKPOS )) + , m_aPropPos( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_POS )) + , m_aPropSize( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_SIZE )) + , m_aPropUIName( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_UINAME )) + , m_aPropStyle( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_STYLE )) + , m_aPropLocked( RTL_CONSTASCII_USTRINGPARAM( WINDOWSTATE_PROPERTY_LOCKED )) + , m_aCustomizeCmd( RTL_CONSTASCII_USTRINGPARAM( "ConfigureDialog" )) + , m_pAddonOptions( 0 ) + , m_aListenerContainer( m_aLock.getShareableOslMutex() ) + , m_pPanelManager( 0 ) +{ + // Initialize statusbar member + m_aStatusBarElement.m_aType = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "statusbar" )); + m_aStatusBarElement.m_aName = m_aStatusBarAlias; + + m_pMiscOptions = new SvtMiscOptions(); + + m_pMiscOptions->AddListenerLink( LINK( this, LayoutManager, OptionsChanged ) ); + Application::AddEventListener( LINK( this, LayoutManager, SettingsChanged ) ); + m_eSymbolsSize = m_pMiscOptions->GetSymbolsSize(); + m_eSymbolsStyle = m_pMiscOptions->GetCurrentSymbolsStyle(); + + m_aAsyncLayoutTimer.SetTimeout( 50 ); + m_aAsyncLayoutTimer.SetTimeoutHdl( LINK( this, LayoutManager, AsyncLayoutHdl ) ); + + registerProperty( LAYOUTMANAGER_PROPNAME_AUTOMATICTOOLBARS, LAYOUTMANAGER_PROPHANDLE_AUTOMATICTOOLBARS, css::beans::PropertyAttribute::TRANSIENT, &m_bAutomaticToolbars, ::getCppuType( &m_bAutomaticToolbars ) ); + registerProperty( LAYOUTMANAGER_PROPNAME_HIDECURRENTUI, LAYOUTMANAGER_PROPHANDLE_HIDECURRENTUI, css::beans::PropertyAttribute::TRANSIENT, &m_bHideCurrentUI, ::getCppuType( &m_bHideCurrentUI ) ); + registerProperty( LAYOUTMANAGER_PROPNAME_LOCKCOUNT, LAYOUTMANAGER_PROPHANDLE_LOCKCOUNT, css::beans::PropertyAttribute::TRANSIENT | css::beans::PropertyAttribute::READONLY, &m_nLockCount, getCppuType( &m_nLockCount ) ); + registerProperty( LAYOUTMANAGER_PROPNAME_MENUBARCLOSER, LAYOUTMANAGER_PROPHANDLE_MENUBARCLOSER, css::beans::PropertyAttribute::TRANSIENT, &m_bMenuBarCloser, ::getCppuType( &m_bMenuBarCloser ) ); + const sal_Bool bRefreshVisibility = sal_False; + registerPropertyNoMember( LAYOUTMANAGER_PROPNAME_REFRESHVISIBILITY, LAYOUTMANAGER_PROPHANDLE_REFRESHVISIBILITY, css::beans::PropertyAttribute::TRANSIENT, ::getCppuType( &bRefreshVisibility ), &bRefreshVisibility ); + registerProperty( LAYOUTMANAGER_PROPNAME_PRESERVE_CONTENT_SIZE, LAYOUTMANAGER_PROPHANDLE_PRESERVE_CONTENT_SIZE, css::beans::PropertyAttribute::TRANSIENT, &m_bPreserveContentSize, ::getCppuType( &m_bPreserveContentSize ) ); +} + +LayoutManager::~LayoutManager() +{ + Application::RemoveEventListener( LINK( this, LayoutManager, SettingsChanged ) ); + if ( m_pMiscOptions ) + { + m_pMiscOptions->RemoveListenerLink( LINK( this, LayoutManager, OptionsChanged ) ); + delete m_pMiscOptions; + m_pMiscOptions = 0; + } + m_aAsyncLayoutTimer.Stop(); +} + +// Internal helper function +void LayoutManager::impl_clearUpMenuBar() +{ + implts_lock(); + + // Clear up VCL menu bar to prepare shutdown + if ( m_xContainerWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); + while ( pWindow && !pWindow->IsSystemWindow() ) + pWindow = pWindow->GetParent(); + + if ( pWindow ) + { + MenuBar* pSetMenuBar = 0; + if ( m_xInplaceMenuBar.is() ) + pSetMenuBar = (MenuBar *)m_pInplaceMenuBar->GetMenuBar(); + else + { + Reference< css::awt::XMenuBar > xMenuBar; + + Reference< XPropertySet > xPropSet( m_xMenuBar, UNO_QUERY ); + if ( xPropSet.is() ) + { + try + { + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMenuBar" ))) >>= xMenuBar; + } + catch ( com::sun::star::beans::UnknownPropertyException ) + { + } + catch ( com::sun::star::lang::WrappedTargetException ) + { + } + } + + VCLXMenu* pAwtMenuBar = VCLXMenu::GetImplementation( xMenuBar ); + if ( pAwtMenuBar ) + pSetMenuBar = (MenuBar*)pAwtMenuBar->GetMenu(); + } + + MenuBar* pTopMenuBar = ((SystemWindow *)pWindow)->GetMenuBar(); + if ( pSetMenuBar == pTopMenuBar ) + ((SystemWindow *)pWindow)->SetMenuBar( 0 ); + } + } + + // reset inplace menubar manager + m_pInplaceMenuBar = 0; + if ( m_xInplaceMenuBar.is() ) + { + m_xInplaceMenuBar->dispose(); + m_xInplaceMenuBar.clear(); + } + + Reference< XComponent > xComp( m_xMenuBar, UNO_QUERY ); + if ( xComp.is() ) + xComp->dispose(); + m_xMenuBar.clear(); + implts_unlock(); +} + +sal_Bool LayoutManager::impl_parseResourceURL( const rtl::OUString aResourceURL, rtl::OUString& aElementType, rtl::OUString& aElementName ) +{ + URL aURL; + sal_Int32 nIndex = 0; + + aURL.Complete = aResourceURL; + m_xURLTransformer->parseStrict( aURL ); + + ::rtl::OUString aUIResource = aURL.Path.getToken( 0, (sal_Unicode)'/', nIndex ); + + if (( aURL.Protocol.equalsIgnoreAsciiCaseAscii( UIRESOURCE_PROTOCO_ASCII )) && + ( aUIResource.equalsIgnoreAsciiCaseAscii( UIRESOURCE_RESOURCE_ASCII ))) + { + aElementType = aURL.Path.getToken( 0, (sal_Unicode)'/', nIndex ); + aElementName = aURL.Path.getToken( 0, (sal_Unicode)'/', nIndex ); + return sal_True; + } + + return sal_False; +} + +void LayoutManager::implts_lock() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + ++m_nLockCount; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +sal_Bool LayoutManager::implts_unlock() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + --m_nLockCount; + if ( m_nLockCount < 0 ) + m_nLockCount = 0; + return ( m_nLockCount == 0 ); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +void LayoutManager::implts_reset( sal_Bool bAttached ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + Reference< XFrame > xFrame = m_xFrame; + Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow ); + Reference< css::awt::XWindow > xTopDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP]; + Reference< css::awt::XWindow > xLeftDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT]; + Reference< css::awt::XWindow > xRightDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT]; + Reference< css::awt::XWindow > xBottomDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM]; + Reference< XUIConfiguration > xModuleCfgMgr( m_xModuleCfgMgr, UNO_QUERY ); + Reference< XUIConfiguration > xDocCfgMgr( m_xDocCfgMgr, UNO_QUERY ); + Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); + Reference< XMultiServiceFactory > xServiceManager( m_xSMGR ); + Reference< XNameAccess > xPersistentWindowStateSupplier( m_xPersistentWindowStateSupplier ); + ::rtl::OUString aModuleIdentifier( m_aModuleIdentifier ); + sal_Bool bAutomaticToolbars( m_bAutomaticToolbars ); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + implts_lock(); + + Reference< XModel > xModel; + if ( xFrame.is() ) + { + if ( bAttached ) + { + ::rtl::OUString aOldModuleIdentifier( aModuleIdentifier ); + try + { + aModuleIdentifier = m_xModuleManager->identify( Reference< XInterface >( xFrame, UNO_QUERY ) ); + } + catch( Exception& ) + { + } + + if ( aModuleIdentifier.getLength() && aOldModuleIdentifier != aModuleIdentifier ) + { + Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier; + if ( xServiceManager.is() ) + xModuleCfgSupplier = Reference< XModuleUIConfigurationManagerSupplier >( + xServiceManager->createInstance( SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER ), UNO_QUERY ); + + if ( xModuleCfgMgr.is() ) + { + try + { + // Remove listener to old module ui configuration manager + xModuleCfgMgr->removeConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); + } + catch ( Exception& ) + { + } + } + + try + { + // Add listener to new module ui configuration manager + xModuleCfgMgr = Reference< XUIConfiguration >( xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier ), UNO_QUERY ); + if ( xModuleCfgMgr.is() ) + xModuleCfgMgr->addConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); + } + catch ( Exception& ) + { + } + + try + { + // Retrieve persistent window state reference for our new module + if ( xPersistentWindowStateSupplier.is() ) + xPersistentWindowStateSupplier->getByName( aModuleIdentifier ) >>= xPersistentWindowState; + } + catch ( NoSuchElementException& ) + { + } + catch ( WrappedTargetException& ) + { + } + } + + xModel = impl_getModelFromFrame( xFrame ); + if ( xModel.is() ) + { + Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier( xModel, UNO_QUERY ); + if ( xUIConfigurationManagerSupplier.is() ) + { + if ( xDocCfgMgr.is() ) + { + try + { + // Remove listener to old ui configuration manager + xDocCfgMgr->removeConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); + } + catch ( Exception& ) + { + } + } + + try + { + xDocCfgMgr = Reference< XUIConfiguration >( xUIConfigurationManagerSupplier->getUIConfigurationManager(), UNO_QUERY ); + if ( xDocCfgMgr.is() ) + xDocCfgMgr->addConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); + } + catch ( Exception& ) + { + } + } + } + } + else + { + // Remove configuration listeners before we can release our references + if ( xModuleCfgMgr.is() ) + { + try + { + xModuleCfgMgr->removeConfigurationListener( + Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); + } + catch ( Exception& ) + { + } + } + + if ( xDocCfgMgr.is() ) + { + try + { + xDocCfgMgr->removeConfigurationListener( + Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); + } + catch ( Exception& ) + { + } + } + + // Release references to our configuration managers as we currently don't have + // an attached module. + xModuleCfgMgr.clear(); + xDocCfgMgr.clear(); + xPersistentWindowState.clear(); + aModuleIdentifier = ::rtl::OUString(); + } + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_xModel = xModel; + m_aDockingArea = css::awt::Rectangle(); + m_bComponentAttached = bAttached; + m_aModuleIdentifier = aModuleIdentifier; + m_xModuleCfgMgr = Reference< XUIConfigurationManager >( xModuleCfgMgr, UNO_QUERY ); + m_xDocCfgMgr = Reference< XUIConfigurationManager >( xDocCfgMgr, UNO_QUERY ); + m_xPersistentWindowState = xPersistentWindowState; + m_aStatusBarElement.m_bStateRead = sal_False; // reset state to read data again! + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( bAttached ) + { + // reset docking area windows back to zero size + try + { + if ( xTopDockingWindow.is() ) + xTopDockingWindow->setPosSize( 0, 0, 0, 0, css::awt::PosSize::POSSIZE ); + if ( xLeftDockingWindow.is() ) + xLeftDockingWindow->setPosSize( 0, 0, 0, 0, css::awt::PosSize::POSSIZE ); + if ( xRightDockingWindow.is() ) + xRightDockingWindow->setPosSize( 0, 0, 0, 0, css::awt::PosSize::POSSIZE ); + if ( xBottomDockingWindow.is() ) + xBottomDockingWindow->setPosSize( 0, 0, 0, 0, css::awt::PosSize::POSSIZE ); + } + catch ( Exception& ) + { + } + + if ( bAutomaticToolbars ) + { + implts_createCustomToolBars(); + implts_createAddonsToolBars(); + implts_createNonContextSensitiveToolBars(); + } + implts_sortUIElements(); + } + else + implts_destroyElements(); + } + + implts_unlock(); +} + +sal_Bool LayoutManager::implts_isEmbeddedLayoutManager() const +{ + // check if this layout manager is currently using the embedded feature + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + Reference< XFrame > xFrame = m_xFrame; + Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow ); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + Reference< css::awt::XWindow > xFrameContainerWindow = xFrame->getContainerWindow(); + if ( xFrameContainerWindow == xContainerWindow ) + return sal_False; + else + return sal_True; +} + +void LayoutManager::implts_destroyElements() +{ + UIElementVector aUIElementVector; + + WriteGuard aWriteLock( m_aLock ); + aUIElementVector = m_aUIElements; + m_aUIElements.clear(); + aWriteLock.unlock(); + + UIElementVector::iterator pIter; + for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ ) + { + Reference< XComponent > xComponent( pIter->m_xUIElement, UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); + } + + implts_destroyStatusBar(); + + aWriteLock.lock(); + impl_clearUpMenuBar(); + aWriteLock.unlock(); +} + +void LayoutManager::implts_destroyDockingAreaWindows() +{ + std::vector< Reference< css::awt::XWindow > > oldDockingAreaWindows; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP] ); + oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM] ); + oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT] ); + oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT] ); + + m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP].clear(); + m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM].clear(); + m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT].clear(); + m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT].clear(); + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + const sal_uInt32 nCount = oldDockingAreaWindows.size(); + for ( sal_uInt32 i=0; i < nCount; i++ ) + { + if ( oldDockingAreaWindows[i].is() ) + { + try + { + oldDockingAreaWindows[i]->dispose(); + } + catch ( Exception& ) + { + } + } + } +} + +void LayoutManager::implts_createCustomToolBar( const rtl::OUString& aTbxResName, const rtl::OUString& aTitle ) +{ + if ( aTbxResName.getLength() > 0 ) + { + createElement( aTbxResName ); + if ( aTitle ) + { + Reference< XUIElement > xUIElement = getElement( aTbxResName ); + if ( xUIElement.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + pWindow->SetText( aTitle ); + } + } + } +} + +void LayoutManager::implts_createCustomToolBars( + const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >& aTbxSeqSeq ) +{ + const Sequence< PropertyValue >* pTbxSeq = aTbxSeqSeq.getConstArray(); + for ( sal_Int32 i = 0; i < aTbxSeqSeq.getLength(); i++ ) + { + const Sequence< PropertyValue >& rTbxSeq = pTbxSeq[i]; + ::rtl::OUString aTbxResName; + ::rtl::OUString aTbxTitle; + for ( sal_Int32 j = 0; j < rTbxSeq.getLength(); j++ ) + { + if ( rTbxSeq[j].Name.equalsAscii( "ResourceURL" )) + rTbxSeq[j].Value >>= aTbxResName; + else if ( rTbxSeq[j].Name.equalsAscii( "UIName" )) + rTbxSeq[j].Value >>= aTbxTitle; + } + + // Only create custom toolbars. Their name have to start with "custom_"! + if ( aTbxResName.getLength() > 0 && aTbxResName.indexOf( m_aCustomTbxPrefix ) != -1 ) + implts_createCustomToolBar( aTbxResName, aTbxTitle ); + } +} + +void LayoutManager::implts_createCustomToolBars() +{ + ReadGuard aReadLock( m_aLock ); + if ( !m_bComponentAttached ) + return; + + Reference< XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager ); + Reference< XFrame > xFrame( m_xFrame ); + Reference< XModel > xModel; + Reference< XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr, UNO_QUERY ); + Reference< XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr, UNO_QUERY ); + aReadLock.unlock(); + + if ( xFrame.is() ) + { + xModel = impl_getModelFromFrame( xFrame ); + if ( implts_isPreviewModel( xModel )) + return; // no custom toolbars for preview frame! + + Sequence< Sequence< PropertyValue > > aTbxSeq; + if ( xDocCfgMgr.is() ) + { + aTbxSeq = xDocCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR ); + implts_createCustomToolBars( aTbxSeq ); // first create all document based toolbars + } + if ( xModuleCfgMgr.is() ) + { + aTbxSeq = xModuleCfgMgr->getUIElementsInfo( UIElementType::TOOLBAR ); + implts_createCustomToolBars( aTbxSeq ); // second create module based toolbars + } + } +} + +rtl::OUString LayoutManager::implts_generateGenericAddonToolbarTitle( sal_Int32 nNumber ) const +{ + String aAddonGenericTitle; + + aAddonGenericTitle = String( FwkResId( STR_TOOLBAR_TITLE_ADDON )); + const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper(); + + String aNumStr = rI18nHelper.GetNum( nNumber, 0, FALSE, FALSE ); + aAddonGenericTitle.SearchAndReplaceAscii( "%num%", aNumStr ); + + return rtl::OUString( aAddonGenericTitle ); +} + +void LayoutManager::implts_createAddonsToolBars() +{ + WriteGuard aWriteLock( m_aLock ); + if ( !m_bComponentAttached ) + return; + + Reference< XModel > xModel; + Reference< XFrame > xFrame( m_xFrame ); + if ( !xFrame.is() ) + return; + + if ( !m_pAddonOptions ) + m_pAddonOptions = new AddonsOptions; + + Reference< XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager ); + aWriteLock.unlock(); + + xModel = impl_getModelFromFrame( xFrame ); + if ( implts_isPreviewModel( xModel )) + return; // no addon toolbars for preview frame! + + UIElementVector aUIElementVector; + Sequence< Sequence< PropertyValue > > aAddonToolBarData; + Reference< XUIElement > xUIElement; + + sal_uInt32 nCount = m_pAddonOptions->GetAddonsToolBarCount(); + ::rtl::OUString aAddonsToolBarStaticName( m_aFullAddonTbxPrefix ); + ::rtl::OUString aElementType( RTL_CONSTASCII_USTRINGPARAM( "toolbar" )); + + Sequence< PropertyValue > aPropSeq( 2 ); + aPropSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); + aPropSeq[0].Value <<= xFrame; + aPropSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationData" )); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + ::rtl::OUString aAddonToolBarName( aAddonsToolBarStaticName + m_pAddonOptions->GetAddonsToolbarResourceName(i) ); + aAddonToolBarData = m_pAddonOptions->GetAddonsToolBarPart( i ); + aPropSeq[1].Value <<= aAddonToolBarData; + + aWriteLock.lock(); + UIElement aElement = impl_findElement( aAddonToolBarName ); + aWriteLock.unlock(); + + // #i79828 + // It's now possible that we are called more than once. Be sure to not create + // add-on toolbars more than once! + if ( aElement.m_xUIElement.is() ) + continue; + + try + { + xUIElement = xUIElementFactory->createUIElement( aAddonToolBarName, aPropSeq ); + if ( xUIElement.is() ) + { + Reference< css::awt::XDockableWindow > xDockWindow( xUIElement->getRealInterface(), UNO_QUERY ); + if ( xDockWindow.is() ) + { + try + { + xDockWindow->addDockableWindowListener( Reference< css::awt::XDockableWindowListener >( static_cast< OWeakObject * >( this ), UNO_QUERY )); + xDockWindow->enableDocking( sal_True ); + Reference< css::awt::XWindow > xWindow( xDockWindow, UNO_QUERY ); + if ( xWindow.is() ) + xWindow->addWindowListener( Reference< css::awt::XWindowListener >( static_cast< OWeakObject * >( this ), UNO_QUERY )); + } + catch ( Exception& ) + { + } + } + + ::rtl::OUString aGenericAddonTitle = implts_generateGenericAddonToolbarTitle( i+1 ); + + if ( aElement.m_aName.getLength() > 0 ) + { + // Reuse a local entry so we are able to use the latest + // UI changes for this document. + implts_setElementData( aElement, xDockWindow ); + aElement.m_xUIElement = xUIElement; + if ( aElement.m_aUIName.getLength() == 0 ) + { + aElement.m_aUIName = aGenericAddonTitle; + implts_writeWindowStateData( aElement.m_aName, aElement ); + } + } + else + { + // Create new UI element and try to read its state data + UIElement aNewToolbar( aAddonToolBarName, aElementType, xUIElement ); + aNewToolbar.m_bFloating = sal_True; + implts_readWindowStateData( aAddonToolBarName, aNewToolbar ); + implts_setElementData( aNewToolbar, xDockWindow ); + if ( aNewToolbar.m_aUIName.getLength() == 0 ) + { + aNewToolbar.m_aUIName = aGenericAddonTitle; + implts_writeWindowStateData( aNewToolbar.m_aName, aNewToolbar ); + } + implts_insertUIElement( aNewToolbar ); + } + + Reference< css::awt::XWindow > xWindow( xDockWindow, UNO_QUERY ); + if ( xWindow.is() ) + { + // Set generic title for add-on toolbar + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow->GetText().Len() == 0 ) + pWindow->SetText( aGenericAddonTitle ); + if ( pWindow->GetType() == WINDOW_TOOLBOX ) + { + ToolBox* pToolbar = (ToolBox *)pWindow; + pToolbar->SetMenuType(); + } + } + } + } + catch ( NoSuchElementException& ) + { + } + catch ( IllegalArgumentException& ) + { + } + } +} + +void LayoutManager::implts_createNonContextSensitiveToolBars() +{ + ReadGuard aReadLock( m_aLock ); + + if ( !m_xPersistentWindowState.is() || + !m_xFrame.is() || + !m_bComponentAttached ) + return; + + Reference< XFrame > xFrame( m_xFrame ); + + Reference< XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager ); + Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); + aReadLock.unlock(); + + if ( implts_isPreviewModel( impl_getModelFromFrame( xFrame ))) + return; + + std::vector< rtl::OUString > aMakeVisibleToolbars; + + try + { + Sequence< rtl::OUString > aToolbarNames = xPersistentWindowState->getElementNames(); + + if ( aToolbarNames.getLength() > 0 ) + { + rtl::OUString aElementType; + rtl::OUString aElementName; + rtl::OUString aName; + + Reference< ::com::sun::star::ui::XUIElement > xUIElement; + aMakeVisibleToolbars.reserve(aToolbarNames.getLength()); + WriteGuard aWriteLock( m_aLock ); + + const rtl::OUString* pTbNames = aToolbarNames.getConstArray(); + for ( sal_Int32 i = 0; i < aToolbarNames.getLength(); i++ ) + { + aName = pTbNames[i]; + if ( impl_parseResourceURL( aName, aElementType, aElementName )) + { + // Check that we only create: + // - Toolbars (the statusbar is also member of the persistent window state) + // - Not custom toolbars, there are created with their own method (implts_createCustomToolbars) + if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" ) && + aElementName.indexOf( m_aCustomTbxPrefix ) == -1 ) + { + UIElement aNewToolbar( aName, aElementType, xUIElement ); + bool bFound = implts_findElement( aName, aNewToolbar ); + if ( !bFound ) + implts_readWindowStateData( aName, aNewToolbar ); + + if ( aNewToolbar.m_bVisible && + !aNewToolbar.m_bContextSensitive ) + { + if ( !bFound ) + implts_insertUIElement( aNewToolbar ); + aMakeVisibleToolbars.push_back( aName ); + } + } + } + } + } + } + catch ( RuntimeException& e ) + { + throw e; + } + catch ( Exception& ) + { + } + + if ( !aMakeVisibleToolbars.empty() ) + { + implts_lock(); + ::std::for_each( aMakeVisibleToolbars.begin(), aMakeVisibleToolbars.end(),::boost::bind( &LayoutManager::requestElement, this,_1 )); + implts_unlock(); + } +} + +void LayoutManager::implts_toggleFloatingUIElementsVisibility( sal_Bool bActive ) +{ + WriteGuard aWriteLock( m_aLock ); + UIElementVector::iterator pIter; + + ReadGuard aReadLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_xUIElement.is() ) + { + Reference< css::awt::XDockableWindow > xDockWindow( pIter->m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XWindow > xWindow( xDockWindow, UNO_QUERY ); + if ( xDockWindow.is() && xWindow.is() ) + { + sal_Bool bVisible( sal_True ); + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + bVisible = pWindow->IsVisible(); + + if ( xDockWindow->isFloating() ) + { + if ( bActive ) + { + if ( !bVisible && pIter->m_bDeactiveHide ) + { + pIter->m_bDeactiveHide = sal_False; + // we need VCL here to pass special flags to Show() + if( pWindow ) + pWindow->Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); + //xWindow->setVisible( sal_True ); + } + } + else + { + if ( bVisible ) + { + pIter->m_bDeactiveHide = sal_True; + xWindow->setVisible( sal_False ); + } + } + } + } + } + } +} + +sal_Bool LayoutManager::implts_findElement( const rtl::OUString& aName, rtl::OUString& aElementType, rtl::OUString& aElementName, Reference< XUIElement >& xUIElement ) +{ + if ( impl_parseResourceURL( aName, aElementType, aElementName )) + { + if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "menubar" )) + { + ReadGuard aReadLock( m_aLock ); + xUIElement = m_xMenuBar; + return sal_True; + } + else if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || + ( m_aStatusBarElement.m_aName == aName )) + { + ReadGuard aReadLock( m_aLock ); + xUIElement = m_aStatusBarElement.m_xUIElement; + return sal_True; + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" )) + { + ReadGuard aReadLock( m_aLock ); + xUIElement = m_aProgressBarElement.m_xUIElement; + return sal_True; + } + else + { + UIElementVector::const_iterator pIter; + + ReadGuard aReadLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aName == aName ) + { + xUIElement = pIter->m_xUIElement; + return sal_True; + } + } + } + } + + return sal_False; +} + +sal_Bool LayoutManager::implts_findElement( const Reference< XInterface >& xUIElement, UIElement& aElementData ) +{ + UIElementVector::const_iterator pIter; + + ReadGuard aReadLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_xUIElement.is() ) + { + Reference< XInterface > xIfac( pIter->m_xUIElement->getRealInterface(), UNO_QUERY ); + if ( xIfac == xUIElement ) + { + aElementData = *pIter; + return sal_True; + } + } + } + + return sal_False; +} + +sal_Bool LayoutManager::implts_findElement( const rtl::OUString& aName, UIElement& aElementData ) +{ + UIElementVector::const_iterator pIter; + + ReadGuard aReadLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aName == aName ) + { + aElementData = *pIter; + return sal_True; + } + } + + return sal_False; +} + +UIElement& LayoutManager::impl_findElement( const rtl::OUString& aName ) +{ + static UIElement aEmptyElement; + + UIElementVector::iterator pIter; + + ReadGuard aReadLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aName == aName ) + return *pIter; + } + + return aEmptyElement; +} + +sal_Bool LayoutManager::implts_insertUIElement( const UIElement& rUIElement ) +{ + UIElement aTempData; + bool bFound = implts_findElement( rUIElement.m_aName, aTempData ); + +#ifdef DBG_UTIL + if ( bFound ) + { + char aBuffer[256]; + const sal_Int32 MAX_NAME_LENGTH = 128; + ::rtl::OString aName = ::rtl::OUStringToOString( rUIElement.m_aName, RTL_TEXTENCODING_ASCII_US ); + aName = aName.copy( ::std::min( MAX_NAME_LENGTH, aName.getLength() )); + sprintf( aBuffer, "Try to insert an already existing user interface element (%s) into the list\n", aName.getStr() ); + DBG_ASSERT( bFound, aBuffer ); + } +#endif + + bool bResult( false ); + if ( !bFound ) + { + WriteGuard aWriteLock( m_aLock ); + m_aUIElements.push_back( rUIElement ); + bResult = true; + } + return bResult; +} + +void LayoutManager::implts_writeNewStateData( const rtl::OUString aName, const Reference< css::awt::XWindow >& xWindow ) +{ + css::awt::Rectangle aPos; + css::awt::Size aSize; + sal_Bool bVisible( sal_False ); + sal_Bool bFloating( sal_True ); + + if ( xWindow.is() ) + { + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + if ( xDockWindow.is() ) + bFloating = xDockWindow->isFloating(); + + Reference< css::awt::XWindow2 > xWindow2( xWindow, UNO_QUERY ); + if( xWindow2.is() ) + { + aPos = xWindow2->getPosSize(); + aSize = xWindow2->getOutputSize(); // always use output size for consistency + bVisible = xWindow2->isVisible(); + } + } + + WriteGuard aWriteLock( m_aLock ); + UIElement& rUIElement = impl_findElement( aName ); + if ( rUIElement.m_xUIElement.is() && xWindow.is() ) + { + rUIElement.m_bVisible = bVisible; + rUIElement.m_bFloating = bFloating; + if ( bFloating ) + { + rUIElement.m_aFloatingData.m_aPos = ::Point( aPos.X, aPos.Y ); + rUIElement.m_aFloatingData.m_aSize = ::Size( aSize.Width, aSize.Height ); + } + } + + implts_writeWindowStateData( aName, rUIElement ); + + aWriteLock.unlock(); +} + +void LayoutManager::implts_refreshContextToolbarsVisibility() +{ + std::vector< UIElementVisibility > aToolbarVisibleVector; + + ReadGuard aReadLock( m_aLock ); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + if ( !m_bVisible || !m_bAutomaticToolbars ) + return; + + UIElementVisibility aUIElementVisible; + + UIElementVector::iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aType.equalsAsciiL( "toolbar", 7 )) + { + aUIElementVisible.aName = pIter->m_aName; + aUIElementVisible.bVisible = pIter->m_bVisible; + aToolbarVisibleVector.push_back( aUIElementVisible ); + } + } + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aReadLock.unlock(); + + UIElement aUIElement; + const sal_uInt32 nCount = aToolbarVisibleVector.size(); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + UIElementVisibility& rToolbar = aToolbarVisibleVector[i]; + + sal_Bool bVisible = rToolbar.bVisible; + if ( implts_readWindowStateData( rToolbar.aName, aUIElement ) && + aUIElement.m_bVisible != bVisible ) + { + WriteGuard aWriteLock( m_aLock ); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + UIElement& rUIElement = impl_findElement( rToolbar.aName ); + + if ( rUIElement.m_aName == rToolbar.aName ) + rUIElement.m_bVisible = aUIElement.m_bVisible; + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aWriteLock.unlock(); + } + } +} + +sal_Bool LayoutManager::implts_readWindowStateData( const rtl::OUString& aName, UIElement& rElementData ) +{ + sal_Bool bGetSettingsState( sal_False ); + + WriteGuard aWriteLock( m_aLock ); + Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); + aWriteLock.unlock(); + + if ( xPersistentWindowState.is() ) + { + aWriteLock.lock(); + sal_Bool bGlobalSettings( m_bGlobalSettings ); + GlobalSettings* pGlobalSettings( 0 ); + if ( m_pGlobalSettings == 0 ) + { + m_pGlobalSettings = new GlobalSettings( m_xSMGR ); + bGetSettingsState = sal_True; + } + pGlobalSettings = m_pGlobalSettings; + aWriteLock.unlock(); + + try + { + Sequence< PropertyValue > aWindowState; + if ( xPersistentWindowState->getByName( aName ) >>= aWindowState ) + { + sal_Bool bValue( sal_False ); + for ( sal_Int32 n = 0; n < aWindowState.getLength(); n++ ) + { + if ( aWindowState[n].Name == m_aPropDocked ) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_bFloating = !bValue; + } + else if ( aWindowState[n].Name == m_aPropVisible ) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_bVisible = bValue; + } + else if ( aWindowState[n].Name == m_aPropDockingArea ) + { + ::com::sun::star::ui::DockingArea eDockingArea; + if ( aWindowState[n].Value >>= eDockingArea ) + rElementData.m_aDockedData.m_nDockedArea = sal_Int16( eDockingArea ); + } + else if ( aWindowState[n].Name == m_aPropDockPos ) + { + css::awt::Point aPoint; + if ( aWindowState[n].Value >>= aPoint ) + { + rElementData.m_aDockedData.m_aPos.X() = aPoint.X; + rElementData.m_aDockedData.m_aPos.Y() = aPoint.Y; + } + } + else if ( aWindowState[n].Name == m_aPropPos ) + { + css::awt::Point aPoint; + if ( aWindowState[n].Value >>= aPoint ) + { + rElementData.m_aFloatingData.m_aPos.X() = aPoint.X; + rElementData.m_aFloatingData.m_aPos.Y() = aPoint.Y; + } + } + else if ( aWindowState[n].Name == m_aPropSize ) + { + css::awt::Size aSize; + if ( aWindowState[n].Value >>= aSize ) + { + rElementData.m_aFloatingData.m_aSize.Width() = aSize.Width; + rElementData.m_aFloatingData.m_aSize.Height() = aSize.Height; + } + } + else if ( aWindowState[n].Name == m_aPropUIName ) + aWindowState[n].Value >>= rElementData.m_aUIName; + else if ( aWindowState[n].Name == m_aPropStyle ) + { + sal_Int32 nStyle = 0; + if ( aWindowState[n].Value >>= nStyle ) + rElementData.m_nStyle = sal_Int16( nStyle ); + } + else if ( aWindowState[n].Name == m_aPropLocked ) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_aDockedData.m_bLocked = bValue; + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXT )) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_bContextSensitive = bValue; + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_NOCLOSE )) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_bNoClose = bValue; + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXTACTIVE )) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_bContextActive = bValue; + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_SOFTCLOSE )) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_bSoftClose = bValue; + } + } + } + + // oversteer values with global settings + if ( pGlobalSettings && ( bGetSettingsState || bGlobalSettings )) + { + if ( pGlobalSettings->HasStatesInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR )) + { + WriteGuard aWriteLock2( m_aLock ); + m_bGlobalSettings = sal_True; + aWriteLock2.unlock(); + + css::uno::Any aValue; + sal_Bool bValue = sal_Bool(); + if ( pGlobalSettings->GetStateInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR, + GlobalSettings::STATEINFO_LOCKED, + aValue )) + aValue >>= rElementData.m_aDockedData.m_bLocked; + if ( pGlobalSettings->GetStateInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR, + GlobalSettings::STATEINFO_DOCKED, + aValue )) + { + if ( aValue >>= bValue ) + rElementData.m_bFloating = !bValue; + } + } + } + + return sal_True; + } + catch ( NoSuchElementException& ) + { + } + } + + return sal_False; +} + +void LayoutManager::implts_writeWindowStateData( const rtl::OUString& aName, const UIElement& rElementData ) +{ + WriteGuard aWriteLock( m_aLock ); + Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); + + // set flag to determine that we triggered the notification + m_bStoreWindowState = sal_True; + aWriteLock.unlock(); + + sal_Bool bPersistent( sal_False ); + Reference< XPropertySet > xPropSet( rElementData.m_xUIElement, UNO_QUERY ); + if ( xPropSet.is() ) + { + try + { + // Check persistent flag of the user interface element + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Persistent" ))) >>= bPersistent; + } + catch ( com::sun::star::beans::UnknownPropertyException ) + { + // Non-configurable elements should at least store their dimension/position + bPersistent = sal_True; + } + catch ( com::sun::star::lang::WrappedTargetException ) + { + } + } + + if ( bPersistent && xPersistentWindowState.is() ) + { + try + { + Sequence< PropertyValue > aWindowState( 8 ); + + aWindowState[0].Name = m_aPropDocked; + aWindowState[0].Value = makeAny( sal_Bool( !rElementData.m_bFloating )); + aWindowState[1].Name = m_aPropVisible; + aWindowState[1].Value = makeAny( sal_Bool( rElementData.m_bVisible )); + + aWindowState[2].Name = m_aPropDockingArea; + aWindowState[2].Value = makeAny( static_cast< DockingArea >( rElementData.m_aDockedData.m_nDockedArea ) ); + + css::awt::Point aPos; + aPos.X = rElementData.m_aDockedData.m_aPos.X(); + aPos.Y = rElementData.m_aDockedData.m_aPos.Y(); + aWindowState[3].Name = m_aPropDockPos; + aWindowState[3].Value <<= aPos; + + aPos.X = rElementData.m_aFloatingData.m_aPos.X(); + aPos.Y = rElementData.m_aFloatingData.m_aPos.Y(); + aWindowState[4].Name = m_aPropPos; + aWindowState[4].Value <<= aPos; + + css::awt::Size aSize; + aSize.Width = rElementData.m_aFloatingData.m_aSize.Width(); + aSize.Height = rElementData.m_aFloatingData.m_aSize.Height(); + aWindowState[5].Name = m_aPropSize; + aWindowState[5].Value <<= aSize; + aWindowState[6].Name = m_aPropUIName; + aWindowState[6].Value = makeAny( rElementData.m_aUIName ); + aWindowState[7].Name = m_aPropLocked; + aWindowState[7].Value = makeAny( rElementData.m_aDockedData.m_bLocked ); + + if ( xPersistentWindowState->hasByName( aName )) + { + Reference< XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY ); + xReplace->replaceByName( aName, makeAny( aWindowState )); + } + else + { + Reference< XNameContainer > xInsert( xPersistentWindowState, uno::UNO_QUERY ); + xInsert->insertByName( aName, makeAny( aWindowState )); + } + } + catch ( Exception& ) + { + } + } + + // Reset flag + aWriteLock.lock(); + m_bStoreWindowState = sal_False; + aWriteLock.unlock(); +} + +void LayoutManager::implts_setElementData( UIElement& rElement, const Reference< css::awt::XDockableWindow >& rDockWindow ) +{ + ReadGuard aReadLock( m_aLock ); + sal_Bool bShowElement( rElement.m_bVisible && !rElement.m_bMasterHide && m_bParentWindowVisible ); + aReadLock.unlock(); + + Reference< css::awt::XDockableWindow > xDockWindow( rDockWindow ); + Reference< css::awt::XWindow2 > xWindow( xDockWindow, UNO_QUERY ); + + Window* pWindow( 0 ); + ToolBox* pToolBox( 0 ); + + if ( xDockWindow.is() && xWindow.is() ) + { + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + { + String aText = pWindow->GetText(); + if ( aText.Len() == 0 ) + pWindow->SetText( rElement.m_aUIName ); + if ( rElement.m_bNoClose ) + pWindow->SetStyle( pWindow->GetStyle() & ~WB_CLOSEABLE ); + if ( pWindow->GetType() == WINDOW_TOOLBOX ) + pToolBox = (ToolBox *)pWindow; + } + if ( pToolBox ) + { + if (( rElement.m_nStyle < 0 ) || + ( rElement.m_nStyle > BUTTON_SYMBOLTEXT )) + rElement.m_nStyle = BUTTON_SYMBOL; + pToolBox->SetButtonType( (ButtonType)rElement.m_nStyle ); + if ( rElement.m_bNoClose ) + pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() & ~WB_CLOSEABLE ); + } + } + + if ( rElement.m_bFloating ) + { + if ( pWindow ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + String aText = pWindow->GetText(); + if ( aText.Len() == 0 ) + pWindow->SetText( rElement.m_aUIName ); + } + + ::Point aPos( rElement.m_aFloatingData.m_aPos.X(), + rElement.m_aFloatingData.m_aPos.Y() ); + sal_Bool bWriteData( sal_False ); + sal_Bool bUndefPos = ( rElement.m_aFloatingData.m_aPos.X() == SAL_MAX_INT32 || + rElement.m_aFloatingData.m_aPos.Y() == SAL_MAX_INT32 ); + sal_Bool bSetSize = ( rElement.m_aFloatingData.m_aSize.Width() != 0 && + rElement.m_aFloatingData.m_aSize.Height() != 0 ); + xDockWindow->setFloatingMode( sal_True ); + if ( bUndefPos ) + { + aPos = implts_findNextCascadeFloatingPos(); + rElement.m_aFloatingData.m_aPos = aPos; // set new cascaded position + bWriteData = sal_True; + } + + if( bSetSize ) + xWindow->setOutputSize( AWTSize( rElement.m_aFloatingData.m_aSize ) ); + else + { + if( pToolBox ) + { + // set an optimal initial floating size + vos::OGuard aGuard( Application::GetSolarMutex() ); + ::Size aSize( pToolBox->CalcFloatingWindowSizePixel() ); + pToolBox->SetOutputSizePixel( aSize ); + } + } + + // #i60882# IMPORTANT: Set position after size as it is + // possible that we position some part of the toolbar + // outside of the desktop. A default constructed toolbar + // always has one line. Now VCL automatically + // position the toolbar back into the desktop. Therefore + // we resize the toolbar with the new (wrong) position. + // To fix this problem we have to set the size BEFORE the + // position. + xWindow->setPosSize( aPos.X(), aPos.Y(), 0, 0, + css::awt::PosSize::POS ); + + if ( bWriteData ) + implts_writeWindowStateData( rElement.m_aName, rElement ); + if ( bShowElement && pWindow ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); + } + } + else + { + ::Point aDockPos; + ::Point aPixelPos; + sal_Bool bSetSize( sal_False ); + ::Size aSize; + + if ( pToolBox ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pToolBox->SetAlign( ImplConvertAlignment(rElement.m_aDockedData.m_nDockedArea ) ); + pToolBox->SetLineCount( 1 ); + if ( rElement.m_aDockedData.m_bLocked ) + xDockWindow->lock(); + aSize = pToolBox->CalcWindowSizePixel(); + bSetSize = sal_True; + + if (( rElement.m_aDockedData.m_aPos.X() == SAL_MAX_INT32 ) && + ( rElement.m_aDockedData.m_aPos.Y() == SAL_MAX_INT32 )) + { + implts_findNextDockingPos( (DockingArea)rElement.m_aDockedData.m_nDockedArea, + aSize, + aDockPos, + aPixelPos ); + rElement.m_aDockedData.m_aPos = aDockPos; + } + } + + xWindow->setPosSize( aPixelPos.X(), + aPixelPos.Y(), + 0, 0, + css::awt::PosSize::POS ); + if( bSetSize ) + xWindow->setOutputSize( AWTSize( aSize) ); + + if ( bShowElement && pWindow ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pWindow->Show( sal_True ); + } + } + } +} + +::Point LayoutManager::implts_findNextCascadeFloatingPos() +{ + const sal_Int32 nHotZoneX = 50; + const sal_Int32 nHotZoneY = 50; + const sal_Int32 nCascadeIndentX = 15; + const sal_Int32 nCascadeIndentY = 15; + + ReadGuard aReadLock( m_aLock ); + Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow; + Reference< css::awt::XWindow > xTopDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP]; + Reference< css::awt::XWindow > xLeftDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT]; + aReadLock.unlock(); + + ::Point aStartPos( nCascadeIndentX, nCascadeIndentY ); + ::Point aCurrPos( aStartPos ); + css::awt::Rectangle aRect; + + Window* pContainerWindow( 0 ); + if ( xContainerWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + if ( pContainerWindow ) + aStartPos = pContainerWindow->OutputToScreenPixel( aStartPos ); + } + + // Determine size of top and left docking area + css::awt::Rectangle aTopRect = xTopDockingWindow->getPosSize(); + css::awt::Rectangle aLeftRect = xLeftDockingWindow->getPosSize(); + + aStartPos.X() += aLeftRect.Width + nCascadeIndentX; + aStartPos.Y() += aTopRect.Height + nCascadeIndentY; + aCurrPos = aStartPos; + + // Try to find a cascaded position for the new floating window + UIElementVector::const_iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_xUIElement.is() ) + { + Reference< css::awt::XDockableWindow > xDockWindow( pIter->m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XWindow > xWindow( xDockWindow, UNO_QUERY ); + if ( xDockWindow.is() && xDockWindow->isFloating() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->IsVisible() ) + { + css::awt::Rectangle aFloatRect = xWindow->getPosSize(); + if ((( aFloatRect.X - nHotZoneX ) <= aCurrPos.X() ) && + ( aFloatRect.X >= aCurrPos.X() ) && + (( aFloatRect.Y - nHotZoneY ) <= aCurrPos.Y() ) && + ( aFloatRect.Y >= aCurrPos.Y() )) + { + aCurrPos.X() = aFloatRect.X + nCascadeIndentX; + aCurrPos.Y() = aFloatRect.Y + nCascadeIndentY; + } + } + } + } + } + + return aCurrPos; +} + +void LayoutManager::implts_findNextDockingPos( DockingArea DockingArea, const ::Size& aUIElementSize, ::Point& rVirtualPos, ::Point& rPixelPos ) +{ + ReadGuard aReadLock( m_aLock ); + Reference< css::awt::XWindow > xDockingWindow = m_xDockAreaWindows[DockingArea]; + ::Size aDockingWinSize; + Window* pDockingWindow( 0 ); + aReadLock.unlock(); + + if (( DockingArea < DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea > DockingArea_DOCKINGAREA_RIGHT )) + DockingArea = DockingArea_DOCKINGAREA_TOP; + + { + // Retrieve output size from container Window + vos::OGuard aGuard( Application::GetSolarMutex() ); + pDockingWindow = VCLUnoHelper::GetWindow( xDockingWindow ); + if ( pDockingWindow ) + aDockingWinSize = pDockingWindow->GetOutputSizePixel(); + } + + sal_Int32 nFreeRowColPixelPos( 0 ); + sal_Int32 nMaxSpace( 0 ); + sal_Int32 nNeededSpace( 0 ); + sal_Int32 nTopDockingAreaSize( 0 ); + + if (( DockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea == DockingArea_DOCKINGAREA_BOTTOM )) + { + nMaxSpace = aDockingWinSize.Width(); + nNeededSpace = aUIElementSize.Width(); + } + else + { + nMaxSpace = aDockingWinSize.Height(); + nNeededSpace = aUIElementSize.Height(); + nTopDockingAreaSize = implts_getTopBottomDockingAreaSizes().Width(); + } + + std::vector< SingleRowColumnWindowData > aRowColumnsWindowData; + + implts_getDockingAreaElementInfos( DockingArea, aRowColumnsWindowData ); + sal_Int32 nPixelPos( 0 ); + const sal_uInt32 nCount = aRowColumnsWindowData.size(); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + SingleRowColumnWindowData& rRowColumnWindowData = aRowColumnsWindowData[i]; + + if (( DockingArea == DockingArea_DOCKINGAREA_BOTTOM ) || + ( DockingArea == DockingArea_DOCKINGAREA_RIGHT )) + nPixelPos += rRowColumnWindowData.nStaticSize; + + if ((( nMaxSpace - rRowColumnWindowData.nVarSize ) >= nNeededSpace ) || + ( rRowColumnWindowData.nSpace >= nNeededSpace )) + { + // Check current row where we can find the needed space + sal_Int32 nCurrPos( 0 ); + const sal_uInt32 nWindowSizesCount = rRowColumnWindowData.aRowColumnWindowSizes.size(); + for ( sal_uInt32 j = 0; j < nWindowSizesCount; j++ ) + { + css::awt::Rectangle rRect = rRowColumnWindowData.aRowColumnWindowSizes[j]; + sal_Int32& rSpace = rRowColumnWindowData.aRowColumnSpace[j]; + if (( DockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea == DockingArea_DOCKINGAREA_BOTTOM )) + { + if ( rSpace >= nNeededSpace ) + { + rVirtualPos = ::Point( nCurrPos, rRowColumnWindowData.nRowColumn ); + if ( DockingArea == DockingArea_DOCKINGAREA_TOP ) + rPixelPos = ::Point( nCurrPos, nPixelPos ); + else + rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos ); + return; + } + nCurrPos = rRect.X + rRect.Width; + } + else + { + if ( rSpace >= nNeededSpace ) + { + rVirtualPos = ::Point( rRowColumnWindowData.nRowColumn, nCurrPos ); + if ( DockingArea == DockingArea_DOCKINGAREA_LEFT ) + rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos ); + else + rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos ); + return; + } + nCurrPos = rRect.Y + rRect.Height; + } + } + + if (( nCurrPos + nNeededSpace ) <= nMaxSpace ) + { + if (( DockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea == DockingArea_DOCKINGAREA_BOTTOM )) + { + rVirtualPos = ::Point( nCurrPos, rRowColumnWindowData.nRowColumn ); + if ( DockingArea == DockingArea_DOCKINGAREA_TOP ) + rPixelPos = ::Point( nCurrPos, nPixelPos ); + else + rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos ); + return; + } + else + { + rVirtualPos = ::Point( rRowColumnWindowData.nRowColumn, nCurrPos ); + if ( DockingArea == DockingArea_DOCKINGAREA_LEFT ) + rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos ); + else + rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos ); + return; + } + } + } + + if (( DockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea == DockingArea_DOCKINGAREA_LEFT )) + nPixelPos += rRowColumnWindowData.nStaticSize; + } + + sal_Int32 nNextFreeRowCol( 0 ); + sal_Int32 nRowColumnsCount = aRowColumnsWindowData.size(); + if ( nRowColumnsCount > 0 ) + nNextFreeRowCol = aRowColumnsWindowData[nRowColumnsCount-1].nRowColumn+1; + else + nNextFreeRowCol = 0; + + if ( nNextFreeRowCol == 0 ) + { + if ( DockingArea == DockingArea_DOCKINGAREA_BOTTOM ) + nFreeRowColPixelPos = aDockingWinSize.Height() - aUIElementSize.Height(); + else if ( DockingArea == DockingArea_DOCKINGAREA_RIGHT ) + nFreeRowColPixelPos = aDockingWinSize.Width() - aUIElementSize.Width(); + } + + if (( DockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea == DockingArea_DOCKINGAREA_BOTTOM )) + { + rVirtualPos = ::Point( 0, nNextFreeRowCol ); + if ( DockingArea == DockingArea_DOCKINGAREA_TOP ) + rPixelPos = ::Point( 0, nFreeRowColPixelPos ); + else + rPixelPos = ::Point( 0, aDockingWinSize.Height() - nFreeRowColPixelPos ); + } + else + { + rVirtualPos = ::Point( nNextFreeRowCol, 0 ); + rPixelPos = ::Point( aDockingWinSize.Width() - nFreeRowColPixelPos, 0 ); + } +} + +::Size LayoutManager::implts_getContainerWindowOutputSize() +{ + ReadGuard aReadLock( m_aLock ); + Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow; + ::Size aContainerWinSize; + Window* pContainerWindow( 0 ); + aReadLock.unlock(); + + // Retrieve output size from container Window + vos::OGuard aGuard( Application::GetSolarMutex() ); + pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + if ( pContainerWindow ) + return pContainerWindow->GetOutputSizePixel(); + else + return ::Size(); +} + +void LayoutManager::implts_sortUIElements() +{ + WriteGuard aWriteLock( m_aLock ); + UIElementVector::iterator pIterStart = m_aUIElements.begin(); + UIElementVector::iterator pIterEnd = m_aUIElements.end(); + + std::stable_sort( pIterStart, pIterEnd ); // first created element should first + + // We have to reset our temporary flags. + UIElementVector::iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + // why check, just set it to false + //if ( pIter->m_bUserActive ) + pIter->m_bUserActive = sal_False; + } + +#ifdef DBG_UTIL + implts_checkElementContainer(); +#endif + aWriteLock.unlock(); +} + +void LayoutManager::implts_getDockingAreaElementInfos( DockingArea eDockingArea, std::vector< SingleRowColumnWindowData >& rRowColumnsWindowData ) +{ + std::vector< UIElement > aWindowVector; + + if (( eDockingArea < DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea > DockingArea_DOCKINGAREA_RIGHT )) + eDockingArea = DockingArea_DOCKINGAREA_TOP; + + Reference< css::awt::XWindow > xDockAreaWindow; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + aWindowVector.reserve(m_aUIElements.size()); + xDockAreaWindow = m_xDockAreaWindows[eDockingArea]; + UIElementVector::iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aDockedData.m_nDockedArea == eDockingArea && pIter->m_bVisible && !pIter->m_bFloating ) + { + Reference< XUIElement > xUIElement( pIter->m_xUIElement ); + if ( xUIElement.is() ) + { + Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + if ( xDockWindow.is() ) + { + // docked windows + aWindowVector.push_back( *pIter ); + } + } + } + } + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + rRowColumnsWindowData.clear(); + + // Collect data from windows that are on the same row/column + sal_Int32 j; + sal_Int32 nIndex( 0 ); + sal_Int32 nLastPos( 0 ); + sal_Int32 nCurrPos( -1 ); + sal_Int32 nLastRowColPixelPos( 0 ); + css::awt::Rectangle aDockAreaRect; + + if ( xDockAreaWindow.is() ) + aDockAreaRect = xDockAreaWindow->getPosSize(); + + if ( eDockingArea == DockingArea_DOCKINGAREA_TOP ) + nLastRowColPixelPos = 0; + else if ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM ) + nLastRowColPixelPos = aDockAreaRect.Height; + else if ( eDockingArea == DockingArea_DOCKINGAREA_LEFT ) + nLastRowColPixelPos = 0; + else + nLastRowColPixelPos = aDockAreaRect.Width; + + const sal_uInt32 nCount = aWindowVector.size(); + for ( j = 0; j < sal_Int32( nCount); j++ ) + { + const UIElement& rElement = aWindowVector[j]; + Reference< css::awt::XWindow > xWindow; + Reference< XUIElement > xUIElement( rElement.m_xUIElement ); + css::awt::Rectangle aPosSize; + if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) ) + continue; + if (( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )) + { + if ( nCurrPos == -1 ) + { + nCurrPos = rElement.m_aDockedData.m_aPos.Y(); + nLastPos = 0; + + SingleRowColumnWindowData aRowColumnWindowData; + aRowColumnWindowData.nRowColumn = nCurrPos; + rRowColumnsWindowData.push_back( aRowColumnWindowData ); + } + + sal_Int32 nSpace( 0 ); + if ( rElement.m_aDockedData.m_aPos.Y() != nCurrPos ) + { + if ( eDockingArea == DockingArea_DOCKINGAREA_TOP ) + nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize; + else + nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize; + ++nIndex; + nLastPos = 0; + nCurrPos = rElement.m_aDockedData.m_aPos.Y(); + SingleRowColumnWindowData aRowColumnWindowData; + aRowColumnWindowData.nRowColumn = nCurrPos; + rRowColumnsWindowData.push_back( aRowColumnWindowData ); + } + + // Calc space before an element and store it + nSpace = ( rElement.m_aDockedData.m_aPos.X() - nLastPos ); + if ( rElement.m_aDockedData.m_aPos.X() >= nLastPos ) + { + rRowColumnsWindowData[nIndex].nSpace += nSpace; + nLastPos = rElement.m_aDockedData.m_aPos.X() + aPosSize.Width; + } + else + { + nSpace = 0; + nLastPos += aPosSize.Width; + } + rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace ); + + rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow ); + rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName ); + rRowColumnsWindowData[nIndex].aRowColumnWindowSizes.push_back( + css::awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), + rElement.m_aDockedData.m_aPos.Y(), + aPosSize.Width, + aPosSize.Height )); + if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Height ) + rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Height; + if ( eDockingArea == DockingArea_DOCKINGAREA_TOP ) + rRowColumnsWindowData[nIndex].aRowColumnRect = css::awt::Rectangle( 0, nLastRowColPixelPos, + aDockAreaRect.Width, aPosSize.Height ); + else + rRowColumnsWindowData[nIndex].aRowColumnRect = css::awt::Rectangle( 0, ( nLastRowColPixelPos - aPosSize.Height ), + aDockAreaRect.Width, aPosSize.Height ); + rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Width + nSpace; + } + else + { + if ( nCurrPos == -1 ) + { + nCurrPos = rElement.m_aDockedData.m_aPos.X(); + nLastPos = 0; + + SingleRowColumnWindowData aRowColumnWindowData; + aRowColumnWindowData.nRowColumn = nCurrPos; + rRowColumnsWindowData.push_back( aRowColumnWindowData ); + } + + sal_Int32 nSpace( 0 ); + if ( rElement.m_aDockedData.m_aPos.X() != nCurrPos ) + { + if ( eDockingArea == DockingArea_DOCKINGAREA_LEFT ) + nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize; + else + nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize; + ++nIndex; + nLastPos = 0; + nCurrPos = rElement.m_aDockedData.m_aPos.X(); + SingleRowColumnWindowData aRowColumnWindowData; + aRowColumnWindowData.nRowColumn = nCurrPos; + rRowColumnsWindowData.push_back( aRowColumnWindowData ); + } + + // Calc space before an element and store it + nSpace = ( rElement.m_aDockedData.m_aPos.Y() - nLastPos ); + if ( rElement.m_aDockedData.m_aPos.Y() > nLastPos ) + { + rRowColumnsWindowData[nIndex].nSpace += nSpace; + nLastPos = rElement.m_aDockedData.m_aPos.Y() + aPosSize.Height; + } + else + { + nSpace = 0; + nLastPos += aPosSize.Height; + } + rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace ); + + rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow ); + rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName ); + rRowColumnsWindowData[nIndex].aRowColumnWindowSizes.push_back( + css::awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), + rElement.m_aDockedData.m_aPos.Y(), + aPosSize.Width, + aPosSize.Height )); + if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Width ) + rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Width; + if ( eDockingArea == DockingArea_DOCKINGAREA_LEFT ) + rRowColumnsWindowData[nIndex].aRowColumnRect = css::awt::Rectangle( nLastRowColPixelPos, 0, + aPosSize.Width, aDockAreaRect.Height ); + else + rRowColumnsWindowData[nIndex].aRowColumnRect = css::awt::Rectangle( ( nLastRowColPixelPos - aPosSize.Width ), 0, + aPosSize.Width, aDockAreaRect.Height ); + rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Height + nSpace; + } + } +} + +void LayoutManager::implts_getDockingAreaElementInfoOnSingleRowCol( DockingArea eDockingArea, sal_Int32 nRowCol, SingleRowColumnWindowData& rRowColumnWindowData ) +{ + std::vector< UIElement > aWindowVector; + + if (( eDockingArea < DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea > DockingArea_DOCKINGAREA_RIGHT )) + eDockingArea = DockingArea_DOCKINGAREA_TOP; + + sal_Bool bHorzDockArea = (( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + UIElementVector::iterator pIter; + UIElementVector::iterator pEnd = m_aUIElements.end(); + for ( pIter = m_aUIElements.begin(); pIter != pEnd; pIter++ ) + { + if ( pIter->m_aDockedData.m_nDockedArea == eDockingArea ) + { + sal_Bool bSameRowCol = bHorzDockArea ? + ( pIter->m_aDockedData.m_aPos.Y() == nRowCol ) : + ( pIter->m_aDockedData.m_aPos.X() == nRowCol ); + Reference< XUIElement > xUIElement( pIter->m_xUIElement ); + + if ( bSameRowCol && xUIElement.is() ) + { + Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); + if ( xWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + if ( pWindow && pIter->m_bVisible && xDockWindow.is() && !pIter->m_bFloating ) + { + // docked windows + aWindowVector.push_back( *pIter ); + } + } + } + } + } + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + // Initialize structure + rRowColumnWindowData.aUIElementNames.clear(); + rRowColumnWindowData.aRowColumnWindows.clear(); + rRowColumnWindowData.aRowColumnWindowSizes.clear(); + rRowColumnWindowData.aRowColumnSpace.clear(); + rRowColumnWindowData.nVarSize = 0; + rRowColumnWindowData.nStaticSize = 0; + rRowColumnWindowData.nSpace = 0; + rRowColumnWindowData.nRowColumn = nRowCol; + + // Collect data from windows that are on the same row/column + sal_Int32 j; + sal_Int32 nLastPos( 0 ); + + const sal_uInt32 nCount = aWindowVector.size(); + for ( j = 0; j < sal_Int32( nCount); j++ ) + { + const UIElement& rElement = aWindowVector[j]; + Reference< css::awt::XWindow > xWindow; + Reference< XUIElement > xUIElement( rElement.m_xUIElement ); + css::awt::Rectangle aPosSize; + if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) ) + continue; + + sal_Int32 nSpace; + if (( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )) + { + nSpace = ( rElement.m_aDockedData.m_aPos.X() - nLastPos ); + + // Calc space before an element and store it + if ( rElement.m_aDockedData.m_aPos.X() > nLastPos ) + rRowColumnWindowData.nSpace += nSpace; + else + nSpace = 0; + + nLastPos = rElement.m_aDockedData.m_aPos.X() + aPosSize.Width; + + + rRowColumnWindowData.aRowColumnWindowSizes.push_back( + css::awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), + rElement.m_aDockedData.m_aPos.Y(), + aPosSize.Width, + aPosSize.Height )); + if ( rRowColumnWindowData.nStaticSize < aPosSize.Height ) + rRowColumnWindowData.nStaticSize = aPosSize.Height; + rRowColumnWindowData.nVarSize += aPosSize.Width; + } + else + { + // Calc space before an element and store it + nSpace = ( rElement.m_aDockedData.m_aPos.Y() - nLastPos ); + if ( rElement.m_aDockedData.m_aPos.Y() > nLastPos ) + rRowColumnWindowData.nSpace += nSpace; + else + nSpace = 0; + + nLastPos = rElement.m_aDockedData.m_aPos.Y() + aPosSize.Height; + + rRowColumnWindowData.aRowColumnWindowSizes.push_back( + css::awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), + rElement.m_aDockedData.m_aPos.Y(), + aPosSize.Width, + aPosSize.Height )); + if ( rRowColumnWindowData.nStaticSize < aPosSize.Width ) + rRowColumnWindowData.nStaticSize = aPosSize.Width; + rRowColumnWindowData.nVarSize += aPosSize.Height; + } + + rRowColumnWindowData.aUIElementNames.push_back( rElement.m_aName ); + rRowColumnWindowData.aRowColumnWindows.push_back( xWindow ); + rRowColumnWindowData.aRowColumnSpace.push_back( nSpace ); + rRowColumnWindowData.nVarSize += nSpace; + } +} + +::Rectangle LayoutManager::implts_determineFrontDockingRect( + DockingArea eDockingArea, + sal_Int32 nRowCol, + const ::Rectangle& rDockedElementRect, + const ::rtl::OUString& rMovedElementName, + const ::Rectangle& rMovedElementRect ) +{ + SingleRowColumnWindowData aRowColumnWindowData; + + sal_Bool bHorzDockArea = (( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )); + + implts_getDockingAreaElementInfoOnSingleRowCol( eDockingArea, nRowCol, aRowColumnWindowData ); + if ( aRowColumnWindowData.aRowColumnWindows.empty() ) + return rMovedElementRect; + else + { + sal_Int32 nSpace( 0 ); + ::Rectangle aFrontDockingRect( rMovedElementRect ); + const sal_uInt32 nCount = aRowColumnWindowData.aRowColumnWindows.size(); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + if ( bHorzDockArea ) + { + if ( aRowColumnWindowData.aRowColumnWindowSizes[i].X >= rDockedElementRect.Left() ) + { + nSpace += aRowColumnWindowData.aRowColumnSpace[i]; + break; + } + else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName ) + nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Width + + aRowColumnWindowData.aRowColumnSpace[i]; + else + nSpace = 0; + } + else + { + if ( aRowColumnWindowData.aRowColumnWindowSizes[i].Y >= rDockedElementRect.Top() ) + { + nSpace += aRowColumnWindowData.aRowColumnSpace[i]; + break; + } + else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName ) + nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Height + + aRowColumnWindowData.aRowColumnSpace[i]; + else + nSpace = 0; + } + } + + if ( nSpace > 0 ) + { + sal_Int32 nMove = std::min( nSpace, static_cast<sal_Int32>(aFrontDockingRect.getWidth()) ); + if ( bHorzDockArea ) + aFrontDockingRect.Move( -nMove, 0 ); + else + aFrontDockingRect.Move( 0, -nMove ); + } + + return aFrontDockingRect; + } +} + +::Rectangle LayoutManager::implts_getWindowRectFromRowColumn( + ::com::sun::star::ui::DockingArea DockingArea, + const SingleRowColumnWindowData& rRowColumnWindowData, + const ::Point& rMousePos, + const rtl::OUString& rExcludeElementName ) +{ + ::Rectangle aWinRect; + + if (( DockingArea < DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea > DockingArea_DOCKINGAREA_RIGHT )) + DockingArea = DockingArea_DOCKINGAREA_TOP; + + if ( rRowColumnWindowData.aRowColumnWindows.empty() ) + return aWinRect; + else + { + ReadGuard aReadLock( m_aLock ); + Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow; + Reference< css::awt::XWindow > xDockingAreaWindow = m_xDockAreaWindows[DockingArea]; + aReadLock.unlock(); + + // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect + vos::OGuard aGuard( Application::GetSolarMutex() ); + + // Retrieve output size from container Window + Window* pContainerWindow( VCLUnoHelper::GetWindow( xContainerWindow )); + Window* pDockingAreaWindow( VCLUnoHelper::GetWindow( xDockingAreaWindow )); + if ( pDockingAreaWindow && pContainerWindow ) + { + const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindows.size(); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + css::awt::Rectangle aWindowRect = rRowColumnWindowData.aRowColumnWindows[i]->getPosSize(); + ::Rectangle aRect( aWindowRect.X, aWindowRect.Y, aWindowRect.X+aWindowRect.Width, aWindowRect.Y+aWindowRect.Height ); + aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() ))); + if ( aRect.IsInside( rMousePos )) + { + // Check if we have found the excluded element. If yes, we have to provide an empty rectangle. + // We prevent that a toolbar cannot be moved when the mouse pointer is inside its own rectangle! + if ( rExcludeElementName != rRowColumnWindowData.aUIElementNames[i] ) + return aRect; + else + break; + } + } + } + } + + return aWinRect; +} + +framework::LayoutManager::DockingOperation +LayoutManager::implts_determineDockingOperation( + ::com::sun::star::ui::DockingArea DockingArea, + const ::Rectangle& rRowColRect, + const Point& rMousePos ) +{ + const sal_Int32 nHorzVerticalRegionSize = 6; + const sal_Int32 nHorzVerticalMoveRegion = 4; + + if ( rRowColRect.IsInside( rMousePos )) + { + if (( DockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea == DockingArea_DOCKINGAREA_BOTTOM )) + { + sal_Int32 nRegion = rRowColRect.getHeight() / nHorzVerticalRegionSize; + sal_Int32 nPosY = rRowColRect.Top() + nRegion; + + if ( rMousePos.Y() < nPosY ) + return ( DockingArea == DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW; + else if ( rMousePos.Y() < ( nPosY + nRegion*nHorzVerticalMoveRegion )) + return DOCKOP_ON_COLROW; + else + return ( DockingArea == DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW; + } + else + { + sal_Int32 nRegion = rRowColRect.getWidth() / nHorzVerticalRegionSize; + sal_Int32 nPosX = rRowColRect.Left() + nRegion; + + if ( rMousePos.X() < nPosX ) + return ( DockingArea == DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW; + else if ( rMousePos.X() < ( nPosX + nRegion*nHorzVerticalMoveRegion )) + return DOCKOP_ON_COLROW; + else + return ( DockingArea == DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW; + } + } + else + return DOCKOP_ON_COLROW; +} + +::Rectangle LayoutManager::implts_calcTrackingAndElementRect( + ::com::sun::star::ui::DockingArea eDockingArea, + sal_Int32 nRowCol, + UIElement& rUIElement, + const ::Rectangle& rTrackingRect, + const ::Rectangle& rRowColumnRect, + const ::Size& rContainerWinSize ) +{ + sal_Bool bHorizontalDockArea( ( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )); + + sal_Int32 nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() ); + sal_Int32 nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() ); + + ::Size aStatusBarSize( implts_getStatusBarSize() ); + sal_Int32 nMaxLeftRightDockAreaSize = rContainerWinSize.Height() - + nTopDockingAreaSize - + nBottomDockingAreaSize - + aStatusBarSize.Height(); + + ::Rectangle aTrackingRect( rTrackingRect ); + if ( bHorizontalDockArea ) + { + sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 ))); + if (( nPosX + rTrackingRect.getWidth()) > rContainerWinSize.Width() ) + nPosX = std::min( nPosX, + std::max( sal_Int32( rContainerWinSize.Width() - rTrackingRect.getWidth() ), + sal_Int32( 0 ))); + + sal_Int32 nSize = std::min( rContainerWinSize.Width(), rTrackingRect.getWidth() ); + + aTrackingRect.SetPos( ::Point( nPosX, rRowColumnRect.Top() )); + aTrackingRect.setWidth( nSize ); + aTrackingRect.setHeight( rRowColumnRect.getHeight() ); + + // Set virtual position + rUIElement.m_aDockedData.m_aPos.X() = nPosX; + rUIElement.m_aDockedData.m_aPos.Y() = nRowCol; + } + else + { + sal_Int32 nMaxDockingAreaHeight = std::max( sal_Int32( 0 ), + sal_Int32( nMaxLeftRightDockAreaSize )); + + sal_Int32 nPosY( std::max( sal_Int32( aTrackingRect.Top()), sal_Int32( nTopDockingAreaSize ))); + if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight )) + nPosY = std::min( nPosY, + std::max( sal_Int32( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() )), + sal_Int32( nTopDockingAreaSize ))); + + sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) ); + + aTrackingRect.SetPos( ::Point( rRowColumnRect.Left(), nPosY )); + aTrackingRect.setWidth( rRowColumnRect.getWidth() ); + aTrackingRect.setHeight( nSize ); + + ReadGuard aReadLock( m_aLock ); + Reference< css::awt::XWindow > xDockingAreaWindow = m_xDockAreaWindows[eDockingArea]; + Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow; + aReadLock.unlock(); + + sal_Int32 nDockPosY( 0 ); + Window* pDockingAreaWindow( 0 ); + Window* pContainerWindow( 0 ); + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow ); + pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + nDockPosY = pDockingAreaWindow->ScreenToOutputPixel( + pContainerWindow->OutputToScreenPixel( ::Point( 0, nPosY ))).Y(); + } + + // Set virtual position + rUIElement.m_aDockedData.m_aPos.X() = nRowCol; + rUIElement.m_aDockedData.m_aPos.Y() = nDockPosY; + } + + return aTrackingRect; +} + +void implts_setTrackingRect( DockingArea eDockingArea, const Point& rMousePos, ::Rectangle& rTrackingRect ) +{ + sal_Bool bHorizontalDockArea( ( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )); + + ::Point aPoint = rTrackingRect.TopLeft(); + if ( bHorizontalDockArea ) + aPoint.X() = rMousePos.X(); + else + aPoint.Y() = rMousePos.Y(); + rTrackingRect.SetPos( aPoint ); +} + +void LayoutManager::implts_calcDockingPosSize( + UIElement& rUIElement, + DockingOperation& rDockingOperation, + ::Rectangle& rTrackingRect, + const Point& rMousePos ) +{ + ReadGuard aReadLock( m_aLock ); + Reference< css::awt::XWindow > xContainerWindow = m_xContainerWindow; + ::Size aContainerWinSize; + Window* pContainerWindow( 0 ); + aReadLock.unlock(); + + { + // Retrieve output size from container Window + vos::OGuard aGuard( Application::GetSolarMutex() ); + pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + aContainerWinSize = pContainerWindow->GetOutputSizePixel(); + } + + if ( !rUIElement.m_xUIElement.is() ) + { + rTrackingRect = ::Rectangle(); + return; + } + + Window* pDockWindow( 0 ); + Window* pDockingAreaWindow( 0 ); + ToolBox* pToolBox( 0 ); + Reference< css::awt::XWindow > xWindow( rUIElement.m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XWindow > xDockingAreaWindow; + ::Rectangle aTrackingRect( rTrackingRect ); + ::com::sun::star::ui::DockingArea eDockedArea( (::com::sun::star::ui::DockingArea)rUIElement.m_aDockedData.m_nDockedArea ); + sal_Int32 nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() ); + sal_Int32 nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() ); + sal_Bool bHorizontalDockArea( ( eDockedArea == DockingArea_DOCKINGAREA_TOP ) || + ( eDockedArea == DockingArea_DOCKINGAREA_BOTTOM )); + ::Size aStatusBarSize( implts_getStatusBarSize() ); + sal_Int32 nMaxLeftRightDockAreaSize = aContainerWinSize.Height() - + nTopDockingAreaSize - + nBottomDockingAreaSize - + aStatusBarSize.Height(); + ::Rectangle aDockingAreaRect; + + aReadLock.lock(); + xDockingAreaWindow = m_xDockAreaWindows[eDockedArea]; + aReadLock.unlock(); + + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow ); + pDockWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pDockWindow && pDockWindow->GetType() == WINDOW_TOOLBOX ) + pToolBox = (ToolBox *)pDockWindow; + + aDockingAreaRect = ::Rectangle( pDockingAreaWindow->GetPosPixel(), pDockingAreaWindow->GetSizePixel() ); + if ( pToolBox ) + { + // docked toolbars always have one line + ::Size aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( sal_Int16( eDockedArea )) ); + aTrackingRect.SetSize( ::Size( aSize.Width(), aSize.Height() )); + } + } + + // default docking operation, dock on the given row/column + sal_Bool bOpOutsideOfDockingArea( !aDockingAreaRect.IsInside( rMousePos )); + std::vector< SingleRowColumnWindowData > aRowColumnsWindowData; + + rDockingOperation = DOCKOP_ON_COLROW; + implts_getDockingAreaElementInfos( eDockedArea, aRowColumnsWindowData ); + + // determine current first row/column and last row/column + sal_Int32 nMaxRowCol( -1 ); + sal_Int32 nMinRowCol( SAL_MAX_INT32 ); + const sal_uInt32 nCount = aRowColumnsWindowData.size(); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + if ( aRowColumnsWindowData[i].nRowColumn > nMaxRowCol ) + nMaxRowCol = aRowColumnsWindowData[i].nRowColumn; + if ( aRowColumnsWindowData[i].nRowColumn < nMinRowCol ) + nMinRowCol = aRowColumnsWindowData[i].nRowColumn; + } + + if ( !bOpOutsideOfDockingArea ) + { + // docking inside our docking area + sal_Int32 nIndex( -1 ); + sal_Int32 nRowCol( -1 ); + ::Rectangle aWindowRect; + ::Rectangle aRowColumnRect; + + const sal_uInt32 nWindowDataCount = aRowColumnsWindowData.size(); + for ( sal_uInt32 i = 0; i < nWindowDataCount; i++ ) + { + ::Rectangle aRect( aRowColumnsWindowData[i].aRowColumnRect.X, + aRowColumnsWindowData[i].aRowColumnRect.Y, + aRowColumnsWindowData[i].aRowColumnRect.X + aRowColumnsWindowData[i].aRowColumnRect.Width, + aRowColumnsWindowData[i].aRowColumnRect.Y + aRowColumnsWindowData[i].aRowColumnRect.Height ); + + { + // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect + vos::OGuard aGuard( Application::GetSolarMutex() ); + aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() ))); + } + + sal_Bool bIsInsideRowCol( aRect.IsInside( rMousePos ) ); + if ( bIsInsideRowCol ) + { + nIndex = i; + nRowCol = aRowColumnsWindowData[i].nRowColumn; + rDockingOperation = implts_determineDockingOperation( eDockedArea, aRect, rMousePos ); + aWindowRect = implts_getWindowRectFromRowColumn( eDockedArea, aRowColumnsWindowData[i], rMousePos, rUIElement.m_aName ); + aRowColumnRect = aRect; + break; + } + } + + OSL_ENSURE( ( nIndex >= 0 ) && ( nRowCol >= 0 ), "Impossible case - no row/column found but mouse pointer is inside our docking area" ); + if (( nIndex >= 0 ) && ( nRowCol >= 0 )) + { + if ( rDockingOperation == DOCKOP_ON_COLROW ) + { + if ( !aWindowRect.IsEmpty()) + { + // Tracking rect is on a row/column and mouse is over a docked toolbar. + // Determine if the tracking rect must be located before/after the docked toolbar. + + ::Rectangle aUIElementRect( aWindowRect ); + sal_Int32 nMiddle( bHorizontalDockArea ? ( aWindowRect.Left() + aWindowRect.getWidth() / 2 ) : + ( aWindowRect.Top() + aWindowRect.getHeight() / 2 )); + sal_Bool bInsertBefore( bHorizontalDockArea ? ( rMousePos.X() < nMiddle ) : ( rMousePos.Y() < nMiddle )); + if ( bInsertBefore ) + { + if ( bHorizontalDockArea ) + { + sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( aContainerWinSize.Width() - aWindowRect.Left() ), + sal_Int32( aTrackingRect.getWidth() ))); + if ( nSize == 0 ) + nSize = aWindowRect.getWidth(); + + aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() )); + aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect,rUIElement.m_aName, aUIElementRect ); + + // Set virtual position + rUIElement.m_aDockedData.m_aPos.X() = aWindowRect.Left(); + rUIElement.m_aDockedData.m_aPos.Y() = nRowCol; + } + else + { + sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( + nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Top() ), + sal_Int32( aTrackingRect.getHeight() ))); + if ( nSize == 0 ) + nSize = aWindowRect.getHeight(); + + aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize )); + aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect, rUIElement.m_aName, aUIElementRect ); + + // Set virtual position + sal_Int32 nPosY = pDockingAreaWindow->ScreenToOutputPixel( + pContainerWindow->OutputToScreenPixel( aWindowRect.TopLeft() )).Y(); + rUIElement.m_aDockedData.m_aPos.X() = nRowCol; + rUIElement.m_aDockedData.m_aPos.Y() = nPosY; + } + + rTrackingRect = aWindowRect; + return; + } + else + { + if ( bHorizontalDockArea ) + { + sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32(( aContainerWinSize.Width() ) - aWindowRect.Right() ), + sal_Int32( aTrackingRect.getWidth() ))); + if ( nSize == 0 ) + { + aUIElementRect.SetPos( ::Point( aContainerWinSize.Width() - aTrackingRect.getWidth(), aWindowRect.Top() )); + aUIElementRect.SetSize( ::Size( aTrackingRect.getWidth(), aWindowRect.getHeight() )); + rUIElement.m_aDockedData.m_aPos.X() = aUIElementRect.Left(); + } + else + { + aUIElementRect.SetPos( ::Point( aWindowRect.Right(), aWindowRect.Top() )); + aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() )); + rUIElement.m_aDockedData.m_aPos.X() = aWindowRect.Right(); + } + + // Set virtual position + rUIElement.m_aDockedData.m_aPos.Y() = nRowCol; + } + else + { + sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Bottom() ), + sal_Int32( aTrackingRect.getHeight() ))); + aUIElementRect.SetPos( ::Point( aWindowRect.Left(), aWindowRect.Bottom() )); + aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize )); + + // Set virtual position + sal_Int32 nPosY( 0 ); + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + nPosY = pDockingAreaWindow->ScreenToOutputPixel( + pContainerWindow->OutputToScreenPixel( aWindowRect.BottomRight() )).Y(); + } + rUIElement.m_aDockedData.m_aPos.X() = nRowCol; + rUIElement.m_aDockedData.m_aPos.Y() = nPosY; + } + + rTrackingRect = aUIElementRect; + return; + } + } + else + { + implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect ); + rTrackingRect = implts_calcTrackingAndElementRect( + eDockedArea, nRowCol, rUIElement, + aTrackingRect, aRowColumnRect, aContainerWinSize ); + return; + } + } + else + { + if ((( nRowCol == nMinRowCol ) && ( rDockingOperation == DOCKOP_BEFORE_COLROW )) || + (( nRowCol == nMaxRowCol ) && ( rDockingOperation == DOCKOP_AFTER_COLROW ))) + bOpOutsideOfDockingArea = sal_True; + else + { + // handle docking before/after a row + implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect ); + rTrackingRect = implts_calcTrackingAndElementRect( + eDockedArea, nRowCol, rUIElement, + aTrackingRect, aRowColumnRect, aContainerWinSize ); + + sal_Int32 nOffsetX( 0 ); + sal_Int32 nOffsetY( 0 ); + if ( bHorizontalDockArea ) + nOffsetY = sal_Int32( floor( aRowColumnRect.getHeight() / 2 + 0.5 )); + else + nOffsetX = sal_Int32( floor( aRowColumnRect.getWidth() / 2 + 0.5 )); + + if ( rDockingOperation == DOCKOP_BEFORE_COLROW ) + { + if (( eDockedArea == DockingArea_DOCKINGAREA_TOP ) || + ( eDockedArea == DockingArea_DOCKINGAREA_LEFT )) + { + // Docking before/after means move track rectangle half column/row. + // As left and top are ordered 0...n instead of right and bottom + // which uses n...0, we have to use negative values for top/left. + nOffsetX *= -1; + nOffsetY *= -1; + } + } + else + { + if (( eDockedArea == DockingArea_DOCKINGAREA_BOTTOM ) || + ( eDockedArea == DockingArea_DOCKINGAREA_RIGHT )) + { + // Docking before/after means move track rectangle half column/row. + // As left and top are ordered 0...n instead of right and bottom + // which uses n...0, we have to use negative values for top/left. + nOffsetX *= -1; + nOffsetY *= -1; + } + nRowCol++; + } + + if ( bHorizontalDockArea ) + rUIElement.m_aDockedData.m_aPos.Y() = nRowCol; + else + rUIElement.m_aDockedData.m_aPos.X() = nRowCol; + + rTrackingRect.Move( nOffsetX, nOffsetY ); + rTrackingRect.SetSize( aTrackingRect.GetSize() ); + } + } + } + } + + // Docking outside of our docking window area => + // Users want to dock before/after first/last docked element or to an empty docking area + if ( bOpOutsideOfDockingArea ) + { + // set correct size for docking + implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect ); + rTrackingRect = aTrackingRect; + + if ( bHorizontalDockArea ) + { + sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 ))); + if (( nPosX + rTrackingRect.getWidth()) > aContainerWinSize.Width() ) + nPosX = std::min( nPosX, + std::max( sal_Int32( aContainerWinSize.Width() - rTrackingRect.getWidth() ), + sal_Int32( 0 ))); + + sal_Int32 nSize = std::min( aContainerWinSize.Width(), rTrackingRect.getWidth() ); + sal_Int32 nDockHeight = std::max( static_cast<sal_Int32>(aDockingAreaRect.getHeight()), sal_Int32( 0 )); + if ( nDockHeight == 0 ) + { + sal_Int32 nPosY( std::max( aDockingAreaRect.Top(), aDockingAreaRect.Bottom() )); + if ( eDockedArea == DockingArea_DOCKINGAREA_BOTTOM ) + nPosY -= rTrackingRect.getHeight(); + rTrackingRect.SetPos( Point( nPosX, nPosY )); + rUIElement.m_aDockedData.m_aPos.Y() = 0; + } + else if ( rMousePos.Y() < ( aDockingAreaRect.Top() + ( nDockHeight / 2 ))) + { + rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Top() - rTrackingRect.getHeight() )); + if ( eDockedArea == DockingArea_DOCKINGAREA_TOP ) + rUIElement.m_aDockedData.m_aPos.Y() = 0; + else + rUIElement.m_aDockedData.m_aPos.Y() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; + rDockingOperation = DOCKOP_BEFORE_COLROW; + } + else + { + rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Bottom() )); + if ( eDockedArea == DockingArea_DOCKINGAREA_TOP ) + rUIElement.m_aDockedData.m_aPos.Y() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; + else + rUIElement.m_aDockedData.m_aPos.Y() = 0; + rDockingOperation = DOCKOP_AFTER_COLROW; + } + rTrackingRect.setWidth( nSize ); + + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + nPosX = pDockingAreaWindow->ScreenToOutputPixel( + pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).X(); + } + rUIElement.m_aDockedData.m_aPos.X() = nPosX; + } + else + { + sal_Int32 nMaxDockingAreaHeight = std::max( sal_Int32( 0 ), + sal_Int32( nMaxLeftRightDockAreaSize )); + + sal_Int32 nPosY( std::max( sal_Int32( aTrackingRect.Top()), sal_Int32( nTopDockingAreaSize ))); + if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight )) + nPosY = std::min( nPosY, + std::max( sal_Int32( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() )), + sal_Int32( nTopDockingAreaSize ))); + + sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) ); + sal_Int32 nDockWidth = std::max( static_cast<sal_Int32>(aDockingAreaRect.getWidth()), sal_Int32( 0 )); + if ( nDockWidth == 0 ) + { + sal_Int32 nPosX( std::max( aDockingAreaRect.Left(), aDockingAreaRect.Right() )); + if ( eDockedArea == DockingArea_DOCKINGAREA_RIGHT ) + nPosX -= rTrackingRect.getWidth(); + rTrackingRect.SetPos( Point( nPosX, nPosY )); + rUIElement.m_aDockedData.m_aPos.X() = 0; + } + else if ( rMousePos.X() < ( aDockingAreaRect.Left() + ( nDockWidth / 2 ))) + { + rTrackingRect.SetPos( Point( aDockingAreaRect.Left() - rTrackingRect.getWidth(), nPosY )); + if ( eDockedArea == DockingArea_DOCKINGAREA_LEFT ) + rUIElement.m_aDockedData.m_aPos.X() = 0; + else + rUIElement.m_aDockedData.m_aPos.X() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; + rDockingOperation = DOCKOP_BEFORE_COLROW; + } + else + { + rTrackingRect.SetPos( Point( aDockingAreaRect.Right(), nPosY )); + if ( eDockedArea == DockingArea_DOCKINGAREA_LEFT ) + rUIElement.m_aDockedData.m_aPos.X() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; + else + rUIElement.m_aDockedData.m_aPos.X() = 0; + rDockingOperation = DOCKOP_AFTER_COLROW; + } + rTrackingRect.setHeight( nSize ); + + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + nPosY = pDockingAreaWindow->ScreenToOutputPixel( + pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).Y(); + } + rUIElement.m_aDockedData.m_aPos.Y() = nPosY; + } + } +} + +void LayoutManager::implts_renumberRowColumnData( + ::com::sun::star::ui::DockingArea eDockingArea, + DockingOperation /*eDockingOperation*/, + const UIElement& rUIElement ) +{ + ReadGuard aReadLock( m_aLock ); + Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); + aReadLock.unlock(); + + sal_Bool bHorzDockingArea(( eDockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM )); + sal_Int32 nRowCol( bHorzDockingArea ? rUIElement.m_aDockedData.m_aPos.Y() : + rUIElement.m_aDockedData.m_aPos.X() ); + + WriteGuard aWriteLock( m_aLock ); + UIElementVector::iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if (( pIter->m_aDockedData.m_nDockedArea == sal_Int16( eDockingArea )) && + ( pIter->m_aName != rUIElement.m_aName )) + { + // Don't change toolbars without a valid docking position! + if (( pIter->m_aDockedData.m_aPos.X() == SAL_MAX_INT32 ) && + ( pIter->m_aDockedData.m_aPos.Y() == SAL_MAX_INT32 )) + continue; + + sal_Int32 nWindowRowCol = ( bHorzDockingArea ) ? + pIter->m_aDockedData.m_aPos.Y() : pIter->m_aDockedData.m_aPos.X(); + if ( nWindowRowCol >= nRowCol ) + { + if ( bHorzDockingArea ) + pIter->m_aDockedData.m_aPos.Y() += 1; + else + pIter->m_aDockedData.m_aPos.X() += 1; + } + } + } + aWriteLock.unlock(); + + // We have to change the persistent window state part + if ( xPersistentWindowState.is() ) + { + try + { + Sequence< rtl::OUString > aWindowElements = xPersistentWindowState->getElementNames(); + for ( sal_Int32 i = 0; i < aWindowElements.getLength(); i++ ) + { + if ( rUIElement.m_aName != aWindowElements[i] ) + { + try + { + Sequence< PropertyValue > aPropValueSeq; + css::awt::Point aDockedPos; + DockingArea nDockedArea( DockingArea_DOCKINGAREA_DEFAULT ); + + xPersistentWindowState->getByName( aWindowElements[i] ) >>= aPropValueSeq; + for ( sal_Int32 j = 0; j < aPropValueSeq.getLength(); j++ ) + { + if ( aPropValueSeq[j].Name == m_aPropDockingArea ) + aPropValueSeq[j].Value >>= nDockedArea; + else if ( aPropValueSeq[j].Name == m_aPropDockPos ) + aPropValueSeq[j].Value >>= aDockedPos; + } + + // Don't change toolbars without a valid docking position! + if (( aDockedPos.X == SAL_MAX_INT32 ) && ( aDockedPos.Y == SAL_MAX_INT32 )) + continue; + + sal_Int32 nWindowRowCol = ( bHorzDockingArea ) ? aDockedPos.Y : aDockedPos.X; + if (( nDockedArea == eDockingArea ) && ( nWindowRowCol >= nRowCol )) + { + if ( bHorzDockingArea ) + aDockedPos.Y += 1; + else + aDockedPos.X += 1; + + Reference< XNameReplace > xReplace( xPersistentWindowState, UNO_QUERY ); + xReplace->replaceByName( aWindowElements[i], makeAny( aPropValueSeq )); + } + } + catch ( Exception& ) + { + } + } + } + } + catch ( Exception& ) + { + } + } +} + +::Size LayoutManager::implts_getTopBottomDockingAreaSizes() +{ + ::Size aSize; + Reference< css::awt::XWindow > xTopDockingAreaWindow; + Reference< css::awt::XWindow > xBottomDockingAreaWindow; + + ReadGuard aReadLock( m_aLock ); + xTopDockingAreaWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP]; + xBottomDockingAreaWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM]; + aReadLock.unlock(); + + if ( xTopDockingAreaWindow.is() ) + aSize.Width() = xTopDockingAreaWindow->getPosSize().Height; + if ( xBottomDockingAreaWindow.is() ) + aSize.Height() = xBottomDockingAreaWindow->getPosSize().Height; + + return aSize; +} + +Reference< XUIElement > LayoutManager::implts_createElement( const rtl::OUString& aName ) +{ + Reference< ::com::sun::star::ui::XUIElement > xUIElement; + + ReadGuard aReadLock( m_aLock ); + Sequence< PropertyValue > aPropSeq( 2 ); + aPropSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); + aPropSeq[0].Value <<= m_xFrame; + aPropSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Persistent" )); + aPropSeq[1].Value <<= sal_True; + + try + { + xUIElement = m_xUIElementFactoryManager->createUIElement( aName, aPropSeq ); + } + catch ( NoSuchElementException& ) + { + } + catch ( IllegalArgumentException& ) + { + } + + return xUIElement; +} + +Reference< css::awt::XWindowPeer > LayoutManager::implts_createToolkitWindow( const Reference< css::awt::XWindowPeer >& rParent ) +{ + Reference< css::awt::XWindowPeer > xPeer; + css::uno::Reference< css::awt::XToolkit > xToolkit( m_xSMGR->createInstance( SERVICENAME_VCLTOOLKIT ), css::uno::UNO_QUERY ); + if ( xToolkit.is() ) + { + // describe window properties. + css::awt::WindowDescriptor aDescriptor; + aDescriptor.Type = css::awt::WindowClass_SIMPLE ; + aDescriptor.WindowServiceName = DECLARE_ASCII("dockingarea") ; + aDescriptor.ParentIndex = -1 ; + aDescriptor.Parent = css::uno::Reference< css::awt::XWindowPeer >( rParent, UNO_QUERY ) ; + aDescriptor.Bounds = css::awt::Rectangle(0,0,0,0) ; + aDescriptor.WindowAttributes = 0 ; + + // create a docking area window + xPeer = xToolkit->createWindow( aDescriptor ); + } + + return xPeer; +} + +void LayoutManager::implts_setVisibleState( sal_Bool bShow ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + UIElementVector::iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + pIter->m_bMasterHide = !bShow; + m_aStatusBarElement.m_bMasterHide = !bShow; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + implts_updateUIElementsVisibleState( bShow ); + //implts_doLayout( sal_False ); +} + +void LayoutManager::implts_updateUIElementsVisibleState( sal_Bool bSetVisible ) +{ + // notify listeners + css::uno::Any a; + if ( bSetVisible ) + implts_notifyListeners( css::frame::LayoutManagerEvents::VISIBLE, a ); + else + implts_notifyListeners( css::frame::LayoutManagerEvents::INVISIBLE, a ); + std::vector< Reference< css::awt::XWindow > > aWinVector; + sal_Bool bOld; + + { + WriteGuard aWriteLock( m_aLock ); + m_bDoLayout = sal_True; + bOld = m_bDoLayout; + } + + ReadGuard aReadLock( m_aLock ); + aWinVector.reserve(m_aUIElements.size()); + UIElementVector::iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_xUIElement.is() ) + { + Reference< css::awt::XWindow > xWindow( pIter->m_xUIElement->getRealInterface(), UNO_QUERY ); + if ( xWindow.is() ) + { + if ( bSetVisible ) + { + if ( pIter->m_bVisible && !pIter->m_bMasterHide ) + aWinVector.push_back( xWindow ); + } + else + aWinVector.push_back( xWindow ); + } + } + } + + aReadLock.unlock(); + + try + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + const sal_uInt32 nCount = aWinVector.size(); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + Reference< css::awt::XWindow > xWindow( aWinVector[i] ); + if ( xWindow.is() ) + { + // we need VCL here to pass special flags to Show() + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if( pWindow ) + pWindow->Show( bSetVisible, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); + } + } + } + catch ( DisposedException& ) + { + } + + // Hide/show menubar according to bSetVisible + aReadLock.lock(); + Reference< XUIElement > xMenuBar( m_xMenuBar, UNO_QUERY ); + Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow ); + Reference< XComponent > xInplaceMenuBar( m_xInplaceMenuBar ); + MenuBarManager* pInplaceMenuBar( m_pInplaceMenuBar ); + aReadLock.unlock(); + + if (( xMenuBar.is() || xInplaceMenuBar.is() ) && xContainerWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + MenuBar* pMenuBar( 0 ); + if ( xInplaceMenuBar.is() ) + pMenuBar = (MenuBar *)pInplaceMenuBar->GetMenuBar(); + else + { + MenuBarWrapper* pMenuBarWrapper = SAL_STATIC_CAST( MenuBarWrapper*, xMenuBar.get() ); + pMenuBar = (MenuBar *)pMenuBarWrapper->GetMenuBarManager()->GetMenuBar(); + } + + Window* pWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + while ( pWindow && !pWindow->IsSystemWindow() ) + pWindow = pWindow->GetParent(); + + if ( pWindow ) + { + SystemWindow* pSysWindow = (SystemWindow *)pWindow; + if ( bSetVisible ) + pSysWindow->SetMenuBar( pMenuBar ); + else + pSysWindow->SetMenuBar( 0 ); + } + } + + // Hide/show the statusbar according to bSetVisible + if ( bSetVisible ) + implts_showStatusBar(); + else + implts_hideStatusBar(); + + if ( !bOld ) + { + WriteGuard aWriteLock( m_aLock ); + m_bDoLayout = sal_False; + } + + if ( bSetVisible ) + { + implts_createNonContextSensitiveToolBars(); + implts_doLayout_notify( sal_False ); + } + else + { + // Set docking area window size to zero + ReadGuard aReadLock2( m_aLock ); + Reference< css::awt::XWindow > xTopDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP]; + Reference< css::awt::XWindow > xLeftDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT]; + Reference< css::awt::XWindow > xRightDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT]; + Reference< css::awt::XWindow > xBottomDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM]; + aReadLock2.unlock(); + + try + { + if ( xTopDockingWindow.is() ) + xTopDockingWindow->setPosSize( 0, 0, 0, 0, css::awt::PosSize::POSSIZE ); + if ( xLeftDockingWindow.is() ) + xLeftDockingWindow->setPosSize( 0, 0, 0, 0, css::awt::PosSize::POSSIZE ); + if ( xRightDockingWindow.is() ) + xRightDockingWindow->setPosSize( 0, 0, 0, 0, css::awt::PosSize::POSSIZE ); + if ( xBottomDockingWindow.is() ) + xBottomDockingWindow->setPosSize( 0, 0, 0, 0, css::awt::PosSize::POSSIZE ); + + WriteGuard aWriteLock( m_aLock ); + m_aDockingArea = css::awt::Rectangle(); + m_bMustDoLayout = sal_True; + aWriteLock.unlock(); + } + catch ( Exception& ) + { + } + } +} + +void LayoutManager::implts_setCurrentUIVisibility( sal_Bool bShow ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + UIElementVector::iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( !bShow && pIter->m_bVisible && pIter->m_xUIElement.is() ) + pIter->m_bMasterHide = true; + else if ( bShow && pIter->m_bMasterHide ) + pIter->m_bMasterHide = false; + } + + if ( !bShow && m_aStatusBarElement.m_bVisible && m_aStatusBarElement.m_xUIElement.is() ) + m_aStatusBarElement.m_bMasterHide = true; + else if ( bShow && m_aStatusBarElement.m_bVisible ) + m_aStatusBarElement.m_bMasterHide = false; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + implts_updateUIElementsVisibleState( bShow ); +} + +void LayoutManager::implts_destroyStatusBar() +{ + Reference< XComponent > xCompStatusBar; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_aStatusBarElement.m_aName = rtl::OUString(); + xCompStatusBar = Reference< XComponent >( m_aStatusBarElement.m_xUIElement, UNO_QUERY ); + m_aStatusBarElement.m_xUIElement.clear(); + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( xCompStatusBar.is() ) + xCompStatusBar->dispose(); + + implts_destroyProgressBar(); +} + +void LayoutManager::implts_createStatusBar( const rtl::OUString& aStatusBarName ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + if ( !m_aStatusBarElement.m_xUIElement.is() ) + { + implts_readStatusBarState( aStatusBarName ); + m_aStatusBarElement.m_aName = aStatusBarName; + m_aStatusBarElement.m_xUIElement = implts_createElement( aStatusBarName ); + } + + implts_createProgressBar(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +void LayoutManager::implts_readStatusBarState( const rtl::OUString& rStatusBarName ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + if ( !m_aStatusBarElement.m_bStateRead ) + { + // Read persistent data for status bar if not yet read! + if ( implts_readWindowStateData( rStatusBarName, m_aStatusBarElement )) + m_aStatusBarElement.m_bStateRead = sal_True; + } + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +void LayoutManager::implts_createProgressBar() +{ + Reference< XUIElement > xStatusBar; + Reference< XUIElement > xProgressBar; + Reference< XUIElement > xProgressBarBackup; + Reference< css::awt::XWindow > xContainerWindow; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + xStatusBar = Reference< XUIElement >( m_aStatusBarElement.m_xUIElement, UNO_QUERY ); + xProgressBar = Reference< XUIElement >( m_aProgressBarElement.m_xUIElement, UNO_QUERY ); + xProgressBarBackup = m_xProgressBarBackup; + m_xProgressBarBackup.clear(); + xContainerWindow = m_xContainerWindow; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + sal_Bool bRecycled = xProgressBarBackup.is(); + ProgressBarWrapper* pWrapper = 0; + if ( bRecycled ) + pWrapper = (ProgressBarWrapper*)xProgressBarBackup.get(); + else if ( xProgressBar.is() ) + pWrapper = (ProgressBarWrapper*)xProgressBar.get(); + else + pWrapper = new ProgressBarWrapper(); + + if ( xStatusBar.is() ) + { + Reference< css::awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY ); + pWrapper->setStatusBar( xWindow ); + } + else + { + Reference< css::awt::XWindow > xStatusBarWindow = pWrapper->getStatusBar(); + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pStatusBarWnd = VCLUnoHelper::GetWindow( xStatusBarWindow ); + if ( !pStatusBarWnd ) + { + Window* pWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + if ( pWindow ) + { + StatusBar* pStatusBar = new StatusBar( pWindow, WinBits( WB_LEFT | WB_3DLOOK ) ); + Reference< css::awt::XWindow > xStatusBarWindow2( VCLUnoHelper::GetInterface( pStatusBar )); + pWrapper->setStatusBar( xStatusBarWindow2, sal_True ); + } + } + } + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aWriteLock.lock(); + m_aProgressBarElement.m_xUIElement = Reference< XUIElement >( + static_cast< cppu::OWeakObject* >( pWrapper ), UNO_QUERY ); + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( bRecycled ) + implts_showProgressBar(); +} + +void LayoutManager::implts_backupProgressBarWrapper() +{ + // SAFE -> ---------------------------------- + WriteGuard aWriteLock(m_aLock); + + if (m_xProgressBarBackup.is()) + return; + + // safe a backup copy of the current progress! + // This copy will be used automaticly inside createProgressBar() which is called + // implictly from implts_doLayout() .-) + m_xProgressBarBackup = m_aProgressBarElement.m_xUIElement; + + // remove the relation between this old progress bar and our old status bar. + // Otherwhise we work on disposed items ... + // The internal used ProgressBarWrapper can handle a NULL reference. + if ( m_xProgressBarBackup.is() ) + { + ProgressBarWrapper* pWrapper = (ProgressBarWrapper*)m_xProgressBarBackup.get(); + if ( pWrapper ) + pWrapper->setStatusBar( Reference< css::awt::XWindow >(), sal_False ); + } + + // prevent us from dispose() the m_aProgressBarElement.m_xUIElement inside implts_reset() + m_aProgressBarElement.m_xUIElement.clear(); + + aWriteLock.unlock(); + // <- SAFE ---------------------------------- +} + +void LayoutManager::implts_destroyProgressBar() +{ + // dont remove the progressbar in general + // We must reuse it if a new status bar is created later. + // Of course there exists one backup only. + // And further this backup will be released inside our dtor. + implts_backupProgressBarWrapper(); +} + +void LayoutManager::implts_setStatusBarPosSize( const ::Point& rPos, const ::Size& rSize ) +{ + Reference< XUIElement > xStatusBar; + Reference< XUIElement > xProgressBar; + Reference< css::awt::XWindow > xContainerWindow; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + xStatusBar = Reference< XUIElement >( m_aStatusBarElement.m_xUIElement, UNO_QUERY ); + xProgressBar = Reference< XUIElement >( m_aProgressBarElement.m_xUIElement, UNO_QUERY ); + xContainerWindow = m_xContainerWindow; + + Reference< css::awt::XWindow > xWindow; + if ( xStatusBar.is() ) + xWindow = Reference< css::awt::XWindow >( xStatusBar->getRealInterface(), UNO_QUERY ); + else if ( xProgressBar.is() ) + { + ProgressBarWrapper* pWrapper = (ProgressBarWrapper*)xProgressBar.get(); + if ( pWrapper ) + xWindow = pWrapper->getStatusBar(); + } + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( xWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pParentWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pParentWindow && ( pWindow && pWindow->GetType() == WINDOW_STATUSBAR )) + { + Window* pOldParentWindow = pWindow->GetParent(); + if ( pParentWindow != pOldParentWindow ) + pWindow->SetParent( pParentWindow ); + ((StatusBar *)pWindow)->SetPosSizePixel( rPos, rSize ); + } + } +} + +sal_Bool LayoutManager::implts_showProgressBar() +{ + Reference< XUIElement > xStatusBar; + Reference< XUIElement > xProgressBar; + Reference< css::awt::XWindow > xWindow; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + xStatusBar = Reference< XUIElement >( m_aStatusBarElement.m_xUIElement, UNO_QUERY ); + xProgressBar = Reference< XUIElement >( m_aProgressBarElement.m_xUIElement, UNO_QUERY ); + sal_Bool bVisible( m_bVisible ); + + m_aProgressBarElement.m_bVisible = sal_True; + if ( bVisible ) + { + if ( xStatusBar.is() && !m_aStatusBarElement.m_bMasterHide ) + { + xWindow = Reference< css::awt::XWindow >( xStatusBar->getRealInterface(), UNO_QUERY ); + } + else if ( xProgressBar.is() ) + { + ProgressBarWrapper* pWrapper = (ProgressBarWrapper*)xProgressBar.get(); + if ( pWrapper ) + xWindow = pWrapper->getStatusBar(); + } + } + aWriteLock.unlock(); + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + { + if ( !pWindow->IsVisible() ) + { + pWindow->Show(); + implts_doLayout_notify( sal_False ); + } + return sal_True; + } + + return sal_False; +} + +sal_Bool LayoutManager::implts_hideProgressBar() +{ + Reference< XUIElement > xProgressBar; + Reference< css::awt::XWindow > xWindow; + sal_Bool bHideStatusBar( sal_False ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + xProgressBar = Reference< XUIElement >( m_aProgressBarElement.m_xUIElement, UNO_QUERY ); + + sal_Bool bInternalStatusBar( sal_False ); + if ( xProgressBar.is() ) + { + Reference< css::awt::XWindow > xStatusBar; + ProgressBarWrapper* pWrapper = (ProgressBarWrapper*)xProgressBar.get(); + if ( pWrapper ) + xWindow = pWrapper->getStatusBar(); + Reference< css::ui::XUIElement > xStatusBarElement = m_aStatusBarElement.m_xUIElement; + if ( xStatusBarElement.is() ) + xStatusBar = Reference< css::awt::XWindow >( xStatusBarElement->getRealInterface(), UNO_QUERY ); + bInternalStatusBar = xStatusBar != xWindow; + } + m_aProgressBarElement.m_bVisible = sal_False; + implts_readStatusBarState( m_aStatusBarAlias ); + bHideStatusBar = !m_aStatusBarElement.m_bVisible; + aWriteLock.unlock(); + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->IsVisible() && + ( bHideStatusBar || bInternalStatusBar )) + { + pWindow->Hide(); + implts_doLayout_notify( sal_False ); + return sal_True; + } + + return sal_False; +} + +sal_Bool LayoutManager::implts_showStatusBar( sal_Bool bStoreState ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + Reference< css::ui::XUIElement > xStatusBar = m_aStatusBarElement.m_xUIElement; + if ( bStoreState ) + m_aStatusBarElement.m_bVisible = sal_True; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( xStatusBar.is() ) + { + Reference< css::awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY ); + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && !pWindow->IsVisible() ) + { + pWindow->Show(); + return sal_True; + } + } + + return sal_False; +} + +sal_Bool LayoutManager::implts_hideStatusBar( sal_Bool bStoreState ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + Reference< css::ui::XUIElement > xStatusBar = m_aStatusBarElement.m_xUIElement; + if ( bStoreState ) + m_aStatusBarElement.m_bVisible = sal_False; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( xStatusBar.is() ) + { + Reference< css::awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY ); + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->IsVisible() ) + { + pWindow->Hide(); + return sal_True; + } + } + + return sal_False; +} + +void LayoutManager::implts_setInplaceMenuBar( const Reference< XIndexAccess >& xMergedMenuBar ) +throw (::com::sun::star::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + + if ( !m_bInplaceMenuSet ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + // Reset old inplace menubar! + m_pInplaceMenuBar = 0; + if ( m_xInplaceMenuBar.is() ) + m_xInplaceMenuBar->dispose(); + m_xInplaceMenuBar.clear(); + m_bInplaceMenuSet = sal_False; + + if ( m_xFrame.is() && + m_xContainerWindow.is() ) + { + rtl::OUString aModuleIdentifier; + Reference< XDispatchProvider > xDispatchProvider; + + MenuBar* pMenuBar = new MenuBar; + m_pInplaceMenuBar = new MenuBarManager( m_xSMGR, m_xFrame, m_xURLTransformer,xDispatchProvider, aModuleIdentifier, pMenuBar, sal_True, sal_True ); + m_pInplaceMenuBar->SetItemContainer( xMergedMenuBar ); + + Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); + while ( pWindow && !pWindow->IsSystemWindow() ) + pWindow = pWindow->GetParent(); + + if ( pWindow ) + { + SystemWindow* pSysWindow = (SystemWindow *)pWindow; + pSysWindow->SetMenuBar( pMenuBar ); + } + + m_bInplaceMenuSet = sal_True; + m_xInplaceMenuBar = Reference< XComponent >( (OWeakObject *)m_pInplaceMenuBar, UNO_QUERY ); + } + + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + implts_updateMenuBarClose(); + } + +} + +void LayoutManager::implts_resetInplaceMenuBar() +throw (::com::sun::star::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_bInplaceMenuSet = sal_False; + + // if ( m_xMenuBar.is() && + if ( m_xContainerWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + MenuBarWrapper* pMenuBarWrapper = SAL_STATIC_CAST( MenuBarWrapper*, m_xMenuBar.get() ); + Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); + while ( pWindow && !pWindow->IsSystemWindow() ) + pWindow = pWindow->GetParent(); + + if ( pWindow ) + { + SystemWindow* pSysWindow = (SystemWindow *)pWindow; + if ( pMenuBarWrapper ) + pSysWindow->SetMenuBar( (MenuBar *)pMenuBarWrapper->GetMenuBarManager()->GetMenuBar() ); + else + pSysWindow->SetMenuBar( 0 ); + } + } + + // Remove inplace menu bar + m_pInplaceMenuBar = 0; + if ( m_xInplaceMenuBar.is() ) + m_xInplaceMenuBar->dispose(); + m_xInplaceMenuBar.clear(); + + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +void SAL_CALL LayoutManager::attachFrame( const Reference< XFrame >& xFrame ) +throw (::com::sun::star::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_xFrame = xFrame; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + // if ( xFrame.is() ) + // xFrame->getContainerWindow()->addWindowListener( Reference< css::awt::XWindowListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); +} + +void SAL_CALL LayoutManager::reset() +throw (RuntimeException) +{ + sal_Bool bComponentAttached( sal_False ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + bComponentAttached = m_bComponentAttached; + aReadLock.unlock(); + + implts_reset( sal_True ); +} + +void SAL_CALL LayoutManager::setInplaceMenuBar( sal_Int64 ) +throw (::com::sun::star::uno::RuntimeException) +{ + OSL_ENSURE( sal_False, "This method is obsolete and should not be used!\n" ); +} + +void SAL_CALL LayoutManager::resetInplaceMenuBar() +throw (::com::sun::star::uno::RuntimeException) +{ + OSL_ENSURE( sal_False, "This method is obsolete and should not be used!\n" ); +} + +//--------------------------------------------------------------------------------------------------------- +// XMenuBarMergingAcceptor +//--------------------------------------------------------------------------------------------------------- +sal_Bool SAL_CALL LayoutManager::setMergedMenuBar( + const Reference< XIndexAccess >& xMergedMenuBar ) +throw (::com::sun::star::uno::RuntimeException) +{ + implts_setInplaceMenuBar( xMergedMenuBar ); + + css::uno::Any a; + implts_notifyListeners( css::frame::LayoutManagerEvents::MERGEDMENUBAR, a ); + return sal_True; +} + +void SAL_CALL LayoutManager::removeMergedMenuBar() +throw (::com::sun::star::uno::RuntimeException) +{ + implts_resetInplaceMenuBar(); +} + +::com::sun::star::awt::Rectangle SAL_CALL LayoutManager::getCurrentDockingArea() +throw ( RuntimeException ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + return m_aDockingArea; +} + +Reference< XDockingAreaAcceptor > SAL_CALL LayoutManager::getDockingAreaAcceptor() +throw (::com::sun::star::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + return m_xDockingAreaAcceptor; +} + +void SAL_CALL LayoutManager::setDockingAreaAcceptor( const Reference< ::com::sun::star::ui::XDockingAreaAcceptor >& xDockingAreaAcceptor ) +throw ( RuntimeException ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + + if (( m_xDockingAreaAcceptor == xDockingAreaAcceptor ) || + !m_xFrame.is() ) + return; + + // IMPORTANT: Be sure to stop layout timer if don't have a docking area acceptor! + if ( !xDockingAreaAcceptor.is() ) + m_aAsyncLayoutTimer.Stop(); + + sal_Bool bAutomaticToolbars( m_bAutomaticToolbars ); + std::vector< Reference< css::awt::XWindow > > oldDockingAreaWindows; + + if ( !xDockingAreaAcceptor.is() ) + m_aAsyncLayoutTimer.Stop(); + + // Remove listener from old docking area acceptor + if ( m_xDockingAreaAcceptor.is() ) + { + Reference< css::awt::XWindow > xWindow( m_xDockingAreaAcceptor->getContainerWindow() ); + if ( xWindow.is() && ( m_xFrame->getContainerWindow() != m_xContainerWindow || !xDockingAreaAcceptor.is() ) ) + xWindow->removeWindowListener( Reference< css::awt::XWindowListener >( static_cast< OWeakObject * >( this ), UNO_QUERY )); + + oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP] ); + oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM] ); + oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT] ); + oldDockingAreaWindows.push_back( m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT] ); + + m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP].clear(); + m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM].clear(); + m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT].clear(); + m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT].clear(); + m_aDockingArea = css::awt::Rectangle(); + + Window* pContainerWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pContainerWindow ) + pContainerWindow->RemoveChildEventListener( LINK( this, LayoutManager, WindowEventListener ) ); + + // destroy panel manager + delete m_pPanelManager; + m_pPanelManager = NULL; + } + + // Set new docking area acceptor and add ourself as window listener on the container window. + // Create our docking area windows which are parents for all docked windows. + css::uno::Reference< css::awt::XWindow > xTopDockWindow; + css::uno::Reference< css::awt::XWindow > xBottomDockWindow; + css::uno::Reference< css::awt::XWindow > xLeftDockWindow; + css::uno::Reference< css::awt::XWindow > xRightDockWindow; + + Reference< ::com::sun::star::ui::XDockingAreaAcceptor > xOldDockingAreaAcceptor( m_xDockingAreaAcceptor ); + m_xDockingAreaAcceptor = xDockingAreaAcceptor; + if ( m_xDockingAreaAcceptor.is() ) + { + m_aDockingArea = css::awt::Rectangle(); + m_xContainerWindow = m_xDockingAreaAcceptor->getContainerWindow(); + m_xContainerTopWindow.set( m_xContainerWindow, UNO_QUERY ); + m_xContainerWindow->addWindowListener( Reference< css::awt::XWindowListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); + + // we always must keep a connection to the window of our frame for resize events + if ( m_xContainerWindow != m_xFrame->getContainerWindow() ) + m_xFrame->getContainerWindow()->addWindowListener( Reference< css::awt::XWindowListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); + + // #i37884# set initial visibility state - in the plugin case the container window is already shown + // and we get no notification anymore + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); + if( pContainerWindow ) + m_bParentWindowVisible = pContainerWindow->IsVisible(); + } + + css::uno::Reference< css::awt::XWindowPeer > xParent( m_xContainerWindow, UNO_QUERY ); + xTopDockWindow = Reference< css::awt::XWindow >( implts_createToolkitWindow( xParent ), UNO_QUERY ); + xBottomDockWindow = Reference< css::awt::XWindow >( implts_createToolkitWindow( xParent ), UNO_QUERY ); + xLeftDockWindow = Reference< css::awt::XWindow >( implts_createToolkitWindow( xParent ), UNO_QUERY ); + xRightDockWindow = Reference< css::awt::XWindow >( implts_createToolkitWindow( xParent ), UNO_QUERY ); + m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP] = xTopDockWindow; + m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM] = xBottomDockWindow; + m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT] = xLeftDockWindow; + m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT] = xRightDockWindow; + + // create new panel manager + m_pPanelManager = new PanelManager( m_xSMGR, m_xFrame ); + m_pPanelManager->createPanels(); + } + + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( xDockingAreaAcceptor.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + ::DockingAreaWindow* pWindow; + pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xTopDockWindow ) ); + if( pWindow ) pWindow->SetAlign( WINDOWALIGN_TOP ); + pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xBottomDockWindow ) ); + if( pWindow ) pWindow->SetAlign( WINDOWALIGN_BOTTOM ); + pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xLeftDockWindow ) ); + if( pWindow ) pWindow->SetAlign( WINDOWALIGN_LEFT ); + pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xRightDockWindow ) ); + if( pWindow ) pWindow->SetAlign( WINDOWALIGN_RIGHT ); + + // Add layout manager as listener to get notifications about toolbar button activties + Window* pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); + if ( pContainerWindow ) + pContainerWindow->AddChildEventListener( LINK( this, LayoutManager, WindowEventListener ) ); + + // We have now a new container window, reparent all child windows! + implts_reparentChildWindows(); + } + else + implts_destroyElements(); // remove all elements + + if ( !oldDockingAreaWindows.empty() ) + { + const sal_uInt32 nCount = oldDockingAreaWindows.size(); + for ( sal_uInt32 i = 0; i < nCount; ++i ) + { + if ( oldDockingAreaWindows[i].is() ) + { + try + { + oldDockingAreaWindows[i]->dispose(); + } + catch ( Exception& ) + { + } + } + } + + // Reset docking area size for our old docking area acceptor + css::awt::Rectangle aEmptyRect; + xOldDockingAreaAcceptor->setDockingAreaSpace( aEmptyRect ); + } + + if ( xDockingAreaAcceptor.is() ) + { + if ( bAutomaticToolbars ) + { + implts_createAddonsToolBars(); // create addon toolbars + implts_createCustomToolBars(); // create custom toolbars + implts_createNonContextSensitiveToolBars(); + } + implts_sortUIElements(); + implts_doLayout( sal_True, sal_False ); + } +} + +void LayoutManager::implts_reparentChildWindows() +{ + UIElementVector aUIElementVector; + UIElement aStatusBarElement; + css::uno::Reference< css::awt::XWindow > xTopDockWindow; + css::uno::Reference< css::awt::XWindow > xBottomDockWindow; + css::uno::Reference< css::awt::XWindow > xLeftDockWindow; + css::uno::Reference< css::awt::XWindow > xRightDockWindow; + css::uno::Reference< css::awt::XWindow > xContainerWindow; + css::uno::Reference< css::awt::XWindow > xStatusBarWindow; + + WriteGuard aWriteLock( m_aLock ); + aUIElementVector = m_aUIElements; + xTopDockWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP]; + xBottomDockWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM]; + xLeftDockWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT]; + xRightDockWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT]; + xContainerWindow = m_xContainerWindow; + aStatusBarElement = m_aStatusBarElement; + aWriteLock.unlock(); + + if ( aStatusBarElement.m_xUIElement.is() ) + { + try + { + xStatusBarWindow = Reference< css::awt::XWindow >( + aStatusBarElement.m_xUIElement->getRealInterface(), + UNO_QUERY ); + } + catch ( RuntimeException& ) + { + throw; + } + catch ( Exception& ) + { + } + } + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + Window* pTopDockWindow = VCLUnoHelper::GetWindow( xTopDockWindow ); + Window* pBottomDockWindow = VCLUnoHelper::GetWindow( xBottomDockWindow ); + Window* pLeftDockWindow = VCLUnoHelper::GetWindow( xLeftDockWindow ); + Window* pRightDockWindow = VCLUnoHelper::GetWindow( xRightDockWindow ); + if ( pContainerWindow ) + { + UIElementVector::iterator pIter; + for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ ) + { + Reference< XUIElement > xUIElement( pIter->m_xUIElement ); + if ( xUIElement.is() ) + { + Reference< css::awt::XWindow > xWindow; + try + { + // We have to retreive the window reference with try/catch as it is + // possible that all elements has been disposed! + xWindow = Reference< css::awt::XWindow >( xUIElement->getRealInterface(), UNO_QUERY ); + } + catch ( RuntimeException& ) + { + throw; + } + catch ( Exception& ) + { + } + + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + { + // Reparent our child windows acording to their current state. + if ( pIter->m_bFloating ) + pWindow->SetParent( pContainerWindow ); + else + { + if ( pIter->m_aDockedData.m_nDockedArea == DockingArea_DOCKINGAREA_TOP ) + pWindow->SetParent( pTopDockWindow ); + else if ( pIter->m_aDockedData.m_nDockedArea == DockingArea_DOCKINGAREA_BOTTOM ) + pWindow->SetParent( pBottomDockWindow ); + else if ( pIter->m_aDockedData.m_nDockedArea == DockingArea_DOCKINGAREA_LEFT ) + pWindow->SetParent( pLeftDockWindow ); + else + pWindow->SetParent( pRightDockWindow ); + } + } + } + } + + if ( xStatusBarWindow.is() ) + { + Window* pWindow = VCLUnoHelper::GetWindow( xStatusBarWindow ); + if ( pWindow ) + pWindow->SetParent( pContainerWindow ); + } + + implts_resetMenuBar(); + } +} + +uno::Reference< ui::XUIElement > LayoutManager::implts_createDockingWindow( const ::rtl::OUString& aElementName ) +{ + Reference< XUIElement > xUIElement = implts_createElement( aElementName ); + return xUIElement; +} + +IMPL_LINK( LayoutManager, WindowEventListener, VclSimpleEvent*, pEvent ) +{ + // To enable toolbar controllers to change their image when a sub-toolbar function + // is activated, we need this mechanism. We have NO connection between these toolbars + // anymore! + if ( pEvent && pEvent->ISA( VclWindowEvent )) + { + if ( pEvent->GetId() == VCLEVENT_TOOLBOX_SELECT ) + { + Window* pWindow( ((VclWindowEvent*)pEvent)->GetWindow() ); + ToolBox* pToolBox( 0 ); + rtl::OUString aToolbarName; + rtl::OUString aCommand; + + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + { + pToolBox = (ToolBox *)pWindow; + aToolbarName = pToolBox->GetSmartHelpId().GetStr(); + sal_Int32 i = aToolbarName.lastIndexOf( ':' ); + if (( aToolbarName.getLength() > 0 ) && + ( i > 0 ) && (( i+ 1 ) < aToolbarName.getLength() )) + { + // Remove ".HelpId:" protocol from toolbar name + aToolbarName = aToolbarName.copy( i+1 ); + + USHORT nId = pToolBox->GetCurItemId(); + if ( nId > 0 ) + aCommand = pToolBox->GetItemCommand( nId ); + } + } + + if (( aToolbarName.getLength() > 0 ) && ( aCommand.getLength() > 0 )) + { + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + std::vector< css::uno::Reference< css::ui::XUIFunctionListener > > aListenerArray; + UIElementVector::iterator pIter; + + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aType.equalsAscii( "toolbar" ) && + pIter->m_xUIElement.is() ) + { + css::uno::Reference< css::ui::XUIFunctionListener > xListener( pIter->m_xUIElement, UNO_QUERY ); + if ( xListener.is() ) + aListenerArray.push_back( xListener ); + } + } + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + const sal_uInt32 nCount = aListenerArray.size(); + for ( sal_uInt32 i = 0; i < nCount; ++i ) + { + try + { + aListenerArray[i]->functionExecute( aToolbarName, aCommand ); + } + catch ( RuntimeException& e ) + { + throw e; + } + catch ( Exception& ) {} + } + } + } + else if ( pEvent->GetId() == VCLEVENT_TOOLBOX_FORMATCHANGED ) + { + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + + Window* pWindow( ((VclWindowEvent*)pEvent)->GetWindow() ); + ToolBox* pToolBox( 0 ); + rtl::OUString aToolbarName; + + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + { + pToolBox = (ToolBox *)pWindow; + aToolbarName = pToolBox->GetSmartHelpId().GetStr(); + if (( aToolbarName.getLength() > 0 ) && ( m_nLockCount == 0 )) + m_aAsyncLayoutTimer.Start(); + } + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + } + } + + return 1; +} + +void SAL_CALL LayoutManager::createElement( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::createElement" ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + Reference< XFrame > xFrame = m_xFrame; + Reference< XURLTransformer > xURLTransformer = m_xURLTransformer; + sal_Bool bInPlaceMenu = m_bInplaceMenuSet; + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( !xFrame.is() ) + return; + + Reference< XModel > xModel( impl_getModelFromFrame( xFrame ) ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + + sal_Bool bFound( sal_False ); + sal_Bool bNotify( sal_False ); + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + Reference< ::com::sun::star::ui::XUIElement > xUIElement; + + implts_findElement( aName, aElementType, aElementName, xUIElement ); + bFound = xUIElement.is(); + + if ( /*xFrame.is() && */m_xContainerWindow.is() && !implts_isPreviewModel( xModel ) ) // no bars on preview mode + { + if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" )) + { + if ( !bFound ) + { + SvtCommandOptions aCmdOptions; + + xUIElement = implts_createElement( aName ); + sal_Bool bVisible( sal_False ); + if ( xUIElement.is() ) + { + Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xUIElement->getRealInterface(), UNO_QUERY ); + if ( xDockWindow.is() && xWindow.is() ) + { + try + { + xDockWindow->addDockableWindowListener( Reference< css::awt::XDockableWindowListener >( + static_cast< OWeakObject * >( this ), UNO_QUERY )); + xWindow->addWindowListener( Reference< css::awt::XWindowListener >( + static_cast< OWeakObject * >( this ), UNO_QUERY )); + xDockWindow->enableDocking( sal_True ); + } + catch ( Exception& ) + { + } + } + + UIElement& rElement = impl_findElement( aName ); + if ( rElement.m_aName.getLength() > 0 ) + { + // Reuse a local entry so we are able to use the latest + // UI changes for this document. + implts_setElementData( rElement, xDockWindow ); + rElement.m_xUIElement = xUIElement; + bVisible = rElement.m_bVisible; + } + else + { + // Create new UI element and try to read its state data + UIElement aNewToolbar( aName, aElementType, xUIElement ); + implts_readWindowStateData( aName, aNewToolbar ); + implts_setElementData( aNewToolbar, xDockWindow ); + implts_insertUIElement( aNewToolbar ); + bVisible = aNewToolbar.m_bVisible; + } + + // set toolbar menu style according to customize command state + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + { + ToolBox* pToolbar = (ToolBox *)pWindow; + USHORT nMenuType = pToolbar->GetMenuType(); + if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, m_aCustomizeCmd )) + pToolbar->SetMenuType( nMenuType & ~TOOLBOX_MENUTYPE_CUSTOMIZE ); + else + pToolbar->SetMenuType( nMenuType | TOOLBOX_MENUTYPE_CUSTOMIZE ); + } + } + aWriteLock.unlock(); + + implts_sortUIElements(); + + if ( bVisible ) + { + doLayout(); + bNotify = sal_True; + } + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" )) + { + if ( aElementName.equalsIgnoreAsciiCaseAscii( "menubar" ) && !bInPlaceMenu ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + // PB 2004-12-15 #i38743# don't create a menubar if frame isn't top + if ( !m_xMenuBar.is() && implts_isFrameOrWindowTop(xFrame) ) + m_xMenuBar = implts_createElement( aName ); + + if ( m_xMenuBar.is() && implts_isFrameOrWindowTop(xFrame) ) + { + Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); + while ( pWindow && !pWindow->IsSystemWindow() ) + pWindow = pWindow->GetParent(); + + if ( pWindow ) + { + SystemWindow* pSysWindow = (SystemWindow *)pWindow; + Reference< css::awt::XMenuBar > xMenuBar; + + Reference< XPropertySet > xPropSet( m_xMenuBar, UNO_QUERY ); + if ( xPropSet.is() ) + { + try + { + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMenuBar" ))) >>= xMenuBar; + } + catch ( com::sun::star::beans::UnknownPropertyException ) + { + } + catch ( com::sun::star::lang::WrappedTargetException ) + { + } + } + + if ( xMenuBar.is() ) + { + VCLXMenu* pAwtMenuBar = VCLXMenu::GetImplementation( xMenuBar ); + if ( pAwtMenuBar ) + { + MenuBar* pMenuBar = (MenuBar*)pAwtMenuBar->GetMenu(); + if ( pMenuBar ) + { + pSysWindow->SetMenuBar( pMenuBar ); + pMenuBar->SetDisplayable( m_bMenuVisible ); + if ( m_bMenuVisible ) + { + bNotify = sal_True; + } + implts_updateMenuBarClose(); + } + } + } + } + } + } + aWriteLock.unlock(); + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && ( implts_isFrameOrWindowTop(xFrame) || implts_isEmbeddedLayoutManager() )) + { + implts_createStatusBar( aName ); + bNotify = sal_True; + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" ) && + implts_isFrameOrWindowTop(xFrame) ) + { + implts_createProgressBar(); + bNotify = sal_True; + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" )) + { + aWriteLock.unlock(); + + aWriteLock.unlock(); + + // Add layout manager as listener for docking and other window events + Reference< css::uno::XInterface > xThis( static_cast< OWeakObject* >(this), css::uno::UNO_QUERY ); + xUIElement = implts_createDockingWindow( aName ); + if ( xUIElement.is() ) + { + impl_addWindowListeners( xThis, xUIElement ); + m_pPanelManager->addDockingWindow( aName, xUIElement ); + } + + // The docking window is created by a factory method located in the sfx2 library. +// CreateDockingWindow( xFrame, aElementName ); + } + } + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + if ( bNotify ) + { + // UI element is invisible - provide information to listeners + implts_notifyListeners( css::frame::LayoutManagerEvents::UIELEMENT_VISIBLE, uno::makeAny( aName ) ); + } +} + +void SAL_CALL LayoutManager::destroyElement( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::destroyElement" ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + + sal_Bool bMustLayouted( sal_False ); + sal_Bool bMustBeDestroyed( sal_False ); + sal_Bool bMustBeSorted( sal_False ); + sal_Bool bNotify( sal_False ); + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + Reference< XComponent > xComponent; + if ( impl_parseResourceURL( aName, aElementType, aElementName )) + { + if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "menubar" )) + { + if ( !m_bInplaceMenuSet ) + { + impl_clearUpMenuBar(); + m_xMenuBar.clear(); + bNotify = sal_True; + } + } + else if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || + ( m_aStatusBarElement.m_aName == aName )) + { + aWriteLock.unlock(); + implts_destroyStatusBar(); + bMustLayouted = sal_True; + bNotify = sal_True; + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" ) ) + { + aWriteLock.unlock(); + implts_createProgressBar(); + bMustLayouted = sal_True; + bNotify = sal_True; + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" )) + { + UIElementVector::iterator pIter; + + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aName == aName ) + { + xComponent.set( pIter->m_xUIElement, UNO_QUERY ); + Reference< XUIElement > xUIElement( pIter->m_xUIElement ); + if ( xUIElement.is() ) + { + Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + + rtl::OUString aAddonTbResourceName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/addon_" )); + if ( aName.indexOf( aAddonTbResourceName ) != 0 ) + { + try + { + if ( xWindow.is() ) + xWindow->removeWindowListener( Reference< css::awt::XWindowListener >( + static_cast< OWeakObject * >( this ), UNO_QUERY )); + } + catch( Exception& ) + { + } + + try + { + if ( xDockWindow.is() ) + xDockWindow->removeDockableWindowListener( Reference< css::awt::XDockableWindowListener >( + static_cast< OWeakObject * >( this ), UNO_QUERY )); + } + catch ( Exception& ) + { + } + + bMustBeDestroyed = sal_True; + } + else + { + pIter->m_bVisible = sal_False; + xWindow->setVisible( sal_False ); + bNotify = sal_True; + } + + if ( !xDockWindow->isFloating() ) + bMustLayouted = sal_True; + if ( bMustBeDestroyed ) + pIter->m_xUIElement.clear(); + + bMustBeSorted = sal_True; + } + + break; + } + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" )) + { + css::uno::Reference< css::frame::XFrame > xFrame( m_xFrame ); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR ); + aWriteLock.unlock(); + + impl_setDockingWindowVisibility( xSMGR, xFrame, aElementName, false ); + bMustLayouted = sal_False; + bNotify = sal_False; + } + } + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( bMustBeDestroyed ) + { + if ( xComponent.is() ) + xComponent->dispose(); + bNotify = sal_True; + } + + if ( bMustBeSorted ) + { + implts_sortUIElements(); + if ( bMustLayouted ) + doLayout(); + } + + if ( bNotify ) + { + // UI element is invisible - provide information to listeners + implts_notifyListeners( css::frame::LayoutManagerEvents::UIELEMENT_INVISIBLE, uno::makeAny( aName ) ); + } +} + +::sal_Bool SAL_CALL LayoutManager::requestElement( const ::rtl::OUString& ResourceURL ) +throw (::com::sun::star::uno::RuntimeException) +{ + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::requestElement" ); + + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + UIElementVector::iterator pIter; + sal_Bool bResult( sal_False ); + sal_Bool bNotify( sal_False ); + + WriteGuard aWriteLock( m_aLock ); + if ( impl_parseResourceURL( ResourceURL, aElementType, aElementName )) + { + ::rtl::OString aResName = rtl::OUStringToOString( aElementName, RTL_TEXTENCODING_ASCII_US ); + RTL_LOGFILE_CONTEXT_TRACE1( aLog, "framework (cd100003) Element %s", aResName.getStr() ); + + if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || + ( m_aStatusBarElement.m_aName == ResourceURL )) + { + implts_readStatusBarState( ResourceURL ); + if ( m_aStatusBarElement.m_bVisible && !m_aStatusBarElement.m_bMasterHide ) + { + createElement( ResourceURL ); + + // There are some situation where we are not able to create an element. + // Therefore we have to check the reference before further action. + // See #i70019# + css::uno::Reference< css::ui::XUIElement > xUIElement( m_aStatusBarElement.m_xUIElement ); + if ( xUIElement.is() ) + { + // we need VCL here to pass special flags to Show() + vos::OGuard aGuard( Application::GetSolarMutex() ); + Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + { + pWindow->Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); + doLayout(); + bResult = sal_True; + bNotify = sal_True; + } + } + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" ) ) + { + aWriteLock.unlock(); + implts_showProgressBar(); + doLayout(); + bResult = sal_True; + bNotify = sal_True; + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" )) + { + if ( m_bVisible ) + { + bool bFound( false ); + bool bShowElement( false ); + + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aName == ResourceURL ) + { + bFound = sal_True; + bShowElement = ( pIter->m_bVisible && !pIter->m_bMasterHide && m_bParentWindowVisible ); + + Reference< css::awt::XWindow2 > xContainerWindow( m_xContainerWindow, UNO_QUERY ); + if ( xContainerWindow.is() && pIter->m_bFloating ) + bShowElement = ( bShowElement && xContainerWindow->isActive() ); + + if ( pIter->m_xUIElement.is() ) + { + Reference< css::awt::XWindow > xWindow( pIter->m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + + if ( xDockWindow.is() && xDockWindow->isFloating() ) + bShowElement = ( bShowElement && xContainerWindow->isActive() ); + + if ( xDockWindow.is() && bShowElement ) + { + pIter->m_bVisible = sal_True; + aWriteLock.unlock(); + + // we need VCL here to pass special flags to Show() + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if( pWindow && !pWindow->IsReallyVisible() ) + { + pWindow->Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); + implts_writeNewStateData( ResourceURL, xWindow ); + + if ( xDockWindow.is() && !xDockWindow->isFloating() ) + doLayout(); + bResult = sal_True; + bNotify = sal_True; + } + + bResult = sal_False; + } + } // if ( pIter->m_xUIElement.is() ) + break; + } + } + + // Create toolbar on demand when it's visible + if ( !bResult ) + { + Reference< ::com::sun::star::ui::XUIElement > xUIElement; + if ( !bFound ) + { + UIElement aNewToolbar( aElementName, aElementType, xUIElement ); + aNewToolbar.m_aName = ResourceURL; + implts_readWindowStateData( ResourceURL, aNewToolbar ); + implts_insertUIElement( aNewToolbar ); + aWriteLock.unlock(); + + implts_sortUIElements(); + if ( aNewToolbar.m_bVisible ) + createElement( ResourceURL ); + bResult = sal_True; + bNotify = sal_True; + } + else if ( bShowElement ) + { + aWriteLock.unlock(); + + createElement( ResourceURL ); + bResult = sal_True; + bNotify = sal_True; + } + } + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" )) + { + css::uno::Reference< css::frame::XFrame > xFrame( m_xFrame ); + aWriteLock.unlock(); + + CreateDockingWindow( xFrame, aElementName ); + } + } + + if ( bNotify ) + { + // UI element is visible - provide information to listeners + implts_notifyListeners( css::frame::LayoutManagerEvents::UIELEMENT_VISIBLE, uno::makeAny( ResourceURL ) ); + } + + return bResult; +} + +Reference< XUIElement > SAL_CALL LayoutManager::getElement( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + Reference< XUIElement > xElement; + + implts_findElement( aName, aElementType, aElementName, xElement ); + return xElement; +} + +Sequence< Reference< ::com::sun::star::ui::XUIElement > > SAL_CALL LayoutManager::getElements() +throw (::com::sun::star::uno::RuntimeException) +{ + ReadGuard aReadLock( m_aLock ); + + sal_Bool bMenuBar( sal_False ); + sal_Bool bStatusBar( sal_False ); + sal_Int32 nSize = m_aUIElements.size(); + + if ( m_xMenuBar.is() ) + { + ++nSize; + bMenuBar = sal_True; + } + if ( m_aStatusBarElement.m_xUIElement.is() ) + { + ++nSize; + bStatusBar = sal_True; + } + + Sequence< Reference< ::com::sun::star::ui::XUIElement > > aSeq( nSize ); + + sal_Int32 nIndex = 0; + UIElementVector::const_iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_xUIElement.is() ) + aSeq[nIndex++] = pIter->m_xUIElement; + } + if ( bMenuBar ) + aSeq[nIndex++] = m_xMenuBar; + if ( bStatusBar ) + aSeq[nIndex++] = m_aStatusBarElement.m_xUIElement; + + // Resize sequence as we now know our correct size + aSeq.realloc( nIndex ); + + return aSeq; +} + +sal_Bool SAL_CALL LayoutManager::showElement( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::showElement" ); + + sal_Bool bResult( sal_False ); + sal_Bool bNotify( sal_False ); + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + if ( impl_parseResourceURL( aName, aElementType, aElementName )) + { + ::rtl::OString aResName = rtl::OUStringToOString( aElementName, RTL_TEXTENCODING_ASCII_US ); + RTL_LOGFILE_CONTEXT_TRACE1( aLog, "framework (cd100003) Element %s", aResName.getStr() ); + + if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "menubar" )) + { + WriteGuard aWriteLock( m_aLock ); + m_bMenuVisible = sal_True; + aWriteLock.unlock(); + + bResult = implts_resetMenuBar(); + bNotify = bResult; + } + else if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || + ( m_aStatusBarElement.m_aName == aName )) + { + WriteGuard aWriteLock( m_aLock ); + if ( m_aStatusBarElement.m_xUIElement.is() && + !m_aStatusBarElement.m_bMasterHide ) + { + if ( implts_showStatusBar( sal_True )) + { + implts_writeWindowStateData( m_aStatusBarAlias, m_aStatusBarElement ); + doLayout(); + bResult = sal_True; + bNotify = sal_True; + } + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" )) + { + bNotify = bResult = implts_showProgressBar(); + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" )) + { + UIElementVector::iterator pIter; + + WriteGuard aWriteLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aName == aName && pIter->m_xUIElement.is() ) + { + UIElement aUIElement = *pIter; + Reference< css::awt::XWindow > xWindow( pIter->m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + + sal_Bool bShowElement( !pIter->m_bMasterHide && m_bParentWindowVisible ); + + pIter->m_bVisible = sal_True; + aWriteLock.unlock(); + + implts_writeWindowStateData( aUIElement.m_aName, aUIElement ); + implts_sortUIElements(); + + if ( xDockWindow.is() && bShowElement ) + { + // we need VCL here to pass special flags to Show() + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if( pWindow ) + { + pWindow->Show( TRUE, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); + bNotify = sal_True; + } + implts_writeNewStateData( aName, xWindow ); + + if ( xDockWindow.is() && !xDockWindow->isFloating() ) + doLayout(); + + bResult = sal_True; + } // if ( xDockWindow.is() && bShowElement ) + break; + } + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" )) + { + ReadGuard aReadGuard( m_aLock ); + css::uno::Reference< css::frame::XFrame > xFrame( m_xFrame ); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR ); + aReadGuard.unlock(); + + impl_setDockingWindowVisibility( xSMGR, xFrame, aElementName, true ); + } + } + + if ( bNotify ) + { + // UI element is visible - provide information to listeners + implts_notifyListeners( css::frame::LayoutManagerEvents::UIELEMENT_VISIBLE, uno::makeAny( aName ) ); + } + + return bResult; +} + +sal_Bool SAL_CALL LayoutManager::hideElement( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::hideElement" ); + + + sal_Bool bResult( sal_False ); + sal_Bool bNotify( sal_False ); + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + if ( impl_parseResourceURL( aName, aElementType, aElementName )) + { + ::rtl::OString aResName = rtl::OUStringToOString( aElementName, RTL_TEXTENCODING_ASCII_US ); + RTL_LOGFILE_CONTEXT_TRACE1( aLog, "framework (cd100003) Element %s", aResName.getStr() ); + + if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "menubar" )) + { + WriteGuard aWriteLock( m_aLock ); + + if ( m_xContainerWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); + while ( pWindow && !pWindow->IsSystemWindow() ) + pWindow = pWindow->GetParent(); + + m_bMenuVisible = sal_False; + if ( pWindow ) + { + MenuBar* pMenuBar = ((SystemWindow *)pWindow)->GetMenuBar(); + if ( pMenuBar ) + { + pMenuBar->SetDisplayable( sal_False ); + bResult = sal_True; + bNotify = sal_True; + } + } + } + } + else if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || + ( m_aStatusBarElement.m_aName == aName )) + { + WriteGuard aWriteLock( m_aLock ); + if ( m_aStatusBarElement.m_xUIElement.is() && + !m_aStatusBarElement.m_bMasterHide ) + { + if ( implts_hideStatusBar( sal_True )) + { + implts_writeWindowStateData( m_aStatusBarAlias, m_aStatusBarElement ); + doLayout(); + bNotify = sal_True; + bResult = sal_True; + } + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" )) + { + bResult = bNotify = implts_hideProgressBar(); + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" )) + { + UIElementVector::iterator pIter; + + WriteGuard aWriteLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aName == aName && pIter->m_xUIElement.is() ) + { + Reference< css::awt::XWindow > xWindow( pIter->m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + + if ( xDockWindow.is() ) + { + pIter->m_bVisible = sal_False; + aWriteLock.unlock(); + + xWindow->setVisible( sal_False ); + implts_writeNewStateData( aName, xWindow ); + + if ( xDockWindow.is() && !xDockWindow->isFloating() ) + doLayout(); + + bResult = sal_True; + bNotify = sal_True; + } // if ( xDockWindow.is() ) + break; + } + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" )) + { + ReadGuard aReadGuard( m_aLock ); + css::uno::Reference< css::frame::XFrame > xFrame( m_xFrame ); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR ); + aReadGuard.unlock(); + + impl_setDockingWindowVisibility( xSMGR, xFrame, aElementName, false ); + } + } + + if ( bNotify ) + { + // UI element is visible - provide information to listeners + implts_notifyListeners( css::frame::LayoutManagerEvents::UIELEMENT_INVISIBLE, uno::makeAny( aName ) ); + } + + return sal_False; +} + +sal_Bool SAL_CALL LayoutManager::dockWindow( const ::rtl::OUString& aName, DockingArea DockingArea, const css::awt::Point& Pos ) +throw (RuntimeException) +{ + UIElement aUIElement; + + if ( implts_findElement( aName, aUIElement ) && aUIElement.m_xUIElement.is() ) + { + try + { + Reference< css::awt::XWindow > xWindow( aUIElement.m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + if ( xDockWindow.is() ) + { + if ( DockingArea != DockingArea_DOCKINGAREA_DEFAULT ) + aUIElement.m_aDockedData.m_nDockedArea = sal_Int16( DockingArea ); + + if (( Pos.X != SAL_MAX_INT32 ) && ( Pos.Y != SAL_MAX_INT32 )) + aUIElement.m_aDockedData.m_aPos = ::Point( Pos.X, Pos.Y ); + + if ( !xDockWindow->isFloating() ) + { + Window* pWindow( 0 ); + ToolBox* pToolBox( 0 ); + + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + { + pToolBox = (ToolBox *)pWindow; + + // We have to set the alignment of the toolbox. It's possible that the toolbox is moved from a + // horizontal to a vertical docking area! + pToolBox->SetAlign( ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea )); + } + } + + if (( aUIElement.m_aDockedData.m_aPos.X() == SAL_MAX_INT32 ) || + ( aUIElement.m_aDockedData.m_aPos.Y() == SAL_MAX_INT32 )) + { + // Docking on its default position without a preset position - + // we have to find a good place for it. + ::Size aSize; + + vos::OGuard aGuard( Application::GetSolarMutex() ); + { + if ( pToolBox ) + aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea ) ); + else + aSize = pWindow->GetSizePixel(); + } + + ::Point aPixelPos; + ::Point aDockPos; + implts_findNextDockingPos( (::com::sun::star::ui::DockingArea)aUIElement.m_aDockedData.m_nDockedArea, + aSize, + aDockPos, + aPixelPos ); + aUIElement.m_aDockedData.m_aPos = aDockPos; + } + } + + WriteGuard aWriteLock( m_aLock ); + UIElement& rUIElement = LayoutManager::impl_findElement( aUIElement.m_aName ); + if ( rUIElement.m_aName == aName ) + { + rUIElement.m_aDockedData.m_nDockedArea = aUIElement.m_aDockedData.m_nDockedArea; + rUIElement.m_aDockedData.m_aPos = aUIElement.m_aDockedData.m_aPos; + } + aWriteLock.unlock(); + + if ( xDockWindow->isFloating() ) + { + // Will call toggle floating mode which will do the rest! + xWindow->setVisible( sal_False ); + xDockWindow->setFloatingMode( sal_False ); + xWindow->setVisible( sal_True ); + } + else + { + implts_writeWindowStateData( aName, aUIElement ); + implts_sortUIElements(); + + if ( aUIElement.m_bVisible ) + doLayout(); + } + + return sal_True; + } + } + catch ( DisposedException& ) + { + } + } + + return sal_False; +} + +::sal_Bool SAL_CALL LayoutManager::dockAllWindows( ::sal_Int16 nElementType ) throw (::com::sun::star::uno::RuntimeException) +{ + if ( nElementType == UIElementType::TOOLBAR ) + { + std::vector< rtl::OUString > aToolBarNameVector; + + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + { + ReadGuard aReadLock( m_aLock ); + UIElementVector::iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aType.equalsAscii( "toolbar" ) && + pIter->m_xUIElement.is() && + pIter->m_bFloating && + pIter->m_bVisible ) + aToolBarNameVector.push_back( pIter->m_aName ); + } + } + + const sal_uInt32 nCount = aToolBarNameVector.size(); + for ( sal_uInt32 i = 0; i < nCount; ++i ) + { + ::com::sun::star::awt::Point aPoint; + aPoint.X = aPoint.Y = SAL_MAX_INT32; + dockWindow( aToolBarNameVector[i], DockingArea_DOCKINGAREA_DEFAULT, aPoint ); + } + } + + return sal_False; +} + +sal_Bool SAL_CALL LayoutManager::floatWindow( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + UIElement aUIElement; + + if ( implts_findElement( aName, aUIElement )) + { + if ( aUIElement.m_xUIElement.is() ) + { + try + { + Reference< css::awt::XWindow > xWindow( aUIElement.m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + if ( xWindow.is() && xDockWindow.is() ) + { + if ( !xDockWindow->isFloating() ) + { + xDockWindow->setFloatingMode( sal_True ); + return sal_True; + } + } + } + catch ( DisposedException& ) + { + } + } + } + + return sal_False; +} + +::sal_Bool SAL_CALL LayoutManager::lockWindow( const ::rtl::OUString& ResourceURL ) +throw (::com::sun::star::uno::RuntimeException) +{ + UIElement aUIElement; + + if ( implts_findElement( ResourceURL, aUIElement )) + { + if ( aUIElement.m_xUIElement.is() ) + { + try + { + Reference< css::awt::XWindow > xWindow( aUIElement.m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && + pWindow->IsVisible() && + xDockWindow.is() && + !xDockWindow->isFloating() ) + { + aUIElement.m_aDockedData.m_bLocked = sal_True; + implts_writeWindowStateData( ResourceURL, aUIElement ); + xDockWindow->lock(); + + // Write back lock state + WriteGuard aWriteLock( m_aLock ); + UIElement& rUIElement = LayoutManager::impl_findElement( aUIElement.m_aName ); + if ( rUIElement.m_aName == aUIElement.m_aName ) + rUIElement.m_aDockedData.m_bLocked = aUIElement.m_aDockedData.m_bLocked; + aWriteLock.unlock(); + + doLayout(); + return sal_True; + } + } + catch ( DisposedException& ) + { + } + } + } + + return sal_False; +} + +::sal_Bool SAL_CALL LayoutManager::unlockWindow( const ::rtl::OUString& ResourceURL ) +throw (::com::sun::star::uno::RuntimeException) +{ + UIElement aUIElement; + + if ( implts_findElement( ResourceURL, aUIElement )) + { + if ( aUIElement.m_xUIElement.is() ) + { + try + { + Reference< css::awt::XWindow > xWindow( aUIElement.m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && + pWindow->IsVisible() && + xDockWindow.is() && + !xDockWindow->isFloating() ) + { + aUIElement.m_aDockedData.m_bLocked = sal_False; + implts_writeWindowStateData( ResourceURL, aUIElement ); + xDockWindow->unlock(); + + // Write back lock state + WriteGuard aWriteLock( m_aLock ); + UIElement& rUIElement = LayoutManager::impl_findElement( aUIElement.m_aName ); + if ( rUIElement.m_aName == aUIElement.m_aName ) + rUIElement.m_aDockedData.m_bLocked = aUIElement.m_aDockedData.m_bLocked; + aWriteLock.unlock(); + + doLayout(); + return sal_True; + } + } + catch ( DisposedException& ) + { + } + } + } + + return sal_False; +} + +void SAL_CALL LayoutManager::setElementSize( const ::rtl::OUString& aName, const css::awt::Size& aSize ) +throw (RuntimeException) +{ + UIElement aUIElement; + + if ( implts_findElement( aName, aUIElement )) + { + if ( aUIElement.m_xUIElement.is() ) + { + try + { + Reference< css::awt::XWindow > xWindow( aUIElement.m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XWindow2 > xWindow2( aUIElement.m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + + if ( xWindow.is() && xWindow2.is() && xDockWindow.is() ) + { + if ( aUIElement.m_bFloating ) + { + xWindow2->setOutputSize( aSize ); + implts_writeNewStateData( aName, xWindow ); + } + } + } + catch ( DisposedException& ) + { + } + } + } +} + +void SAL_CALL LayoutManager::setElementPos( const ::rtl::OUString& aName, const css::awt::Point& aPos ) +throw (RuntimeException) +{ + UIElement aUIElement; + + if ( implts_findElement( aName, aUIElement ) && aUIElement.m_xUIElement.is() ) + { + try + { + Reference< css::awt::XWindow > xWindow( aUIElement.m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + + if ( xWindow.is() && xDockWindow.is() ) + { + if ( aUIElement.m_bFloating ) + { + xWindow->setPosSize( aPos.X, aPos.Y, 0, 0, css::awt::PosSize::POS ); + implts_writeNewStateData( aName, xWindow ); + } + else + { + WriteGuard aWriteLock( m_aLock ); + UIElement& rUIElement = LayoutManager::impl_findElement( aUIElement.m_aName ); + if ( rUIElement.m_aName == aName ) + rUIElement.m_aDockedData.m_aPos = ::Point( aPos.X, aPos.Y ); + aWriteLock.unlock(); + + aUIElement.m_aDockedData.m_aPos = ::Point( aPos.X, aPos.Y ); + implts_writeWindowStateData( aName, aUIElement ); + implts_sortUIElements(); + + if ( aUIElement.m_bVisible ) + doLayout(); + } + } + } + catch ( DisposedException& ) + { + } + } +} + +void SAL_CALL LayoutManager::setElementPosSize( const ::rtl::OUString& aName, const css::awt::Point& aPos, const css::awt::Size& aSize ) +throw (RuntimeException) +{ + UIElement aUIElement; + + if ( implts_findElement( aName, aUIElement )) + { + if ( aUIElement.m_xUIElement.is() ) + { + try + { + Reference< css::awt::XWindow > xWindow( aUIElement.m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XWindow2 > xWindow2( aUIElement.m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + + if ( xWindow.is() && xWindow2.is() && xDockWindow.is() ) + { + if ( aUIElement.m_bFloating ) + { + xWindow2->setPosSize( aPos.X, aPos.Y, 0, 0, css::awt::PosSize::POS ); + xWindow2->setOutputSize( aSize ); + implts_writeNewStateData( aName, xWindow ); + } + else + { + WriteGuard aWriteLock( m_aLock ); + UIElement& rUIElement = LayoutManager::impl_findElement( aUIElement.m_aName ); + if ( rUIElement.m_aName == aName ) + rUIElement.m_aDockedData.m_aPos = ::Point( aPos.X, aPos.Y ); + aWriteLock.unlock(); + + aUIElement.m_aDockedData.m_aPos = ::Point( aPos.X, aPos.Y ); + implts_writeWindowStateData( aName, rUIElement ); + implts_sortUIElements(); + + if ( aUIElement.m_bVisible ) + doLayout(); + } + } + } + catch ( DisposedException& ) + { + } + } + } +} + +sal_Bool SAL_CALL LayoutManager::isElementVisible( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + if ( impl_parseResourceURL( aName, aElementType, aElementName )) + { + if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "menubar" )) + { + ReadGuard aReadLock( m_aLock ); + if ( m_xContainerWindow.is() ) + { + aReadLock.unlock(); + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); + while ( pWindow && !pWindow->IsSystemWindow() ) + pWindow = pWindow->GetParent(); + + if ( pWindow ) + { + MenuBar* pMenuBar = ((SystemWindow *)pWindow)->GetMenuBar(); + if ( pMenuBar && pMenuBar->IsDisplayable() ) + return sal_True; + } + else + { + aReadLock.lock(); + return m_bMenuVisible; + } + } + } + else if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || + ( m_aStatusBarElement.m_aName == aName )) + { + if ( m_aStatusBarElement.m_xUIElement.is() ) + { + Reference< css::awt::XWindow > xWindow( + m_aStatusBarElement.m_xUIElement->getRealInterface(), UNO_QUERY ); + if ( xWindow.is() ) + { + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->IsVisible() ) + return sal_True; + else + return sal_False; + } + } + } + else if (( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" ))) + { + if ( m_aProgressBarElement.m_xUIElement.is() ) + return m_aProgressBarElement.m_bVisible; + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" )) + { + UIElementVector::const_iterator pIter; + + ReadGuard aReadLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aName == aName && pIter->m_xUIElement.is() ) + { + Reference< css::awt::XWindow > xWindow( pIter->m_xUIElement->getRealInterface(), UNO_QUERY ); + if ( xWindow.is() ) + { + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + return pWindow && pWindow->IsVisible(); + } + } + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" )) + { + ReadGuard aReadGuard( m_aLock ); + css::uno::Reference< css::frame::XFrame > xFrame( m_xFrame ); + aReadGuard.unlock(); + + return IsDockingWindowVisible( xFrame, aElementName ); + } + } + + return sal_False; +} + +sal_Bool SAL_CALL LayoutManager::isElementFloating( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + UIElementVector::const_iterator pIter; + + ReadGuard aReadLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aName == aName && pIter->m_xUIElement.is() ) + { + Reference< css::awt::XDockableWindow > xDockWindow( pIter->m_xUIElement->getRealInterface(), UNO_QUERY ); + return xDockWindow.is() && xDockWindow->isFloating(); + } + } + + return sal_False; +} + +sal_Bool SAL_CALL LayoutManager::isElementDocked( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + UIElementVector::const_iterator pIter; + + ReadGuard aReadLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aName == aName && pIter->m_xUIElement.is() ) + { + Reference< css::awt::XDockableWindow > xDockWindow( pIter->m_xUIElement->getRealInterface(), UNO_QUERY ); + return xDockWindow.is() && !xDockWindow->isFloating(); + } + } + + return sal_False; +} + +::sal_Bool SAL_CALL LayoutManager::isElementLocked( const ::rtl::OUString& ResourceURL ) +throw (::com::sun::star::uno::RuntimeException) +{ + UIElementVector::const_iterator pIter; + + ReadGuard aReadLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if (( pIter->m_aName == ResourceURL ) && ( pIter->m_xUIElement.is() )) + { + Reference< css::awt::XDockableWindow > xDockWindow( pIter->m_xUIElement->getRealInterface(), UNO_QUERY ); + return xDockWindow.is() && !xDockWindow->isLocked(); + } + } + + return sal_False; +} + +css::awt::Size SAL_CALL LayoutManager::getElementSize( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + ReadGuard aReadLock( m_aLock ); + UIElement aElementData; + if ( implts_findElement( aName,aElementData ) && aElementData.m_xUIElement.is() ) + { + Reference< css::awt::XWindow > xWindow( aElementData.m_xUIElement->getRealInterface(), UNO_QUERY ); + if ( xWindow.is() ) + { + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + { + ::Size aSize = pWindow->GetSizePixel(); + css::awt::Size aElementSize; + aElementSize.Width = aSize.Width(); + aElementSize.Height = aSize.Height(); + return aElementSize; + } // if ( pWindow ) + } + } + return css::awt::Size(); +} + +css::awt::Point SAL_CALL LayoutManager::getElementPos( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + ReadGuard aReadLock( m_aLock ); + UIElement aElementData; + if ( implts_findElement( aName,aElementData ) && aElementData.m_xUIElement.is() ) + { + Reference< css::awt::XWindow > xWindow( aElementData.m_xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + if ( xDockWindow.is() ) + { + css::awt::Point aPos; + if ( aElementData.m_bFloating ) + { + css::awt::Rectangle aRect = xWindow->getPosSize(); + aPos.X = aRect.X; + aPos.Y = aRect.Y; + } + else + { + ::Point aVirtualPos = aElementData.m_aDockedData.m_aPos; + aPos.X = aVirtualPos.X(); + aPos.Y = aVirtualPos.Y(); + } + + return aPos; + } + } + + return css::awt::Point(); +} + +void SAL_CALL LayoutManager::lock() +throw (RuntimeException) +{ + implts_lock(); + + ReadGuard aReadLock( m_aLock ); + sal_Int32 nLockCount( m_nLockCount ); + aReadLock.unlock(); + + RTL_LOGFILE_TRACE1( "framework (cd100003) ::LayoutManager::lock lockCount=%d", nLockCount ); +#ifdef DBG_UTIL + ByteString aStr("LayoutManager::lock "); + aStr += ByteString::CreateFromInt32((long)this); + aStr += " - "; + aStr += ByteString::CreateFromInt32(nLockCount); + DBG_TRACE( aStr.GetBuffer() ); +#endif + + Any a( nLockCount ); + implts_notifyListeners( css::frame::LayoutManagerEvents::LOCK, a ); +} + +void SAL_CALL LayoutManager::unlock() +throw (RuntimeException) +{ + sal_Bool bDoLayout( implts_unlock() ); + + ReadGuard aReadLock( m_aLock ); + sal_Int32 nLockCount( m_nLockCount ); + aReadLock.unlock(); + + RTL_LOGFILE_TRACE1( "framework (cd100003) ::LayoutManager::unlock lockCount=%d", nLockCount ); +#ifdef DBG_UTIL + ByteString aStr("LayoutManager::unlock "); + aStr += ByteString::CreateFromInt32((long)this); + aStr += " - "; + aStr += ByteString::CreateFromInt32(nLockCount); + DBG_TRACE( aStr.GetBuffer() ); +#endif + // conform to documentation: unlock with lock count == 0 means force a layout + + WriteGuard aWriteLock( m_aLock ); + if ( bDoLayout ) + m_aAsyncLayoutTimer.Stop(); + aWriteLock.unlock(); + + Any a( nLockCount ); + implts_notifyListeners( css::frame::LayoutManagerEvents::UNLOCK, a ); + + if ( bDoLayout ) + implts_doLayout_notify( sal_True ); +} + +void SAL_CALL LayoutManager::doLayout() +throw (RuntimeException) +{ + implts_doLayout_notify( sal_True ); +} + +void LayoutManager::implts_doLayout_notify( sal_Bool bOuterResize ) +{ + sal_Bool bLayouted = implts_doLayout( sal_False, bOuterResize ); + if ( bLayouted ) + implts_notifyListeners( css::frame::LayoutManagerEvents::LAYOUT, Any() ); +} + +sal_Bool LayoutManager::implts_doLayout( sal_Bool bForceRequestBorderSpace, sal_Bool bOuterResize ) +{ + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::implts_doLayout" ); + + sal_Bool bNoLock( sal_False ); + css::awt::Rectangle aCurrBorderSpace; + Reference< css::awt::XWindow > xContainerWindow; + Reference< css::awt::XTopWindow2 > xContainerTopWindow; + Reference< css::awt::XWindow > xComponentWindow; + Reference< XDockingAreaAcceptor > xDockingAreaAcceptor; + bool bPreserveContentSize( false ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + + sal_Bool bMustDoLayout( m_bMustDoLayout ); + if ( !m_bParentWindowVisible ) + return sal_False; + + bNoLock = ( m_nLockCount == 0 ); + xContainerWindow = m_xContainerWindow; + xContainerTopWindow = m_xContainerTopWindow; + xComponentWindow = m_xFrame->getComponentWindow(); + xDockingAreaAcceptor = m_xDockingAreaAcceptor; + aCurrBorderSpace = m_aDockingArea; + bPreserveContentSize = m_bPreserveContentSize; + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + sal_Bool bLayouted( sal_False ); + + if ( bNoLock && + xDockingAreaAcceptor.is() && + xContainerWindow.is() && + xComponentWindow.is() ) + { + bLayouted = sal_True; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteGuard( m_aLock ); + m_bDoLayout = sal_True; + aWriteGuard.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + css::awt::Rectangle aBorderSpace = implts_calcDockingAreaSizes(); + sal_Bool bGotRequestedBorderSpace( sal_True ); + sal_Bool bEqual = implts_compareRectangles( aBorderSpace, aCurrBorderSpace ); + + if ( !bEqual || bForceRequestBorderSpace || bMustDoLayout ) + { + // we always resize the content window (instead of the complete container window) if we're not set up + // to (attempt to) preserve the content window's size + if ( bOuterResize && !bPreserveContentSize ) + bOuterResize = sal_False; + + // maximized windows can resized their content window only, not their container window + if ( bOuterResize && xContainerTopWindow.is() && xContainerTopWindow->getIsMaximized() ) + bOuterResize = sal_False; + + // if the component window does not have a size (yet), then we can't use it to calc the container + // window size + css::awt::Rectangle aComponentRect = xComponentWindow->getPosSize(); + if ( bOuterResize && ( aComponentRect.Width == 0 ) && ( aComponentRect.Height == 0 ) ) + bOuterResize = sal_False; + + bGotRequestedBorderSpace = sal_False; + if ( bOuterResize ) + { + Reference< awt::XDevice > xDevice( xContainerWindow, uno::UNO_QUERY ); + awt::DeviceInfo aContainerInfo = xDevice->getInfo(); + + awt::Size aRequestedSize( aComponentRect.Width + aContainerInfo.LeftInset + aContainerInfo.RightInset + aBorderSpace.X + aBorderSpace.Width, + aComponentRect.Height + aContainerInfo.TopInset + aContainerInfo.BottomInset + aBorderSpace.Y + aBorderSpace.Height ); + awt::Point aComponentPos( aBorderSpace.X, aBorderSpace.Y ); + + bGotRequestedBorderSpace = implts_resizeContainerWindow( aRequestedSize, aComponentPos ); + } + + // if we did not do an container window resize, or it failed, then use the DockingAcceptor as usual + if ( !bGotRequestedBorderSpace ) + { + bGotRequestedBorderSpace = xDockingAreaAcceptor->requestDockingAreaSpace( aBorderSpace ); + if ( bGotRequestedBorderSpace ) + xDockingAreaAcceptor->setDockingAreaSpace( aBorderSpace ); + } + + if ( bGotRequestedBorderSpace ) + { + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aWriteGuard.lock(); + m_aDockingArea = aBorderSpace; + m_bMustDoLayout = sal_False; + aWriteGuard.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + } + } + + if ( bGotRequestedBorderSpace ) + { + ::Size aContainerSize; + ::Size aStatusBarSize; + + aStatusBarSize = implts_getStatusBarSize(); + aBorderSpace.Height -= aStatusBarSize.Height(); + implts_setDockingAreaWindowSizes( aBorderSpace ); + + // Subtract status bar size from our container output size. Docking area windows + // don't contain the status bar! + aContainerSize = implts_getContainerWindowOutputSize(); + aContainerSize.Height() -= aStatusBarSize.Height(); + + // Retrieve row/column dependent data from all docked user-interface elements + for ( sal_Int32 i = 0; i < DOCKINGAREAS_COUNT; i++ ) + { + std::vector< SingleRowColumnWindowData > aRowColumnsWindowData; + + implts_getDockingAreaElementInfos( (DockingArea)i, aRowColumnsWindowData ); + + sal_Int32 nOffset( 0 ); + const sal_uInt32 nCount = aRowColumnsWindowData.size(); + for ( sal_uInt32 j = 0; j < nCount; ++j ) + { + implts_calcWindowPosSizeOnSingleRowColumn( i, nOffset, aRowColumnsWindowData[j], aContainerSize ); + nOffset += aRowColumnsWindowData[j].nStaticSize; + } + } + + // Position the status bar + if ( aStatusBarSize.Height() > 0 ) + { + implts_setStatusBarPosSize( ::Point( 0, std::max(( aContainerSize.Height() ), long( 0 ))), + ::Size( aContainerSize.Width(),aStatusBarSize.Height() )); + } + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aWriteGuard.lock(); + m_bDoLayout = sal_False; + aWriteGuard.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + } + } + + return bLayouted; +} + +sal_Bool LayoutManager::implts_compareRectangles( const css::awt::Rectangle& rRect1, + const css::awt::Rectangle& rRect2 ) +{ + return (( rRect1.X == rRect2.X ) && + ( rRect1.Y == rRect2.Y ) && + ( rRect1.Width == rRect2.Width ) && + ( rRect1.Height == rRect2.Height )); +} + +sal_Bool LayoutManager::implts_resizeContainerWindow( const awt::Size& rContainerSize, + const awt::Point& rComponentPos ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + Reference< awt::XWindow > xContainerWindow = m_xContainerWindow; + Reference< awt::XTopWindow2 > xContainerTopWindow = m_xContainerTopWindow; + Reference< awt::XWindow > xComponentWindow = m_xFrame->getComponentWindow(); + Reference< container::XIndexAccess > xDisplayAccess = m_xDisplayAccess; + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + // calculate the maximum size we have for the container window + awt::Rectangle aWorkArea; + try + { + sal_Int32 nDisplay = xContainerTopWindow->getDisplay(); + Reference< beans::XPropertySet > xDisplayInfo( xDisplayAccess->getByIndex( nDisplay ), UNO_QUERY_THROW ); + OSL_VERIFY( xDisplayInfo->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "WorkArea" ) ) ) >>= aWorkArea ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + if ( ( aWorkArea.Width > 0 ) && ( aWorkArea.Height > 0 ) ) + { + if ( ( rContainerSize.Width > aWorkArea.Width ) + || ( rContainerSize.Height > aWorkArea.Height ) + ) + return sal_False; + // Strictly, this is not correct. If we have a multi-screen display (css.awt.DisplayAccess.MultiDisplay == true), + // the the "effective work area" would be much larger than the work area of a single display, since we could in theory + // position the container window across multiple screens. + // However, this should suffice as a heuristics here ... (nobody really wants to check whethere the different screens are + // stacked horizontally or vertically, whether their work areas can really be combined, or are separated by non-work-areas, + // and the like ... right?) + } + + // resize our container window + xContainerWindow->setPosSize( 0, 0, rContainerSize.Width, rContainerSize.Height, css::awt::PosSize::SIZE ); + // position the component window + xComponentWindow->setPosSize( rComponentPos.X, rComponentPos.Y, 0, 0, css::awt::PosSize::POS ); + return sal_True; +} + +void SAL_CALL LayoutManager::setVisible( sal_Bool bVisible ) +throw (::com::sun::star::uno::RuntimeException) +{ + sal_Bool bWasVisible( sal_True ); + + WriteGuard aWriteLock( m_aLock ); + bWasVisible = m_bVisible; + m_bVisible = bVisible; + aWriteLock.unlock(); + + if ( bWasVisible != bVisible ) + implts_setVisibleState( bVisible ); +} + +sal_Bool SAL_CALL LayoutManager::isVisible() +throw (::com::sun::star::uno::RuntimeException) +{ + ReadGuard aReadLock( m_aLock ); + return m_bVisible; +} + +void LayoutManager::implts_calcWindowPosSizeOnSingleRowColumn( sal_Int32 nDockingArea, + sal_Int32 nOffset, + SingleRowColumnWindowData& rRowColumnWindowData, + const ::Size& rContainerSize ) +{ + sal_Int32 nDiff( 0 ); + sal_Int32 nRCSpace( rRowColumnWindowData.nSpace ); + sal_Int32 nTopDockingAreaSize; + sal_Int32 nBottomDockingAreaSize; + sal_Int32 nContainerClientSize; + + if ( rRowColumnWindowData.aRowColumnWindows.empty() ) + return; + + if (( nDockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( nDockingArea == DockingArea_DOCKINGAREA_BOTTOM )) + { + nContainerClientSize = rContainerSize.Width(); + nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize; + } + else + { + nTopDockingAreaSize = implts_getTopBottomDockingAreaSizes().Width(); + nBottomDockingAreaSize = implts_getTopBottomDockingAreaSizes().Height(); + nContainerClientSize = ( rContainerSize.Height() - nTopDockingAreaSize - nBottomDockingAreaSize ); + nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize; + } + + const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindowSizes.size(); + if (( nDiff < 0 ) && ( nRCSpace > 0 )) + { + // First we try to reduce the size of blank space before/behind docked windows + sal_Int32 i = nCount - 1; + while ( i >= 0 ) + { + sal_Int32 nSpace = rRowColumnWindowData.aRowColumnSpace[i]; + if ( nSpace >= -nDiff ) + { + + if (( nDockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( nDockingArea == DockingArea_DOCKINGAREA_BOTTOM )) + { + // Try to move this and all user elements behind with the calculated difference + for ( sal_uInt32 j = i; j < nCount ; j++ ) + rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff; + } + else + { + // Try to move this and all user elements behind with the calculated difference + for ( sal_uInt32 j = i; j < nCount ; j++ ) + rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff; + } + nDiff = 0; + + break; + } + else if ( nSpace > 0 ) + { + if (( nDockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( nDockingArea == DockingArea_DOCKINGAREA_BOTTOM )) + { + // Try to move this and all user elements behind with the calculated difference + for ( sal_uInt32 j = i; j < nCount; j++ ) + rRowColumnWindowData.aRowColumnWindowSizes[j].X -= nSpace; + } + else + { + // Try to move this and all user elements behind with the calculated difference + for ( sal_uInt32 j = i; j < nCount; j++ ) + rRowColumnWindowData.aRowColumnWindowSizes[j].Y -= nSpace; + } + nDiff += nSpace; + } + --i; + } + } + + // Check if we have to reduce further + if ( nDiff < 0 ) + { + // Now we have to reduce the size of certain docked windows + sal_Int32 i = sal_Int32( nCount - 1 ); + while ( i >= 0 ) + { + css::awt::Rectangle& rWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i]; + ::Size aMinSize; + + vos::OGuard aGuard( Application::GetSolarMutex() ); + { + Reference< css::awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i]; + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + aMinSize = ((ToolBox *)pWindow)->CalcMinimumWindowSizePixel(); + } + + if (( aMinSize.Width() > 0 ) && ( aMinSize.Height() > 0 )) + { + if (( nDockingArea == DockingArea_DOCKINGAREA_TOP ) || + ( nDockingArea == DockingArea_DOCKINGAREA_BOTTOM )) + { + sal_Int32 nMaxReducation = ( rWinRect.Width - aMinSize.Width() ); + if ( nMaxReducation >= -nDiff ) + { + rWinRect.Width = rWinRect.Width + nDiff; + nDiff = 0; + } + else + { + rWinRect.Width = aMinSize.Width(); + nDiff += nMaxReducation; + } + + // Try to move this and all user elements behind with the calculated difference + for ( sal_uInt32 j = i; j < nCount; j++ ) + rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff; + } + else + { + sal_Int32 nMaxReducation = ( rWinRect.Height - aMinSize.Height() ); + if ( nMaxReducation >= -nDiff ) + { + rWinRect.Height = rWinRect.Height + nDiff; + nDiff = 0; + } + else + { + rWinRect.Height = aMinSize.Height(); + nDiff += nMaxReducation; + } + + // Try to move this and all user elements behind with the calculated difference + for ( sal_uInt32 j = i; j < nCount; j++ ) + rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff; + } + } + + if ( nDiff >= 0 ) + break; + + --i; + } + } + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + Window* pDockAreaWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[nDockingArea] ); + aReadLock.unlock(); + + sal_Int32 nCurrPos( 0 ); + sal_Int32 nStartOffset( 0 ); + + if ( nDockingArea == DockingArea_DOCKINGAREA_RIGHT ) + nStartOffset = pDockAreaWindow->GetSizePixel().Width() - rRowColumnWindowData.nStaticSize; + else if ( nDockingArea == DockingArea_DOCKINGAREA_BOTTOM ) + nStartOffset = pDockAreaWindow->GetSizePixel().Height() - rRowColumnWindowData.nStaticSize; + + vos::OGuard aGuard( Application::GetSolarMutex() ); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + Reference< css::awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i]; + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + Window* pOldParentWindow = pWindow->GetParent(); + + if ( pDockAreaWindow != pOldParentWindow ) + pWindow->SetParent( pDockAreaWindow ); + + css::awt::Rectangle aWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i]; + if ( nDockingArea == DockingArea_DOCKINGAREA_TOP ) + { + if ( aWinRect.X < nCurrPos ) + aWinRect.X = nCurrPos; + pWindow->SetPosSizePixel( ::Point( aWinRect.X, nOffset ), + ::Size( aWinRect.Width, rRowColumnWindowData.nStaticSize )); + nCurrPos += ( aWinRect.X - nCurrPos ) + aWinRect.Width; + } + else if ( nDockingArea == DockingArea_DOCKINGAREA_BOTTOM ) + { + if ( aWinRect.X < nCurrPos ) + aWinRect.X = nCurrPos; + pWindow->SetPosSizePixel( ::Point( aWinRect.X, nStartOffset - nOffset ), + ::Size( aWinRect.Width, rRowColumnWindowData.nStaticSize )); + nCurrPos += ( aWinRect.X - nCurrPos ) + aWinRect.Width; + } + else if ( nDockingArea == DockingArea_DOCKINGAREA_LEFT ) + { + if ( aWinRect.Y < nCurrPos ) + aWinRect.Y = nCurrPos; + pWindow->SetPosSizePixel( ::Point( nOffset, aWinRect.Y ), + ::Size( rRowColumnWindowData.nStaticSize, aWinRect.Height )); + nCurrPos += ( aWinRect.Y - nCurrPos ) + aWinRect.Height; + } + else if ( nDockingArea == DockingArea_DOCKINGAREA_RIGHT ) + { + if ( aWinRect.Y < nCurrPos ) + aWinRect.Y = nCurrPos; + pWindow->SetPosSizePixel( ::Point( nStartOffset - nOffset, aWinRect.Y ), + ::Size( rRowColumnWindowData.nStaticSize, aWinRect.Height )); + nCurrPos += ( aWinRect.Y - nCurrPos ) + aWinRect.Height; + } + } +} + +::Size LayoutManager::implts_getStatusBarSize() +{ + ReadGuard aReadLock( m_aLock ); + sal_Bool bStatusBarVisible( isElementVisible( m_aStatusBarAlias )); + sal_Bool bProgressBarVisible( isElementVisible( m_aProgressBarAlias )); + sal_Bool bVisible = m_bVisible; + Reference< XUIElement > xStatusBar = m_aStatusBarElement.m_xUIElement; + Reference< XUIElement > xProgressBar = m_aProgressBarElement.m_xUIElement; + + Reference< css::awt::XWindow > xWindow; + if ( bStatusBarVisible && bVisible && xStatusBar.is() ) + xWindow = Reference< css::awt::XWindow >( xStatusBar->getRealInterface(), UNO_QUERY ); + else if ( xProgressBar.is() && !xStatusBar.is() && bProgressBarVisible ) + { + ProgressBarWrapper* pWrapper = (ProgressBarWrapper*)xProgressBar.get(); + if ( pWrapper ) + xWindow = pWrapper->getStatusBar(); + } + aReadLock.unlock(); + + if ( xWindow.is() ) + { + css::awt::Rectangle aPosSize = xWindow->getPosSize(); + return ::Size( aPosSize.Width, aPosSize.Height ); + } + else + return ::Size(); +} + +css::awt::Rectangle LayoutManager::implts_calcDockingAreaSizes() +{ + Reference< css::awt::XWindow > xContainerWindow; + Reference< XDockingAreaAcceptor > xDockingAreaAcceptor; + + ReadGuard aReadLock( m_aLock ); + xContainerWindow = m_xContainerWindow; + xDockingAreaAcceptor = m_xDockingAreaAcceptor; + UIElementVector aWindowVector( m_aUIElements ); + aReadLock.unlock(); + + css::awt::Rectangle aBorderSpace; + if ( xDockingAreaAcceptor.is() && xContainerWindow.is() ) + { + sal_Int32 nCurrRowColumn( 0 ); + sal_Int32 nCurrPos( 0 ); + sal_Int32 nCurrDockingArea( DockingArea_DOCKINGAREA_TOP ); + std::vector< sal_Int32 > aRowColumnSizes[DOCKINGAREAS_COUNT]; + UIElementVector::const_iterator pConstIter; + + aRowColumnSizes[nCurrDockingArea].clear(); + aRowColumnSizes[nCurrDockingArea].push_back( 0 ); + + for ( pConstIter = aWindowVector.begin(); pConstIter != aWindowVector.end(); pConstIter++ ) + { + Reference< XUIElement > xUIElement( pConstIter->m_xUIElement, UNO_QUERY ); + if ( xUIElement.is() ) + { + Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + if ( xWindow.is() && xDockWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->IsVisible() && !xDockWindow->isFloating() ) + { + css::awt::Rectangle aPosSize = xWindow->getPosSize(); + if ( pConstIter->m_aDockedData.m_nDockedArea != nCurrDockingArea ) + { + nCurrDockingArea = pConstIter->m_aDockedData.m_nDockedArea; + nCurrRowColumn = 0; + nCurrPos = 0; + aRowColumnSizes[nCurrDockingArea].clear(); + aRowColumnSizes[nCurrDockingArea].push_back( 0 ); + } + + if ( pConstIter->m_aDockedData.m_nDockedArea == nCurrDockingArea ) + { + if (( pConstIter->m_aDockedData.m_nDockedArea == DockingArea_DOCKINGAREA_TOP ) || + ( pConstIter->m_aDockedData.m_nDockedArea == DockingArea_DOCKINGAREA_BOTTOM )) + { + if ( pConstIter->m_aDockedData.m_aPos.Y() > nCurrPos ) + { + ++nCurrRowColumn; + nCurrPos = pConstIter->m_aDockedData.m_aPos.Y(); + aRowColumnSizes[nCurrDockingArea].push_back( 0 ); + } + + if ( aPosSize.Height > aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] ) + aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] = aPosSize.Height; + } + else + { + if ( pConstIter->m_aDockedData.m_aPos.X() > nCurrPos ) + { + ++nCurrRowColumn; + nCurrPos = pConstIter->m_aDockedData.m_aPos.X(); + aRowColumnSizes[nCurrDockingArea].push_back( 0 ); + } + + if ( aPosSize.Width > aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] ) + aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] = aPosSize.Width; + } + } + } + } + } + } + + // Sum up max heights from every row/column + if ( !aWindowVector.empty() ) + { + for ( sal_Int32 i = 0; i <= DockingArea_DOCKINGAREA_RIGHT; i++ ) + { + sal_Int32 nSize( 0 ); + const sal_uInt32 nCount = aRowColumnSizes[i].size(); + for ( sal_uInt32 j = 0; j < nCount; j++ ) + nSize += aRowColumnSizes[i][j]; + + if ( i == DockingArea_DOCKINGAREA_TOP ) + aBorderSpace.Y = nSize; + else if ( i == DockingArea_DOCKINGAREA_BOTTOM ) + aBorderSpace.Height = nSize; + else if ( i == DockingArea_DOCKINGAREA_LEFT ) + aBorderSpace.X = nSize; + else + aBorderSpace.Width = nSize; + } + } + + // We have to add the height of a possible status bar + aBorderSpace.Height += implts_getStatusBarSize().Height(); + } + + return aBorderSpace; +} + +void LayoutManager::implts_setDockingAreaWindowSizes( const css::awt::Rectangle& rBorderSpace ) +{ + Reference< css::awt::XWindow > xContainerWindow; + + ReadGuard aReadLock( m_aLock ); + xContainerWindow = m_xContainerWindow; + aReadLock.unlock(); + + css::uno::Reference< css::awt::XDevice > xDevice( xContainerWindow, css::uno::UNO_QUERY ); + // Convert relativ size to output size. + css::awt::Rectangle aRectangle = xContainerWindow->getPosSize(); + css::awt::DeviceInfo aInfo = xDevice->getInfo(); + css::awt::Size aContainerClientSize = css::awt::Size( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset , + aRectangle.Height - aInfo.TopInset - aInfo.BottomInset ); + ::Size aStatusBarSize = implts_getStatusBarSize(); + + sal_Int32 nLeftRightDockingAreaHeight( aContainerClientSize.Height ); + if ( rBorderSpace.Y >= 0 ) + { + // Top docking area window + aReadLock.lock(); + Reference< css::awt::XWindow > xDockAreaWindow( m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP] ); + aReadLock.unlock(); + + xDockAreaWindow->setPosSize( 0, 0, aContainerClientSize.Width, rBorderSpace.Y, css::awt::PosSize::POSSIZE ); + xDockAreaWindow->setVisible( sal_True ); + nLeftRightDockingAreaHeight -= rBorderSpace.Y; + } + + if ( rBorderSpace.Height >= 0 ) + { + // Bottom docking area window + sal_Int32 nBottomPos = std::max( sal_Int32( aContainerClientSize.Height - rBorderSpace.Height - aStatusBarSize.Height() ), sal_Int32( 0 )); + sal_Int32 nHeight = ( nBottomPos == 0 ) ? 0 : rBorderSpace.Height; + + aReadLock.lock(); + Reference< css::awt::XWindow > xDockAreaWindow( m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM] ); + aReadLock.unlock(); + + xDockAreaWindow->setPosSize( 0, nBottomPos, aContainerClientSize.Width, nHeight, css::awt::PosSize::POSSIZE ); + xDockAreaWindow->setVisible( sal_True ); + nLeftRightDockingAreaHeight -= nHeight; + } + + nLeftRightDockingAreaHeight -= aStatusBarSize.Height(); + if ( rBorderSpace.X >= 0 || nLeftRightDockingAreaHeight > 0 ) + { + // Left docking area window + aReadLock.lock(); + Reference< css::awt::XWindow > xDockAreaWindow( m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT] ); + aReadLock.unlock(); + + // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority! + sal_Int32 nHeight = std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight )); + + xDockAreaWindow->setPosSize( 0, rBorderSpace.Y, rBorderSpace.X, nHeight, css::awt::PosSize::POSSIZE ); + xDockAreaWindow->setVisible( sal_True ); + } + if ( rBorderSpace.Width >= 0 || nLeftRightDockingAreaHeight > 0 ) + { + // Right docking area window + aReadLock.lock(); + Reference< css::awt::XWindow > xDockAreaWindow( m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT] ); + aReadLock.unlock(); + + // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority! + sal_Int32 nLeftPos = std::max( sal_Int32( 0 ), sal_Int32( aContainerClientSize.Width - rBorderSpace.Width )); + sal_Int32 nHeight = std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight )); + sal_Int32 nWidth = ( nLeftPos == 0 ) ? 0 : rBorderSpace.Width; + + xDockAreaWindow->setPosSize( nLeftPos, rBorderSpace.Y, nWidth, nHeight, css::awt::PosSize::POSSIZE ); + xDockAreaWindow->setVisible( sal_True ); + } + + // Position the status bar + if ( aStatusBarSize.Height() > 0 ) + { + implts_setStatusBarPosSize( ::Point( 0, std::max(( aContainerClientSize.Height - aStatusBarSize.Height() ), long( 0 ))), + ::Size( aContainerClientSize.Width, aStatusBarSize.Height() )); + } +} + +//--------------------------------------------------------------------------------------------------------- +// XMenuCloser +//--------------------------------------------------------------------------------------------------------- +void LayoutManager::implts_updateMenuBarClose() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + sal_Bool bShowCloser = m_bMenuBarCloser; + Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow ); + aWriteLock.unlock(); + + if ( xContainerWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + Window* pWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + while ( pWindow && !pWindow->IsSystemWindow() ) + pWindow = pWindow->GetParent(); + + if ( pWindow ) + { + SystemWindow* pSysWindow = (SystemWindow *)pWindow; + MenuBar* pMenuBar = pSysWindow->GetMenuBar(); + if ( pMenuBar ) + { + // TODO remove link on FALSE ?! + if ( bShowCloser ) + { + pMenuBar->ShowCloser( TRUE ); + pMenuBar->SetCloserHdl( LINK( this, LayoutManager, MenuBarClose )); + } + else + { + pMenuBar->ShowCloser( FALSE ); + pMenuBar->SetCloserHdl( LINK( this, LayoutManager, MenuBarClose )); + } + } + } + } +} + +sal_Bool LayoutManager::implts_resetMenuBar() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + sal_Bool bMenuVisible( m_bMenuVisible ); + Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow ); + + MenuBar* pSetMenuBar = 0; + if ( m_xInplaceMenuBar.is() ) + pSetMenuBar = (MenuBar *)m_pInplaceMenuBar->GetMenuBar(); + else + { + MenuBarWrapper* pMenuBarWrapper = SAL_STATIC_CAST( MenuBarWrapper*, m_xMenuBar.get() ); + if ( pMenuBarWrapper ) + pSetMenuBar = (MenuBar *)pMenuBarWrapper->GetMenuBarManager()->GetMenuBar(); + } + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); + while ( pWindow && !pWindow->IsSystemWindow() ) + pWindow = pWindow->GetParent(); + + if ( pWindow && bMenuVisible && pSetMenuBar ) + { + ((SystemWindow *)pWindow)->SetMenuBar( pSetMenuBar ); + pSetMenuBar->SetDisplayable( sal_True ); + return sal_True; + } + + return sal_False; +} + +void LayoutManager::implts_setMenuBarCloser(sal_Bool bCloserState) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_bMenuBarCloser = bCloserState; + aWriteLock.unlock(); + + implts_updateMenuBarClose(); +} + +sal_Int16 LayoutManager::implts_getCurrentSymbolsSize() +{ + sal_Int16 eOptSymbolsSize( 0 ); + + { + ReadGuard aReadLock( m_aLock ); + vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( m_pMiscOptions ) + eOptSymbolsSize = m_pMiscOptions->GetCurrentSymbolsSize(); + } + + return eOptSymbolsSize; +} + +sal_Int16 LayoutManager::implts_getCurrentSymbolsStyle() +{ + sal_Int16 eOptSymbolsStyle( 0 ); + + { + ReadGuard aReadLock( m_aLock ); + vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( m_pMiscOptions ) + eOptSymbolsStyle = m_pMiscOptions->GetCurrentSymbolsStyle(); + } + + return eOptSymbolsStyle; +} + +IMPL_LINK( LayoutManager, MenuBarClose, MenuBar *, EMPTYARG ) +{ + ReadGuard aReadLock( m_aLock ); + css::uno::Reference< css::frame::XDispatchProvider > xProvider(m_xFrame, css::uno::UNO_QUERY); + css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR; + aReadLock.unlock(); + + if (! xProvider.is()) + return 0; + + css::uno::Reference< css::frame::XDispatchHelper > xDispatcher( + xSMGR->createInstance(SERVICENAME_DISPATCHHELPER), css::uno::UNO_QUERY_THROW); + + xDispatcher->executeDispatch( + xProvider, + ::rtl::OUString::createFromAscii(".uno:CloseWin"), + ::rtl::OUString::createFromAscii("_self"), + 0, + css::uno::Sequence< css::beans::PropertyValue >()); + + return 0; +} + +IMPL_LINK( LayoutManager, OptionsChanged, void*, EMPTYARG ) +{ + sal_Int16 eSymbolsSize( implts_getCurrentSymbolsSize() ); + sal_Int16 eSymbolsStyle( implts_getCurrentSymbolsStyle() ); + + ReadGuard aReadLock( m_aLock ); + sal_Int16 eOldSymbolsSize = m_eSymbolsSize; + sal_Int16 eOldSymbolsStyle = m_eSymbolsStyle; + aReadLock.unlock(); + + if ( eSymbolsSize != eOldSymbolsSize || eSymbolsStyle != eOldSymbolsStyle ) + { + WriteGuard aWriteLock( m_aLock ); + m_eSymbolsSize = eSymbolsSize; + m_eSymbolsStyle = eSymbolsStyle; + aWriteLock.unlock(); + + std::vector< Reference< XUpdatable > > aToolBarVector; + + aReadLock.lock(); + { + UIElementVector::iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_xUIElement.is() ) + aToolBarVector.push_back( Reference< XUpdatable >( pIter->m_xUIElement, UNO_QUERY )); + } + } + aReadLock.unlock(); + + lock(); + { + std::vector< Reference< XUpdatable > >::iterator pIter; + for ( pIter = aToolBarVector.begin(); pIter != aToolBarVector.end(); pIter++ ) + { + if ( (*pIter).is() ) + (*pIter)->update(); + } + } + unlock(); + doLayout(); + } + + return 1; +} + +IMPL_LINK( LayoutManager, SettingsChanged, void*, EMPTYARG ) +{ + return 1; +} + +//--------------------------------------------------------------------------------------------------------- +// XDockableWindowListener +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL LayoutManager::startDocking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException) +{ + sal_Bool bWinFound( sal_False ); + UIElement aUIElement; + + ReadGuard aReadGuard( m_aLock ); + Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow ); + Reference< css::awt::XWindow2 > xWindow( e.Source, UNO_QUERY ); + aReadGuard.unlock(); + + Window* pContainerWindow( 0 ); + Window* pWindow( 0 ); + ::Point aMousePos; + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + aMousePos = pContainerWindow->ScreenToOutputPixel( ::Point( e.MousePos.X, e.MousePos.Y )); + } + + bWinFound = implts_findElement( e.Source, aUIElement ); + + if ( !bWinFound ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + PanelWindow* pPanelWindow = dynamic_cast<PanelWindow*>(pWindow); + if ( pPanelWindow ) + m_pPanelManager->startDocking( e ); + } + else if ( xWindow.is() ) + { + css::awt::Rectangle aRect; + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + if ( xDockWindow->isFloating() ) + { + css::awt::Rectangle aPos = xWindow->getPosSize(); + css::awt::Size aSize = xWindow->getOutputSize(); + + aUIElement.m_aFloatingData.m_aPos = ::Point( aPos.X, aPos.Y ); + aUIElement.m_aFloatingData.m_aSize = ::Size( aSize.Width, aSize.Height ); + + vos::OGuard aGuard( Application::GetSolarMutex() ); + pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + { + ToolBox* pToolBox = (ToolBox *)pWindow; + aUIElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines(); + aUIElement.m_aFloatingData.m_bIsHorizontal = (( pToolBox->GetAlign() == WINDOWALIGN_TOP ) || + ( pToolBox->GetAlign() == WINDOWALIGN_BOTTOM )); + } + } + } + + WriteGuard aWriteLock( m_aLock ); + m_bDockingInProgress = bWinFound; + m_aDockUIElement = aUIElement; + m_aDockUIElement.m_bUserActive = sal_True; + m_aStartDockMousePos = aMousePos; + aWriteLock.unlock(); +} + +::Rectangle LayoutManager::implts_calcHotZoneRect( const ::Rectangle& rRect, sal_Int32 nHotZoneOffset ) +{ + ::Rectangle aRect( rRect ); + + aRect.Left() -= nHotZoneOffset; + aRect.Top() -= nHotZoneOffset; + aRect.Right() += nHotZoneOffset; + aRect.Bottom() += nHotZoneOffset; + return aRect; +} + +css::awt::DockingData SAL_CALL LayoutManager::docking( const ::com::sun::star::awt::DockingEvent& e ) +throw (::com::sun::star::uno::RuntimeException) +{ + const sal_Int32 MAGNETIC_DISTANCE_UNDOCK = 25; + const sal_Int32 MAGNETIC_DISTANCE_DOCK = 20; + + css::awt::DockingData aDockingData; + Reference< css::awt::XDockableWindow > xDockWindow( e.Source, UNO_QUERY ); + Reference< css::awt::XWindow > xWindow( e.Source, UNO_QUERY ); + Reference< css::awt::XWindow > xTopDockingWindow; + Reference< css::awt::XWindow > xLeftDockingWindow; + Reference< css::awt::XWindow > xRightDockingWindow; + Reference< css::awt::XWindow > xBottomDockingWindow; + Reference< css::awt::XWindow > xContainerWindow; + UIElement aUIDockingElement; + DockingOperation eDockingOperation( DOCKOP_ON_COLROW ); + ::Size aStatusBarSize; + + aDockingData.TrackingRectangle = e.TrackingRectangle; + sal_Bool bDockingInProgress; + + { + ReadGuard aReadLock( m_aLock ); + bDockingInProgress = m_bDockingInProgress; + if ( bDockingInProgress ) + { + xContainerWindow = m_xContainerWindow; + xTopDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_TOP]; + xLeftDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_LEFT]; + xRightDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_RIGHT]; + xBottomDockingWindow = m_xDockAreaWindows[DockingArea_DOCKINGAREA_BOTTOM]; + aUIDockingElement = m_aDockUIElement; + aStatusBarSize = implts_getStatusBarSize(); + } + } + + if ( bDockingInProgress && + xDockWindow.is() && + xWindow.is() ) + { + try + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + sal_Int16 eDockingArea( -1 ); // none + sal_Int32 nMagneticZone( aUIDockingElement.m_bFloating ? MAGNETIC_DISTANCE_DOCK : MAGNETIC_DISTANCE_UNDOCK ); + css::awt::Rectangle aNewTrackingRect; + ::Rectangle aTrackingRect( e.TrackingRectangle.X, + e.TrackingRectangle.Y, + ( e.TrackingRectangle.X + e.TrackingRectangle.Width ), + ( e.TrackingRectangle.Y + e.TrackingRectangle.Height )); + + css::awt::Rectangle aTmpRect = xTopDockingWindow->getPosSize(); + ::Rectangle aTopDockRect( aTmpRect.X, aTmpRect.Y, aTmpRect.Width, aTmpRect.Height ); + ::Rectangle aHotZoneTopDockRect( implts_calcHotZoneRect( aTopDockRect, nMagneticZone )); + + aTmpRect = xBottomDockingWindow->getPosSize(); + ::Rectangle aBottomDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width), ( aTmpRect.Y + aTmpRect.Height )); + ::Rectangle aHotZoneBottomDockRect( implts_calcHotZoneRect( aBottomDockRect, nMagneticZone )); + + aTmpRect = xLeftDockingWindow->getPosSize(); + ::Rectangle aLeftDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height )); + ::Rectangle aHotZoneLeftDockRect( implts_calcHotZoneRect( aLeftDockRect, nMagneticZone )); + + aTmpRect = xRightDockingWindow->getPosSize(); + ::Rectangle aRightDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height )); + ::Rectangle aHotZoneRightDockRect( implts_calcHotZoneRect( aRightDockRect, nMagneticZone )); + + Window* pContainerWindow( VCLUnoHelper::GetWindow( xContainerWindow ) ); + Window* pDockingAreaWindow( 0 ); + ::Point aMousePos( pContainerWindow->ScreenToOutputPixel( ::Point( e.MousePos.X, e.MousePos.Y ))); + + if ( aHotZoneTopDockRect.IsInside( aMousePos )) + eDockingArea = DockingArea_DOCKINGAREA_TOP; + else if ( aHotZoneBottomDockRect.IsInside( aMousePos )) + eDockingArea = DockingArea_DOCKINGAREA_BOTTOM; + else if ( aHotZoneLeftDockRect.IsInside( aMousePos )) + eDockingArea = DockingArea_DOCKINGAREA_LEFT; + else if ( aHotZoneRightDockRect.IsInside( aMousePos )) + eDockingArea = DockingArea_DOCKINGAREA_RIGHT; + + // Higher priority for movements inside the real docking area + if ( aTopDockRect.IsInside( aMousePos )) + eDockingArea = DockingArea_DOCKINGAREA_TOP; + else if ( aBottomDockRect.IsInside( aMousePos )) + eDockingArea = DockingArea_DOCKINGAREA_BOTTOM; + else if ( aLeftDockRect.IsInside( aMousePos )) + eDockingArea = DockingArea_DOCKINGAREA_LEFT; + else if ( aRightDockRect.IsInside( aMousePos )) + eDockingArea = DockingArea_DOCKINGAREA_RIGHT; + + // Determine if we have a toolbar and set alignment according to the docking area! + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + ToolBox* pToolBox = 0; + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + pToolBox = (ToolBox *)pWindow; + + if ( eDockingArea != -1 ) + { + if ( eDockingArea == DockingArea_DOCKINGAREA_TOP ) + { + aUIDockingElement.m_aDockedData.m_nDockedArea = DockingArea_DOCKINGAREA_TOP; + aUIDockingElement.m_bFloating = sal_False; + pDockingAreaWindow = VCLUnoHelper::GetWindow( xTopDockingWindow ); + } + else if ( eDockingArea == DockingArea_DOCKINGAREA_BOTTOM ) + { + aUIDockingElement.m_aDockedData.m_nDockedArea = DockingArea_DOCKINGAREA_BOTTOM; + aUIDockingElement.m_bFloating = sal_False; + pDockingAreaWindow = VCLUnoHelper::GetWindow( xBottomDockingWindow ); + } + else if ( eDockingArea == DockingArea_DOCKINGAREA_LEFT ) + { + aUIDockingElement.m_aDockedData.m_nDockedArea = DockingArea_DOCKINGAREA_LEFT; + aUIDockingElement.m_bFloating = sal_False; + pDockingAreaWindow = VCLUnoHelper::GetWindow( xLeftDockingWindow ); + } + else if ( eDockingArea == DockingArea_DOCKINGAREA_RIGHT ) + { + aUIDockingElement.m_aDockedData.m_nDockedArea = DockingArea_DOCKINGAREA_RIGHT; + aUIDockingElement.m_bFloating = sal_False; + pDockingAreaWindow = VCLUnoHelper::GetWindow( xRightDockingWindow ); + } + + ::Point aOutputPos = pContainerWindow->ScreenToOutputPixel( aTrackingRect.TopLeft() ); + aTrackingRect.SetPos( aOutputPos ); + + ::Rectangle aNewDockingRect( aTrackingRect ); + implts_calcDockingPosSize( aUIDockingElement, eDockingOperation, aNewDockingRect, aMousePos ); + + ::Point aScreenPos = pContainerWindow->OutputToScreenPixel( aNewDockingRect.TopLeft() ); + aNewTrackingRect = css::awt::Rectangle( aScreenPos.X(), + aScreenPos.Y(), + aNewDockingRect.getWidth(), + aNewDockingRect.getHeight() ); + aDockingData.TrackingRectangle = aNewTrackingRect; + } + else if ( pToolBox && bDockingInProgress ) + { + sal_Bool bIsHorizontal = (( pToolBox->GetAlign() == WINDOWALIGN_TOP ) || + ( pToolBox->GetAlign() == WINDOWALIGN_BOTTOM )); + ::Size aFloatSize = aUIDockingElement.m_aFloatingData.m_aSize; + if ( aFloatSize.Width() > 0 && aFloatSize.Height() > 0 ) + { + aUIDockingElement.m_aFloatingData.m_aPos = pContainerWindow->ScreenToOutputPixel( + ::Point( e.MousePos.X, e.MousePos.Y )); + aDockingData.TrackingRectangle.Height = aFloatSize.Height(); + aDockingData.TrackingRectangle.Width = aFloatSize.Width(); + } + else + { + aFloatSize = pToolBox->CalcWindowSizePixel(); + if ( !bIsHorizontal ) + { + // Floating toolbars are always horizontal aligned! We have to swap + // width/height if we have a vertical aligned toolbar. + sal_Int32 nTemp = aFloatSize.Height(); + aFloatSize.Height() = aFloatSize.Width(); + aFloatSize.Width() = nTemp; + } + + aDockingData.TrackingRectangle.Height = aFloatSize.Height(); + aDockingData.TrackingRectangle.Width = aFloatSize.Width(); + + // For the first time we don't have any data about the floating size of a toolbar. + // We calculate it and store it for later use. + aUIDockingElement.m_aFloatingData.m_aPos = pContainerWindow->ScreenToOutputPixel( + ::Point( e.MousePos.X, e.MousePos.Y )); + aUIDockingElement.m_aFloatingData.m_aSize = aFloatSize; + aUIDockingElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines(); + aUIDockingElement.m_aFloatingData.m_bIsHorizontal = (( pToolBox->GetAlign() == WINDOWALIGN_TOP ) || + ( pToolBox->GetAlign() == WINDOWALIGN_BOTTOM )); + } + aDockingData.TrackingRectangle.X = e.MousePos.X; + aDockingData.TrackingRectangle.Y = e.MousePos.Y; + } + + aDockingData.bFloating = ( eDockingArea == -1 ); + + // Write current data to the member docking progress data + WriteGuard aWriteLock( m_aLock ); + m_aDockUIElement.m_bFloating = aDockingData.bFloating; + if ( !aDockingData.bFloating ) + { + m_aDockUIElement.m_aDockedData = aUIDockingElement.m_aDockedData; + m_eDockOperation = eDockingOperation; + } + else + m_aDockUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData; + aWriteLock.unlock(); + } + catch ( Exception& ) + { + } + } + + return aDockingData; +} + +void SAL_CALL LayoutManager::endDocking( const ::com::sun::star::awt::EndDockingEvent& e ) +throw (::com::sun::star::uno::RuntimeException) +{ + sal_Bool bDockingInProgress( sal_False ); + sal_Bool bStartDockFloated( sal_False ); + sal_Bool bFloating( sal_False ); + UIElement aUIDockingElement; + + WriteGuard aWriteLock( m_aLock ); + bDockingInProgress = m_bDockingInProgress; + aUIDockingElement = m_aDockUIElement; + bFloating = aUIDockingElement.m_bFloating; + + UIElement& rUIElement = impl_findElement( aUIDockingElement.m_aName ); + if ( rUIElement.m_aName == aUIDockingElement.m_aName ) + { + if ( aUIDockingElement.m_bFloating ) + { + // Write last position into position data + Reference< css::awt::XWindow > xWindow( aUIDockingElement.m_xUIElement->getRealInterface(), UNO_QUERY ); + rUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData; + css::awt::Rectangle aTmpRect = xWindow->getPosSize(); + rUIElement.m_aFloatingData.m_aPos = ::Point( aTmpRect.X, aTmpRect.Y ); + // make changes also for our local data as we use it to make data persistent + aUIDockingElement.m_aFloatingData = rUIElement.m_aFloatingData; + } + else + { + rUIElement.m_aDockedData = aUIDockingElement.m_aDockedData; + rUIElement.m_aFloatingData.m_aSize = aUIDockingElement.m_aFloatingData.m_aSize; + + if ( m_eDockOperation != DOCKOP_ON_COLROW ) + { + // we have to renumber our row/column data to insert a new row/column + implts_renumberRowColumnData( (::com::sun::star::ui::DockingArea)aUIDockingElement.m_aDockedData.m_nDockedArea, + m_eDockOperation, + aUIDockingElement ); + } + } + + bStartDockFloated = rUIElement.m_bFloating; + rUIElement.m_bFloating = m_aDockUIElement.m_bFloating; + rUIElement.m_bUserActive = sal_True; + } + + // reset member for next docking operation + m_aDockUIElement.m_xUIElement.clear(); + m_eDockOperation = DOCKOP_ON_COLROW; + aWriteLock.unlock(); + + implts_writeWindowStateData( aUIDockingElement.m_aName, aUIDockingElement ); + + if ( bDockingInProgress ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( Reference< css::awt::XWindow >( e.Source, UNO_QUERY )); + ToolBox* pToolBox = 0; + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + pToolBox = (ToolBox *)pWindow; + + if ( pToolBox ) + { + if( e.bFloating ) + { + if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal ) + pToolBox->SetAlign( WINDOWALIGN_TOP ); + else + pToolBox->SetAlign( WINDOWALIGN_LEFT ); + } + else + { + ::Size aSize; + + pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) ); + + // Docked toolbars have always one line + aSize = pToolBox->CalcWindowSizePixel( 1 ); + + // Lock layouting updates as our listener would be called due to SetSizePixel + pToolBox->SetOutputSizePixel( aSize ); + } + } + } + + aWriteLock.lock(); + m_bDockingInProgress = sal_False; + aWriteLock.unlock(); + + implts_sortUIElements(); + if ( !bStartDockFloated || !bFloating ) + { + // Optimization: Don't layout if we started floating and now floating again. + // This would not change anything for the docked user-interface elements. + doLayout(); + } +} + +sal_Bool SAL_CALL LayoutManager::prepareToggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) +throw (::com::sun::star::uno::RuntimeException) +{ + sal_Bool bDockingInProgress( sal_False ); + + ReadGuard aReadLock( m_aLock ); + bDockingInProgress = m_bDockingInProgress; + aReadLock.unlock(); + + UIElement aUIDockingElement; + sal_Bool bWinFound( implts_findElement( e.Source, aUIDockingElement ) ); + Reference< css::awt::XWindow > xWindow( e.Source, UNO_QUERY ); + + if ( bWinFound && xWindow.is() ) + { + if ( !bDockingInProgress ) + { + css::awt::Rectangle aRect; + Reference< css::awt::XDockableWindow > xDockWindow( xWindow, UNO_QUERY ); + if ( xDockWindow->isFloating() ) + { + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + { + if ( pWindow->GetType() == WINDOW_TOOLBOX ) + { + ToolBox* pToolBox = (ToolBox *)pWindow; + aUIDockingElement.m_aFloatingData.m_aPos = pToolBox->GetPosPixel(); + aUIDockingElement.m_aFloatingData.m_aSize = pToolBox->GetOutputSizePixel(); + aUIDockingElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines(); + aUIDockingElement.m_aFloatingData.m_bIsHorizontal = (( pToolBox->GetAlign() == WINDOWALIGN_TOP ) || + ( pToolBox->GetAlign() == WINDOWALIGN_BOTTOM )); + } + } + } + + WriteGuard aWriteLock( m_aLock ); + UIElement& rUIElement = LayoutManager::impl_findElement( aUIDockingElement.m_aName ); + if ( rUIElement.m_aName == aUIDockingElement.m_aName ) + rUIElement = aUIDockingElement; + aWriteLock.unlock(); + } + } + } + + return sal_True; +} + +void SAL_CALL LayoutManager::toggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) +throw (::com::sun::star::uno::RuntimeException) +{ + sal_Bool bDockingInProgress( sal_False ); + UIElement aUIDockingElement; + + ReadGuard aReadLock( m_aLock ); + bDockingInProgress = m_bDockingInProgress; + if ( bDockingInProgress ) + aUIDockingElement = m_aDockUIElement; + aReadLock.unlock(); + + Window* pWindow( 0 ); + ToolBox* pToolBox( 0 ); + Reference< css::awt::XWindow2 > xWindow; + + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + xWindow = Reference< css::awt::XWindow2 >( e.Source, UNO_QUERY ); + pWindow = VCLUnoHelper::GetWindow( xWindow ); + + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + pToolBox = (ToolBox *)pWindow; + } + + if ( !bDockingInProgress ) + { + sal_Bool bWinFound( implts_findElement( e.Source, aUIDockingElement ) ); + if ( bWinFound && xWindow.is() ) + { + aUIDockingElement.m_bFloating = !aUIDockingElement.m_bFloating; + aUIDockingElement.m_bUserActive = sal_True; + + WriteGuard aWriteLock( m_aLock ); + m_bDoLayout = sal_True; + aWriteLock.unlock(); + + if ( aUIDockingElement.m_bFloating ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( pToolBox ) + { + pToolBox->SetLineCount( aUIDockingElement.m_aFloatingData.m_nLines ); + if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal ) + pToolBox->SetAlign( WINDOWALIGN_TOP ); + else + pToolBox->SetAlign( WINDOWALIGN_LEFT ); + } + + sal_Bool bUndefPos = ( aUIDockingElement.m_aFloatingData.m_aPos.X() == SAL_MAX_INT32 || + aUIDockingElement.m_aFloatingData.m_aPos.Y() == SAL_MAX_INT32 ); + sal_Bool bSetSize = ( aUIDockingElement.m_aFloatingData.m_aSize.Width() != 0 && + aUIDockingElement.m_aFloatingData.m_aSize.Height() != 0 ); + + if ( bUndefPos ) + aUIDockingElement.m_aFloatingData.m_aPos = implts_findNextCascadeFloatingPos(); + + if ( !bSetSize ) + { + if ( pToolBox ) + aUIDockingElement.m_aFloatingData.m_aSize = pToolBox->CalcFloatingWindowSizePixel(); + else + aUIDockingElement.m_aFloatingData.m_aSize = pWindow->GetOutputSizePixel(); + } + + xWindow->setPosSize( aUIDockingElement.m_aFloatingData.m_aPos.X(), + aUIDockingElement.m_aFloatingData.m_aPos.Y(), + 0, 0, css::awt::PosSize::POS ); + xWindow->setOutputSize( AWTSize( aUIDockingElement.m_aFloatingData.m_aSize ) ); + } + else + { + if (( aUIDockingElement.m_aDockedData.m_aPos.X() == SAL_MAX_INT32 ) && + ( aUIDockingElement.m_aDockedData.m_aPos.Y() == SAL_MAX_INT32 )) + { + // Docking on its default position without a preset position - + // we have to find a good place for it. + ::Point aPixelPos; + ::Point aDockPos; + ::Size aSize; + + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( pToolBox ) + aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea ) ); + else + aSize = pWindow->GetSizePixel(); + } + + implts_findNextDockingPos( (::com::sun::star::ui::DockingArea)aUIDockingElement.m_aDockedData.m_nDockedArea, + aSize, + aDockPos, + aPixelPos ); + aUIDockingElement.m_aDockedData.m_aPos = aDockPos; + } + + vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( pToolBox ) + { + pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) ); + ::Size aSize = pToolBox->CalcWindowSizePixel( 1 ); + css::awt::Rectangle aRect = xWindow->getPosSize(); + xWindow->setPosSize( aRect.X, aRect.Y, 0, 0, css::awt::PosSize::POS ); + xWindow->setOutputSize( AWTSize( aSize ) ); + } + } + + aWriteLock.lock(); + m_bDoLayout = sal_False; + UIElement& rUIElement = LayoutManager::impl_findElement( aUIDockingElement.m_aName ); + if ( rUIElement.m_aName == aUIDockingElement.m_aName ) + rUIElement = aUIDockingElement; + aWriteLock.unlock(); + + implts_writeWindowStateData( aUIDockingElement.m_aName, aUIDockingElement ); + + implts_sortUIElements(); + doLayout(); + } + } + else + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( pToolBox ) + { + if ( aUIDockingElement.m_bFloating ) + { + if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal ) + pToolBox->SetAlign( WINDOWALIGN_TOP ); + else + pToolBox->SetAlign( WINDOWALIGN_LEFT ); + } + else + { + pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) ); + } + } + } +} + +void SAL_CALL LayoutManager::closed( const ::com::sun::star::lang::EventObject& e ) +throw (::com::sun::star::uno::RuntimeException) +{ + rtl::OUString aName; + UIElement aUIElement; + UIElementVector::iterator pIter; + + WriteGuard aWriteLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + Reference< XUIElement > xUIElement( pIter->m_xUIElement ); + if ( xUIElement.is() ) + { + Reference< XInterface > xIfac( xUIElement->getRealInterface(), UNO_QUERY ); + if ( xIfac == e.Source ) + { + aName = pIter->m_aName; + + // user closes a toolbar => + // context sensitive toolbar: only destroy toolbar and store state. + // context sensitive toolbar: make it invisible, store state and destroy it. + if ( !pIter->m_bContextSensitive ) + pIter->m_bVisible = sal_False; + + aUIElement = *pIter; + break; + } + } + } + aWriteLock.unlock(); + + + // destroy element + if ( aName.getLength() > 0 ) + { + implts_writeWindowStateData( aName, aUIElement ); + destroyElement( aName ); + } +} + +void SAL_CALL LayoutManager::endPopupMode( const ::com::sun::star::awt::EndPopupModeEvent& ) +throw (::com::sun::star::uno::RuntimeException) +{ + +} + +//--------------------------------------------------------------------------------------------------------- +// XLayoutManagerEventBroadcaster +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL LayoutManager::addLayoutManagerEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManagerListener >& xListener ) +throw (::com::sun::star::uno::RuntimeException) +{ + m_aListenerContainer.addInterface( ::getCppuType( (const css::uno::Reference< css::frame::XLayoutManagerListener >*)NULL ), xListener ); +} + +void SAL_CALL LayoutManager::removeLayoutManagerEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XLayoutManagerListener >& xListener ) +throw (::com::sun::star::uno::RuntimeException) +{ + m_aListenerContainer.removeInterface( ::getCppuType( (const css::uno::Reference< css::frame::XLayoutManagerListener >*)NULL ), xListener ); +} + +void LayoutManager::implts_notifyListeners( short nEvent, ::com::sun::star::uno::Any aInfoParam ) +{ + css::lang::EventObject aSource (static_cast< ::cppu::OWeakObject*>(this)); + ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const css::uno::Reference< css::frame::XLayoutManagerListener >*) NULL ) ); + if (pContainer!=NULL) + { + ::cppu::OInterfaceIteratorHelper pIterator(*pContainer); + while (pIterator.hasMoreElements()) + { + try + { + ((css::frame::XLayoutManagerListener*)pIterator.next())->layoutEvent( aSource, nEvent, aInfoParam ); + } + catch( css::uno::RuntimeException& ) + { + pIterator.remove(); + } + } + } +} + +//--------------------------------------------------------------------------------------------------------- +// XWindowListener +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL LayoutManager::windowResized( const css::awt::WindowEvent& aEvent ) +throw( css::uno::RuntimeException ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + + if ( !m_xDockingAreaAcceptor.is() ) + return; + + // Request to set docking area space again. + css::awt::Rectangle aDockingArea( m_aDockingArea ); + Reference< XDockingAreaAcceptor > xDockingAreaAcceptor( m_xDockingAreaAcceptor ); + Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow ); + + Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY ); + if ( xIfac == aEvent.Source && m_bVisible ) + { + // We have to call our resize handler at least once synchronously, as some + // application modules need this. So we have to check if this is the first + // call after the async layout time expired. + m_bMustDoLayout = sal_True; + if ( !m_aAsyncLayoutTimer.IsActive() ) + { + const Link& aLink = m_aAsyncLayoutTimer.GetTimeoutHdl(); + if ( aLink.IsSet() ) + aLink.Call( &m_aAsyncLayoutTimer ); + } + if ( m_nLockCount == 0 ) + m_aAsyncLayoutTimer.Start(); + } + else if ( m_xFrame.is() && aEvent.Source == m_xFrame->getContainerWindow() ) + { + // the container window of my DockingAreaAcceptor is not the same as of my frame + // I still have to resize my frames' window as nobody else will do it + Reference< css::awt::XWindow > xComponentWindow( m_xFrame->getComponentWindow() ); + if( xComponentWindow.is() == sal_True ) + { + css::uno::Reference< css::awt::XDevice > xDevice( m_xFrame->getContainerWindow(), css::uno::UNO_QUERY ); + + // Convert relativ size to output size. + css::awt::Rectangle aRectangle = m_xFrame->getContainerWindow()->getPosSize(); + css::awt::DeviceInfo aInfo = xDevice->getInfo(); + css::awt::Size aSize ( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset , + aRectangle.Height - aInfo.TopInset - aInfo.BottomInset ); + + // Resize our component window. + xComponentWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, css::awt::PosSize::POSSIZE ); + } + } + else + { + // resize event for one of the UIElements + sal_Bool bLocked( m_bDockingInProgress ); + sal_Bool bDoLayout( m_bDoLayout ); + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( !bLocked && !bDoLayout ) + { + // Do not do anything if we are in the middle of a docking process. This would interfere all other + // operations. We will store the new position and size in the docking handlers. + // Do not do anything if we are in the middle of our layouting process. We will adapt the position + // and size of the user interface elements. + UIElement aUIElement; + if ( implts_findElement( aEvent.Source, aUIElement )) + { + if ( aUIElement.m_bFloating ) + implts_writeNewStateData( aUIElement.m_aName, + Reference< css::awt::XWindow >( aEvent.Source, UNO_QUERY )); + else + doLayout(); + } + } + } +} + +void SAL_CALL LayoutManager::windowMoved( const css::awt::WindowEvent& ) throw( css::uno::RuntimeException ) +{ +} + +void SAL_CALL LayoutManager::windowShown( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + + // Request to set docking area space again. + Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow ); + bool bParentWindowVisible( m_bParentWindowVisible ); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY ); + if ( xIfac == aEvent.Source ) + { + bool bSetVisible = false; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_bParentWindowVisible = true; + bSetVisible = ( m_bParentWindowVisible != bParentWindowVisible ); + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( bSetVisible ) + { + implts_updateUIElementsVisibleState( sal_True ); + //implts_doLayout( sal_False ); + } + } +} + +void SAL_CALL LayoutManager::windowHidden( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + + // Request to set docking area space again. + Reference< css::awt::XWindow > xContainerWindow( m_xContainerWindow ); + bool bParentWindowVisible( m_bParentWindowVisible ); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY ); + if ( xIfac == aEvent.Source ) + { + bool bSetInvisible = false; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_bParentWindowVisible = false; + bSetInvisible = ( m_bParentWindowVisible != bParentWindowVisible ); + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( bSetInvisible ) + implts_updateUIElementsVisibleState( sal_False ); + } +} + +IMPL_LINK( LayoutManager, AsyncLayoutHdl, Timer *, EMPTYARG ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + + // Request to set docking area space again. + m_aAsyncLayoutTimer.Stop(); + + if( !m_xContainerWindow.is() ) + return 0; + + css::awt::Rectangle aDockingArea( m_aDockingArea ); + ::Size aStatusBarSize( implts_getStatusBarSize() ); + + // Subtract status bar height + aDockingArea.Height -= aStatusBarSize.Height(); + aReadLock.unlock(); + + implts_setDockingAreaWindowSizes( aDockingArea ); + implts_doLayout( sal_True, sal_False ); + + return 0; +} + +#ifdef DBG_UTIL +void LayoutManager::implts_checkElementContainer() +{ +#ifdef DBG_UTIL + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + + BaseHash< sal_Int32 > aUIElementHash; + + UIElementVector::iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + aUIElementHash[pIter->m_aName]++; + + + BaseHash< sal_Int32 >::const_iterator pCheckIter = aUIElementHash.begin(); + for ( ; pCheckIter != aUIElementHash.end(); pCheckIter++ ) + { + if ( pCheckIter->second > 1 ) + { + ::rtl::OString aName = ::rtl::OUStringToOString( pCheckIter->first, RTL_TEXTENCODING_ASCII_US ); + DBG_ASSERT( "More than one element (%s) with the same name found!", aName.getStr() ); + } + } // for ( ; pCheckIter != aUIElementHash.end(); pCheckIter++ ) +#endif +} +#endif + +//--------------------------------------------------------------------------------------------------------- +// XFrameActionListener +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL LayoutManager::frameAction( const FrameActionEvent& aEvent ) +throw ( RuntimeException ) +{ + if (( aEvent.Action == FrameAction_COMPONENT_ATTACHED ) || + ( aEvent.Action == FrameAction_COMPONENT_REATTACHED )) + { + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::frameAction (COMPONENT_ATTACHED|REATTACHED)" ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_bComponentAttached = sal_True; + m_bMustDoLayout = sal_True; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + implts_reset( sal_True ); + implts_doLayout( sal_True, sal_False ); + implts_doLayout( sal_True, sal_True ); + } + else if (( aEvent.Action == FrameAction_FRAME_UI_ACTIVATED ) || + ( aEvent.Action == FrameAction_FRAME_UI_DEACTIVATING )) + { + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::frameAction (FRAME_UI_ACTIVATED|DEACTIVATING)" ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_bActive = ( aEvent.Action == FrameAction_FRAME_UI_ACTIVATED ); + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + implts_toggleFloatingUIElementsVisibility( aEvent.Action == FrameAction_FRAME_UI_ACTIVATED ); +// doLayout(); + } + else if ( aEvent.Action == FrameAction_COMPONENT_DETACHING ) + { + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::frameAction (COMPONENT_DETACHING)" ); + + // SAFE AREA ----------------------------------------------------------------------------------------------- + WriteGuard aWriteLock( m_aLock ); + m_bComponentAttached = sal_False; + aWriteLock.unlock(); + // SAFE AREA ----------------------------------------------------------------------------------------------- + + implts_reset( sal_False ); + } +} + +// ______________________________________________ + +void SAL_CALL LayoutManager::disposing( const css::lang::EventObject& rEvent ) +throw( RuntimeException ) +{ + sal_Bool bDisposeAndClear( sal_False ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + + if ( rEvent.Source == Reference< XInterface >( m_xFrame, UNO_QUERY )) + { + // Our frame gets disposed, release all our references that depends on a working + // frame reference. + Application::RemoveEventListener( LINK( this, LayoutManager, SettingsChanged ) ); + if ( m_pMiscOptions ) + { + m_pMiscOptions->RemoveListenerLink( LINK( this, LayoutManager, OptionsChanged ) ); + delete m_pMiscOptions; + m_pMiscOptions = 0; + } + + delete m_pAddonOptions; + m_pAddonOptions = 0; + + // destroy all elements, it's possible that dettaching is NOT called! + implts_destroyElements(); + + m_aUIElements.clear(); + impl_clearUpMenuBar(); + m_xMenuBar.clear(); + if ( m_xInplaceMenuBar.is() ) + { + m_pInplaceMenuBar = 0; + m_xInplaceMenuBar->dispose(); + } + m_xInplaceMenuBar.clear(); + m_xContainerWindow.clear(); + m_xContainerTopWindow.clear(); + implts_destroyDockingAreaWindows(); + + if ( m_xModuleCfgMgr.is() ) + { + try + { + Reference< XUIConfiguration > xModuleCfgMgr( m_xModuleCfgMgr, UNO_QUERY ); + xModuleCfgMgr->removeConfigurationListener( + Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); + } + catch ( Exception& ) + { + } + } + + if ( m_xDocCfgMgr.is() ) + { + try + { + Reference< XUIConfiguration > xDocCfgMgr( m_xDocCfgMgr, UNO_QUERY ); + xDocCfgMgr->removeConfigurationListener( + Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY )); + } + catch ( Exception& ) + { + } + } + + m_xDocCfgMgr.clear(); + m_xModuleCfgMgr.clear(); + m_xFrame.clear(); + delete m_pGlobalSettings; + m_pGlobalSettings = 0; + m_xDockingAreaAcceptor = Reference< ::com::sun::star::ui::XDockingAreaAcceptor >(); + + bDisposeAndClear = sal_True; + } + else if ( rEvent.Source == Reference< XInterface >( m_xContainerWindow, UNO_QUERY )) + { + // Our container window gets disposed. Remove all user interface elements. + m_aUIElements.clear(); + impl_clearUpMenuBar(); + m_xMenuBar.clear(); + if ( m_xInplaceMenuBar.is() ) + { + m_pInplaceMenuBar = 0; + m_xInplaceMenuBar->dispose(); + } + m_xInplaceMenuBar.clear(); + m_xContainerWindow.clear(); + m_xContainerTopWindow.clear(); + } + else if ( rEvent.Source == Reference< XInterface >( m_xDocCfgMgr, UNO_QUERY )) + { + m_xDocCfgMgr.clear(); + } + else if ( rEvent.Source == Reference< XInterface >( m_xModuleCfgMgr , UNO_QUERY )) + { + m_xModuleCfgMgr.clear(); + } + + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + // Send disposing to our listener when we have lost our frame. + if ( bDisposeAndClear ) + { + // Send message to all listener and forget her references. + css::uno::Reference< css::frame::XLayoutManager > xThis( static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY ); + css::lang::EventObject aEvent( xThis ); + m_aListenerContainer.disposeAndClear( aEvent ); + } +} + +void SAL_CALL LayoutManager::elementInserted( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + ReadGuard aReadLock( m_aLock ); + + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + Reference< XUIElement > xElement; + Reference< XFrame > xFrame( m_xFrame ); + + if ( m_xFrame.is() ) + { + implts_findElement( Event.ResourceURL, aElementType, aElementName, xElement ); + + Reference< XUIElementSettings > xElementSettings( xElement, UNO_QUERY ); + if ( xElementSettings.is() ) + { + ::rtl::OUString aConfigSourcePropName( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" )); + Reference< XPropertySet > xPropSet( xElementSettings, UNO_QUERY ); + if ( xPropSet.is() ) + { + if ( Event.Source == Reference< XInterface >( m_xDocCfgMgr, UNO_QUERY )) + xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( m_xDocCfgMgr )); + } + xElementSettings->updateSettings(); + } + else + { + if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" ) && + ( aElementName.indexOf( m_aCustomTbxPrefix ) != -1 )) + { + // custom toolbar must be directly created, shown and layouted! + createElement( Event.ResourceURL ); + Reference< XUIElement > xUIElement = getElement( Event.ResourceURL ); + if ( xUIElement.is() ) + { + Reference< XUIConfigurationManager > xCfgMgr; + Reference< XPropertySet > xPropSet; + ::rtl::OUString aUIName; + + try + { + xCfgMgr = Reference< XUIConfigurationManager >( Event.Source, UNO_QUERY ); + xPropSet = Reference< XPropertySet >( xCfgMgr->getSettings( Event.ResourceURL, sal_False ), UNO_QUERY ); + + if ( xPropSet.is() ) + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= aUIName; + } + catch ( com::sun::star::container::NoSuchElementException& ) + { + } + catch ( com::sun::star::beans::UnknownPropertyException& ) + { + } + catch ( com::sun::star::lang::WrappedTargetException& ) + { + } + + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + pWindow->SetText( aUIName ); + } + + showElement( Event.ResourceURL ); + } + } + } + } +} + +void SAL_CALL LayoutManager::elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + Reference< XUIElement > xUIElement; + Reference< XFrame > xFrame( m_xFrame ); + + if ( m_xFrame.is() ) + { + implts_findElement( Event.ResourceURL, aElementType, aElementName, xUIElement ); + + Reference< XUIElementSettings > xElementSettings( xUIElement, UNO_QUERY ); + if ( xElementSettings.is() ) + { + bool bNoSettings( false ); + ::rtl::OUString aConfigSourcePropName( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" )); + Reference< XInterface > xElementCfgMgr; + Reference< XPropertySet > xPropSet( xElementSettings, UNO_QUERY ); + + if ( xPropSet.is() ) + xPropSet->getPropertyValue( aConfigSourcePropName ) >>= xElementCfgMgr; + + if ( !xElementCfgMgr.is() ) + return; + + // Check if the same UI configuration manager has changed => check further + if ( Event.Source == xElementCfgMgr ) + { + // Same UI configuration manager where our element has its settings + if ( Event.Source == Reference< XInterface >( m_xDocCfgMgr, UNO_QUERY )) + { + // document settings removed + if ( m_xModuleCfgMgr->hasSettings( Event.ResourceURL )) + { + xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( m_xModuleCfgMgr )); + xElementSettings->updateSettings(); + return; + } + } + + bNoSettings = true; + } + + // No settings anymore, element must be destroyed + if ( m_xContainerWindow.is() && bNoSettings ) + { + if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && + aElementName.equalsIgnoreAsciiCaseAscii( "menubar" )) + { + Window* pWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); + while ( pWindow && !pWindow->IsSystemWindow() ) + pWindow = pWindow->GetParent(); + + if ( pWindow && !m_bInplaceMenuSet ) + ((SystemWindow *)pWindow)->SetMenuBar( 0 ); + + Reference< XComponent > xComp( m_xMenuBar, UNO_QUERY ); + if ( xComp.is() ) + xComp->dispose(); + m_xMenuBar.clear(); + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" )) + { + destroyElement( Event.ResourceURL ); + } + } + } + } +} + +void SAL_CALL LayoutManager::elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException) +{ + ReadGuard aReadLock( m_aLock ); + + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + Reference< XUIElement > xUIElement; + Reference< XFrame > xFrame( m_xFrame ); + + if ( m_xFrame.is() ) + { + implts_findElement( Event.ResourceURL, aElementType, aElementName, xUIElement ); + + Reference< XUIElementSettings > xElementSettings( xUIElement, UNO_QUERY ); + if ( xElementSettings.is() ) + { + ::rtl::OUString aConfigSourcePropName( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" )); + Reference< XInterface > xElementCfgMgr; + Reference< XPropertySet > xPropSet( xElementSettings, UNO_QUERY ); + + if ( xPropSet.is() ) + xPropSet->getPropertyValue( aConfigSourcePropName ) >>= xElementCfgMgr; + + if ( !xElementCfgMgr.is() ) + return; + + // Check if the same UI configuration manager has changed => update settings + if ( Event.Source == xElementCfgMgr ) + { + xElementSettings->updateSettings(); + if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" )) + doLayout(); + } + } + } +} + +//--------------------------------------------------------------------------------------------------------- +// OPropertySetHelper +//--------------------------------------------------------------------------------------------------------- +// XPropertySet helper +sal_Bool SAL_CALL LayoutManager::convertFastPropertyValue( Any& aConvertedValue , + Any& aOldValue , + sal_Int32 nHandle , + const Any& aValue ) throw( com::sun::star::lang::IllegalArgumentException ) +{ + return LayoutManager_PBase::convertFastPropertyValue( aConvertedValue, aOldValue, nHandle, aValue ); +} + +void SAL_CALL LayoutManager::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle , + const com::sun::star::uno::Any& aValue ) throw( com::sun::star::uno::Exception ) +{ + if ( nHandle != LAYOUTMANAGER_PROPHANDLE_REFRESHVISIBILITY ) + LayoutManager_PBase::setFastPropertyValue_NoBroadcast( nHandle, aValue ); + + switch( nHandle ) + { + case LAYOUTMANAGER_PROPHANDLE_MENUBARCLOSER: + implts_updateMenuBarClose(); + break; + + case LAYOUTMANAGER_PROPHANDLE_REFRESHVISIBILITY: + { + sal_Bool bValue = sal_Bool(); + if (( aValue >>= bValue ) && bValue ) + implts_refreshContextToolbarsVisibility(); + break; + } + + case LAYOUTMANAGER_PROPHANDLE_HIDECURRENTUI: + implts_setCurrentUIVisibility( !m_bHideCurrentUI ); + break; + } +} + +void SAL_CALL LayoutManager::getFastPropertyValue( com::sun::star::uno::Any& aValue , + sal_Int32 nHandle ) const +{ + LayoutManager_PBase::getFastPropertyValue( aValue, nHandle ); +} + +::cppu::IPropertyArrayHelper& SAL_CALL LayoutManager::getInfoHelper() +{ + // Optimize this method ! + // We initialize a static variable only one time. And we don't must use a mutex at every call! + // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL! + static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL; + + if( pInfoHelper == NULL ) + { + // Ready for multithreading + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + + // Control this pointer again, another instance can be faster then these! + if( pInfoHelper == NULL ) + { + // Define static member to give structure of properties to baseclass "OPropertySetHelper". + uno::Sequence< beans::Property > aProperties; + describeProperties( aProperties ); + static ::cppu::OPropertyArrayHelper aInfoHelper( aProperties, sal_True ); + pInfoHelper = &aInfoHelper; + } + } + + return(*pInfoHelper); +} + +com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL LayoutManager::getPropertySetInfo() throw (::com::sun::star::uno::RuntimeException) +{ + // Optimize this method ! + // We initialize a static variable only one time. And we don't must use a mutex at every call! + // For the first call; pInfo is NULL - for the second call pInfo is different from NULL! + static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >* pInfo = NULL; + + if( pInfo == NULL ) + { + // Ready for multithreading + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + // Control this pointer again, another instance can be faster then these! + if( pInfo == NULL ) + { + // Create structure of propertysetinfo for baseclass "OPropertySetHelper". + // (Use method "getInfoHelper()".) + static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + pInfo = &xInfo; + } + } + + return (*pInfo); +} + +} // namespace framework + diff --git a/framework/source/layoutmanager/makefile.mk b/framework/source/layoutmanager/makefile.mk index 70215a36578d..7ce19a71f2f9 100644 --- a/framework/source/layoutmanager/makefile.mk +++ b/framework/source/layoutmanager/makefile.mk @@ -2,10 +2,14 @@ # # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # -# Copyright 2000, 2010 Oracle and/or its affiliates. +# Copyright 2008 by Sun Microsystems, Inc. # # OpenOffice.org - a multi-platform office productivity suite # +# $RCSfile: makefile.mk,v $ +# +# $Revision: 1.5 $ +# # This file is part of OpenOffice.org. # # OpenOffice.org is free software: you can redistribute it and/or modify @@ -35,12 +39,15 @@ ENABLE_EXCEPTIONS= TRUE .INCLUDE : settings.mk -VISIBILITY_HIDDEN = TRUE - # --- Generate ----------------------------------------------------- SLOFILES= \ - $(SLO)$/layoutmanager.obj + $(SLO)$/panelmanager.obj \ + $(SLO)$/layoutmanager.obj \ + $(SLO)$/panel.obj \ + $(SLO)$/helpers.obj \ + $(SLO)$/uielement.obj \ + $(SLO)$/toolbarlayoutmanager.obj # --- Targets ------------------------------------------------------ diff --git a/framework/source/layoutmanager/panel.cxx b/framework/source/layoutmanager/panel.cxx new file mode 100755 index 000000000000..69f6ad0f51d9 --- /dev/null +++ b/framework/source/layoutmanager/panel.cxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutmanager.hxx,v $ + * $Revision: 1.34 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include "panel.hxx" +#include "helpers.hxx" + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <vos/mutex.hxx> +#include <vcl/svapp.hxx> +#include <toolkit/unohlp.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +using namespace ::com::sun::star; + +namespace framework +{ + +Panel::Panel( + const uno::Reference< lang::XMultiServiceFactory >& rSMGR, + const uno::Reference< awt::XWindow >& rParent, + PanelPosition nPanel ) : + m_xSMGR(rSMGR), m_nPanelPosition(nPanel) +{ + uno::Reference< awt::XWindowPeer > xWindowPeer( rParent, uno::UNO_QUERY ); + m_xPanelWindow = uno::Reference< awt::XWindow >( createToolkitWindow( rSMGR, xWindowPeer, "splitwindow" ), uno::UNO_QUERY ); + + vos::OGuard aGuard( Application::GetSolarMutex() ); + SplitWindow* pSplitWindow = dynamic_cast< SplitWindow* >( VCLUnoHelper::GetWindow( m_xPanelWindow )); + + if ( pSplitWindow ) + { + // Set alignment + if (nPanel == PANEL_TOP) + pSplitWindow->SetAlign( WINDOWALIGN_TOP ); + else if (nPanel == PANEL_BOTTOM) + pSplitWindow->SetAlign( WINDOWALIGN_BOTTOM ); + else if (nPanel == PANEL_LEFT) + pSplitWindow->SetAlign( WINDOWALIGN_LEFT ); + else + pSplitWindow->SetAlign( WINDOWALIGN_RIGHT ); + } +} + +Panel::~Panel() +{ +} + +} // namespace framework diff --git a/framework/source/layoutmanager/panel.hxx b/framework/source/layoutmanager/panel.hxx new file mode 100755 index 000000000000..e183c97ed5da --- /dev/null +++ b/framework/source/layoutmanager/panel.hxx @@ -0,0 +1,88 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutmanager.hxx,v $ + * $Revision: 1.34 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_LAYOUTMANAGER_PANEL_HXX_ +#define __FRAMEWORK_LAYOUTMANAGER_PANEL_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <macros/generic.hxx> +#include <stdtypes.h> +#include <properties.h> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <vcl/window.hxx> +#include <vcl/splitwin.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework +{ + +enum PanelPosition +{ + PANEL_TOP, + PANEL_LEFT, + PANEL_RIGHT, + PANEL_BOTTOM, + PANEL_COUNT +}; + +class Panel +{ + public: + Panel( const css::uno::Reference< css::lang::XMultiServiceFactory >& rSMGR, + const css::uno::Reference< css::awt::XWindow >& rParent, + PanelPosition nPanel ); + virtual ~Panel(); + + private: + css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR; + css::uno::Reference< css::awt::XWindow > m_xPanelWindow; + PanelPosition m_nPanelPosition; +}; + +} + +#endif // __FRAMEWORK_LAYOUTMANAGER_PANEL_HXX_ diff --git a/framework/source/layoutmanager/panelmanager.cxx b/framework/source/layoutmanager/panelmanager.cxx new file mode 100755 index 000000000000..3c82a4fd4f28 --- /dev/null +++ b/framework/source/layoutmanager/panelmanager.cxx @@ -0,0 +1,184 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutmanager.hxx,v $ + * $Revision: 1.34 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include "panelmanager.hxx" +#include "services.h" +#include "services/modelwinservice.hxx" + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <vcl/svapp.hxx> +#include <toolkit/unohlp.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +using namespace ::com::sun::star; + +namespace framework +{ + +//_________________________________________________________________________________________________________________ +// non exported definitions +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + + +PanelManager::PanelManager( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rSMGR, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame ) : + m_xSMGR( rSMGR ), + m_xFrame( rFrame ) +{ + m_aPanels[PANEL_TOP] = 0; + m_aPanels[PANEL_BOTTOM] = 0; + m_aPanels[PANEL_LEFT] = 0; + m_aPanels[PANEL_RIGHT] = 0; +} + +PanelManager::~PanelManager() +{ +} + +//--------------------------------------------------------------------------------------------------------- +// Creation and layouting +//--------------------------------------------------------------------------------------------------------- +bool PanelManager::createPanels() +{ + if ( m_xFrame.is() ) + { + uno::Reference< awt::XWindow > xWindow; + vos::OGuard aGuard( Application::GetSolarMutex() ); + xWindow = m_xFrame->getContainerWindow(), uno::UNO_QUERY; + if ( xWindow.is() ) + { + // destroy old panel windows + delete m_aPanels[PANEL_TOP ]; + delete m_aPanels[PANEL_BOTTOM]; + delete m_aPanels[PANEL_LEFT ]; + delete m_aPanels[PANEL_RIGHT ]; + + m_aPanels[PANEL_TOP ] = new Panel( m_xSMGR, xWindow, PANEL_TOP ); + m_aPanels[PANEL_BOTTOM] = new Panel( m_xSMGR, xWindow, PANEL_BOTTOM ); + m_aPanels[PANEL_LEFT ] = new Panel( m_xSMGR, xWindow, PANEL_LEFT ); + m_aPanels[PANEL_RIGHT ] = new Panel( m_xSMGR, xWindow, PANEL_RIGHT ); + return true; + } + } + + return false; +} + +awt::Rectangle PanelManager::getPreferredSize() const +{ + return awt::Rectangle(); +} + +void PanelManager::layoutPanels( const awt::Rectangle /*newSize*/ ) +{ +} + +//--------------------------------------------------------------------------------------------------------- +// Panel functions +//--------------------------------------------------------------------------------------------------------- +UIElement* PanelManager::findDockingWindow( const ::rtl::OUString& /*rResourceName*/ ) +{ + return NULL; +} + +bool PanelManager::addDockingWindow( const ::rtl::OUString& /*rResourceName*/, const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement >& /*xUIElement*/ ) +{ + return false; +} + +bool PanelManager::destroyDockingWindow( const ::rtl::OUString& /*rResourceName*/ ) +{ + return false; +} + +//--------------------------------------------------------------------------------------------------------- +// XDockableWindowListener +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL PanelManager::startDocking( const awt::DockingEvent& ) +throw (uno::RuntimeException) +{ +} + +awt::DockingData SAL_CALL PanelManager::docking( const awt::DockingEvent& ) +throw (uno::RuntimeException) +{ + return awt::DockingData(); +} + +void SAL_CALL PanelManager::endDocking( const awt::EndDockingEvent& ) +throw (uno::RuntimeException) +{ +} + +sal_Bool SAL_CALL PanelManager::prepareToggleFloatingMode( const lang::EventObject& ) +throw (uno::RuntimeException) +{ + return false; +} + +void SAL_CALL PanelManager::toggleFloatingMode( const lang::EventObject& ) +throw (uno::RuntimeException) +{ +} + +void SAL_CALL PanelManager::closed( const lang::EventObject& ) +throw (uno::RuntimeException) +{ +} + +void SAL_CALL PanelManager::endPopupMode( const awt::EndPopupModeEvent& ) +throw (uno::RuntimeException) +{ +} + +} // namespace framework diff --git a/framework/source/layoutmanager/panelmanager.hxx b/framework/source/layoutmanager/panelmanager.hxx new file mode 100755 index 000000000000..fd3e892414fa --- /dev/null +++ b/framework/source/layoutmanager/panelmanager.hxx @@ -0,0 +1,109 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutmanager.hxx,v $ + * $Revision: 1.34 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_LAYOUTMANAGER_PANELMANAGER_HXX_ +#define __FRAMEWORK_LAYOUTMANAGER_PANELMANAGER_HXX_ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <threadhelp/threadhelpbase.hxx> +#include <macros/generic.hxx> +#include <macros/debug.hxx> +#include <macros/xinterface.hxx> +#include <macros/xtypeprovider.hxx> +#include <macros/xserviceinfo.hxx> +#include <general.h> +#include <stdtypes.h> +#include "panel.hxx" +#include <uielement/uielement.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/awt/XWindow.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/awt/XDockableWindowListener.hpp> +#include <com/sun/star/frame/XFrame.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <cppuhelper/weak.hxx> +#include <vcl/window.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework +{ + +class PanelManager : private ThreadHelpBase // Struct for right initalization of mutex member! Must be first of baseclasses. +{ + public: + PanelManager( + const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rSMGR, + const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& rFrame ); + virtual ~PanelManager(); + + bool createPanels(); + ::com::sun::star::awt::Rectangle getPreferredSize() const; + void layoutPanels( const ::com::sun::star::awt::Rectangle newSize ); + + UIElement* findDockingWindow( const ::rtl::OUString& rResourceName ); + bool addDockingWindow( const ::rtl::OUString& rResourceName, const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement >& xUIElement ); + bool destroyDockingWindow( const ::rtl::OUString& rResourceName ); + + //--------------------------------------------------------------------------------------------------------- + // XDockableWindowListener + //--------------------------------------------------------------------------------------------------------- + virtual void SAL_CALL startDocking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::DockingData SAL_CALL docking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL endDocking( const ::com::sun::star::awt::EndDockingEvent& e ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL prepareToggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL toggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL closed( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL endPopupMode( const ::com::sun::star::awt::EndPopupModeEvent& e ) throw (::com::sun::star::uno::RuntimeException); + + private: + Panel* m_aPanels[PANEL_COUNT]; + css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR; + css::uno::Reference< css::frame::XFrame > m_xFrame; +}; + +} // namespace framework + +#endif // __FRAMEWORK_LAYOUTMANAGER_PANELMANAGER_HXX_ diff --git a/framework/source/layoutmanager/toolbarlayoutmanager.cxx b/framework/source/layoutmanager/toolbarlayoutmanager.cxx new file mode 100755 index 000000000000..076a82b24ebd --- /dev/null +++ b/framework/source/layoutmanager/toolbarlayoutmanager.cxx @@ -0,0 +1,3915 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutmanager.cxx,v $ + * $Revision: 1.72 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <toolbarlayoutmanager.hxx> +#include <helpers.hxx> +#include <services.h> +#include <classes/resource.hrc> +#include <classes/fwkresid.hxx> +#include <uiconfiguration/windowstateconfiguration.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/ui/UIElementType.hpp> +#include <com/sun/star/container/XNameReplace.hpp> +#include <com/sun/star/container/XNameContainer.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <unotools/cmdoptions.hxx> +#include <toolkit/unohlp.hxx> +#include <toolkit/helper/convert.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <vcl/i18nhelp.hxx> + +using namespace ::com::sun::star; + +namespace framework +{ + +ToolbarLayoutManager::ToolbarLayoutManager( + const uno::Reference< lang::XMultiServiceFactory >& xSMGR, + const uno::Reference< ui::XUIElementFactory >& xUIElementFactory ) + : ThreadHelpBase( &Application::GetSolarMutex() ), + m_xSMGR( xSMGR ), + m_xUIElementFactoryManager( xUIElementFactory ), + m_eDockOperation( DOCKOP_ON_COLROW ), + m_pAddonOptions( 0 ), + m_pGlobalSettings( 0 ), + m_bComponentAttached( false ), + m_bMustLayout( false ), + m_bLayoutDirty( false ), + m_bStoreWindowState( false ), + m_bGlobalSettings( false ), + m_bDockingInProgress( false ), + m_aFullAddonTbxPrefix( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/addon_" )), + m_aCustomTbxPrefix( RTL_CONSTASCII_USTRINGPARAM( "custom_" )), + m_aCustomizeCmd( RTL_CONSTASCII_USTRINGPARAM( "ConfigureDialog" )) +{ + m_xToolkit = uno::Reference< css::awt::XToolkit >( m_xSMGR->createInstance( SERVICENAME_VCLTOOLKIT ), uno::UNO_QUERY ); +} + +ToolbarLayoutManager::~ToolbarLayoutManager() +{ +} + +//--------------------------------------------------------------------------------------------------------- +// XInterface +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL ToolbarLayoutManager::acquire() throw() +{ + OWeakObject::acquire(); +} + +void SAL_CALL ToolbarLayoutManager::release() throw() +{ + OWeakObject::release(); +} + +uno::Any SAL_CALL ToolbarLayoutManager::queryInterface( const uno::Type & rType ) throw( uno::RuntimeException ) +{ + uno::Any a = + ::cppu::queryInterface( rType, + SAL_STATIC_CAST( ::com::sun::star::awt::XDockableWindowListener*, this ), + SAL_STATIC_CAST( ::com::sun::star::ui::XUIConfigurationListener*, this )); + + if ( a.hasValue() ) + return a; + + return OWeakObject::queryInterface( rType ); +} + +void SAL_CALL ToolbarLayoutManager::disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException ) +{ + if ( aEvent.Source == m_xFrame ) + { + // Reset all internal references + reset(); + implts_destroyDockingAreaWindows(); + } +} + +::com::sun::star::awt::Rectangle ToolbarLayoutManager::getDockingArea() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + Rectangle aNewDockingArea( m_aDockingArea ); + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( isLayoutDirty() ) + aNewDockingArea = implts_calcDockingArea(); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aWriteLock.lock(); + m_aDockingArea = aNewDockingArea; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + return impl_convertRectangleToAWT( aNewDockingArea ); +} + +void ToolbarLayoutManager::setDockingArea( const awt::Rectangle& rDockingArea ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_aDockingArea = impl_convertAWTToRectangle( rDockingArea ); + m_bLayoutDirty = true; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + implts_setDockingAreaWindowSizes( rDockingArea ); +} + +void ToolbarLayoutManager::implts_setDockingAreaWindowSizes( const awt::Rectangle& rBorderSpace ) +{ + uno::Reference< css::awt::XWindow2 > xContainerWindow; + + ReadGuard aReadLock( m_aLock ); + xContainerWindow = m_xContainerWindow; + Rectangle aDockOffsets = m_aDockingAreaOffsets; + aReadLock.unlock(); + + uno::Reference< awt::XDevice > xDevice( xContainerWindow, uno::UNO_QUERY ); + + // Convert relativ size to output size. + awt::Rectangle aRectangle = xContainerWindow->getPosSize(); + awt::DeviceInfo aInfo = xDevice->getInfo(); + awt::Size aContainerClientSize = awt::Size( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset , + aRectangle.Height - aInfo.TopInset - aInfo.BottomInset ); + long aStatusBarHeight = aDockOffsets.GetHeight(); + + sal_Int32 nLeftRightDockingAreaHeight( aContainerClientSize.Height ); + if ( rBorderSpace.Y >= 0 ) + { + // Top docking area window + aReadLock.lock(); + uno::Reference< awt::XWindow > xDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] ); + aReadLock.unlock(); + + xDockAreaWindow->setPosSize( 0, 0, aContainerClientSize.Width, rBorderSpace.Y, awt::PosSize::POSSIZE ); + xDockAreaWindow->setVisible( sal_True ); + nLeftRightDockingAreaHeight -= rBorderSpace.Y; + } + + if ( rBorderSpace.Height >= 0 ) + { + // Bottom docking area window + sal_Int32 nBottomPos = std::max( sal_Int32( aContainerClientSize.Height - rBorderSpace.Height - aStatusBarHeight ), sal_Int32( 0 )); + sal_Int32 nHeight = ( nBottomPos == 0 ) ? 0 : rBorderSpace.Height; + + aReadLock.lock(); + uno::Reference< awt::XWindow > xDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] ); + aReadLock.unlock(); + + xDockAreaWindow->setPosSize( 0, nBottomPos, aContainerClientSize.Width, nHeight, awt::PosSize::POSSIZE ); + xDockAreaWindow->setVisible( sal_True ); + nLeftRightDockingAreaHeight -= nHeight; + } + + nLeftRightDockingAreaHeight -= aStatusBarHeight; + if ( rBorderSpace.X >= 0 || nLeftRightDockingAreaHeight > 0 ) + { + // Left docking area window + aReadLock.lock(); + uno::Reference< awt::XWindow > xDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] ); + aReadLock.unlock(); + + // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority! + sal_Int32 nHeight = std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight )); + + xDockAreaWindow->setPosSize( 0, rBorderSpace.Y, rBorderSpace.X, nHeight, awt::PosSize::POSSIZE ); + xDockAreaWindow->setVisible( sal_True ); + } + if ( rBorderSpace.Width >= 0 || nLeftRightDockingAreaHeight > 0 ) + { + // Right docking area window + aReadLock.lock(); + uno::Reference< awt::XWindow > xDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] ); + aReadLock.unlock(); + + // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority! + sal_Int32 nLeftPos = std::max( sal_Int32( 0 ), sal_Int32( aContainerClientSize.Width - rBorderSpace.Width )); + sal_Int32 nHeight = std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight )); + sal_Int32 nWidth = ( nLeftPos == 0 ) ? 0 : rBorderSpace.Width; + + xDockAreaWindow->setPosSize( nLeftPos, rBorderSpace.Y, nWidth, nHeight, awt::PosSize::POSSIZE ); + xDockAreaWindow->setVisible( sal_True ); + } +} + +bool ToolbarLayoutManager::isLayoutDirty() +{ + return m_bLayoutDirty; +} + +void ToolbarLayoutManager::doLayout(const ::Size& aContainerSize) +{ + // Retrieve row/column dependent data from all docked user-interface elements + for ( sal_Int32 i = 0; i < DOCKINGAREAS_COUNT; i++ ) + { + std::vector< SingleRowColumnWindowData > aRowColumnsWindowData; + + implts_getDockingAreaElementInfos( (ui::DockingArea)i, aRowColumnsWindowData ); + + sal_Int32 nOffset( 0 ); + const sal_uInt32 nCount = aRowColumnsWindowData.size(); + for ( sal_uInt32 j = 0; j < nCount; ++j ) + { + implts_calcWindowPosSizeOnSingleRowColumn( i, nOffset, aRowColumnsWindowData[j], aContainerSize ); + nOffset += aRowColumnsWindowData[j].nStaticSize; + } + } +} + +bool ToolbarLayoutManager::implts_isParentWindowVisible() const +{ + bool bVisible( false ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + if ( m_xContainerWindow.is() ) + bVisible = m_xContainerWindow->isVisible(); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + return bVisible; +} + +Rectangle ToolbarLayoutManager::implts_calcDockingArea() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + UIElementVector aWindowVector( m_aUIElements ); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + Rectangle aBorderSpace; + sal_Int32 nCurrRowColumn( 0 ); + sal_Int32 nCurrPos( 0 ); + sal_Int32 nCurrDockingArea( ui::DockingArea_DOCKINGAREA_TOP ); + std::vector< sal_Int32 > aRowColumnSizes[DOCKINGAREAS_COUNT]; + UIElementVector::const_iterator pConstIter; + + aRowColumnSizes[nCurrDockingArea].clear(); + aRowColumnSizes[nCurrDockingArea].push_back( 0 ); + + for ( pConstIter = aWindowVector.begin(); pConstIter != aWindowVector.end(); pConstIter++ ) + { + uno::Reference< ui::XUIElement > xUIElement( pConstIter->m_xUIElement, uno::UNO_QUERY ); + if ( xUIElement.is() ) + { + uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY ); + uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); + if ( xWindow.is() && xDockWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->IsVisible() && !xDockWindow->isFloating() ) + { + awt::Rectangle aPosSize = xWindow->getPosSize(); + if ( pConstIter->m_aDockedData.m_nDockedArea != nCurrDockingArea ) + { + nCurrDockingArea = pConstIter->m_aDockedData.m_nDockedArea; + nCurrRowColumn = 0; + nCurrPos = 0; + aRowColumnSizes[nCurrDockingArea].clear(); + aRowColumnSizes[nCurrDockingArea].push_back( 0 ); + } + + if ( pConstIter->m_aDockedData.m_nDockedArea == nCurrDockingArea ) + { + if (( pConstIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( pConstIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM )) + { + if ( pConstIter->m_aDockedData.m_aPos.Y() > nCurrPos ) + { + ++nCurrRowColumn; + nCurrPos = pConstIter->m_aDockedData.m_aPos.Y(); + aRowColumnSizes[nCurrDockingArea].push_back( 0 ); + } + + if ( aPosSize.Height > aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] ) + aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] = aPosSize.Height; + } + else + { + if ( pConstIter->m_aDockedData.m_aPos.X() > nCurrPos ) + { + ++nCurrRowColumn; + nCurrPos = pConstIter->m_aDockedData.m_aPos.X(); + aRowColumnSizes[nCurrDockingArea].push_back( 0 ); + } + + if ( aPosSize.Width > aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] ) + aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] = aPosSize.Width; + } + } + } + } + } + } + + // Sum up max heights from every row/column + if ( !aWindowVector.empty() ) + { + for ( sal_Int32 i = 0; i <= ui::DockingArea_DOCKINGAREA_RIGHT; i++ ) + { + sal_Int32 nSize( 0 ); + const sal_uInt32 nCount = aRowColumnSizes[i].size(); + for ( sal_uInt32 j = 0; j < nCount; j++ ) + nSize += aRowColumnSizes[i][j]; + + if ( i == ui::DockingArea_DOCKINGAREA_TOP ) + aBorderSpace.Top() = nSize; + else if ( i == ui::DockingArea_DOCKINGAREA_BOTTOM ) + aBorderSpace.Bottom() = nSize; + else if ( i == ui::DockingArea_DOCKINGAREA_LEFT ) + aBorderSpace.Left() = nSize; + else + aBorderSpace.Right() = nSize; + } + } + + return aBorderSpace; +} + +void ToolbarLayoutManager::reset() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + uno::Reference< ui::XUIConfigurationManager > xModuleCfgMgr = m_xModuleCfgMgr; + uno::Reference< ui::XUIConfigurationManager > xDocCfgMgr = m_xDocCfgMgr; + m_xModuleCfgMgr.clear(); + m_xDocCfgMgr.clear(); + m_bComponentAttached = false; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + destroyToolbars(); +} + +void ToolbarLayoutManager::attach( + const uno::Reference< frame::XFrame >& xFrame, + const uno::Reference< ui::XUIConfigurationManager >& xModuleCfgMgr, + const uno::Reference< ui::XUIConfigurationManager >& xDocCfgMgr, + const uno::Reference< container::XNameAccess >& xPersistentWindowState ) +{ + // reset toolbar manager if we lose our current frame + if ( m_xFrame.is() && m_xFrame != xFrame ) + reset(); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_xFrame = xFrame; + m_xModuleCfgMgr = xModuleCfgMgr; + m_xDocCfgMgr = xDocCfgMgr; + m_xPersistentWindowState = xPersistentWindowState; + m_bComponentAttached = true; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +void ToolbarLayoutManager::createToolbars() +{ + resetDockingArea(); + implts_createCustomToolBars(); + implts_createAddonsToolBars(); + implts_createNonContextSensitiveToolBars(); + implts_sortUIElements(); +} + +bool ToolbarLayoutManager::createToolbar( const ::rtl::OUString& rResourceURL ) +{ + bool bNotify( false ); + uno::Reference< ui::XUIElement > xUITempElement; + + implts_createElement( rResourceURL, bNotify, xUITempElement ); + return bNotify; +} + +bool ToolbarLayoutManager::destroyToolbar( const ::rtl::OUString& rResourceURL ) +{ + UIElementVector::iterator pIter; + uno::Reference< lang::XComponent > xComponent; + + bool bMustBeDestroyed( false ); + bool bMustBeSorted( false ); + bool bNotify( false ); + bool bMustLayouted( false ); + rtl::OUString aAddonTbResourceName( RTL_CONSTASCII_USTRINGPARAM( "private:resource/toolbar/addon_" )); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aName == rResourceURL ) + { + xComponent.set( pIter->m_xUIElement, uno::UNO_QUERY ); + uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement ); + if ( xUIElement.is() ) + { + uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY ); + uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); + + if ( rResourceURL.indexOf( aAddonTbResourceName ) != 0 ) + { + try + { + if ( xWindow.is() ) + xWindow->removeWindowListener( uno::Reference< awt::XWindowListener >( + static_cast< OWeakObject * >( this ), uno::UNO_QUERY )); + } + catch( uno::Exception& ) + { + } + + try + { + if ( xDockWindow.is() ) + xDockWindow->removeDockableWindowListener( uno::Reference< awt::XDockableWindowListener >( + static_cast< OWeakObject * >( this ), uno::UNO_QUERY )); + } + catch ( uno::Exception& ) + { + } + + bMustBeDestroyed = true; + } + else + { + pIter->m_bVisible = sal_False; + xWindow->setVisible( sal_False ); + bNotify = true; + } + + if ( !xDockWindow->isFloating() ) + bMustLayouted = true; + if ( bMustBeDestroyed ) + pIter->m_xUIElement.clear(); + + bMustBeSorted = true; + } + break; + } + } + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( bMustBeDestroyed ) + { + if ( xComponent.is() ) + xComponent->dispose(); + bNotify = true; + } + + if ( bMustLayouted ) + { + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aWriteLock.lock(); + m_bLayoutDirty = true; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + } + + if ( bMustBeSorted ) + implts_sortUIElements(); + + return bNotify; +} + +void ToolbarLayoutManager::destroyToolbars() +{ + UIElementVector aUIElementVector; + + WriteGuard aWriteLock( m_aLock ); + aUIElementVector = m_aUIElements; + m_aUIElements.clear(); + aWriteLock.unlock(); + + UIElementVector::iterator pIter; + for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ ) + { + uno::Reference< lang::XComponent > xComponent( pIter->m_xUIElement, uno::UNO_QUERY ); + if ( xComponent.is() ) + xComponent->dispose(); + } +} + +void ToolbarLayoutManager::dockToolbar( + const ::rtl::OUString& /*rResourceURL*/, + ::com::sun::star::ui::DockingArea /*eDockingArea*/, + const ::com::sun::star::awt::Point& /*aPos*/ ) +{ +} + +void ToolbarLayoutManager::resetDockingArea() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + uno::Reference< awt::XWindow > xTopDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP]; + uno::Reference< awt::XWindow > xLeftDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT]; + uno::Reference< awt::XWindow > xRightDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT]; + uno::Reference< awt::XWindow > xBottomDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM]; + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( xTopDockingWindow.is() ) + xTopDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE ); + if ( xLeftDockingWindow.is() ) + xLeftDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE ); + if ( xRightDockingWindow.is() ) + xRightDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE ); + if ( xBottomDockingWindow.is() ) + xBottomDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE ); +} + +void ToolbarLayoutManager::setParentWindow( + const uno::Reference< awt::XWindowPeer >& xParentWindow ) +{ + uno::Reference< awt::XWindow > xTopDockingWindow = uno::Reference< awt::XWindow >( implts_createToolkitWindow( m_xToolkit, xParentWindow ), uno::UNO_QUERY ); + uno::Reference< awt::XWindow > xLeftDockingWindow = uno::Reference< awt::XWindow >( implts_createToolkitWindow( m_xToolkit, xParentWindow ), uno::UNO_QUERY ); + uno::Reference< awt::XWindow > xRightDockingWindow = uno::Reference< awt::XWindow >( implts_createToolkitWindow( m_xToolkit, xParentWindow ), uno::UNO_QUERY ); + uno::Reference< awt::XWindow > xBottomDockingWindow = uno::Reference< awt::XWindow >( implts_createToolkitWindow( m_xToolkit, xParentWindow ), uno::UNO_QUERY ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_xContainerWindow = uno::Reference< awt::XWindow2 >( xParentWindow, uno::UNO_QUERY ); + + m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] = xTopDockingWindow; + m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] = xLeftDockingWindow; + m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] = xRightDockingWindow; + m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] = xBottomDockingWindow; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + implts_reparentToolbars(); +} + +void ToolbarLayoutManager::setDockingAreaOffsets( const ::Rectangle aOffsets ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_aDockingAreaOffsets = aOffsets; + m_bLayoutDirty = true; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +rtl::OUString ToolbarLayoutManager::implts_generateGenericAddonToolbarTitle( sal_Int32 nNumber ) const +{ + String aAddonGenericTitle; + + aAddonGenericTitle = String( FwkResId( STR_TOOLBAR_TITLE_ADDON )); + const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper(); + + String aNumStr = rI18nHelper.GetNum( nNumber, 0, FALSE, FALSE ); + aAddonGenericTitle.SearchAndReplaceAscii( "%num%", aNumStr ); + + return rtl::OUString( aAddonGenericTitle ); +} + +void ToolbarLayoutManager::implts_createAddonsToolBars() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + if ( !m_pAddonOptions ) + m_pAddonOptions = new AddonsOptions; + + uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager ); + uno::Reference< frame::XFrame > xFrame( m_xFrame ); + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + uno::Reference< frame::XModel > xModel( impl_getModelFromFrame( xFrame )); + if ( implts_isPreviewModel( xModel )) + return; // no addon toolbars for preview frame! + + UIElementVector aUIElementVector; + uno::Sequence< uno::Sequence< beans::PropertyValue > > aAddonToolBarData; + uno::Reference< ui::XUIElement > xUIElement; + + sal_uInt32 nCount = m_pAddonOptions->GetAddonsToolBarCount(); + ::rtl::OUString aAddonsToolBarStaticName( m_aFullAddonTbxPrefix ); + ::rtl::OUString aElementType( RTL_CONSTASCII_USTRINGPARAM( "toolbar" )); + + uno::Sequence< beans::PropertyValue > aPropSeq( 2 ); + aPropSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); + aPropSeq[0].Value <<= xFrame; + aPropSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationData" )); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + ::rtl::OUString aAddonToolBarName( aAddonsToolBarStaticName + m_pAddonOptions->GetAddonsToolbarResourceName(i) ); + aAddonToolBarData = m_pAddonOptions->GetAddonsToolBarPart( i ); + aPropSeq[1].Value <<= aAddonToolBarData; + + UIElement aElement = implts_findElement( aAddonToolBarName ); + + // #i79828 + // It's now possible that we are called more than once. Be sure to not create + // add-on toolbars more than once! + if ( aElement.m_xUIElement.is() ) + continue; + + try + { + xUIElement = xUIElementFactory->createUIElement( aAddonToolBarName, aPropSeq ); + if ( xUIElement.is() ) + { + uno::Reference< awt::XDockableWindow > xDockWindow( xUIElement->getRealInterface(), uno::UNO_QUERY ); + if ( xDockWindow.is() ) + { + try + { + xDockWindow->addDockableWindowListener( uno::Reference< awt::XDockableWindowListener >( static_cast< OWeakObject * >( this ), uno::UNO_QUERY )); + xDockWindow->enableDocking( sal_True ); + uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY ); + if ( xWindow.is() ) + xWindow->addWindowListener( uno::Reference< awt::XWindowListener >( static_cast< OWeakObject * >( this ), uno::UNO_QUERY )); + } + catch ( uno::Exception& ) + { + } + } + + ::rtl::OUString aGenericAddonTitle = implts_generateGenericAddonToolbarTitle( i+1 ); + + if ( aElement.m_aName.getLength() > 0 ) + { + // Reuse a local entry so we are able to use the latest + // UI changes for this document. + implts_setElementData( aElement, xDockWindow ); + aElement.m_xUIElement = xUIElement; + if ( aElement.m_aUIName.getLength() == 0 ) + { + aElement.m_aUIName = aGenericAddonTitle; + implts_writeWindowStateData( aElement.m_aName, aElement ); + } + } + else + { + // Create new UI element and try to read its state data + UIElement aNewToolbar( aAddonToolBarName, aElementType, xUIElement ); + aNewToolbar.m_bFloating = sal_True; + implts_readWindowStateData( aAddonToolBarName, aNewToolbar ); + implts_setElementData( aNewToolbar, xDockWindow ); + if ( aNewToolbar.m_aUIName.getLength() == 0 ) + { + aNewToolbar.m_aUIName = aGenericAddonTitle; + implts_writeWindowStateData( aNewToolbar.m_aName, aNewToolbar ); + } + implts_insertElement( aNewToolbar ); + } + + uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY ); + if ( xWindow.is() ) + { + // Set generic title for add-on toolbar + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow->GetText().Len() == 0 ) + pWindow->SetText( aGenericAddonTitle ); + if ( pWindow->GetType() == WINDOW_TOOLBOX ) + { + ToolBox* pToolbar = (ToolBox *)pWindow; + pToolbar->SetMenuType(); + } + } + } + } + catch ( container::NoSuchElementException& ) + { + } + catch ( lang::IllegalArgumentException& ) + { + } + } +} + +void ToolbarLayoutManager::implts_createCustomToolBars() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + if ( !m_bComponentAttached ) + return; + + uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager ); + uno::Reference< frame::XFrame > xFrame( m_xFrame ); + uno::Reference< frame::XModel > xModel; + uno::Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr, uno::UNO_QUERY ); + uno::Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr, uno::UNO_QUERY ); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( xFrame.is() ) + { + xModel = impl_getModelFromFrame( xFrame ); + if ( implts_isPreviewModel( xModel )) + return; // no custom toolbars for preview frame! + + uno::Sequence< uno::Sequence< beans::PropertyValue > > aTbxSeq; + if ( xDocCfgMgr.is() ) + { + aTbxSeq = xDocCfgMgr->getUIElementsInfo( ui::UIElementType::TOOLBAR ); + implts_createCustomToolBars( aTbxSeq ); // first create all document based toolbars + } + if ( xModuleCfgMgr.is() ) + { + aTbxSeq = xModuleCfgMgr->getUIElementsInfo( ui::UIElementType::TOOLBAR ); + implts_createCustomToolBars( aTbxSeq ); // second create module based toolbars + } + } +} + +void ToolbarLayoutManager::implts_createNonContextSensitiveToolBars() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + + if ( !m_xPersistentWindowState.is() || + !m_xFrame.is() || + !m_bComponentAttached ) + return; + + uno::Reference< frame::XFrame > xFrame( m_xFrame ); + + uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager ); + uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( implts_isPreviewModel( impl_getModelFromFrame( xFrame ))) + return; + + std::vector< rtl::OUString > aMakeVisibleToolbars; + + try + { + uno::Sequence< ::rtl::OUString > aToolbarNames = xPersistentWindowState->getElementNames(); + + if ( aToolbarNames.getLength() > 0 ) + { + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + ::rtl::OUString aName; + + uno::Reference< ui::XUIElement > xUIElement; + aMakeVisibleToolbars.reserve(aToolbarNames.getLength()); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + + const rtl::OUString* pTbNames = aToolbarNames.getConstArray(); + for ( sal_Int32 i = 0; i < aToolbarNames.getLength(); i++ ) + { + aName = pTbNames[i]; + if ( impl_parseResourceURL( aName, aElementType, aElementName )) + { + // Check that we only create: + // - Toolbars (the statusbar is also member of the persistent window state) + // - Not custom toolbars, there are created with their own method (implts_createCustomToolbars) + if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolbar" ) && + aElementName.indexOf( m_aCustomTbxPrefix ) == -1 ) + { + UIElement aNewToolbar = implts_findElement( aName ); + bool bFound = ( aNewToolbar.m_aName == aName ); + if ( !bFound ) + implts_readWindowStateData( aName, aNewToolbar ); + + if ( aNewToolbar.m_bVisible && !aNewToolbar.m_bContextSensitive ) + { + if ( !bFound ) + implts_insertElement( aNewToolbar ); + aMakeVisibleToolbars.push_back( aName ); + } + } + } + } + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + } + } + catch ( uno::RuntimeException& e ) + { + throw e; + } + catch ( uno::Exception& ) + { + } + + if ( !aMakeVisibleToolbars.empty() ) + { +// implts_lock(); +// ::std::for_each( aMakeVisibleToolbars.begin(), aMakeVisibleToolbars.end(),::boost::bind( &LayoutManager::requestElement, this,_1 )); +// implts_unlock(); + } +} + +void ToolbarLayoutManager::implts_createCustomToolBars( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >& aTbxSeqSeq ) +{ + const uno::Sequence< beans::PropertyValue >* pTbxSeq = aTbxSeqSeq.getConstArray(); + for ( sal_Int32 i = 0; i < aTbxSeqSeq.getLength(); i++ ) + { + const uno::Sequence< beans::PropertyValue >& rTbxSeq = pTbxSeq[i]; + ::rtl::OUString aTbxResName; + ::rtl::OUString aTbxTitle; + for ( sal_Int32 j = 0; j < rTbxSeq.getLength(); j++ ) + { + if ( rTbxSeq[j].Name.equalsAscii( "ResourceURL" )) + rTbxSeq[j].Value >>= aTbxResName; + else if ( rTbxSeq[j].Name.equalsAscii( "UIName" )) + rTbxSeq[j].Value >>= aTbxTitle; + } + + // Only create custom toolbars. Their name have to start with "custom_"! + if ( aTbxResName.getLength() > 0 && aTbxResName.indexOf( m_aCustomTbxPrefix ) != -1 ) + implts_createCustomToolBar( aTbxResName, aTbxTitle ); + } +} + +void ToolbarLayoutManager::implts_createCustomToolBar( const rtl::OUString& aTbxResName, const rtl::OUString& aTitle ) +{ + if ( aTbxResName.getLength() > 0 ) + { + bool bNotify( false ); + uno::Reference< ui::XUIElement > xUIElement; + implts_createElement( aTbxResName, bNotify, xUIElement ); + + if ( aTitle && xUIElement.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + pWindow->SetText( aTitle ); + } + } +} + +void ToolbarLayoutManager::implts_reparentToolbars() +{ + UIElementVector aUIElementVector; + uno::Reference< awt::XWindow > xTopDockWindow; + uno::Reference< awt::XWindow > xBottomDockWindow; + uno::Reference< awt::XWindow > xLeftDockWindow; + uno::Reference< awt::XWindow > xRightDockWindow; + uno::Reference< awt::XWindow2 > xContainerWindow; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + aUIElementVector = m_aUIElements; + xTopDockWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP]; + xBottomDockWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM]; + xLeftDockWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT]; + xRightDockWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT]; + xContainerWindow = m_xContainerWindow; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + Window* pTopDockWindow = VCLUnoHelper::GetWindow( xTopDockWindow ); + Window* pBottomDockWindow = VCLUnoHelper::GetWindow( xBottomDockWindow ); + Window* pLeftDockWindow = VCLUnoHelper::GetWindow( xLeftDockWindow ); + Window* pRightDockWindow = VCLUnoHelper::GetWindow( xRightDockWindow ); + + if ( pContainerWindow ) + { + UIElementVector::iterator pIter; + for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); pIter++ ) + { + uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement ); + if ( xUIElement.is() ) + { + uno::Reference< awt::XWindow > xWindow; + try + { + // We have to retreive the window reference with try/catch as it is + // possible that all elements have been disposed! + xWindow = uno::Reference< awt::XWindow >( xUIElement->getRealInterface(), uno::UNO_QUERY ); + } + catch ( uno::RuntimeException& ) + { + throw; + } + catch ( uno::Exception& ) + { + } + + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + { + // Reparent our child windows acording to their current state. + if ( pIter->m_bFloating ) + pWindow->SetParent( pContainerWindow ); + else + { + if ( pIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) + pWindow->SetParent( pTopDockWindow ); + else if ( pIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) + pWindow->SetParent( pBottomDockWindow ); + else if ( pIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_LEFT ) + pWindow->SetParent( pLeftDockWindow ); + else + pWindow->SetParent( pRightDockWindow ); + } + } + } + } + } +} + +void ToolbarLayoutManager::implts_createElement( const ::rtl::OUString& aName, bool& bNotify, uno::Reference< ui::XUIElement >& rUIElement ) +{ + bNotify = false; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + uno::Reference< frame::XFrame > xFrame( m_xFrame ); + uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow ); + uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager ); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( !xFrame.is() || !xContainerWindow.is() ) + return; + + bool bFound( false ); + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + uno::Reference< ui::XUIElement > xUIElement; + + UIElement aToolbarElement = implts_findElement( aName ); + bFound = aToolbarElement.m_xUIElement.is(); + + if ( !bFound ) + { + uno::Sequence< beans::PropertyValue > aPropSeq( 2 ); + aPropSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); + aPropSeq[0].Value <<= xFrame; + aPropSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Persistent" )); + aPropSeq[1].Value <<= sal_True; + + xUIElement = xUIElementFactory->createUIElement( aName, aPropSeq ); + sal_Bool bVisible( sal_False ); + if ( xUIElement.is() ) + { + rUIElement = xUIElement; + + uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY ); + uno::Reference< awt::XDockableWindow > xDockWindow( xUIElement->getRealInterface(), uno::UNO_QUERY ); + if ( xDockWindow.is() && xWindow.is() ) + { + try + { + xDockWindow->addDockableWindowListener( uno::Reference< awt::XDockableWindowListener >( + static_cast< OWeakObject * >( this ), uno::UNO_QUERY )); + xWindow->addWindowListener( uno::Reference< awt::XWindowListener >( + static_cast< OWeakObject * >( this ), uno::UNO_QUERY )); + xDockWindow->enableDocking( sal_True ); + } + catch ( uno::Exception& ) + { + } + } + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + + UIElement rElement = impl_findElement( aName ); + if ( rElement.m_aName.getLength() > 0 ) + { + // Reuse a local entry so we are able to use the latest + // UI changes for this document. + implts_setElementData( rElement, xDockWindow ); + rElement.m_xUIElement = xUIElement; + bVisible = rElement.m_bVisible; + } + else + { + // Create new UI element and try to read its state data + UIElement aNewToolbar( aName, aElementType, xUIElement ); + implts_readWindowStateData( aName, aNewToolbar ); + implts_setElementData( aNewToolbar, xDockWindow ); + implts_insertElement( aNewToolbar ); + bVisible = aNewToolbar.m_bVisible; + } + + // set toolbar menu style according to customize command state + SvtCommandOptions aCmdOptions; + + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + { + ToolBox* pToolbar = (ToolBox *)pWindow; + USHORT nMenuType = pToolbar->GetMenuType(); + if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, m_aCustomizeCmd )) + pToolbar->SetMenuType( nMenuType & ~TOOLBOX_MENUTYPE_CUSTOMIZE ); + else + pToolbar->SetMenuType( nMenuType | TOOLBOX_MENUTYPE_CUSTOMIZE ); + } + + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + } + + implts_sortUIElements(); + + if ( bVisible ) + { + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_bLayoutDirty = true; + bNotify = true; + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + } + } +} + +uno::Reference< ui::XUIElement > ToolbarLayoutManager::implts_createElement( const ::rtl::OUString& aName ) +{ + uno::Reference< ui::XUIElement > xUIElement; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + uno::Sequence< beans::PropertyValue > aPropSeq( 2 ); + aPropSeq[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); + aPropSeq[0].Value <<= m_xFrame; + aPropSeq[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Persistent" )); + aPropSeq[1].Value <<= sal_True; + + try + { + if ( m_xUIElementFactoryManager.is() ) + xUIElement = m_xUIElementFactoryManager->createUIElement( aName, aPropSeq ); + } + catch ( container::NoSuchElementException& ) + { + } + catch ( lang::IllegalArgumentException& ) + { + } + + return xUIElement; +} + +void ToolbarLayoutManager::implts_setElementData( UIElement& rElement, const uno::Reference< awt::XDockableWindow >& rDockWindow ) +{ + ReadGuard aReadLock( m_aLock ); + sal_Bool bShowElement( rElement.m_bVisible && !rElement.m_bMasterHide && implts_isParentWindowVisible() ); + aReadLock.unlock(); + + uno::Reference< awt::XDockableWindow > xDockWindow( rDockWindow ); + uno::Reference< awt::XWindow2 > xWindow( xDockWindow, uno::UNO_QUERY ); + + Window* pWindow( 0 ); + ToolBox* pToolBox( 0 ); + + if ( xDockWindow.is() && xWindow.is() ) + { + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + { + String aText = pWindow->GetText(); + if ( aText.Len() == 0 ) + pWindow->SetText( rElement.m_aUIName ); + if ( rElement.m_bNoClose ) + pWindow->SetStyle( pWindow->GetStyle() & ~WB_CLOSEABLE ); + if ( pWindow->GetType() == WINDOW_TOOLBOX ) + pToolBox = (ToolBox *)pWindow; + } + if ( pToolBox ) + { + if (( rElement.m_nStyle < 0 ) || + ( rElement.m_nStyle > BUTTON_SYMBOLTEXT )) + rElement.m_nStyle = BUTTON_SYMBOL; + pToolBox->SetButtonType( (ButtonType)rElement.m_nStyle ); + if ( rElement.m_bNoClose ) + pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() & ~WB_CLOSEABLE ); + } + } + + if ( rElement.m_bFloating ) + { + if ( pWindow ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + String aText = pWindow->GetText(); + if ( aText.Len() == 0 ) + pWindow->SetText( rElement.m_aUIName ); + } + + ::Point aPos( rElement.m_aFloatingData.m_aPos.X(), + rElement.m_aFloatingData.m_aPos.Y() ); + sal_Bool bWriteData( sal_False ); + sal_Bool bUndefPos = ( rElement.m_aFloatingData.m_aPos.X() == SAL_MAX_INT32 || + rElement.m_aFloatingData.m_aPos.Y() == SAL_MAX_INT32 ); + sal_Bool bSetSize = ( rElement.m_aFloatingData.m_aSize.Width() != 0 && + rElement.m_aFloatingData.m_aSize.Height() != 0 ); + xDockWindow->setFloatingMode( sal_True ); + if ( bUndefPos ) + { + aPos = implts_findNextCascadeFloatingPos(); + rElement.m_aFloatingData.m_aPos = aPos; // set new cascaded position + bWriteData = sal_True; + } + + if( bSetSize ) + xWindow->setOutputSize( AWTSize( rElement.m_aFloatingData.m_aSize ) ); + else + { + if( pToolBox ) + { + // set an optimal initial floating size + vos::OGuard aGuard( Application::GetSolarMutex() ); + ::Size aSize( pToolBox->CalcFloatingWindowSizePixel() ); + pToolBox->SetOutputSizePixel( aSize ); + } + } + + // #i60882# IMPORTANT: Set position after size as it is + // possible that we position some part of the toolbar + // outside of the desktop. A default constructed toolbar + // always has one line. Now VCL automatically + // position the toolbar back into the desktop. Therefore + // we resize the toolbar with the new (wrong) position. + // To fix this problem we have to set the size BEFORE the + // position. + xWindow->setPosSize( aPos.X(), aPos.Y(), 0, 0, + css::awt::PosSize::POS ); + + if ( bWriteData ) + implts_writeWindowStateData( rElement.m_aName, rElement ); + if ( bShowElement && pWindow ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); + } + } + else + { + ::Point aDockPos; + ::Point aPixelPos; + sal_Bool bSetSize( sal_False ); + ::Size aSize; + + if ( pToolBox ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pToolBox->SetAlign( ImplConvertAlignment(rElement.m_aDockedData.m_nDockedArea ) ); + pToolBox->SetLineCount( 1 ); + if ( rElement.m_aDockedData.m_bLocked ) + xDockWindow->lock(); + aSize = pToolBox->CalcWindowSizePixel(); + bSetSize = sal_True; + + if (( rElement.m_aDockedData.m_aPos.X() == SAL_MAX_INT32 ) && + ( rElement.m_aDockedData.m_aPos.Y() == SAL_MAX_INT32 )) + { + implts_findNextDockingPos( (ui::DockingArea)rElement.m_aDockedData.m_nDockedArea, + aSize, + aDockPos, + aPixelPos ); + rElement.m_aDockedData.m_aPos = aDockPos; + } + } + + xWindow->setPosSize( aPixelPos.X(), + aPixelPos.Y(), + 0, 0, + css::awt::PosSize::POS ); + if( bSetSize ) + xWindow->setOutputSize( AWTSize( aSize) ); + + if ( bShowElement && pWindow ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pWindow->Show( sal_True ); + } + } + } +} + +void ToolbarLayoutManager::implts_destroyDockingAreaWindows() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + uno::Reference< awt::XWindow > xTopDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP]; + uno::Reference< awt::XWindow > xLeftDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT]; + uno::Reference< awt::XWindow > xRightDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT]; + uno::Reference< awt::XWindow > xBottomDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM]; + m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP].clear(); + m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT].clear(); + m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT].clear(); + m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM].clear(); + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + // destroy windows + xTopDockingWindow->dispose(); + xLeftDockingWindow->dispose(); + xRightDockingWindow->dispose(); + xBottomDockingWindow->dispose(); +} + +//--------------------------------------------------------------------------------------------------------- +// persistence methods +//--------------------------------------------------------------------------------------------------------- + +sal_Bool ToolbarLayoutManager::implts_readWindowStateData( const rtl::OUString& aName, UIElement& rElementData ) +{ + sal_Bool bGetSettingsState( sal_False ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( xPersistentWindowState.is() ) + { + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aWriteLock.lock(); + sal_Bool bGlobalSettings( m_bGlobalSettings ); + GlobalSettings* pGlobalSettings( 0 ); + if ( m_pGlobalSettings == 0 ) + { + m_pGlobalSettings = new GlobalSettings( m_xSMGR ); + bGetSettingsState = sal_True; + } + pGlobalSettings = m_pGlobalSettings; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + try + { + uno::Sequence< beans::PropertyValue > aWindowState; + if ( xPersistentWindowState->getByName( aName ) >>= aWindowState ) + { + sal_Bool bValue( sal_False ); + for ( sal_Int32 n = 0; n < aWindowState.getLength(); n++ ) + { + if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKED )) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_bFloating = !bValue; + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_VISIBLE )) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_bVisible = bValue; + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKINGAREA )) + { + ui::DockingArea eDockingArea; + if ( aWindowState[n].Value >>= eDockingArea ) + rElementData.m_aDockedData.m_nDockedArea = sal_Int16( eDockingArea ); + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKPOS )) + { + awt::Point aPoint; + if ( aWindowState[n].Value >>= aPoint ) + { + rElementData.m_aDockedData.m_aPos.X() = aPoint.X; + rElementData.m_aDockedData.m_aPos.Y() = aPoint.Y; + } + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_POS )) + { + awt::Point aPoint; + if ( aWindowState[n].Value >>= aPoint ) + { + rElementData.m_aFloatingData.m_aPos.X() = aPoint.X; + rElementData.m_aFloatingData.m_aPos.Y() = aPoint.Y; + } + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_SIZE )) + { + awt::Size aSize; + if ( aWindowState[n].Value >>= aSize ) + { + rElementData.m_aFloatingData.m_aSize.Width() = aSize.Width; + rElementData.m_aFloatingData.m_aSize.Height() = aSize.Height; + } + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_UINAME )) + aWindowState[n].Value >>= rElementData.m_aUIName; + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_STYLE )) + { + sal_Int32 nStyle = 0; + if ( aWindowState[n].Value >>= nStyle ) + rElementData.m_nStyle = sal_Int16( nStyle ); + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_LOCKED )) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_aDockedData.m_bLocked = bValue; + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXT )) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_bContextSensitive = bValue; + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_NOCLOSE )) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_bNoClose = bValue; + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_CONTEXTACTIVE )) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_bContextActive = bValue; + } + else if ( aWindowState[n].Name.equalsAscii( WINDOWSTATE_PROPERTY_SOFTCLOSE )) + { + if ( aWindowState[n].Value >>= bValue ) + rElementData.m_bSoftClose = bValue; + } + } + } + + // oversteer values with global settings + if ( pGlobalSettings && ( bGetSettingsState || bGlobalSettings )) + { + if ( pGlobalSettings->HasStatesInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR )) + { + WriteGuard aWriteLock2( m_aLock ); + m_bGlobalSettings = sal_True; + aWriteLock2.unlock(); + + css::uno::Any aValue; + sal_Bool bValue = sal_Bool(); + if ( pGlobalSettings->GetStateInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR, + GlobalSettings::STATEINFO_LOCKED, + aValue )) + aValue >>= rElementData.m_aDockedData.m_bLocked; + if ( pGlobalSettings->GetStateInfo( GlobalSettings::UIELEMENT_TYPE_TOOLBAR, + GlobalSettings::STATEINFO_DOCKED, + aValue )) + { + if ( aValue >>= bValue ) + rElementData.m_bFloating = !bValue; + } + } + } + + return sal_True; + } + catch ( container::NoSuchElementException& ) + { + } + } + + return sal_False; +} + +void ToolbarLayoutManager::implts_writeWindowStateData( const rtl::OUString& aName, const UIElement& rElementData ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); + + // set flag to determine that we triggered the notification + m_bStoreWindowState = true; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + sal_Bool bPersistent( sal_False ); + uno::Reference< beans::XPropertySet > xPropSet( rElementData.m_xUIElement, uno::UNO_QUERY ); + if ( xPropSet.is() ) + { + try + { + // Check persistent flag of the user interface element + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Persistent" ))) >>= bPersistent; + } + catch ( beans::UnknownPropertyException ) + { + // Non-configurable elements should at least store their dimension/position + bPersistent = sal_True; + } + catch ( lang::WrappedTargetException ) + { + } + } + + if ( bPersistent && xPersistentWindowState.is() ) + { + try + { + uno::Sequence< beans::PropertyValue > aWindowState( 8 ); + + aWindowState[0].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_DOCKED ); + aWindowState[0].Value = ::uno::makeAny( sal_Bool( !rElementData.m_bFloating )); + aWindowState[1].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_VISIBLE ); + aWindowState[1].Value = uno::makeAny( sal_Bool( rElementData.m_bVisible )); + + aWindowState[2].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_DOCKINGAREA ); + aWindowState[2].Value = uno::makeAny( static_cast< ui::DockingArea >( rElementData.m_aDockedData.m_nDockedArea ) ); + + awt::Point aPos; + aPos.X = rElementData.m_aDockedData.m_aPos.X(); + aPos.Y = rElementData.m_aDockedData.m_aPos.Y(); + aWindowState[3].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_DOCKPOS ); + aWindowState[3].Value <<= aPos; + + aPos.X = rElementData.m_aFloatingData.m_aPos.X(); + aPos.Y = rElementData.m_aFloatingData.m_aPos.Y(); + aWindowState[4].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_POS ); + aWindowState[4].Value <<= aPos; + + awt::Size aSize; + aSize.Width = rElementData.m_aFloatingData.m_aSize.Width(); + aSize.Height = rElementData.m_aFloatingData.m_aSize.Height(); + aWindowState[5].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_SIZE ); + aWindowState[5].Value <<= aSize; + aWindowState[6].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_UINAME ); + aWindowState[6].Value = uno::makeAny( rElementData.m_aUIName ); + aWindowState[7].Name = ::rtl::OUString::createFromAscii( WINDOWSTATE_PROPERTY_LOCKED ); + aWindowState[7].Value = uno::makeAny( rElementData.m_aDockedData.m_bLocked ); + + if ( xPersistentWindowState->hasByName( aName )) + { + uno::Reference< container::XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY ); + xReplace->replaceByName( aName, uno::makeAny( aWindowState )); + } + else + { + uno::Reference< container::XNameContainer > xInsert( xPersistentWindowState, uno::UNO_QUERY ); + xInsert->insertByName( aName, uno::makeAny( aWindowState )); + } + } + catch ( uno::Exception& ) + { + } + } + + // Reset flag + aWriteLock.lock(); + m_bStoreWindowState = false; + aWriteLock.unlock(); +} + +/****************************************************************************** + LOOKUP PART FOR TOOLBARS +******************************************************************************/ + +UIElement& ToolbarLayoutManager::impl_findElement( + const rtl::OUString& aName ) +{ + static UIElement aEmptyElement; + UIElementVector::iterator pIter; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aName == aName ) + return *pIter; + } + + return aEmptyElement; + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +UIElement ToolbarLayoutManager::implts_findElement( + const rtl::OUString& aName ) +{ + UIElement aEmptyElement; + UIElementVector::iterator pIter; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aName == aName ) + return *pIter; + } + + return aEmptyElement; + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +UIElement ToolbarLayoutManager::implts_findElement( + const uno::Reference< uno::XInterface >& xToolbar ) +{ + UIElement aToolbar; + UIElementVector::const_iterator pIter; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_xUIElement.is() ) + { + uno::Reference< uno::XInterface > xIfac( pIter->m_xUIElement->getRealInterface(), uno::UNO_QUERY ); + if ( xIfac == xToolbar ) + { + aToolbar = *pIter; + break; + } + } + } + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + return aToolbar; +} + +bool ToolbarLayoutManager::implts_insertElement( const UIElement& rUIElement ) +{ + UIElement aTempData; + bool bFound( false ); + bool bResult( false ); + + aTempData = implts_findElement( rUIElement.m_aName ); + if ( aTempData.m_aName == rUIElement.m_aName ) + bFound = true; + + if ( !bFound ) + { + WriteGuard aWriteLock( m_aLock ); + m_aUIElements.push_back( rUIElement ); + bResult = true; + } + + return bResult; +} + +void ToolbarLayoutManager::implts_setElement( const UIElement& rUIElement ) +{ + WriteGuard aWriteLock( m_aLock ); + UIElement& rData = impl_findElement( rUIElement.m_aName ); + if ( rData.m_aName == rUIElement.m_aName ) + rData = rUIElement; + else + m_aUIElements.push_back( rUIElement ); +} + +/****************************************************************************** + LAYOUT CODE PART FOR TOOLBARS +******************************************************************************/ + +::Point ToolbarLayoutManager::implts_findNextCascadeFloatingPos() +{ + const sal_Int32 nHotZoneX = 50; + const sal_Int32 nHotZoneY = 50; + const sal_Int32 nCascadeIndentX = 15; + const sal_Int32 nCascadeIndentY = 15; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + uno::Reference< awt::XWindow2 > xContainerWindow = m_xContainerWindow; + uno::Reference< awt::XWindow > xTopDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP]; + uno::Reference< awt::XWindow > xLeftDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT]; + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + ::Point aStartPos( nCascadeIndentX, nCascadeIndentY ); + ::Point aCurrPos( aStartPos ); + css::awt::Rectangle aRect; + + Window* pContainerWindow( 0 ); + if ( xContainerWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + if ( pContainerWindow ) + aStartPos = pContainerWindow->OutputToScreenPixel( aStartPos ); + } + + // Determine size of top and left docking area + css::awt::Rectangle aTopRect = xTopDockingWindow->getPosSize(); + css::awt::Rectangle aLeftRect = xLeftDockingWindow->getPosSize(); + + aStartPos.X() += aLeftRect.Width + nCascadeIndentX; + aStartPos.Y() += aTopRect.Height + nCascadeIndentY; + aCurrPos = aStartPos; + + // Try to find a cascaded position for the new floating window + UIElementVector::const_iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_xUIElement.is() ) + { + uno::Reference< awt::XDockableWindow > xDockWindow( pIter->m_xUIElement->getRealInterface(), uno::UNO_QUERY ); + uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY ); + if ( xDockWindow.is() && xDockWindow->isFloating() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->IsVisible() ) + { + css::awt::Rectangle aFloatRect = xWindow->getPosSize(); + if ((( aFloatRect.X - nHotZoneX ) <= aCurrPos.X() ) && + ( aFloatRect.X >= aCurrPos.X() ) && + (( aFloatRect.Y - nHotZoneY ) <= aCurrPos.Y() ) && + ( aFloatRect.Y >= aCurrPos.Y() )) + { + aCurrPos.X() = aFloatRect.X + nCascadeIndentX; + aCurrPos.Y() = aFloatRect.Y + nCascadeIndentY; + } + } + } + } + } + + return aCurrPos; +} + +void ToolbarLayoutManager::implts_sortUIElements() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + UIElementVector::iterator pIterStart = m_aUIElements.begin(); + UIElementVector::iterator pIterEnd = m_aUIElements.end(); + + std::stable_sort( pIterStart, pIterEnd ); // first created element should first + + // We have to reset our temporary flags. + UIElementVector::iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + pIter->m_bUserActive = sal_False; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +::Size ToolbarLayoutManager::implts_getTopBottomDockingAreaSizes() +{ + ::Size aSize; + uno::Reference< awt::XWindow > xTopDockingAreaWindow; + uno::Reference< awt::XWindow > xBottomDockingAreaWindow; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + xTopDockingAreaWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP]; + xBottomDockingAreaWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM]; + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( xTopDockingAreaWindow.is() ) + aSize.Width() = xTopDockingAreaWindow->getPosSize().Height; + if ( xBottomDockingAreaWindow.is() ) + aSize.Height() = xBottomDockingAreaWindow->getPosSize().Height; + + return aSize; +} + +void ToolbarLayoutManager::implts_getDockingAreaElementInfos( ui::DockingArea eDockingArea, std::vector< SingleRowColumnWindowData >& rRowColumnsWindowData ) +{ + std::vector< UIElement > aWindowVector; + + if (( eDockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea > ui::DockingArea_DOCKINGAREA_RIGHT )) + eDockingArea = ui::DockingArea_DOCKINGAREA_TOP; + + uno::Reference< awt::XWindow > xDockAreaWindow; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + aWindowVector.reserve(m_aUIElements.size()); + xDockAreaWindow = m_xDockAreaWindows[eDockingArea]; + UIElementVector::iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if ( pIter->m_aDockedData.m_nDockedArea == eDockingArea && pIter->m_bVisible && !pIter->m_bFloating ) + { + uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement ); + if ( xUIElement.is() ) + { + uno::Reference< css::awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY ); + uno::Reference< css::awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); + if ( xDockWindow.is() ) + { + // docked windows + aWindowVector.push_back( *pIter ); + } + } + } + } + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + rRowColumnsWindowData.clear(); + + // Collect data from windows that are on the same row/column + sal_Int32 j; + sal_Int32 nIndex( 0 ); + sal_Int32 nLastPos( 0 ); + sal_Int32 nCurrPos( -1 ); + sal_Int32 nLastRowColPixelPos( 0 ); + awt::Rectangle aDockAreaRect; + + if ( xDockAreaWindow.is() ) + aDockAreaRect = xDockAreaWindow->getPosSize(); + + if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) + nLastRowColPixelPos = 0; + else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) + nLastRowColPixelPos = aDockAreaRect.Height; + else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) + nLastRowColPixelPos = 0; + else + nLastRowColPixelPos = aDockAreaRect.Width; + + const sal_uInt32 nCount = aWindowVector.size(); + for ( j = 0; j < sal_Int32( nCount); j++ ) + { + const UIElement& rElement = aWindowVector[j]; + uno::Reference< awt::XWindow > xWindow; + uno::Reference< ui::XUIElement > xUIElement( rElement.m_xUIElement ); + awt::Rectangle aPosSize; + + if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) ) + continue; + if (( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )) + { + if ( nCurrPos == -1 ) + { + nCurrPos = rElement.m_aDockedData.m_aPos.Y(); + nLastPos = 0; + + SingleRowColumnWindowData aRowColumnWindowData; + aRowColumnWindowData.nRowColumn = nCurrPos; + rRowColumnsWindowData.push_back( aRowColumnWindowData ); + } + + sal_Int32 nSpace( 0 ); + if ( rElement.m_aDockedData.m_aPos.Y() != nCurrPos ) + { + if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) + nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize; + else + nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize; + ++nIndex; + nLastPos = 0; + nCurrPos = rElement.m_aDockedData.m_aPos.Y(); + SingleRowColumnWindowData aRowColumnWindowData; + aRowColumnWindowData.nRowColumn = nCurrPos; + rRowColumnsWindowData.push_back( aRowColumnWindowData ); + } + + // Calc space before an element and store it + nSpace = ( rElement.m_aDockedData.m_aPos.X() - nLastPos ); + if ( rElement.m_aDockedData.m_aPos.X() >= nLastPos ) + { + rRowColumnsWindowData[nIndex].nSpace += nSpace; + nLastPos = rElement.m_aDockedData.m_aPos.X() + aPosSize.Width; + } + else + { + nSpace = 0; + nLastPos += aPosSize.Width; + } + rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace ); + + rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow ); + rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName ); + rRowColumnsWindowData[nIndex].aRowColumnWindowSizes.push_back( + css::awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), + rElement.m_aDockedData.m_aPos.Y(), + aPosSize.Width, + aPosSize.Height )); + if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Height ) + rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Height; + if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) + rRowColumnsWindowData[nIndex].aRowColumnRect = css::awt::Rectangle( 0, nLastRowColPixelPos, + aDockAreaRect.Width, aPosSize.Height ); + else + rRowColumnsWindowData[nIndex].aRowColumnRect = css::awt::Rectangle( 0, ( nLastRowColPixelPos - aPosSize.Height ), + aDockAreaRect.Width, aPosSize.Height ); + rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Width + nSpace; + } + else + { + if ( nCurrPos == -1 ) + { + nCurrPos = rElement.m_aDockedData.m_aPos.X(); + nLastPos = 0; + + SingleRowColumnWindowData aRowColumnWindowData; + aRowColumnWindowData.nRowColumn = nCurrPos; + rRowColumnsWindowData.push_back( aRowColumnWindowData ); + } + + sal_Int32 nSpace( 0 ); + if ( rElement.m_aDockedData.m_aPos.X() != nCurrPos ) + { + if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) + nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize; + else + nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize; + ++nIndex; + nLastPos = 0; + nCurrPos = rElement.m_aDockedData.m_aPos.X(); + SingleRowColumnWindowData aRowColumnWindowData; + aRowColumnWindowData.nRowColumn = nCurrPos; + rRowColumnsWindowData.push_back( aRowColumnWindowData ); + } + + // Calc space before an element and store it + nSpace = ( rElement.m_aDockedData.m_aPos.Y() - nLastPos ); + if ( rElement.m_aDockedData.m_aPos.Y() > nLastPos ) + { + rRowColumnsWindowData[nIndex].nSpace += nSpace; + nLastPos = rElement.m_aDockedData.m_aPos.Y() + aPosSize.Height; + } + else + { + nSpace = 0; + nLastPos += aPosSize.Height; + } + rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace ); + + rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow ); + rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName ); + rRowColumnsWindowData[nIndex].aRowColumnWindowSizes.push_back( + css::awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), + rElement.m_aDockedData.m_aPos.Y(), + aPosSize.Width, + aPosSize.Height )); + if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Width ) + rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Width; + if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) + rRowColumnsWindowData[nIndex].aRowColumnRect = css::awt::Rectangle( nLastRowColPixelPos, 0, + aPosSize.Width, aDockAreaRect.Height ); + else + rRowColumnsWindowData[nIndex].aRowColumnRect = css::awt::Rectangle( ( nLastRowColPixelPos - aPosSize.Width ), 0, + aPosSize.Width, aDockAreaRect.Height ); + rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Height + nSpace; + } + } +} + +void ToolbarLayoutManager::implts_getDockingAreaElementInfoOnSingleRowCol( ui::DockingArea eDockingArea, sal_Int32 nRowCol, SingleRowColumnWindowData& rRowColumnWindowData ) +{ + std::vector< UIElement > aWindowVector; + + if (( eDockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea > ui::DockingArea_DOCKINGAREA_RIGHT )) + eDockingArea = ui::DockingArea_DOCKINGAREA_TOP; + + sal_Bool bHorzDockArea = (( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + UIElementVector::iterator pIter; + UIElementVector::iterator pEnd = m_aUIElements.end(); + for ( pIter = m_aUIElements.begin(); pIter != pEnd; pIter++ ) + { + if ( pIter->m_aDockedData.m_nDockedArea == eDockingArea ) + { + sal_Bool bSameRowCol = bHorzDockArea ? + ( pIter->m_aDockedData.m_aPos.Y() == nRowCol ) : + ( pIter->m_aDockedData.m_aPos.X() == nRowCol ); + uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement ); + + if ( bSameRowCol && xUIElement.is() ) + { + uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY ); + if ( xWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); + if ( pWindow && pIter->m_bVisible && xDockWindow.is() && !pIter->m_bFloating ) + { + // docked windows + aWindowVector.push_back( *pIter ); + } + } + } + } + } + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + // Initialize structure + rRowColumnWindowData.aUIElementNames.clear(); + rRowColumnWindowData.aRowColumnWindows.clear(); + rRowColumnWindowData.aRowColumnWindowSizes.clear(); + rRowColumnWindowData.aRowColumnSpace.clear(); + rRowColumnWindowData.nVarSize = 0; + rRowColumnWindowData.nStaticSize = 0; + rRowColumnWindowData.nSpace = 0; + rRowColumnWindowData.nRowColumn = nRowCol; + + // Collect data from windows that are on the same row/column + sal_Int32 j; + sal_Int32 nLastPos( 0 ); + + const sal_uInt32 nCount = aWindowVector.size(); + for ( j = 0; j < sal_Int32( nCount); j++ ) + { + const UIElement& rElement = aWindowVector[j]; + uno::Reference< awt::XWindow > xWindow; + uno::Reference< ui::XUIElement > xUIElement( rElement.m_xUIElement ); + awt::Rectangle aPosSize; + if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) ) + continue; + + sal_Int32 nSpace; + if (( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )) + { + nSpace = ( rElement.m_aDockedData.m_aPos.X() - nLastPos ); + + // Calc space before an element and store it + if ( rElement.m_aDockedData.m_aPos.X() > nLastPos ) + rRowColumnWindowData.nSpace += nSpace; + else + nSpace = 0; + + nLastPos = rElement.m_aDockedData.m_aPos.X() + aPosSize.Width; + + + rRowColumnWindowData.aRowColumnWindowSizes.push_back( + css::awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), + rElement.m_aDockedData.m_aPos.Y(), + aPosSize.Width, + aPosSize.Height )); + if ( rRowColumnWindowData.nStaticSize < aPosSize.Height ) + rRowColumnWindowData.nStaticSize = aPosSize.Height; + rRowColumnWindowData.nVarSize += aPosSize.Width; + } + else + { + // Calc space before an element and store it + nSpace = ( rElement.m_aDockedData.m_aPos.Y() - nLastPos ); + if ( rElement.m_aDockedData.m_aPos.Y() > nLastPos ) + rRowColumnWindowData.nSpace += nSpace; + else + nSpace = 0; + + nLastPos = rElement.m_aDockedData.m_aPos.Y() + aPosSize.Height; + + rRowColumnWindowData.aRowColumnWindowSizes.push_back( + css::awt::Rectangle( rElement.m_aDockedData.m_aPos.X(), + rElement.m_aDockedData.m_aPos.Y(), + aPosSize.Width, + aPosSize.Height )); + if ( rRowColumnWindowData.nStaticSize < aPosSize.Width ) + rRowColumnWindowData.nStaticSize = aPosSize.Width; + rRowColumnWindowData.nVarSize += aPosSize.Height; + } + + rRowColumnWindowData.aUIElementNames.push_back( rElement.m_aName ); + rRowColumnWindowData.aRowColumnWindows.push_back( xWindow ); + rRowColumnWindowData.aRowColumnSpace.push_back( nSpace ); + rRowColumnWindowData.nVarSize += nSpace; + } +} + +::Rectangle ToolbarLayoutManager::implts_getWindowRectFromRowColumn( + ui::DockingArea DockingArea, + const SingleRowColumnWindowData& rRowColumnWindowData, + const ::Point& rMousePos, + const rtl::OUString& rExcludeElementName ) +{ + ::Rectangle aWinRect; + + if (( DockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea > ui::DockingArea_DOCKINGAREA_RIGHT )) + DockingArea = ui::DockingArea_DOCKINGAREA_TOP; + + if ( rRowColumnWindowData.aRowColumnWindows.empty() ) + return aWinRect; + else + { + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + uno::Reference< awt::XWindow2 > xContainerWindow = m_xContainerWindow; + uno::Reference< awt::XWindow > xDockingAreaWindow = m_xDockAreaWindows[DockingArea]; + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect + vos::OGuard aGuard( Application::GetSolarMutex() ); + + // Retrieve output size from container Window + Window* pContainerWindow( VCLUnoHelper::GetWindow( xContainerWindow )); + Window* pDockingAreaWindow( VCLUnoHelper::GetWindow( xDockingAreaWindow )); + if ( pDockingAreaWindow && pContainerWindow ) + { + const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindows.size(); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + awt::Rectangle aWindowRect = rRowColumnWindowData.aRowColumnWindows[i]->getPosSize(); + ::Rectangle aRect( aWindowRect.X, aWindowRect.Y, aWindowRect.X+aWindowRect.Width, aWindowRect.Y+aWindowRect.Height ); + aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() ))); + if ( aRect.IsInside( rMousePos )) + { + // Check if we have found the excluded element. If yes, we have to provide an empty rectangle. + // We prevent that a toolbar cannot be moved when the mouse pointer is inside its own rectangle! + if ( rExcludeElementName != rRowColumnWindowData.aUIElementNames[i] ) + return aRect; + else + break; + } + } + } + } + + return aWinRect; +} + +::Rectangle ToolbarLayoutManager::implts_determineFrontDockingRect( + ui::DockingArea eDockingArea, + sal_Int32 nRowCol, + const ::Rectangle& rDockedElementRect, + const ::rtl::OUString& rMovedElementName, + const ::Rectangle& rMovedElementRect ) +{ + SingleRowColumnWindowData aRowColumnWindowData; + + sal_Bool bHorzDockArea = (( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )); + + implts_getDockingAreaElementInfoOnSingleRowCol( eDockingArea, nRowCol, aRowColumnWindowData ); + if ( aRowColumnWindowData.aRowColumnWindows.empty() ) + return rMovedElementRect; + else + { + sal_Int32 nSpace( 0 ); + ::Rectangle aFrontDockingRect( rMovedElementRect ); + const sal_uInt32 nCount = aRowColumnWindowData.aRowColumnWindows.size(); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + if ( bHorzDockArea ) + { + if ( aRowColumnWindowData.aRowColumnWindowSizes[i].X >= rDockedElementRect.Left() ) + { + nSpace += aRowColumnWindowData.aRowColumnSpace[i]; + break; + } + else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName ) + nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Width + + aRowColumnWindowData.aRowColumnSpace[i]; + else + nSpace = 0; + } + else + { + if ( aRowColumnWindowData.aRowColumnWindowSizes[i].Y >= rDockedElementRect.Top() ) + { + nSpace += aRowColumnWindowData.aRowColumnSpace[i]; + break; + } + else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName ) + nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Height + + aRowColumnWindowData.aRowColumnSpace[i]; + else + nSpace = 0; + } + } + + if ( nSpace > 0 ) + { + sal_Int32 nMove = std::min( nSpace, static_cast<sal_Int32>(aFrontDockingRect.getWidth()) ); + if ( bHorzDockArea ) + aFrontDockingRect.Move( -nMove, 0 ); + else + aFrontDockingRect.Move( 0, -nMove ); + } + + return aFrontDockingRect; + } +} + +void ToolbarLayoutManager::implts_findNextDockingPos( ui::DockingArea DockingArea, const ::Size& aUIElementSize, ::Point& rVirtualPos, ::Point& rPixelPos ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + uno::Reference< awt::XWindow > xDockingWindow = m_xDockAreaWindows[DockingArea]; + ::Size aDockingWinSize; + Window* pDockingWindow( 0 ); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if (( DockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea > ui::DockingArea_DOCKINGAREA_RIGHT )) + DockingArea = ui::DockingArea_DOCKINGAREA_TOP; + + { + // Retrieve output size from container Window + vos::OGuard aGuard( Application::GetSolarMutex() ); + pDockingWindow = VCLUnoHelper::GetWindow( xDockingWindow ); + if ( pDockingWindow ) + aDockingWinSize = pDockingWindow->GetOutputSizePixel(); + } + + sal_Int32 nFreeRowColPixelPos( 0 ); + sal_Int32 nMaxSpace( 0 ); + sal_Int32 nNeededSpace( 0 ); + sal_Int32 nTopDockingAreaSize( 0 ); + + if (( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )) + { + nMaxSpace = aDockingWinSize.Width(); + nNeededSpace = aUIElementSize.Width(); + } + else + { + nMaxSpace = aDockingWinSize.Height(); + nNeededSpace = aUIElementSize.Height(); + nTopDockingAreaSize = implts_getTopBottomDockingAreaSizes().Width(); + } + + std::vector< SingleRowColumnWindowData > aRowColumnsWindowData; + + implts_getDockingAreaElementInfos( DockingArea, aRowColumnsWindowData ); + sal_Int32 nPixelPos( 0 ); + const sal_uInt32 nCount = aRowColumnsWindowData.size(); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + SingleRowColumnWindowData& rRowColumnWindowData = aRowColumnsWindowData[i]; + + if (( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) || + ( DockingArea == ui::DockingArea_DOCKINGAREA_RIGHT )) + nPixelPos += rRowColumnWindowData.nStaticSize; + + if ((( nMaxSpace - rRowColumnWindowData.nVarSize ) >= nNeededSpace ) || + ( rRowColumnWindowData.nSpace >= nNeededSpace )) + { + // Check current row where we can find the needed space + sal_Int32 nCurrPos( 0 ); + const sal_uInt32 nWindowSizesCount = rRowColumnWindowData.aRowColumnWindowSizes.size(); + for ( sal_uInt32 j = 0; j < nWindowSizesCount; j++ ) + { + css::awt::Rectangle rRect = rRowColumnWindowData.aRowColumnWindowSizes[j]; + sal_Int32& rSpace = rRowColumnWindowData.aRowColumnSpace[j]; + if (( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )) + { + if ( rSpace >= nNeededSpace ) + { + rVirtualPos = ::Point( nCurrPos, rRowColumnWindowData.nRowColumn ); + if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) + rPixelPos = ::Point( nCurrPos, nPixelPos ); + else + rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos ); + return; + } + nCurrPos = rRect.X + rRect.Width; + } + else + { + if ( rSpace >= nNeededSpace ) + { + rVirtualPos = ::Point( rRowColumnWindowData.nRowColumn, nCurrPos ); + if ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) + rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos ); + else + rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos ); + return; + } + nCurrPos = rRect.Y + rRect.Height; + } + } + + if (( nCurrPos + nNeededSpace ) <= nMaxSpace ) + { + if (( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )) + { + rVirtualPos = ::Point( nCurrPos, rRowColumnWindowData.nRowColumn ); + if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) + rPixelPos = ::Point( nCurrPos, nPixelPos ); + else + rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos ); + return; + } + else + { + rVirtualPos = ::Point( rRowColumnWindowData.nRowColumn, nCurrPos ); + if ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) + rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos ); + else + rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos ); + return; + } + } + } + + if (( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT )) + nPixelPos += rRowColumnWindowData.nStaticSize; + } + + sal_Int32 nNextFreeRowCol( 0 ); + sal_Int32 nRowColumnsCount = aRowColumnsWindowData.size(); + if ( nRowColumnsCount > 0 ) + nNextFreeRowCol = aRowColumnsWindowData[nRowColumnsCount-1].nRowColumn+1; + else + nNextFreeRowCol = 0; + + if ( nNextFreeRowCol == 0 ) + { + if ( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) + nFreeRowColPixelPos = aDockingWinSize.Height() - aUIElementSize.Height(); + else if ( DockingArea == ui::DockingArea_DOCKINGAREA_RIGHT ) + nFreeRowColPixelPos = aDockingWinSize.Width() - aUIElementSize.Width(); + } + + if (( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )) + { + rVirtualPos = ::Point( 0, nNextFreeRowCol ); + if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) + rPixelPos = ::Point( 0, nFreeRowColPixelPos ); + else + rPixelPos = ::Point( 0, aDockingWinSize.Height() - nFreeRowColPixelPos ); + } + else + { + rVirtualPos = ::Point( nNextFreeRowCol, 0 ); + rPixelPos = ::Point( aDockingWinSize.Width() - nFreeRowColPixelPos, 0 ); + } +} + +void ToolbarLayoutManager::implts_calcWindowPosSizeOnSingleRowColumn( + sal_Int32 nDockingArea, + sal_Int32 nOffset, + SingleRowColumnWindowData& rRowColumnWindowData, + const ::Size& rContainerSize ) +{ + sal_Int32 nDiff( 0 ); + sal_Int32 nRCSpace( rRowColumnWindowData.nSpace ); + sal_Int32 nTopDockingAreaSize; + sal_Int32 nBottomDockingAreaSize; + sal_Int32 nContainerClientSize; + + if ( rRowColumnWindowData.aRowColumnWindows.empty() ) + return; + + if (( nDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( nDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )) + { + nContainerClientSize = rContainerSize.Width(); + nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize; + } + else + { + nTopDockingAreaSize = implts_getTopBottomDockingAreaSizes().Width(); + nBottomDockingAreaSize = implts_getTopBottomDockingAreaSizes().Height(); + nContainerClientSize = ( rContainerSize.Height() - nTopDockingAreaSize - nBottomDockingAreaSize ); + nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize; + } + + const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindowSizes.size(); + if (( nDiff < 0 ) && ( nRCSpace > 0 )) + { + // First we try to reduce the size of blank space before/behind docked windows + sal_Int32 i = nCount - 1; + while ( i >= 0 ) + { + sal_Int32 nSpace = rRowColumnWindowData.aRowColumnSpace[i]; + if ( nSpace >= -nDiff ) + { + + if (( nDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( nDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )) + { + // Try to move this and all user elements behind with the calculated difference + for ( sal_uInt32 j = i; j < nCount ; j++ ) + rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff; + } + else + { + // Try to move this and all user elements behind with the calculated difference + for ( sal_uInt32 j = i; j < nCount ; j++ ) + rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff; + } + nDiff = 0; + + break; + } + else if ( nSpace > 0 ) + { + if (( nDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( nDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )) + { + // Try to move this and all user elements behind with the calculated difference + for ( sal_uInt32 j = i; j < nCount; j++ ) + rRowColumnWindowData.aRowColumnWindowSizes[j].X -= nSpace; + } + else + { + // Try to move this and all user elements behind with the calculated difference + for ( sal_uInt32 j = i; j < nCount; j++ ) + rRowColumnWindowData.aRowColumnWindowSizes[j].Y -= nSpace; + } + nDiff += nSpace; + } + --i; + } + } + + // Check if we have to reduce further + if ( nDiff < 0 ) + { + // Now we have to reduce the size of certain docked windows + sal_Int32 i = sal_Int32( nCount - 1 ); + while ( i >= 0 ) + { + css::awt::Rectangle& rWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i]; + ::Size aMinSize; + + vos::OGuard aGuard( Application::GetSolarMutex() ); + { + uno::Reference< awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i]; + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + aMinSize = ((ToolBox *)pWindow)->CalcMinimumWindowSizePixel(); + } + + if (( aMinSize.Width() > 0 ) && ( aMinSize.Height() > 0 )) + { + if (( nDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( nDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )) + { + sal_Int32 nMaxReducation = ( rWinRect.Width - aMinSize.Width() ); + if ( nMaxReducation >= -nDiff ) + { + rWinRect.Width = rWinRect.Width + nDiff; + nDiff = 0; + } + else + { + rWinRect.Width = aMinSize.Width(); + nDiff += nMaxReducation; + } + + // Try to move this and all user elements behind with the calculated difference + for ( sal_uInt32 j = i; j < nCount; j++ ) + rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff; + } + else + { + sal_Int32 nMaxReducation = ( rWinRect.Height - aMinSize.Height() ); + if ( nMaxReducation >= -nDiff ) + { + rWinRect.Height = rWinRect.Height + nDiff; + nDiff = 0; + } + else + { + rWinRect.Height = aMinSize.Height(); + nDiff += nMaxReducation; + } + + // Try to move this and all user elements behind with the calculated difference + for ( sal_uInt32 j = i; j < nCount; j++ ) + rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff; + } + } + + if ( nDiff >= 0 ) + break; + + --i; + } + } + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + Window* pDockAreaWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[nDockingArea] ); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + sal_Int32 nCurrPos( 0 ); + sal_Int32 nStartOffset( 0 ); + + if ( nDockingArea == ui::DockingArea_DOCKINGAREA_RIGHT ) + nStartOffset = pDockAreaWindow->GetSizePixel().Width() - rRowColumnWindowData.nStaticSize; + else if ( nDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) + nStartOffset = pDockAreaWindow->GetSizePixel().Height() - rRowColumnWindowData.nStaticSize; + + vos::OGuard aGuard( Application::GetSolarMutex() ); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + uno::Reference< awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i]; + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + Window* pOldParentWindow = pWindow->GetParent(); + + if ( pDockAreaWindow != pOldParentWindow ) + pWindow->SetParent( pDockAreaWindow ); + + awt::Rectangle aWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i]; + if ( nDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) + { + if ( aWinRect.X < nCurrPos ) + aWinRect.X = nCurrPos; + pWindow->SetPosSizePixel( ::Point( aWinRect.X, nOffset ), + ::Size( aWinRect.Width, rRowColumnWindowData.nStaticSize )); + nCurrPos += ( aWinRect.X - nCurrPos ) + aWinRect.Width; + } + else if ( nDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) + { + if ( aWinRect.X < nCurrPos ) + aWinRect.X = nCurrPos; + pWindow->SetPosSizePixel( ::Point( aWinRect.X, nStartOffset - nOffset ), + ::Size( aWinRect.Width, rRowColumnWindowData.nStaticSize )); + nCurrPos += ( aWinRect.X - nCurrPos ) + aWinRect.Width; + } + else if ( nDockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) + { + if ( aWinRect.Y < nCurrPos ) + aWinRect.Y = nCurrPos; + pWindow->SetPosSizePixel( ::Point( nOffset, aWinRect.Y ), + ::Size( rRowColumnWindowData.nStaticSize, aWinRect.Height )); + nCurrPos += ( aWinRect.Y - nCurrPos ) + aWinRect.Height; + } + else if ( nDockingArea == ui::DockingArea_DOCKINGAREA_RIGHT ) + { + if ( aWinRect.Y < nCurrPos ) + aWinRect.Y = nCurrPos; + pWindow->SetPosSizePixel( ::Point( nStartOffset - nOffset, aWinRect.Y ), + ::Size( rRowColumnWindowData.nStaticSize, aWinRect.Height )); + nCurrPos += ( aWinRect.Y - nCurrPos ) + aWinRect.Height; + } + } +} + +::Rectangle ToolbarLayoutManager::implts_calcHotZoneRect( const ::Rectangle& rRect, sal_Int32 nHotZoneOffset ) +{ + ::Rectangle aRect( rRect ); + + aRect.Left() -= nHotZoneOffset; + aRect.Top() -= nHotZoneOffset; + aRect.Right() += nHotZoneOffset; + aRect.Bottom() += nHotZoneOffset; + + return aRect; +} + +void ToolbarLayoutManager::implts_calcDockingPosSize( + UIElement& rUIElement, + DockingOperation& rDockingOperation, + ::Rectangle& rTrackingRect, + const Point& rMousePos ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow ); + ::Size aContainerWinSize; + Window* pContainerWindow( 0 ); + ::Rectangle aDockingAreaOffsets( m_aDockingAreaOffsets ); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + { + // Retrieve output size from container Window + vos::OGuard aGuard( Application::GetSolarMutex() ); + pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + aContainerWinSize = pContainerWindow->GetOutputSizePixel(); + } + + if ( !rUIElement.m_xUIElement.is() ) + { + rTrackingRect = ::Rectangle(); + return; + } + + Window* pDockWindow( 0 ); + Window* pDockingAreaWindow( 0 ); + ToolBox* pToolBox( 0 ); + uno::Reference< awt::XWindow > xWindow( rUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY ); + uno::Reference< awt::XWindow > xDockingAreaWindow; + ::Rectangle aTrackingRect( rTrackingRect ); + ::com::sun::star::ui::DockingArea eDockedArea( (::com::sun::star::ui::DockingArea)rUIElement.m_aDockedData.m_nDockedArea ); + sal_Int32 nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() ); + sal_Int32 nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() ); + sal_Bool bHorizontalDockArea(( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM )); + sal_Int32 nMaxLeftRightDockAreaSize = aContainerWinSize.Height() - + nTopDockingAreaSize - + nBottomDockingAreaSize - + aDockingAreaOffsets.Top() - + aDockingAreaOffsets.Bottom(); + ::Rectangle aDockingAreaRect; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aReadLock.lock(); + xDockingAreaWindow = m_xDockAreaWindows[eDockedArea]; + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow ); + pDockWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pDockWindow && pDockWindow->GetType() == WINDOW_TOOLBOX ) + pToolBox = (ToolBox *)pDockWindow; + + aDockingAreaRect = ::Rectangle( pDockingAreaWindow->GetPosPixel(), pDockingAreaWindow->GetSizePixel() ); + if ( pToolBox ) + { + // docked toolbars always have one line + ::Size aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( sal_Int16( eDockedArea )) ); + aTrackingRect.SetSize( ::Size( aSize.Width(), aSize.Height() )); + } + } + + // default docking operation, dock on the given row/column + sal_Bool bOpOutsideOfDockingArea( !aDockingAreaRect.IsInside( rMousePos )); + std::vector< SingleRowColumnWindowData > aRowColumnsWindowData; + + rDockingOperation = DOCKOP_ON_COLROW; + implts_getDockingAreaElementInfos( eDockedArea, aRowColumnsWindowData ); + + // determine current first row/column and last row/column + sal_Int32 nMaxRowCol( -1 ); + sal_Int32 nMinRowCol( SAL_MAX_INT32 ); + const sal_uInt32 nCount = aRowColumnsWindowData.size(); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + if ( aRowColumnsWindowData[i].nRowColumn > nMaxRowCol ) + nMaxRowCol = aRowColumnsWindowData[i].nRowColumn; + if ( aRowColumnsWindowData[i].nRowColumn < nMinRowCol ) + nMinRowCol = aRowColumnsWindowData[i].nRowColumn; + } + + if ( !bOpOutsideOfDockingArea ) + { + // docking inside our docking area + sal_Int32 nIndex( -1 ); + sal_Int32 nRowCol( -1 ); + ::Rectangle aWindowRect; + ::Rectangle aRowColumnRect; + + const sal_uInt32 nWindowDataCount = aRowColumnsWindowData.size(); + for ( sal_uInt32 i = 0; i < nWindowDataCount; i++ ) + { + ::Rectangle aRect( aRowColumnsWindowData[i].aRowColumnRect.X, + aRowColumnsWindowData[i].aRowColumnRect.Y, + aRowColumnsWindowData[i].aRowColumnRect.X + aRowColumnsWindowData[i].aRowColumnRect.Width, + aRowColumnsWindowData[i].aRowColumnRect.Y + aRowColumnsWindowData[i].aRowColumnRect.Height ); + + { + // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect + vos::OGuard aGuard( Application::GetSolarMutex() ); + aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() ))); + } + + sal_Bool bIsInsideRowCol( aRect.IsInside( rMousePos ) ); + if ( bIsInsideRowCol ) + { + nIndex = i; + nRowCol = aRowColumnsWindowData[i].nRowColumn; + rDockingOperation = implts_determineDockingOperation( eDockedArea, aRect, rMousePos ); + aWindowRect = implts_getWindowRectFromRowColumn( eDockedArea, aRowColumnsWindowData[i], rMousePos, rUIElement.m_aName ); + aRowColumnRect = aRect; + break; + } + } + + OSL_ENSURE( ( nIndex >= 0 ) && ( nRowCol >= 0 ), "Impossible case - no row/column found but mouse pointer is inside our docking area" ); + if (( nIndex >= 0 ) && ( nRowCol >= 0 )) + { + if ( rDockingOperation == DOCKOP_ON_COLROW ) + { + if ( !aWindowRect.IsEmpty()) + { + // Tracking rect is on a row/column and mouse is over a docked toolbar. + // Determine if the tracking rect must be located before/after the docked toolbar. + + ::Rectangle aUIElementRect( aWindowRect ); + sal_Int32 nMiddle( bHorizontalDockArea ? ( aWindowRect.Left() + aWindowRect.getWidth() / 2 ) : + ( aWindowRect.Top() + aWindowRect.getHeight() / 2 )); + sal_Bool bInsertBefore( bHorizontalDockArea ? ( rMousePos.X() < nMiddle ) : ( rMousePos.Y() < nMiddle )); + if ( bInsertBefore ) + { + if ( bHorizontalDockArea ) + { + sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( aContainerWinSize.Width() - aWindowRect.Left() ), + sal_Int32( aTrackingRect.getWidth() ))); + if ( nSize == 0 ) + nSize = aWindowRect.getWidth(); + + aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() )); + aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect,rUIElement.m_aName, aUIElementRect ); + + // Set virtual position + rUIElement.m_aDockedData.m_aPos.X() = aWindowRect.Left(); + rUIElement.m_aDockedData.m_aPos.Y() = nRowCol; + } + else + { + sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( + nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Top() ), + sal_Int32( aTrackingRect.getHeight() ))); + if ( nSize == 0 ) + nSize = aWindowRect.getHeight(); + + aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize )); + aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect, rUIElement.m_aName, aUIElementRect ); + + // Set virtual position + sal_Int32 nPosY = pDockingAreaWindow->ScreenToOutputPixel( + pContainerWindow->OutputToScreenPixel( aWindowRect.TopLeft() )).Y(); + rUIElement.m_aDockedData.m_aPos.X() = nRowCol; + rUIElement.m_aDockedData.m_aPos.Y() = nPosY; + } + + rTrackingRect = aWindowRect; + return; + } + else + { + if ( bHorizontalDockArea ) + { + sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32(( aContainerWinSize.Width() ) - aWindowRect.Right() ), + sal_Int32( aTrackingRect.getWidth() ))); + if ( nSize == 0 ) + { + aUIElementRect.SetPos( ::Point( aContainerWinSize.Width() - aTrackingRect.getWidth(), aWindowRect.Top() )); + aUIElementRect.SetSize( ::Size( aTrackingRect.getWidth(), aWindowRect.getHeight() )); + rUIElement.m_aDockedData.m_aPos.X() = aUIElementRect.Left(); + } + else + { + aUIElementRect.SetPos( ::Point( aWindowRect.Right(), aWindowRect.Top() )); + aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() )); + rUIElement.m_aDockedData.m_aPos.X() = aWindowRect.Right(); + } + + // Set virtual position + rUIElement.m_aDockedData.m_aPos.Y() = nRowCol; + } + else + { + sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Bottom() ), + sal_Int32( aTrackingRect.getHeight() ))); + aUIElementRect.SetPos( ::Point( aWindowRect.Left(), aWindowRect.Bottom() )); + aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize )); + + // Set virtual position + sal_Int32 nPosY( 0 ); + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + nPosY = pDockingAreaWindow->ScreenToOutputPixel( + pContainerWindow->OutputToScreenPixel( aWindowRect.BottomRight() )).Y(); + } + rUIElement.m_aDockedData.m_aPos.X() = nRowCol; + rUIElement.m_aDockedData.m_aPos.Y() = nPosY; + } + + rTrackingRect = aUIElementRect; + return; + } + } + else + { + implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect ); + rTrackingRect = implts_calcTrackingAndElementRect( + eDockedArea, nRowCol, rUIElement, + aTrackingRect, aRowColumnRect, aContainerWinSize ); + return; + } + } + else + { + if ((( nRowCol == nMinRowCol ) && ( rDockingOperation == DOCKOP_BEFORE_COLROW )) || + (( nRowCol == nMaxRowCol ) && ( rDockingOperation == DOCKOP_AFTER_COLROW ))) + bOpOutsideOfDockingArea = sal_True; + else + { + // handle docking before/after a row + implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect ); + rTrackingRect = implts_calcTrackingAndElementRect( + eDockedArea, nRowCol, rUIElement, + aTrackingRect, aRowColumnRect, aContainerWinSize ); + + sal_Int32 nOffsetX( 0 ); + sal_Int32 nOffsetY( 0 ); + if ( bHorizontalDockArea ) + nOffsetY = sal_Int32( floor( aRowColumnRect.getHeight() / 2 + 0.5 )); + else + nOffsetX = sal_Int32( floor( aRowColumnRect.getWidth() / 2 + 0.5 )); + + if ( rDockingOperation == DOCKOP_BEFORE_COLROW ) + { + if (( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT )) + { + // Docking before/after means move track rectangle half column/row. + // As left and top are ordered 0...n instead of right and bottom + // which uses n...0, we have to use negative values for top/left. + nOffsetX *= -1; + nOffsetY *= -1; + } + } + else + { + if (( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) || + ( eDockedArea == ui::DockingArea_DOCKINGAREA_RIGHT )) + { + // Docking before/after means move track rectangle half column/row. + // As left and top are ordered 0...n instead of right and bottom + // which uses n...0, we have to use negative values for top/left. + nOffsetX *= -1; + nOffsetY *= -1; + } + nRowCol++; + } + + if ( bHorizontalDockArea ) + rUIElement.m_aDockedData.m_aPos.Y() = nRowCol; + else + rUIElement.m_aDockedData.m_aPos.X() = nRowCol; + + rTrackingRect.Move( nOffsetX, nOffsetY ); + rTrackingRect.SetSize( aTrackingRect.GetSize() ); + } + } + } + } + + // Docking outside of our docking window area => + // Users want to dock before/after first/last docked element or to an empty docking area + if ( bOpOutsideOfDockingArea ) + { + // set correct size for docking + implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect ); + rTrackingRect = aTrackingRect; + + if ( bHorizontalDockArea ) + { + sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 ))); + if (( nPosX + rTrackingRect.getWidth()) > aContainerWinSize.Width() ) + nPosX = std::min( nPosX, + std::max( sal_Int32( aContainerWinSize.Width() - rTrackingRect.getWidth() ), + sal_Int32( 0 ))); + + sal_Int32 nSize = std::min( aContainerWinSize.Width(), rTrackingRect.getWidth() ); + sal_Int32 nDockHeight = std::max( static_cast<sal_Int32>(aDockingAreaRect.getHeight()), sal_Int32( 0 )); + if ( nDockHeight == 0 ) + { + sal_Int32 nPosY( std::max( aDockingAreaRect.Top(), aDockingAreaRect.Bottom() )); + if ( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) + nPosY -= rTrackingRect.getHeight(); + rTrackingRect.SetPos( Point( nPosX, nPosY )); + rUIElement.m_aDockedData.m_aPos.Y() = 0; + } + else if ( rMousePos.Y() < ( aDockingAreaRect.Top() + ( nDockHeight / 2 ))) + { + rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Top() - rTrackingRect.getHeight() )); + if ( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) + rUIElement.m_aDockedData.m_aPos.Y() = 0; + else + rUIElement.m_aDockedData.m_aPos.Y() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; + rDockingOperation = DOCKOP_BEFORE_COLROW; + } + else + { + rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Bottom() )); + if ( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) + rUIElement.m_aDockedData.m_aPos.Y() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; + else + rUIElement.m_aDockedData.m_aPos.Y() = 0; + rDockingOperation = DOCKOP_AFTER_COLROW; + } + rTrackingRect.setWidth( nSize ); + + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + nPosX = pDockingAreaWindow->ScreenToOutputPixel( + pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).X(); + } + rUIElement.m_aDockedData.m_aPos.X() = nPosX; + } + else + { + sal_Int32 nMaxDockingAreaHeight = std::max( sal_Int32( 0 ), + sal_Int32( nMaxLeftRightDockAreaSize )); + + sal_Int32 nPosY( std::max( sal_Int32( aTrackingRect.Top()), sal_Int32( nTopDockingAreaSize ))); + if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight )) + nPosY = std::min( nPosY, + std::max( sal_Int32( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() )), + sal_Int32( nTopDockingAreaSize ))); + + sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) ); + sal_Int32 nDockWidth = std::max( static_cast<sal_Int32>(aDockingAreaRect.getWidth()), sal_Int32( 0 )); + if ( nDockWidth == 0 ) + { + sal_Int32 nPosX( std::max( aDockingAreaRect.Left(), aDockingAreaRect.Right() )); + if ( eDockedArea == ui::DockingArea_DOCKINGAREA_RIGHT ) + nPosX -= rTrackingRect.getWidth(); + rTrackingRect.SetPos( Point( nPosX, nPosY )); + rUIElement.m_aDockedData.m_aPos.X() = 0; + } + else if ( rMousePos.X() < ( aDockingAreaRect.Left() + ( nDockWidth / 2 ))) + { + rTrackingRect.SetPos( Point( aDockingAreaRect.Left() - rTrackingRect.getWidth(), nPosY )); + if ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT ) + rUIElement.m_aDockedData.m_aPos.X() = 0; + else + rUIElement.m_aDockedData.m_aPos.X() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; + rDockingOperation = DOCKOP_BEFORE_COLROW; + } + else + { + rTrackingRect.SetPos( Point( aDockingAreaRect.Right(), nPosY )); + if ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT ) + rUIElement.m_aDockedData.m_aPos.X() = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0; + else + rUIElement.m_aDockedData.m_aPos.X() = 0; + rDockingOperation = DOCKOP_AFTER_COLROW; + } + rTrackingRect.setHeight( nSize ); + + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + nPosY = pDockingAreaWindow->ScreenToOutputPixel( + pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).Y(); + } + rUIElement.m_aDockedData.m_aPos.Y() = nPosY; + } + } +} + +framework::ToolbarLayoutManager::DockingOperation ToolbarLayoutManager::implts_determineDockingOperation( + ui::DockingArea DockingArea, + const ::Rectangle& rRowColRect, + const Point& rMousePos ) +{ + const sal_Int32 nHorzVerticalRegionSize = 6; + const sal_Int32 nHorzVerticalMoveRegion = 4; + + if ( rRowColRect.IsInside( rMousePos )) + { + if (( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )) + { + sal_Int32 nRegion = rRowColRect.getHeight() / nHorzVerticalRegionSize; + sal_Int32 nPosY = rRowColRect.Top() + nRegion; + + if ( rMousePos.Y() < nPosY ) + return ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW; + else if ( rMousePos.Y() < ( nPosY + nRegion*nHorzVerticalMoveRegion )) + return DOCKOP_ON_COLROW; + else + return ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW; + } + else + { + sal_Int32 nRegion = rRowColRect.getWidth() / nHorzVerticalRegionSize; + sal_Int32 nPosX = rRowColRect.Left() + nRegion; + + if ( rMousePos.X() < nPosX ) + return ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW; + else if ( rMousePos.X() < ( nPosX + nRegion*nHorzVerticalMoveRegion )) + return DOCKOP_ON_COLROW; + else + return ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW; + } + } + else + return DOCKOP_ON_COLROW; +} + +::Rectangle ToolbarLayoutManager::implts_calcTrackingAndElementRect( + ui::DockingArea eDockingArea, + sal_Int32 nRowCol, + UIElement& rUIElement, + const ::Rectangle& rTrackingRect, + const ::Rectangle& rRowColumnRect, + const ::Size& rContainerWinSize ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadGuard( m_aLock ); + ::Rectangle aDockingAreaOffsets( m_aDockingAreaOffsets ); + aReadGuard.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + sal_Bool bHorizontalDockArea(( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )); + + sal_Int32 nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() ); + sal_Int32 nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() ); + + sal_Int32 nMaxLeftRightDockAreaSize = rContainerWinSize.Height() - + nTopDockingAreaSize - + nBottomDockingAreaSize - + aDockingAreaOffsets.Top() - + aDockingAreaOffsets.Bottom(); + + ::Rectangle aTrackingRect( rTrackingRect ); + if ( bHorizontalDockArea ) + { + sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 ))); + if (( nPosX + rTrackingRect.getWidth()) > rContainerWinSize.Width() ) + nPosX = std::min( nPosX, + std::max( sal_Int32( rContainerWinSize.Width() - rTrackingRect.getWidth() ), + sal_Int32( 0 ))); + + sal_Int32 nSize = std::min( rContainerWinSize.Width(), rTrackingRect.getWidth() ); + + aTrackingRect.SetPos( ::Point( nPosX, rRowColumnRect.Top() )); + aTrackingRect.setWidth( nSize ); + aTrackingRect.setHeight( rRowColumnRect.getHeight() ); + + // Set virtual position + rUIElement.m_aDockedData.m_aPos.X() = nPosX; + rUIElement.m_aDockedData.m_aPos.Y() = nRowCol; + } + else + { + sal_Int32 nMaxDockingAreaHeight = std::max( sal_Int32( 0 ), + sal_Int32( nMaxLeftRightDockAreaSize )); + + sal_Int32 nPosY( std::max( sal_Int32( aTrackingRect.Top()), sal_Int32( nTopDockingAreaSize ))); + if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight )) + nPosY = std::min( nPosY, + std::max( sal_Int32( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() )), + sal_Int32( nTopDockingAreaSize ))); + + sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) ); + + aTrackingRect.SetPos( ::Point( rRowColumnRect.Left(), nPosY )); + aTrackingRect.setWidth( rRowColumnRect.getWidth() ); + aTrackingRect.setHeight( nSize ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aReadGuard.lock(); + uno::Reference< awt::XWindow > xDockingAreaWindow = m_xDockAreaWindows[eDockingArea]; + uno::Reference< awt::XWindow2 > xContainerWindow = m_xContainerWindow; + aReadGuard.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + sal_Int32 nDockPosY( 0 ); + Window* pDockingAreaWindow( 0 ); + Window* pContainerWindow( 0 ); + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow ); + pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + nDockPosY = pDockingAreaWindow->ScreenToOutputPixel( + pContainerWindow->OutputToScreenPixel( ::Point( 0, nPosY ))).Y(); + } + + // Set virtual position + rUIElement.m_aDockedData.m_aPos.X() = nRowCol; + rUIElement.m_aDockedData.m_aPos.Y() = nDockPosY; + } + + return aTrackingRect; +} + +void ToolbarLayoutManager::implts_setTrackingRect( ui::DockingArea eDockingArea, const ::Point& rMousePos, ::Rectangle& rTrackingRect ) +{ + sal_Bool bHorizontalDockArea( ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )); + + ::Point aPoint = rTrackingRect.TopLeft(); + if ( bHorizontalDockArea ) + aPoint.X() = rMousePos.X(); + else + aPoint.Y() = rMousePos.Y(); + + rTrackingRect.SetPos( aPoint ); +} + +void ToolbarLayoutManager::implts_renumberRowColumnData( + ui::DockingArea eDockingArea, + DockingOperation /*eDockingOperation*/, + const UIElement& rUIElement ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState ); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + sal_Bool bHorzDockingArea(( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || + ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )); + sal_Int32 nRowCol( bHorzDockingArea ? rUIElement.m_aDockedData.m_aPos.Y() : + rUIElement.m_aDockedData.m_aPos.X() ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + UIElementVector::iterator pIter; + for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); pIter++ ) + { + if (( pIter->m_aDockedData.m_nDockedArea == sal_Int16( eDockingArea )) && + ( pIter->m_aName != rUIElement.m_aName )) + { + // Don't change toolbars without a valid docking position! + if (( pIter->m_aDockedData.m_aPos.X() == SAL_MAX_INT32 ) && + ( pIter->m_aDockedData.m_aPos.Y() == SAL_MAX_INT32 )) + continue; + + sal_Int32 nWindowRowCol = ( bHorzDockingArea ) ? + pIter->m_aDockedData.m_aPos.Y() : pIter->m_aDockedData.m_aPos.X(); + if ( nWindowRowCol >= nRowCol ) + { + if ( bHorzDockingArea ) + pIter->m_aDockedData.m_aPos.Y() += 1; + else + pIter->m_aDockedData.m_aPos.X() += 1; + } + } + } + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + // We have to change the persistent window state part + if ( xPersistentWindowState.is() ) + { + try + { + uno::Sequence< ::rtl::OUString > aWindowElements = xPersistentWindowState->getElementNames(); + for ( sal_Int32 i = 0; i < aWindowElements.getLength(); i++ ) + { + if ( rUIElement.m_aName != aWindowElements[i] ) + { + try + { + uno::Sequence< beans::PropertyValue > aPropValueSeq; + awt::Point aDockedPos; + ui::DockingArea nDockedArea( ui::DockingArea_DOCKINGAREA_DEFAULT ); + + xPersistentWindowState->getByName( aWindowElements[i] ) >>= aPropValueSeq; + for ( sal_Int32 j = 0; j < aPropValueSeq.getLength(); j++ ) + { + if ( aPropValueSeq[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKINGAREA )) + aPropValueSeq[j].Value >>= nDockedArea; + else if ( aPropValueSeq[j].Name.equalsAscii( WINDOWSTATE_PROPERTY_DOCKPOS )) + aPropValueSeq[j].Value >>= aDockedPos; + } + + // Don't change toolbars without a valid docking position! + if (( aDockedPos.X == SAL_MAX_INT32 ) && ( aDockedPos.Y == SAL_MAX_INT32 )) + continue; + + sal_Int32 nWindowRowCol = ( bHorzDockingArea ) ? aDockedPos.Y : aDockedPos.X; + if (( nDockedArea == eDockingArea ) && ( nWindowRowCol >= nRowCol )) + { + if ( bHorzDockingArea ) + aDockedPos.Y += 1; + else + aDockedPos.X += 1; + + uno::Reference< container::XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY ); + xReplace->replaceByName( aWindowElements[i], makeAny( aPropValueSeq )); + } + } + catch ( uno::Exception& ) + { + } + } + } + } + catch ( uno::Exception& ) + { + } + } +} + +//--------------------------------------------------------------------------------------------------------- +// XDockableWindowListener +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL ToolbarLayoutManager::startDocking( + const awt::DockingEvent& e ) +throw (uno::RuntimeException) +{ + sal_Bool bWinFound( sal_False ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadGuard( m_aLock ); + uno::Reference< css::awt::XWindow2 > xContainerWindow( m_xContainerWindow ); + uno::Reference< css::awt::XWindow2 > xWindow( e.Source, uno::UNO_QUERY ); + aReadGuard.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + Window* pContainerWindow( 0 ); + Window* pWindow( 0 ); + ::Point aMousePos; + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + aMousePos = pContainerWindow->ScreenToOutputPixel( ::Point( e.MousePos.X, e.MousePos.Y )); + } + + UIElement aUIElement = implts_findElement( e.Source ); + + if ( aUIElement.m_xUIElement.is() && xWindow.is() ) + { + awt::Rectangle aRect; + uno::Reference< css::awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); + if ( xDockWindow->isFloating() ) + { + awt::Rectangle aPos = xWindow->getPosSize(); + awt::Size aSize = xWindow->getOutputSize(); + + aUIElement.m_aFloatingData.m_aPos = ::Point( aPos.X, aPos.Y ); + aUIElement.m_aFloatingData.m_aSize = ::Size( aSize.Width, aSize.Height ); + + vos::OGuard aGuard( Application::GetSolarMutex() ); + pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + { + ToolBox* pToolBox = (ToolBox *)pWindow; + aUIElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines(); + aUIElement.m_aFloatingData.m_bIsHorizontal = (( pToolBox->GetAlign() == WINDOWALIGN_TOP ) || + ( pToolBox->GetAlign() == WINDOWALIGN_BOTTOM )); + } + } + } + + WriteGuard aWriteLock( m_aLock ); + m_bDockingInProgress = bWinFound; + m_aDockUIElement = aUIElement; + m_aDockUIElement.m_bUserActive = sal_True; + m_aStartDockMousePos = aMousePos; + aWriteLock.unlock(); +} + +awt::DockingData SAL_CALL ToolbarLayoutManager::docking( + const awt::DockingEvent& e ) +throw (uno::RuntimeException) +{ + const sal_Int32 MAGNETIC_DISTANCE_UNDOCK = 25; + const sal_Int32 MAGNETIC_DISTANCE_DOCK = 20; + + awt::DockingData aDockingData; + uno::Reference< awt::XDockableWindow > xDockWindow( e.Source, uno::UNO_QUERY ); + uno::Reference< awt::XWindow > xWindow( e.Source, uno::UNO_QUERY ); + uno::Reference< awt::XWindow > xTopDockingWindow; + uno::Reference< awt::XWindow > xLeftDockingWindow; + uno::Reference< awt::XWindow > xRightDockingWindow; + uno::Reference< awt::XWindow > xBottomDockingWindow; + uno::Reference< awt::XWindow2 > xContainerWindow; + UIElement aUIDockingElement; + DockingOperation eDockingOperation( DOCKOP_ON_COLROW ); + + aDockingData.TrackingRectangle = e.TrackingRectangle; + sal_Bool bDockingInProgress; + + { + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + bDockingInProgress = m_bDockingInProgress; + if ( bDockingInProgress ) + { + xContainerWindow = m_xContainerWindow; + xTopDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP]; + xLeftDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT]; + xRightDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT]; + xBottomDockingWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM]; + aUIDockingElement = m_aDockUIElement; + } + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + } + + if ( bDockingInProgress && xDockWindow.is() && xWindow.is() ) + { + try + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + sal_Int16 eDockingArea( -1 ); // none + sal_Int32 nMagneticZone( aUIDockingElement.m_bFloating ? MAGNETIC_DISTANCE_DOCK : MAGNETIC_DISTANCE_UNDOCK ); + awt::Rectangle aNewTrackingRect; + ::Rectangle aTrackingRect( e.TrackingRectangle.X, + e.TrackingRectangle.Y, + ( e.TrackingRectangle.X + e.TrackingRectangle.Width ), + ( e.TrackingRectangle.Y + e.TrackingRectangle.Height )); + + awt::Rectangle aTmpRect = xTopDockingWindow->getPosSize(); + ::Rectangle aTopDockRect( aTmpRect.X, aTmpRect.Y, aTmpRect.Width, aTmpRect.Height ); + ::Rectangle aHotZoneTopDockRect( implts_calcHotZoneRect( aTopDockRect, nMagneticZone )); + + aTmpRect = xBottomDockingWindow->getPosSize(); + ::Rectangle aBottomDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width), ( aTmpRect.Y + aTmpRect.Height )); + ::Rectangle aHotZoneBottomDockRect( implts_calcHotZoneRect( aBottomDockRect, nMagneticZone )); + + aTmpRect = xLeftDockingWindow->getPosSize(); + ::Rectangle aLeftDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height )); + ::Rectangle aHotZoneLeftDockRect( implts_calcHotZoneRect( aLeftDockRect, nMagneticZone )); + + aTmpRect = xRightDockingWindow->getPosSize(); + ::Rectangle aRightDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height )); + ::Rectangle aHotZoneRightDockRect( implts_calcHotZoneRect( aRightDockRect, nMagneticZone )); + + Window* pContainerWindow( VCLUnoHelper::GetWindow( xContainerWindow ) ); + Window* pDockingAreaWindow( 0 ); + ::Point aMousePos( pContainerWindow->ScreenToOutputPixel( ::Point( e.MousePos.X, e.MousePos.Y ))); + + if ( aHotZoneTopDockRect.IsInside( aMousePos )) + eDockingArea = ui::DockingArea_DOCKINGAREA_TOP; + else if ( aHotZoneBottomDockRect.IsInside( aMousePos )) + eDockingArea = ui::DockingArea_DOCKINGAREA_BOTTOM; + else if ( aHotZoneLeftDockRect.IsInside( aMousePos )) + eDockingArea = ui::DockingArea_DOCKINGAREA_LEFT; + else if ( aHotZoneRightDockRect.IsInside( aMousePos )) + eDockingArea = ui::DockingArea_DOCKINGAREA_RIGHT; + + // Higher priority for movements inside the real docking area + if ( aTopDockRect.IsInside( aMousePos )) + eDockingArea = ui::DockingArea_DOCKINGAREA_TOP; + else if ( aBottomDockRect.IsInside( aMousePos )) + eDockingArea = ui::DockingArea_DOCKINGAREA_BOTTOM; + else if ( aLeftDockRect.IsInside( aMousePos )) + eDockingArea = ui::DockingArea_DOCKINGAREA_LEFT; + else if ( aRightDockRect.IsInside( aMousePos )) + eDockingArea = ui::DockingArea_DOCKINGAREA_RIGHT; + + // Determine if we have a toolbar and set alignment according to the docking area! + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + ToolBox* pToolBox = 0; + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + pToolBox = (ToolBox *)pWindow; + + if ( eDockingArea != -1 ) + { + if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP ) + { + aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_TOP; + aUIDockingElement.m_bFloating = sal_False; + pDockingAreaWindow = VCLUnoHelper::GetWindow( xTopDockingWindow ); + } + else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) + { + aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_BOTTOM; + aUIDockingElement.m_bFloating = sal_False; + pDockingAreaWindow = VCLUnoHelper::GetWindow( xBottomDockingWindow ); + } + else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) + { + aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_LEFT; + aUIDockingElement.m_bFloating = sal_False; + pDockingAreaWindow = VCLUnoHelper::GetWindow( xLeftDockingWindow ); + } + else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_RIGHT ) + { + aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_RIGHT; + aUIDockingElement.m_bFloating = sal_False; + pDockingAreaWindow = VCLUnoHelper::GetWindow( xRightDockingWindow ); + } + + ::Point aOutputPos = pContainerWindow->ScreenToOutputPixel( aTrackingRect.TopLeft() ); + aTrackingRect.SetPos( aOutputPos ); + + ::Rectangle aNewDockingRect( aTrackingRect ); + implts_calcDockingPosSize( aUIDockingElement, eDockingOperation, aNewDockingRect, aMousePos ); + + ::Point aScreenPos = pContainerWindow->OutputToScreenPixel( aNewDockingRect.TopLeft() ); + aNewTrackingRect = css::awt::Rectangle( aScreenPos.X(), + aScreenPos.Y(), + aNewDockingRect.getWidth(), + aNewDockingRect.getHeight() ); + aDockingData.TrackingRectangle = aNewTrackingRect; + } + else if ( pToolBox && bDockingInProgress ) + { + sal_Bool bIsHorizontal = (( pToolBox->GetAlign() == WINDOWALIGN_TOP ) || + ( pToolBox->GetAlign() == WINDOWALIGN_BOTTOM )); + ::Size aFloatSize = aUIDockingElement.m_aFloatingData.m_aSize; + if ( aFloatSize.Width() > 0 && aFloatSize.Height() > 0 ) + { + aUIDockingElement.m_aFloatingData.m_aPos = pContainerWindow->ScreenToOutputPixel( + ::Point( e.MousePos.X, e.MousePos.Y )); + aDockingData.TrackingRectangle.Height = aFloatSize.Height(); + aDockingData.TrackingRectangle.Width = aFloatSize.Width(); + } + else + { + aFloatSize = pToolBox->CalcWindowSizePixel(); + if ( !bIsHorizontal ) + { + // Floating toolbars are always horizontal aligned! We have to swap + // width/height if we have a vertical aligned toolbar. + sal_Int32 nTemp = aFloatSize.Height(); + aFloatSize.Height() = aFloatSize.Width(); + aFloatSize.Width() = nTemp; + } + + aDockingData.TrackingRectangle.Height = aFloatSize.Height(); + aDockingData.TrackingRectangle.Width = aFloatSize.Width(); + + // For the first time we don't have any data about the floating size of a toolbar. + // We calculate it and store it for later use. + aUIDockingElement.m_aFloatingData.m_aPos = pContainerWindow->ScreenToOutputPixel( + ::Point( e.MousePos.X, e.MousePos.Y )); + aUIDockingElement.m_aFloatingData.m_aSize = aFloatSize; + aUIDockingElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines(); + aUIDockingElement.m_aFloatingData.m_bIsHorizontal = (( pToolBox->GetAlign() == WINDOWALIGN_TOP ) || + ( pToolBox->GetAlign() == WINDOWALIGN_BOTTOM )); + } + aDockingData.TrackingRectangle.X = e.MousePos.X; + aDockingData.TrackingRectangle.Y = e.MousePos.Y; + } + + aDockingData.bFloating = ( eDockingArea == -1 ); + + // Write current data to the member docking progress data + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_aDockUIElement.m_bFloating = aDockingData.bFloating; + if ( !aDockingData.bFloating ) + { + m_aDockUIElement.m_aDockedData = aUIDockingElement.m_aDockedData; + m_eDockOperation = eDockingOperation; + } + else + m_aDockUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + } + catch ( uno::Exception& ) + { + } + } + + return aDockingData; +} + +void SAL_CALL ToolbarLayoutManager::endDocking( + const awt::EndDockingEvent& e ) +throw (uno::RuntimeException) +{ + bool bDockingInProgress( false ); + bool bStartDockFloated( false ); + bool bFloating( false ); + UIElement aUIDockingElement; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + bDockingInProgress = m_bDockingInProgress; + aUIDockingElement = m_aDockUIElement; + bFloating = aUIDockingElement.m_bFloating; + + UIElement& rUIElement = impl_findElement( aUIDockingElement.m_aName ); + if ( rUIElement.m_aName == aUIDockingElement.m_aName ) + { + if ( aUIDockingElement.m_bFloating ) + { + // Write last position into position data + uno::Reference< awt::XWindow > xWindow( aUIDockingElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY ); + rUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData; + awt::Rectangle aTmpRect = xWindow->getPosSize(); + rUIElement.m_aFloatingData.m_aPos = ::Point( aTmpRect.X, aTmpRect.Y ); + // make changes also for our local data as we use it to make data persistent + aUIDockingElement.m_aFloatingData = rUIElement.m_aFloatingData; + } + else + { + rUIElement.m_aDockedData = aUIDockingElement.m_aDockedData; + rUIElement.m_aFloatingData.m_aSize = aUIDockingElement.m_aFloatingData.m_aSize; + + if ( m_eDockOperation != DOCKOP_ON_COLROW ) + { + // we have to renumber our row/column data to insert a new row/column + implts_renumberRowColumnData( (::com::sun::star::ui::DockingArea)aUIDockingElement.m_aDockedData.m_nDockedArea, + m_eDockOperation, + aUIDockingElement ); + } + } + + bStartDockFloated = rUIElement.m_bFloating; + rUIElement.m_bFloating = m_aDockUIElement.m_bFloating; + rUIElement.m_bUserActive = sal_True; + } + + // reset member for next docking operation + m_aDockUIElement.m_xUIElement.clear(); + m_eDockOperation = DOCKOP_ON_COLROW; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + implts_writeWindowStateData( aUIDockingElement.m_aName, aUIDockingElement ); + + if ( bDockingInProgress ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( uno::Reference< awt::XWindow >( e.Source, uno::UNO_QUERY )); + ToolBox* pToolBox = 0; + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + pToolBox = (ToolBox *)pWindow; + + if ( pToolBox ) + { + if( e.bFloating ) + { + if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal ) + pToolBox->SetAlign( WINDOWALIGN_TOP ); + else + pToolBox->SetAlign( WINDOWALIGN_LEFT ); + } + else + { + ::Size aSize; + + pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) ); + + // Docked toolbars have always one line + aSize = pToolBox->CalcWindowSizePixel( 1 ); + + // Lock layouting updates as our listener would be called due to SetSizePixel + pToolBox->SetOutputSizePixel( aSize ); + } + } + } + + implts_sortUIElements(); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + aWriteLock.lock(); + m_bDockingInProgress = sal_False; + m_bLayoutDirty = !bStartDockFloated || !bFloating; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +sal_Bool SAL_CALL ToolbarLayoutManager::prepareToggleFloatingMode( + const lang::EventObject& e ) +throw (uno::RuntimeException) +{ + sal_Bool bDockingInProgress( sal_False ); + + ReadGuard aReadLock( m_aLock ); + bDockingInProgress = m_bDockingInProgress; + aReadLock.unlock(); + + UIElement aUIDockingElement = implts_findElement( e.Source ); + bool bWinFound( aUIDockingElement.m_aName.getLength() > 0 ); + uno::Reference< awt::XWindow > xWindow( e.Source, uno::UNO_QUERY ); + + if ( bWinFound && xWindow.is() ) + { + if ( !bDockingInProgress ) + { + awt::Rectangle aRect; + uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); + if ( xDockWindow->isFloating() ) + { + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + { + if ( pWindow->GetType() == WINDOW_TOOLBOX ) + { + ToolBox* pToolBox = (ToolBox *)pWindow; + aUIDockingElement.m_aFloatingData.m_aPos = pToolBox->GetPosPixel(); + aUIDockingElement.m_aFloatingData.m_aSize = pToolBox->GetOutputSizePixel(); + aUIDockingElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines(); + aUIDockingElement.m_aFloatingData.m_bIsHorizontal = (( pToolBox->GetAlign() == WINDOWALIGN_TOP ) || + ( pToolBox->GetAlign() == WINDOWALIGN_BOTTOM )); + } + } + } + + UIElement aUIElement = implts_findElement( aUIDockingElement.m_aName ); + if ( aUIElement.m_aName == aUIDockingElement.m_aName ) + implts_setElement( aUIDockingElement ); + } + } + } + + return sal_True; +} + +void SAL_CALL ToolbarLayoutManager::toggleFloatingMode( + const lang::EventObject& e ) +throw (uno::RuntimeException) +{ + sal_Bool bDockingInProgress( sal_False ); + UIElement aUIDockingElement; + + ReadGuard aReadLock( m_aLock ); + bDockingInProgress = m_bDockingInProgress; + if ( bDockingInProgress ) + aUIDockingElement = m_aDockUIElement; + aReadLock.unlock(); + + Window* pWindow( 0 ); + ToolBox* pToolBox( 0 ); + uno::Reference< css::awt::XWindow2 > xWindow; + + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + xWindow = uno::Reference< awt::XWindow2 >( e.Source, uno::UNO_QUERY ); + pWindow = VCLUnoHelper::GetWindow( xWindow ); + + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + pToolBox = (ToolBox *)pWindow; + } + + if ( !bDockingInProgress ) + { + aUIDockingElement = implts_findElement( e.Source ); + bool bWinFound = ( aUIDockingElement.m_aName.getLength() > 0 ); + + if ( bWinFound && xWindow.is() ) + { + aUIDockingElement.m_bFloating = !aUIDockingElement.m_bFloating; + aUIDockingElement.m_bUserActive = sal_True; + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_bLayoutDirty = true; + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( aUIDockingElement.m_bFloating ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( pToolBox ) + { + pToolBox->SetLineCount( aUIDockingElement.m_aFloatingData.m_nLines ); + if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal ) + pToolBox->SetAlign( WINDOWALIGN_TOP ); + else + pToolBox->SetAlign( WINDOWALIGN_LEFT ); + } + + sal_Bool bUndefPos = ( aUIDockingElement.m_aFloatingData.m_aPos.X() == SAL_MAX_INT32 || + aUIDockingElement.m_aFloatingData.m_aPos.Y() == SAL_MAX_INT32 ); + sal_Bool bSetSize = ( aUIDockingElement.m_aFloatingData.m_aSize.Width() != 0 && + aUIDockingElement.m_aFloatingData.m_aSize.Height() != 0 ); + + if ( bUndefPos ) + aUIDockingElement.m_aFloatingData.m_aPos = implts_findNextCascadeFloatingPos(); + + if ( !bSetSize ) + { + if ( pToolBox ) + aUIDockingElement.m_aFloatingData.m_aSize = pToolBox->CalcFloatingWindowSizePixel(); + else + aUIDockingElement.m_aFloatingData.m_aSize = pWindow->GetOutputSizePixel(); + } + + xWindow->setPosSize( aUIDockingElement.m_aFloatingData.m_aPos.X(), + aUIDockingElement.m_aFloatingData.m_aPos.Y(), + 0, 0, css::awt::PosSize::POS ); + xWindow->setOutputSize( AWTSize( aUIDockingElement.m_aFloatingData.m_aSize ) ); + } + else + { + if (( aUIDockingElement.m_aDockedData.m_aPos.X() == SAL_MAX_INT32 ) && + ( aUIDockingElement.m_aDockedData.m_aPos.Y() == SAL_MAX_INT32 )) + { + // Docking on its default position without a preset position - + // we have to find a good place for it. + ::Point aPixelPos; + ::Point aDockPos; + ::Size aSize; + + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( pToolBox ) + aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea ) ); + else + aSize = pWindow->GetSizePixel(); + } + + implts_findNextDockingPos( (::com::sun::star::ui::DockingArea)aUIDockingElement.m_aDockedData.m_nDockedArea, + aSize, + aDockPos, + aPixelPos ); + aUIDockingElement.m_aDockedData.m_aPos = aDockPos; + } + + vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( pToolBox ) + { + pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) ); + ::Size aSize = pToolBox->CalcWindowSizePixel( 1 ); + css::awt::Rectangle aRect = xWindow->getPosSize(); + xWindow->setPosSize( aRect.X, aRect.Y, 0, 0, css::awt::PosSize::POS ); + xWindow->setOutputSize( AWTSize( aSize ) ); + } + } + + aWriteLock.lock(); + UIElement& rUIElement = impl_findElement( aUIDockingElement.m_aName ); + if ( rUIElement.m_aName == aUIDockingElement.m_aName ) + rUIElement = aUIDockingElement; + m_bLayoutDirty = true; + aWriteLock.unlock(); + + implts_writeWindowStateData( aUIDockingElement.m_aName, aUIDockingElement ); + implts_sortUIElements(); + } + } + else + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + if ( pToolBox ) + { + if ( aUIDockingElement.m_bFloating ) + { + if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal ) + pToolBox->SetAlign( WINDOWALIGN_TOP ); + else + pToolBox->SetAlign( WINDOWALIGN_LEFT ); + } + else + { + pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) ); + } + } + } +} + +void SAL_CALL ToolbarLayoutManager::closed( + const lang::EventObject& /*e*/ ) +throw (uno::RuntimeException) +{ +} + +void SAL_CALL ToolbarLayoutManager::endPopupMode( + const awt::EndPopupModeEvent& /*e*/ ) +throw (uno::RuntimeException) +{ +} + +//--------------------------------------------------------------------------------------------------------- +// XUIConfigurationListener +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL ToolbarLayoutManager::elementInserted( + const ui::ConfigurationEvent& /*Event*/ ) +throw (uno::RuntimeException) +{ +} + +void SAL_CALL ToolbarLayoutManager::elementRemoved( + const ui::ConfigurationEvent& /*Event*/ ) +throw (uno::RuntimeException) +{ +} + +void SAL_CALL ToolbarLayoutManager::elementReplaced( + const ui::ConfigurationEvent& /*Event*/ ) +throw (uno::RuntimeException) +{ +} + +//--------------------------------------------------------------------------------------------------------- +// XLayoutManager forwards +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL ToolbarLayoutManager::createElement( const ::rtl::OUString& /*aName*/ ) +throw (uno::RuntimeException) +{ +} + +void SAL_CALL ToolbarLayoutManager::destroyElement( const ::rtl::OUString& /*aName*/ ) +throw (uno::RuntimeException) +{ +} + +::sal_Bool SAL_CALL ToolbarLayoutManager::requestElement( const ::rtl::OUString& /*ResourceURL*/ ) +throw (uno::RuntimeException) +{ + return false; +} + +uno::Reference< ui::XUIElement > SAL_CALL ToolbarLayoutManager::getElement( const ::rtl::OUString& /*aName*/ ) +throw (uno::RuntimeException) +{ + return uno::Reference< ui::XUIElement >(); +} + +uno::Sequence< uno::Reference< ui::XUIElement > > SAL_CALL ToolbarLayoutManager::getElements() +throw (uno::RuntimeException) +{ + return uno::Sequence< uno::Reference< ui::XUIElement > >(); +} + +sal_Bool SAL_CALL ToolbarLayoutManager::showElement( const ::rtl::OUString& /*aName*/ ) +throw (uno::RuntimeException) +{ + return false; +} + +sal_Bool SAL_CALL ToolbarLayoutManager::hideElement( const ::rtl::OUString& /*aName*/ ) +throw (uno::RuntimeException) +{ + return false; +} + +sal_Bool SAL_CALL ToolbarLayoutManager::dockWindow( const ::rtl::OUString& /*aName*/, ui::DockingArea /*DockingArea*/, const awt::Point& /*Pos*/ ) +throw (uno::RuntimeException) +{ +/* + UIElement& rUIElement = impl_findElement( aUIElement.m_aName ); + + if ( rUIElement.m_xUIElement.is() ) + { + try + { + uno::Reference< awt::XWindow > xWindow( rUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY ); + uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY ); + if ( xDockWindow.is() ) + { + if ( DockingArea != DockingArea_DOCKINGAREA_DEFAULT ) + aUIElement.m_aDockedData.m_nDockedArea = sal_Int16( DockingArea ); + + if (( Pos.X != SAL_MAX_INT32 ) && ( Pos.Y != SAL_MAX_INT32 )) + aUIElement.m_aDockedData.m_aPos = ::Point( Pos.X, Pos.Y ); + + if ( !xDockWindow->isFloating() ) + { + Window* pWindow( 0 ); + ToolBox* pToolBox( 0 ); + + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + { + pToolBox = (ToolBox *)pWindow; + + // We have to set the alignment of the toolbox. It's possible that the toolbox is moved from a + // horizontal to a vertical docking area! + pToolBox->SetAlign( ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea )); + } + } + + if (( aUIElement.m_aDockedData.m_aPos.X() == SAL_MAX_INT32 ) || + ( aUIElement.m_aDockedData.m_aPos.Y() == SAL_MAX_INT32 )) + { + // Docking on its default position without a preset position - + // we have to find a good place for it. + ::Size aSize; + + vos::OGuard aGuard( Application::GetSolarMutex() ); + { + if ( pToolBox ) + aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea ) ); + else + aSize = pWindow->GetSizePixel(); + } + + ::Point aPixelPos; + ::Point aDockPos; + implts_findNextDockingPos( (::com::sun::star::ui::DockingArea)aUIElement.m_aDockedData.m_nDockedArea, + aSize, + aDockPos, + aPixelPos ); + aUIElement.m_aDockedData.m_aPos = aDockPos; + } + } + + WriteGuard aWriteLock( m_aLock ); + UIElement& rUIElement = LayoutManager::impl_findElement( aUIElement.m_aName ); + if ( rUIElement.m_aName == aName ) + { + rUIElement.m_aDockedData.m_nDockedArea = aUIElement.m_aDockedData.m_nDockedArea; + rUIElement.m_aDockedData.m_aPos = aUIElement.m_aDockedData.m_aPos; + } + aWriteLock.unlock(); + + if ( xDockWindow->isFloating() ) + { + // Will call toggle floating mode which will do the rest! + xWindow->setVisible( sal_False ); + xDockWindow->setFloatingMode( sal_False ); + xWindow->setVisible( sal_True ); + } + else + { + implts_writeWindowStateData( aName, aUIElement ); + implts_sortUIElements(); + + if ( aUIElement.m_bVisible ) + { + m_bLayoutDirty = true; + } + } + + return sal_True; + } + } + catch ( uno::DisposedException& ) + { + } + } +*/ + return false; +} + +::sal_Bool SAL_CALL ToolbarLayoutManager::dockAllWindows( ::sal_Int16 /*nElementType*/ ) +throw (uno::RuntimeException) +{ + return false; +} + +sal_Bool SAL_CALL ToolbarLayoutManager::floatWindow( const ::rtl::OUString& /*aName*/ ) +throw (uno::RuntimeException) +{ + return false; +} + +::sal_Bool SAL_CALL ToolbarLayoutManager::lockWindow( const ::rtl::OUString& /*ResourceURL*/ ) +throw (uno::RuntimeException) +{ + return false; +} + +::sal_Bool SAL_CALL ToolbarLayoutManager::unlockWindow( const ::rtl::OUString& /*ResourceURL*/ ) +throw (uno::RuntimeException) +{ + return false; +} + +void SAL_CALL ToolbarLayoutManager::setElementSize( const ::rtl::OUString& /*aName*/, const awt::Size& /*aSize*/ ) +throw (uno::RuntimeException) +{ +} + +void SAL_CALL ToolbarLayoutManager::setElementPos( const ::rtl::OUString& /*aName*/, const awt::Point& /*aPos*/ ) +throw (uno::RuntimeException) +{ +} + +void SAL_CALL ToolbarLayoutManager::setElementPosSize( const ::rtl::OUString& /*aName*/, const awt::Point& /*aPos*/, const awt::Size& /*aSize*/ ) +throw (uno::RuntimeException) +{ +} + +sal_Bool SAL_CALL ToolbarLayoutManager::isElementVisible( const ::rtl::OUString& /*aName*/ ) +throw (uno::RuntimeException) +{ + return false; +} + +sal_Bool SAL_CALL ToolbarLayoutManager::isElementFloating( const ::rtl::OUString& /*aName*/ ) +throw (uno::RuntimeException) +{ + return false; +} + +sal_Bool SAL_CALL ToolbarLayoutManager::isElementDocked( const ::rtl::OUString& /*aName*/ ) +throw (uno::RuntimeException) +{ + return false; +} + +::sal_Bool SAL_CALL ToolbarLayoutManager::isElementLocked( const ::rtl::OUString& /*ResourceURL*/ ) +throw (uno::RuntimeException) +{ + return false; +} + +awt::Size SAL_CALL ToolbarLayoutManager::getElementSize( const ::rtl::OUString& /*aName*/ ) +throw (uno::RuntimeException) +{ + return awt::Size(); +} + +awt::Point SAL_CALL ToolbarLayoutManager::getElementPos( const ::rtl::OUString& /*aName*/ ) +throw (uno::RuntimeException) +{ + return awt::Point(); +} + +} // namespace framework diff --git a/framework/source/layoutmanager/toolbarlayoutmanager.hxx b/framework/source/layoutmanager/toolbarlayoutmanager.hxx new file mode 100755 index 000000000000..95b27f69c9c9 --- /dev/null +++ b/framework/source/layoutmanager/toolbarlayoutmanager.hxx @@ -0,0 +1,318 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutmanager.hxx,v $ + * $Revision: 1.34 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef __FRAMEWORK_LAYOUTMANAGER_TOOLBARLAYOUTMANAGER_HXX_ +#define __FRAMEWORK_LAYOUTMANAGER_TOOLBARLAYOUTMANAGER_HXX_ + +/** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble + with solaris headers ... +*/ +#include <vector> + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <threadhelp/threadhelpbase.hxx> +#include <threadhelp/resetableguard.hxx> +#include <threadhelp/writeguard.hxx> +#include <threadhelp/readguard.hxx> +#include <macros/generic.hxx> +#include <macros/xinterface.hxx> +#include <macros/xtypeprovider.hxx> +#include <macros/xserviceinfo.hxx> +#include <stdtypes.h> +#include <properties.h> +#include <stdtypes.h> +#include <uiconfiguration/globalsettings.hxx> +#include <uiconfiguration/windowstateconfiguration.hxx> +#include <classes/addonsoptions.hxx> +#include <uielement/uielement.hxx> +#include <uielement/menubarmanager.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XTypeProvider.hpp> +#include <com/sun/star/frame/XLayoutManager.hpp> +#include <com/sun/star/ui/XUIConfigurationManager.hpp> +#include <com/sun/star/ui/XUIConfiguration.hpp> +#include <com/sun/star/frame/XModuleManager.hpp> +#include <com/sun/star/frame/XFrameActionListener.hpp> +#include <com/sun/star/awt/XWindowListener.hpp> +#include <com/sun/star/util/XURLTransformer.hpp> +#include <com/sun/star/ui/XUIElementFactory.hpp> +#include <com/sun/star/frame/XInplaceLayout.hpp> +#include <com/sun/star/ui/DockingArea.hpp> +#include <com/sun/star/awt/XTopWindow2.hpp> +#include <com/sun/star/awt/XWindow2.hpp> +#include <com/sun/star/awt/XDockableWindow.hpp> +#include <com/sun/star/awt/XDockableWindowListener.hpp> +#include <com/sun/star/frame/XMenuBarMergingAcceptor.hpp> +#include <com/sun/star/frame/XLayoutManagerEventBroadcaster.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <cppuhelper/implbase2.hxx> + + +namespace framework +{ + +class ToolbarLayoutManager : public ::cppu::WeakImplHelper2< ::com::sun::star::awt::XDockableWindowListener, + ::com::sun::star::ui::XUIConfigurationListener >, + private ThreadHelpBase // Struct for right initalization of mutex member! Must be first of baseclasses. +{ + public: + enum { DOCKINGAREAS_COUNT = 4 }; + + ToolbarLayoutManager( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xSMGR, + const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElementFactory >& xUIElementFactory ); + virtual ~ToolbarLayoutManager(); + + void reset(); + void attach( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame, + const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager >& xModuleCfgMgr, + const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager >& xDocCfgMgr, + const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& xPersistentWindowState ); + + void setParentWindow( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindowPeer >& xParentWindow ); + void setDockingAreaOffsets( const ::Rectangle aOffsets ); + + void resetDockingArea(); + + ::com::sun::star::awt::Rectangle getDockingArea(); + void setDockingArea( const ::com::sun::star::awt::Rectangle& rDockingArea ); + + bool isLayoutDirty(); + void doLayout(const ::Size& aContainerSize); + + void createToolbars(); + void destroyToolbars(); + + bool createToolbar( const ::rtl::OUString& rResourceURL ); + bool destroyToolbar( const ::rtl::OUString& rResourceURL ); + void implts_createNonContextSensitiveToolBars(); + + // docking API + void dockToolbar( const ::rtl::OUString& rResourceURL, ::com::sun::star::ui::DockingArea eDockingArea, const ::com::sun::star::awt::Point& aPos ); + + //--------------------------------------------------------------------------------------------------------- + // XInterface + //--------------------------------------------------------------------------------------------------------- + virtual void SAL_CALL acquire() throw(); + virtual void SAL_CALL release() throw(); + virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw( ::com::sun::star::uno::RuntimeException ); + + //--------------------------------------------------------------------------------------------------------- + // XEventListener + //--------------------------------------------------------------------------------------------------------- + virtual void SAL_CALL disposing( const css::lang::EventObject& aEvent ) throw( css::uno::RuntimeException ); + + //--------------------------------------------------------------------------------------------------------- + // XDockableWindowListener + //--------------------------------------------------------------------------------------------------------- + virtual void SAL_CALL startDocking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::DockingData SAL_CALL docking( const ::com::sun::star::awt::DockingEvent& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL endDocking( const ::com::sun::star::awt::EndDockingEvent& e ) throw (::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL prepareToggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL toggleFloatingMode( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL closed( const ::com::sun::star::lang::EventObject& e ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL endPopupMode( const ::com::sun::star::awt::EndPopupModeEvent& e ) throw (::com::sun::star::uno::RuntimeException); + + //--------------------------------------------------------------------------------------------------------- + // XUIConfigurationListener + //--------------------------------------------------------------------------------------------------------- + virtual void SAL_CALL elementInserted( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL elementRemoved( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL elementReplaced( const ::com::sun::star::ui::ConfigurationEvent& Event ) throw (::com::sun::star::uno::RuntimeException); + + //--------------------------------------------------------------------------------------------------------- + // XLayoutManager forwards + //--------------------------------------------------------------------------------------------------------- + void SAL_CALL createElement( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + void SAL_CALL destroyElement( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + ::sal_Bool SAL_CALL requestElement( const ::rtl::OUString& ResourceURL ) throw (::com::sun::star::uno::RuntimeException); + ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement > SAL_CALL getElement( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement > > SAL_CALL getElements( ) throw (::com::sun::star::uno::RuntimeException); + sal_Bool SAL_CALL showElement( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + sal_Bool SAL_CALL hideElement( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + sal_Bool SAL_CALL dockWindow( const ::rtl::OUString& aName, ::com::sun::star::ui::DockingArea DockingArea, const ::com::sun::star::awt::Point& Pos ) throw (::com::sun::star::uno::RuntimeException); + ::sal_Bool SAL_CALL dockAllWindows( ::sal_Int16 nElementType ) throw (::com::sun::star::uno::RuntimeException); + sal_Bool SAL_CALL floatWindow( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + ::sal_Bool SAL_CALL lockWindow( const ::rtl::OUString& ResourceURL ) throw (::com::sun::star::uno::RuntimeException); + ::sal_Bool SAL_CALL unlockWindow( const ::rtl::OUString& ResourceURL ) throw (::com::sun::star::uno::RuntimeException); + void SAL_CALL setElementSize( const ::rtl::OUString& aName, const ::com::sun::star::awt::Size& aSize ) throw (::com::sun::star::uno::RuntimeException); + void SAL_CALL setElementPos( const ::rtl::OUString& aName, const ::com::sun::star::awt::Point& aPos ) throw (::com::sun::star::uno::RuntimeException); + void SAL_CALL setElementPosSize( const ::rtl::OUString& aName, const ::com::sun::star::awt::Point& aPos, const ::com::sun::star::awt::Size& aSize ) throw (::com::sun::star::uno::RuntimeException); + sal_Bool SAL_CALL isElementVisible( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + sal_Bool SAL_CALL isElementFloating( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + sal_Bool SAL_CALL isElementDocked( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + ::sal_Bool SAL_CALL isElementLocked( const ::rtl::OUString& ResourceURL ) throw (::com::sun::star::uno::RuntimeException); + ::com::sun::star::awt::Size SAL_CALL getElementSize( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + ::com::sun::star::awt::Point SAL_CALL getElementPos( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException); + + private: + enum DockingOperation + { + DOCKOP_BEFORE_COLROW, + DOCKOP_ON_COLROW, + DOCKOP_AFTER_COLROW + }; + + typedef std::vector< UIElement > UIElementVector; + struct SingleRowColumnWindowData + { + SingleRowColumnWindowData() : nVarSize( 0 ), nStaticSize( 0 ), nSpace( 0 ) {} + + std::vector< rtl::OUString > aUIElementNames; + std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow > > aRowColumnWindows; + std::vector< ::com::sun::star::awt::Rectangle > aRowColumnWindowSizes; + std::vector< sal_Int32 > aRowColumnSpace; + ::com::sun::star::awt::Rectangle aRowColumnRect; + sal_Int32 nVarSize; + sal_Int32 nStaticSize; + sal_Int32 nSpace; + sal_Int32 nRowColumn; + }; + + //--------------------------------------------------------------------------------------------------------- + // internal helper methods + //--------------------------------------------------------------------------------------------------------- + bool implts_isParentWindowVisible() const; + ::Rectangle implts_calcDockingArea(); + void implts_sortUIElements(); + void implts_reparentToolbars(); + rtl::OUString implts_generateGenericAddonToolbarTitle( sal_Int32 nNumber ) const; + void implts_setElementData( UIElement& rUIElement, const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDockableWindow >& rDockWindow ); + void implts_destroyDockingAreaWindows(); + + //--------------------------------------------------------------------------------------------------------- + // layout methods + //--------------------------------------------------------------------------------------------------------- + void implts_setDockingAreaWindowSizes( const ::com::sun::star::awt::Rectangle& rBorderSpace ); + ::Point implts_findNextCascadeFloatingPos(); + void implts_renumberRowColumnData( ::com::sun::star::ui::DockingArea eDockingArea, DockingOperation eDockingOperation, const UIElement& rUIElement ); + void implts_calcWindowPosSizeOnSingleRowColumn( sal_Int32 nDockingArea, + sal_Int32 nOffset, + SingleRowColumnWindowData& rRowColumnWindowData, + const ::Size& rContainerSize ); + + //--------------------------------------------------------------------------------------------------------- + // lookup/container methods + //--------------------------------------------------------------------------------------------------------- + UIElement implts_findElement( const rtl::OUString& aName ); + UIElement implts_findElement( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xToolbar ); + UIElement& impl_findElement( const rtl::OUString& aName ); + bool implts_insertElement( const UIElement& rUIElement ); + void implts_setElement( const UIElement& rUIElement ); + ::Size implts_getTopBottomDockingAreaSizes(); + + //--------------------------------------------------------------------------------------------------------- + // internal docking methods + //--------------------------------------------------------------------------------------------------------- + ::Rectangle implts_calcHotZoneRect( const ::Rectangle& rRect, sal_Int32 nHotZoneOffset ); + void implts_calcDockingPosSize( UIElement& aUIElement, DockingOperation& eDockOperation, ::Rectangle& rTrackingRect, const Point& rMousePos ); + DockingOperation implts_determineDockingOperation( ::com::sun::star::ui::DockingArea DockingArea, const ::Rectangle& rRowColRect, const Point& rMousePos ); + ::Rectangle implts_getWindowRectFromRowColumn( ::com::sun::star::ui::DockingArea DockingArea, const SingleRowColumnWindowData& rRowColumnWindowData, const ::Point& rMousePos, const rtl::OUString& rExcludeElementName ); + ::Rectangle implts_determineFrontDockingRect( ::com::sun::star::ui::DockingArea eDockingArea, + sal_Int32 nRowCol, + const ::Rectangle& rDockedElementRect, + const ::rtl::OUString& rMovedElementName, + const ::Rectangle& rMovedElementRect ); + ::Rectangle implts_calcTrackingAndElementRect( ::com::sun::star::ui::DockingArea eDockingArea, + sal_Int32 nRowCol, + UIElement& rUIElement, + const ::Rectangle& rTrackingRect, + const ::Rectangle& rRowColumnRect, + const ::Size& rContainerWinSize ); + + void implts_getDockingAreaElementInfos( ::com::sun::star::ui::DockingArea DockingArea, std::vector< SingleRowColumnWindowData >& rRowColumnsWindowData ); + void implts_getDockingAreaElementInfoOnSingleRowCol( ::com::sun::star::ui::DockingArea, sal_Int32 nRowCol, SingleRowColumnWindowData& rRowColumnWindowData ); + void implts_findNextDockingPos( ::com::sun::star::ui::DockingArea DockingArea, const ::Size& aUIElementSize, ::Point& rVirtualPos, ::Point& rPixelPos ); + void implts_setTrackingRect( ::com::sun::star::ui::DockingArea eDockingArea, const ::Point& rMousePos, ::Rectangle& rTrackingRect ); + + //--------------------------------------------------------------------------------------------------------- + // creation methods + //--------------------------------------------------------------------------------------------------------- + void implts_createAddonsToolBars(); + void implts_createCustomToolBars(); +// void implts_createNonContextSensitiveToolBars(); + void implts_createCustomToolBars( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > >& aCustomTbxSeq ); + void implts_createCustomToolBar( const rtl::OUString& aTbxResName, const rtl::OUString& aTitle ); + void implts_createElement( const ::rtl::OUString& aName, bool& bNotify, ::com::sun::star::uno::Reference< ::com::sun::star::ui::XUIElement >& rUIElement ); + css::uno::Reference< css::ui::XUIElement > implts_createElement( const ::rtl::OUString& aName ); + + //--------------------------------------------------------------------------------------------------------- + // persistence methods + //--------------------------------------------------------------------------------------------------------- + sal_Bool implts_readWindowStateData( const rtl::OUString& aName, UIElement& rElementData ); + void implts_writeWindowStateData( const rtl::OUString& aName, const UIElement& rElementData ); + + //--------------------------------------------------------------------------------------------------------- + // members + //--------------------------------------------------------------------------------------------------------- + css::uno::Reference< css::lang::XMultiServiceFactory > m_xSMGR; + css::uno::Reference< css::frame::XFrame > m_xFrame; + css::uno::Reference< css::awt::XWindow2 > m_xContainerWindow; + css::uno::Reference< css::awt::XWindow > m_xDockAreaWindows[DOCKINGAREAS_COUNT]; + css::uno::Reference< ::com::sun::star::ui::XUIElementFactory > m_xUIElementFactoryManager; + css::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > m_xModuleCfgMgr; + css::uno::Reference< ::com::sun::star::ui::XUIConfigurationManager > m_xDocCfgMgr; + css::uno::Reference< ::com::sun::star::awt::XToolkit > m_xToolkit; + css::uno::Reference< ::com::sun::star::container::XNameAccess > m_xPersistentWindowState; + + UIElementVector m_aUIElements; + UIElement m_aDockUIElement; + Point m_aStartDockMousePos; + Rectangle m_aDockingArea; + Rectangle m_aDockingAreaOffsets; + DockingOperation m_eDockOperation; + + AddonsOptions* m_pAddonOptions; + GlobalSettings* m_pGlobalSettings; + + bool m_bComponentAttached; + bool m_bMustLayout; + bool m_bLayoutDirty; + bool m_bStoreWindowState; + bool m_bGlobalSettings; + bool m_bDockingInProgress; + + ::rtl::OUString m_aFullAddonTbxPrefix; + ::rtl::OUString m_aCustomTbxPrefix; + ::rtl::OUString m_aCustomizeCmd; +}; + +} // namespace framework + +#endif // __FRAMEWORK_LAYOUTMANAGER_TOOLBARLAYOUTMANAGER_HXX_ diff --git a/framework/source/layoutmanager/uielement.cxx b/framework/source/layoutmanager/uielement.cxx new file mode 100755 index 000000000000..dda5aa352a08 --- /dev/null +++ b/framework/source/layoutmanager/uielement.cxx @@ -0,0 +1,156 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: layoutmanager.hxx,v $ + * $Revision: 1.34 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <uielement/uielement.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/ui/DockingArea.hpp> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +using namespace ::com::sun::star; + +namespace framework +{ + + bool UIElement::operator< ( const ::framework::UIElement& aUIElement ) const +{ + if ( !m_xUIElement.is() && aUIElement.m_xUIElement.is() ) + return false; + else if ( m_xUIElement.is() && !aUIElement.m_xUIElement.is() ) + return true; + else if ( !m_bVisible && aUIElement.m_bVisible ) + return false; + else if ( m_bVisible && !aUIElement.m_bVisible ) + return true; + else if ( !m_bFloating && aUIElement.m_bFloating ) + return true; + else if ( m_bFloating && !aUIElement.m_bFloating ) + return false; + else + { + if ( m_bFloating ) + { + bool bEqual = ( m_aFloatingData.m_aPos.Y() == aUIElement.m_aFloatingData.m_aPos.Y() ); + if ( bEqual ) + return ( m_aFloatingData.m_aPos.X() < aUIElement.m_aFloatingData.m_aPos.X() ); + else + return ( m_aFloatingData.m_aPos.Y() < aUIElement.m_aFloatingData.m_aPos.Y() ); + } + else + { + if ( m_aDockedData.m_nDockedArea < aUIElement.m_aDockedData.m_nDockedArea ) + return true; + else if ( m_aDockedData.m_nDockedArea > aUIElement.m_aDockedData.m_nDockedArea ) + return false; + else + { + if ( m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_TOP || + m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) + { + if ( !( m_aDockedData.m_aPos.Y() == aUIElement.m_aDockedData.m_aPos.Y() ) ) + return ( m_aDockedData.m_aPos.Y() < aUIElement.m_aDockedData.m_aPos.Y() ); + else + { + bool bEqual = ( m_aDockedData.m_aPos.X() == aUIElement.m_aDockedData.m_aPos.X() ); + if ( bEqual ) + { + if ( m_bUserActive && !aUIElement.m_bUserActive ) + return sal_True; + else if ( !m_bUserActive && aUIElement.m_bUserActive ) + return sal_False; + else + return sal_False; + } + else + return ( m_aDockedData.m_aPos.X() <= aUIElement.m_aDockedData.m_aPos.X() ); + } + } + else + { + if ( !( m_aDockedData.m_aPos.X() == aUIElement.m_aDockedData.m_aPos.X() ) ) + return ( m_aDockedData.m_aPos.X() < aUIElement.m_aDockedData.m_aPos.X() ); + else + { + bool bEqual = ( m_aDockedData.m_aPos.Y() == aUIElement.m_aDockedData.m_aPos.Y() ); + if ( bEqual ) + { + if ( m_bUserActive && !aUIElement.m_bUserActive ) + return sal_True; + else if ( !m_bUserActive && aUIElement.m_bUserActive ) + return sal_False; + else + return sal_False; + } + else + return ( m_aDockedData.m_aPos.Y() <= aUIElement.m_aDockedData.m_aPos.Y() ); + } + } + } + } + } +} + +UIElement& UIElement::operator= ( const UIElement& rUIElement ) +{ + m_aType = rUIElement.m_aType; + m_aName = rUIElement.m_aName; + m_aUIName = rUIElement.m_aUIName; + m_xUIElement = rUIElement.m_xUIElement; + m_bFloating = rUIElement.m_bFloating; + m_bVisible = rUIElement.m_bVisible; + m_bUserActive = rUIElement.m_bUserActive; + m_bCreateNewRowCol0 = rUIElement.m_bCreateNewRowCol0; + m_bDeactiveHide = rUIElement.m_bDeactiveHide; + m_bMasterHide = rUIElement.m_bMasterHide; + m_bContextSensitive = rUIElement.m_bContextSensitive; + m_bContextActive = rUIElement.m_bContextActive; + m_bNoClose = rUIElement.m_bNoClose; + m_bSoftClose = rUIElement.m_bSoftClose; + m_bStateRead = rUIElement.m_bStateRead; + m_nStyle = rUIElement.m_nStyle; + m_aDockedData = rUIElement.m_aDockedData; + m_aFloatingData = rUIElement.m_aFloatingData; + return *this; +} + +} // namespace framework diff --git a/framework/source/services/makefile.mk b/framework/source/services/makefile.mk index 2978d9aacf5e..eaeaae1f8a82 100644 --- a/framework/source/services/makefile.mk +++ b/framework/source/services/makefile.mk @@ -53,7 +53,8 @@ SLOFILES=\ $(SLO)$/sessionlistener.obj \ $(SLO)$/taskcreatorsrv.obj \ $(SLO)$/uriabbreviation.obj \ - $(SLO)$/tabwindowservice.obj + $(SLO)$/tabwindowservice.obj \ + $(SLO)$/modelwinservice.obj SRS1NAME=$(TARGET) SRC1FILES= fwk_services.src diff --git a/framework/source/services/modelwinservice.cxx b/framework/source/services/modelwinservice.cxx new file mode 100755 index 000000000000..d50fe7dcc653 --- /dev/null +++ b/framework/source/services/modelwinservice.cxx @@ -0,0 +1,279 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: urltransformer.cxx,v $ + * $Revision: 1.17 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include "services.h" +#include "services/modelwinservice.hxx" + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/awt/XControlModel.hpp> + +using namespace ::com::sun::star; + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// non exported definitions +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +class Impl_ModelWinService +{ + public: + ~Impl_ModelWinService(); + + static Impl_ModelWinService* getSingleInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager ); + + uno::Any getByName( const ::rtl::OUString& sName ) + throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException ); + + uno::Sequence< ::rtl::OUString > getElementNames() + throw( uno::RuntimeException ); + + sal_Bool hasByName( const ::rtl::OUString& sName ) + throw( uno::RuntimeException ); + + uno::Type getElementType() + throw( css::uno::RuntimeException ); + + sal_Bool hasElements() + throw( css::uno::RuntimeException ); + + void registerModelForXWindow( const uno::Reference< awt::XWindow >& rWindow, const uno::Reference< awt::XControlModel >& rModel ); + + void deregisterModelForXWindow( const uno::Reference< awt::XWindow >& rWindow ); + + private: + typedef BaseHash< uno::WeakReference< awt::XControlModel > > ModelWinMap; + + Impl_ModelWinService(); + Impl_ModelWinService( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager ); + + static Impl_ModelWinService* m_pModelWinService; + + ::com::sun::star::uno::WeakReference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager; + ModelWinMap m_aModelMap; +}; + +Impl_ModelWinService* Impl_ModelWinService::m_pModelWinService = 0; + +Impl_ModelWinService* Impl_ModelWinService::getSingleInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager ) +{ + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + if ( !m_pModelWinService ) + m_pModelWinService = new Impl_ModelWinService( rServiceManager ); + return m_pModelWinService; +} + +Impl_ModelWinService::Impl_ModelWinService( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& rServiceManager ) : + m_xServiceManager( rServiceManager ) +{ +} + +Impl_ModelWinService::Impl_ModelWinService() +{ +} + +Impl_ModelWinService::~Impl_ModelWinService() +{ +} + +void Impl_ModelWinService::registerModelForXWindow( const uno::Reference< awt::XWindow >& rWindow, const uno::Reference< awt::XControlModel >& rModel ) +{ + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + + ::rtl::OUString sName = rtl::OUString::valueOf( reinterpret_cast< sal_Int64 >((void*)rWindow.get())); + ModelWinMap::iterator pIter = m_aModelMap.find( sName ); + if ( pIter != m_aModelMap.end() ) + pIter->second = rModel; + else + m_aModelMap[sName] = rModel; +} + +void Impl_ModelWinService::deregisterModelForXWindow( const uno::Reference< awt::XWindow >& /*rWindow*/ ) +{ +} + +uno::Any Impl_ModelWinService::getByName( const ::rtl::OUString& sName ) +throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException ) +{ + uno::Any aAny; + + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + ModelWinMap::iterator pIter = m_aModelMap.find( sName ); + if ( pIter != m_aModelMap.end()) + { + uno::Reference< awt::XControlModel > xModel( pIter->second ); + aAny = uno::makeAny(xModel); + } + + return aAny; +} + +uno::Sequence< ::rtl::OUString > Impl_ModelWinService::getElementNames() +throw( uno::RuntimeException ) +{ + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + uno::Sequence< ::rtl::OUString > aResult( m_aModelMap.size() ); + + sal_Int32 i = 0; + ModelWinMap::const_iterator pIter = m_aModelMap.begin(); + while ( pIter != m_aModelMap.end()) + aResult[i++] = pIter->first; + + return aResult; +} + +sal_Bool Impl_ModelWinService::hasByName( const ::rtl::OUString& sName ) +throw( uno::RuntimeException ) +{ + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + ModelWinMap::iterator pIter = m_aModelMap.find( sName ); + if ( pIter != m_aModelMap.end()) + return true; + else + return false; +} + +uno::Type Impl_ModelWinService::getElementType() +throw( css::uno::RuntimeException ) +{ + return ::getCppuType(( const uno::Reference< awt::XControlModel >*)NULL ); +} + +sal_Bool Impl_ModelWinService::hasElements() +throw( css::uno::RuntimeException ) +{ + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + return (m_aModelMap.size() > 0); +} + +//***************************************************************************************************************** +// css::uno::XInterface, XTypeProvider, XServiceInfo +//***************************************************************************************************************** + +DEFINE_XINTERFACE_4 ( ModelWinService , + OWeakObject , + DIRECT_INTERFACE(css::lang::XTypeProvider ), + DIRECT_INTERFACE(css::lang::XServiceInfo ), + DIRECT_INTERFACE(css::container::XNameAccess ), + DIRECT_INTERFACE(css::container::XElementAccess ) + ) + +DEFINE_XTYPEPROVIDER_4 ( ModelWinService , + css::lang::XTypeProvider , + css::lang::XServiceInfo , + css::container::XNameAccess , + css::container::XElementAccess + ) + +DEFINE_XSERVICEINFO_MULTISERVICE ( ModelWinService , + OWeakObject , + SERVICENAME_MODELWINSERVICE , + IMPLEMENTATIONNAME_MODELWINSERVICE + ) + +DEFINE_INIT_SERVICE ( ModelWinService, + { + } + ) + +//***************************************************************************************************************** +// constructor +//***************************************************************************************************************** +ModelWinService::ModelWinService(const uno::Reference< lang::XMultiServiceFactory >& rServiceManager ) : + m_xServiceManager( rServiceManager ) +{ +} + +ModelWinService::~ModelWinService() +{ +} + +void ModelWinService::registerModelForXWindow( const uno::Reference< awt::XWindow >& rWindow, const uno::Reference< awt::XControlModel >& rModel ) +{ + Impl_ModelWinService::getSingleInstance(m_xServiceManager)->registerModelForXWindow( rWindow, rModel ); +} + +void ModelWinService::deregisterModelForXWindow( const uno::Reference< awt::XWindow >& rWindow ) +{ + Impl_ModelWinService::getSingleInstance(m_xServiceManager)->deregisterModelForXWindow( rWindow ); +} + +uno::Any SAL_CALL ModelWinService::getByName( const ::rtl::OUString& sName ) +throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException ) +{ + return Impl_ModelWinService::getSingleInstance(m_xServiceManager)->getByName( sName ); +} + +uno::Sequence< ::rtl::OUString > SAL_CALL ModelWinService::getElementNames() +throw( uno::RuntimeException ) +{ + return Impl_ModelWinService::getSingleInstance(m_xServiceManager)->getElementNames( ); +} + +sal_Bool SAL_CALL ModelWinService::hasByName( const ::rtl::OUString& sName ) +throw( uno::RuntimeException ) +{ + return Impl_ModelWinService::getSingleInstance(m_xServiceManager)->hasByName( sName ); +} + +//--------------------------------------------------------------------------------------------------------- +// XElementAccess +//--------------------------------------------------------------------------------------------------------- +uno::Type SAL_CALL ModelWinService::getElementType() +throw( uno::RuntimeException ) +{ + return ::getCppuType( (const uno::Reference< awt::XControlModel > *)NULL ); +} + +sal_Bool SAL_CALL ModelWinService::hasElements() +throw( uno::RuntimeException ) +{ + return Impl_ModelWinService::getSingleInstance(m_xServiceManager)->hasElements(); +} + +} diff --git a/framework/source/uielement/makefile.mk b/framework/source/uielement/makefile.mk index da4ab3d34c74..620f32421aea 100644 --- a/framework/source/uielement/makefile.mk +++ b/framework/source/uielement/makefile.mk @@ -80,6 +80,8 @@ SLOFILES= \ $(SLO)$/toolbarsmenucontroller.obj \ $(SLO)$/toolbarwrapper.obj \ $(SLO)$/uicommanddescription.obj \ + $(SLO)$/panelwrapper.obj \ + $(SLO)$/panelwindow.obj # --- Targets ------------------------------------------------------ diff --git a/framework/source/uielement/panelwindow.cxx b/framework/source/uielement/panelwindow.cxx new file mode 100755 index 000000000000..c8729dbb028d --- /dev/null +++ b/framework/source/uielement/panelwindow.cxx @@ -0,0 +1,77 @@ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <uielement/panelwindow.hxx> + +namespace framework +{ + +PanelWindow::PanelWindow( Window* pParent, WinBits nWinBits ) : + DockingWindow( pParent, nWinBits ) +{ +} + +PanelWindow::~PanelWindow() +{ +} + +const ::rtl::OUString& PanelWindow::getResourceURL() const +{ + return m_aResourceURL; +} + +void PanelWindow::setResourceURL(const ::rtl::OUString& rResourceURL) +{ + m_aResourceURL = rResourceURL; +} + +Window* PanelWindow::getContentWindow() const +{ + return m_pContentWindow; +} + +void PanelWindow::setContentWindow( Window* pContentWindow ) +{ + m_pContentWindow = pContentWindow; + if ( m_pContentWindow != NULL ) + { + m_pContentWindow->SetParent(this); + m_pContentWindow->SetSizePixel( GetOutputSizePixel() ); + m_pContentWindow->Show(); + } +} + +void PanelWindow::Command( const CommandEvent& rCEvt ) +{ + if ( m_aCommandHandler.IsSet() ) + m_aCommandHandler.Call( (void *)( &rCEvt )); + DockingWindow::Command( rCEvt ); +} + +void PanelWindow::StateChanged( StateChangedType nType ) +{ + DockingWindow::StateChanged( nType ); + if ( m_aStateChangedHandler.IsSet() ) + m_aStateChangedHandler.Call( &nType ); +} + +void PanelWindow::DataChanged( const DataChangedEvent& rDCEvt ) +{ + DockingWindow::DataChanged( rDCEvt ); + if ( m_aDataChangedHandler.IsSet() ) + m_aDataChangedHandler.Call( (void*)&rDCEvt ); +} + +void PanelWindow::Resize() +{ + DockingWindow::Resize(); + if ( m_pContentWindow ) + m_pContentWindow->SetSizePixel( GetOutputSizePixel() ); +} + +} diff --git a/framework/source/uielement/panelwrapper.cxx b/framework/source/uielement/panelwrapper.cxx new file mode 100755 index 000000000000..91bc6fa9dac8 --- /dev/null +++ b/framework/source/uielement/panelwrapper.cxx @@ -0,0 +1,227 @@ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <services.h> +#include <uielement/panelwrapper.hxx> +#include <threadhelp/resetableguard.hxx> +#include <helper/actiontriggerhelper.hxx> +#include <uielement/constitemcontainer.hxx> +#include <uielement/rootitemcontainer.hxx> +#include <uielement/panelwindow.hxx> +#include <services/modelwinservice.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/awt/XSystemDependentMenuPeer.hpp> +#include <com/sun/star/awt/XMenuBar.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/ui/UIElementType.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +#include <toolkit/unohlp.hxx> +#include <toolkit/awt/vclxwindow.hxx> +#include <comphelper/processfactory.hxx> +#include <svtools/miscopt.hxx> +#include <vcl/svapp.hxx> +#include <rtl/logfile.hxx> + +using namespace com::sun::star; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::frame; +using namespace com::sun::star::lang; +using namespace com::sun::star::container; +using namespace com::sun::star::awt; +using namespace ::com::sun::star::ui; + +namespace framework +{ + +PanelWrapper::PanelWrapper( const Reference< XMultiServiceFactory >& xServiceManager ) : + UIElementWrapperBase( UIElementType::DOCKINGWINDOW ), + m_xServiceManager( xServiceManager ), + m_bNoClose(false) +{ +} + +PanelWrapper::~PanelWrapper() +{ +} + +// XInterface +void SAL_CALL PanelWrapper::acquire() throw() +{ + UIElementWrapperBase::acquire(); +} + +void SAL_CALL PanelWrapper::release() throw() +{ + UIElementWrapperBase::release(); +} + +uno::Any SAL_CALL PanelWrapper::queryInterface( const uno::Type & rType ) +throw( ::com::sun::star::uno::RuntimeException ) +{ + return UIElementWrapperBase::queryInterface( rType ); +} + +// XComponent +void SAL_CALL PanelWrapper::dispose() throw ( RuntimeException ) +{ + Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY ); + Reference< XMultiServiceFactory > xSMGR( m_xServiceManager ); + Reference< XWindow > xWindow; + + { + ResetableGuard aLock( m_aLock ); + if ( m_bDisposed ) + return; + xSMGR = m_xServiceManager; + } + + com::sun::star::lang::EventObject aEvent( xThis ); + m_aListenerContainer.disposeAndClear( aEvent ); + + rtl::OUString aModelWinService( SERVICENAME_MODELWINSERVICE ); + Reference< XNameAccess > xNameAccess( xSMGR->createInstance( aModelWinService ), UNO_QUERY ); + if ( xNameAccess.is() ) + { + ModelWinService* pService = dynamic_cast< ModelWinService* >( xNameAccess.get() ); + if ( pService != 0 ) + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + PanelWindow* pPanelWindow = dynamic_cast< PanelWindow* >( m_xPanelWindow.get() ); + if ( pPanelWindow != NULL ) + { + xWindow = VCLUnoHelper::GetInterface( pPanelWindow->getContentWindow() ); + pService->deregisterModelForXWindow( xWindow ); + } + } + } + + ResetableGuard aLock( m_aLock ); + m_xPanelWindow.clear(); + m_bDisposed = sal_True; +} + +// XInitialization +void SAL_CALL PanelWrapper::initialize( const Sequence< Any >& aArguments ) throw ( Exception, RuntimeException ) +{ + ResetableGuard aLock( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); + + if ( !m_bInitialized ) + { + UIElementWrapperBase::initialize( aArguments ); + + sal_Bool bPopupMode( sal_False ); + Reference< XWindow > xContentWindow; + for ( sal_Int32 i = 0; i < aArguments.getLength(); i++ ) + { + PropertyValue aPropValue; + if ( aArguments[i] >>= aPropValue ) + { + if ( aPropValue.Name.equalsAsciiL( "PopupMode", 9 )) + aPropValue.Value >>= bPopupMode; + else if ( aPropValue.Name.equalsAsciiL( "ContentWindow", 13 )) + aPropValue.Value >>= xContentWindow; + } + } + + Reference< XFrame > xFrame( m_xWeakFrame ); + if ( xFrame.is() ) + { + PanelWindow* pPanelWindow(0); + Window* pContentWindow(0); + { + vos::OGuard aSolarMutexGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xFrame->getContainerWindow() ); + pContentWindow = VCLUnoHelper::GetWindow( xContentWindow ); + if ( pWindow ) + { + ULONG nStyles = WB_LINESPACING | WB_BORDER | WB_SCROLL | WB_MOVEABLE | WB_3DLOOK | WB_DOCKABLE | WB_SIZEABLE | WB_CLOSEABLE; + + pPanelWindow = new PanelWindow( pWindow, nStyles ); + m_xPanelWindow = VCLUnoHelper::GetInterface( pPanelWindow ); + pPanelWindow->setResourceURL( m_aResourceURL ); + pPanelWindow->setContentWindow( pContentWindow ); + } + } + + try + { + } + catch ( NoSuchElementException& ) + { + } + } + } +} + +// XEventListener +void SAL_CALL PanelWrapper::disposing( const ::com::sun::star::lang::EventObject& ) throw (::com::sun::star::uno::RuntimeException) +{ + // nothing todo +} + +// XUpdatable +void SAL_CALL PanelWrapper::update() throw (::com::sun::star::uno::RuntimeException) +{ + ResetableGuard aLock( m_aLock ); + + if ( m_bDisposed ) + throw DisposedException(); +} + +// XUIElement interface +Reference< XInterface > SAL_CALL PanelWrapper::getRealInterface( ) throw (::com::sun::star::uno::RuntimeException) +{ + ResetableGuard aLock( m_aLock ); + return m_xPanelWindow; +} + +void SAL_CALL PanelWrapper::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const com::sun::star::uno::Any& aValue ) throw( com::sun::star::uno::Exception ) +{ + ResetableGuard aLock( m_aLock ); + sal_Bool bNoClose( m_bNoClose ); + aLock.unlock(); + + UIElementWrapperBase::setFastPropertyValue_NoBroadcast( nHandle, aValue ); + + aLock.lock(); + + sal_Bool bNewNoClose( m_bNoClose ); + if ( m_xPanelWindow.is() && !m_bDisposed && ( bNewNoClose != bNoClose )) + { + PanelWindow* pPanelWindow = dynamic_cast< PanelWindow* >( VCLUnoHelper::GetWindow( m_xPanelWindow ) ); + if ( pPanelWindow ) + { + if ( bNewNoClose ) + { + pPanelWindow->SetStyle( pPanelWindow->GetStyle() & ~WB_CLOSEABLE ); + pPanelWindow->SetFloatStyle( pPanelWindow->GetFloatStyle() & ~WB_CLOSEABLE ); + } + else + { + pPanelWindow->SetStyle( pPanelWindow->GetStyle() | WB_CLOSEABLE ); + pPanelWindow->SetFloatStyle( pPanelWindow->GetFloatStyle() | WB_CLOSEABLE ); + } + } + } +} + +} // namespace framework diff --git a/framework/util/makefile.mk b/framework/util/makefile.mk index ed7e2e131550..553f9e10e6b8 100644 --- a/framework/util/makefile.mk +++ b/framework/util/makefile.mk @@ -337,8 +337,14 @@ SHL4OBJS= \ $(SLO)$/windowcommanddispatch.obj \ $(SLO)$/windowstateconfiguration.obj \ $(SLO)$/windowcontentfactorymanager.obj \ - $(SLO)$/startmoduledispatcher.obj - + $(SLO)$/startmoduledispatcher.obj \ + $(SLO)$/modelwinservice.obj \ + $(SLO)$/panelmanager.obj \ + $(SLO)$/panel.obj \ + $(SLO)$/helpers.obj \ + $(SLO)$/uielement.obj \ + $(SLO)$/toolbarlayoutmanager.obj + SHL4STDLIBS= \ $(FWILIB) \ $(FWELIB) \ |