diff options
Diffstat (limited to 'framework/source/layoutmanager/layoutmanager.cxx')
-rw-r--r-- | framework/source/layoutmanager/layoutmanager.cxx | 3265 |
1 files changed, 3265 insertions, 0 deletions
diff --git a/framework/source/layoutmanager/layoutmanager.cxx b/framework/source/layoutmanager/layoutmanager.cxx new file mode 100644 index 000000000000..43176fe82b72 --- /dev/null +++ b/framework/source/layoutmanager/layoutmanager.cxx @@ -0,0 +1,3265 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * 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 <framework/sfxhelperfunctions.hxx> +#include <framework/sfxhelperfunctions.hxx> +#include <uielement/menubarwrapper.hxx> +#include <framework/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> +#include <toolbarlayoutmanager.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/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/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; + + +// 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 framework +{ + +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( false ) + , m_bInplaceMenuSet( false ) + , m_bDockingInProgress( false ) + , m_bMenuVisible( true ) + , m_bComponentAttached( false ) + , m_bDoLayout( false ) + , m_bVisible( true ) + , m_bParentWindowVisible( false ) + , m_bMustDoLayout( true ) + , m_bAutomaticToolbars( true ) + , m_bStoreWindowState( false ) + , m_bHideCurrentUI( false ) + , m_bGlobalSettings( false ) + , m_bPreserveContentSize( false ) + , m_bMenuBarCloser( false ) + , m_pInplaceMenuBar( NULL ) + , m_xModuleManager( Reference< XModuleManager >( xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY )) + , m_xUIElementFactoryManager( Reference< ui::XUIElementFactory >( + xServiceManager->createInstance( SERVICENAME_UIELEMENTFACTORYMANAGER ), UNO_QUERY )) + , m_xPersistentWindowStateSupplier( Reference< XNameAccess >( + xServiceManager->createInstance( SERVICENAME_WINDOWSTATECONFIGURATION ), UNO_QUERY )) + , m_pGlobalSettings( 0 ) + , 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_aListenerContainer( m_aLock.getShareableOslMutex() ) + , m_pPanelManager( 0 ) + , m_pToolbarManager( 0 ) +{ + // Initialize statusbar member + const sal_Bool bRefreshVisibility = sal_False; + m_aStatusBarElement.m_aType = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "statusbar" )); + m_aStatusBarElement.m_aName = m_aStatusBarAlias; + + m_pToolbarManager = new ToolbarLayoutManager( xServiceManager, m_xUIElementFactoryManager, this ); + m_xToolbarManager = uno::Reference< ui::XUIConfigurationListener >( static_cast< OWeakObject* >( m_pToolbarManager ), uno::UNO_QUERY ); + + Application::AddEventListener( LINK( this, LayoutManager, SettingsChanged ) ); + + 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, beans::PropertyAttribute::TRANSIENT, &m_bHideCurrentUI, ::getCppuType( &m_bHideCurrentUI ) ); + registerProperty( LAYOUTMANAGER_PROPNAME_LOCKCOUNT, LAYOUTMANAGER_PROPHANDLE_LOCKCOUNT, beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY, &m_nLockCount, getCppuType( &m_nLockCount ) ); + registerProperty( LAYOUTMANAGER_PROPNAME_MENUBARCLOSER, LAYOUTMANAGER_PROPHANDLE_MENUBARCLOSER, beans::PropertyAttribute::TRANSIENT, &m_bMenuBarCloser, ::getCppuType( &m_bMenuBarCloser ) ); + registerPropertyNoMember( LAYOUTMANAGER_PROPNAME_REFRESHVISIBILITY, LAYOUTMANAGER_PROPHANDLE_REFRESHVISIBILITY, beans::PropertyAttribute::TRANSIENT, ::getCppuType( &bRefreshVisibility ), &bRefreshVisibility ); + registerProperty( LAYOUTMANAGER_PROPNAME_PRESERVE_CONTENT_SIZE, LAYOUTMANAGER_PROPHANDLE_PRESERVE_CONTENT_SIZE, beans::PropertyAttribute::TRANSIENT, &m_bPreserveContentSize, ::getCppuType( &m_bPreserveContentSize ) ); +} + +LayoutManager::~LayoutManager() +{ + Application::RemoveEventListener( LINK( this, LayoutManager, SettingsChanged ) ); + 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() ); + + SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow ); + if ( pSysWindow ) + { + MenuBar* pSetMenuBar = 0; + if ( m_xInplaceMenuBar.is() ) + pSetMenuBar = (MenuBar *)m_pInplaceMenuBar->GetMenuBar(); + else + { + Reference< awt::XMenuBar > xMenuBar; + + Reference< XPropertySet > xPropSet( m_xMenuBar, UNO_QUERY ); + if ( xPropSet.is() ) + { + try + { + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMenuBar" ))) >>= xMenuBar; + } + catch ( beans::UnknownPropertyException ) {} + catch ( lang::WrappedTargetException ) {} + } + + VCLXMenu* pAwtMenuBar = VCLXMenu::GetImplementation( xMenuBar ); + if ( pAwtMenuBar ) + pSetMenuBar = (MenuBar*)pAwtMenuBar->GetMenu(); + } + + MenuBar* pTopMenuBar = pSysWindow->GetMenuBar(); + if ( pSetMenuBar == pTopMenuBar ) + pSysWindow->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(); +} + +void LayoutManager::implts_lock() +{ + WriteGuard aWriteLock( m_aLock ); + ++m_nLockCount; +} + +sal_Bool LayoutManager::implts_unlock() +{ + WriteGuard aWriteLock( m_aLock ); + m_nLockCount = std::max( --m_nLockCount, static_cast<sal_Int32>(0) ); + return ( m_nLockCount == 0 ); +} + +void LayoutManager::implts_reset( sal_Bool bAttached ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + Reference< XFrame > xFrame = m_xFrame; + Reference< awt::XWindow > xContainerWindow( m_xContainerWindow ); + 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 ); + Reference< awt::XWindowListener > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY ); + ToolbarLayoutManager* pToolbarManager( m_pToolbarManager ); + ::rtl::OUString aModuleIdentifier( m_aModuleIdentifier ); + 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(); + } + + Reference< XUIConfigurationManager > xModCfgMgr( xModuleCfgMgr, UNO_QUERY ); + Reference< XUIConfigurationManager > xDokCfgMgr( xDocCfgMgr, UNO_QUERY ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + m_xModel = xModel; + m_aDockingArea = awt::Rectangle(); + m_bComponentAttached = bAttached; + m_aModuleIdentifier = aModuleIdentifier; + m_xModuleCfgMgr = xModCfgMgr; + m_xDocCfgMgr = xDokCfgMgr; + m_xPersistentWindowState = xPersistentWindowState; + m_aStatusBarElement.m_bStateRead = sal_False; // reset state to read data again! + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + // reset/notify toolbar layout manager + if ( pToolbarManager ) + { + if ( bAttached ) + { + pToolbarManager->attach( xFrame, xModCfgMgr, xDokCfgMgr, xPersistentWindowState ); + uno::Reference< awt::XWindowPeer > xParent( xContainerWindow, UNO_QUERY ); + pToolbarManager->setParentWindow( xParent ); + if ( bAutomaticToolbars ) + pToolbarManager->createStaticToolbars(); + } + else + { + pToolbarManager->reset(); + implts_destroyElements(); + } + } + } + + implts_unlock(); +} + +sal_Bool LayoutManager::implts_isEmbeddedLayoutManager() const +{ + ReadGuard aReadLock( m_aLock ); + Reference< XFrame > xFrame = m_xFrame; + Reference< awt::XWindow > xContainerWindow( m_xContainerWindow ); + aReadLock.unlock(); + + Reference< awt::XWindow > xFrameContainerWindow = xFrame->getContainerWindow(); + if ( xFrameContainerWindow == xContainerWindow ) + return sal_False; + else + return sal_True; +} + +void LayoutManager::implts_destroyElements() +{ + WriteGuard aWriteLock( m_aLock ); + uno::Reference< ui::XUIConfigurationListener > xThis( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aWriteLock.unlock(); + + if ( pToolbarManager ) + pToolbarManager->destroyToolbars(); + + implts_destroyStatusBar(); + + aWriteLock.lock(); + impl_clearUpMenuBar(); + aWriteLock.unlock(); +} + +void LayoutManager::implts_toggleFloatingUIElementsVisibility( sal_Bool bActive ) +{ + ReadGuard aReadLock( m_aLock ); + uno::Reference< ui::XUIConfigurationListener > xThis( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + pToolbarManager->setFloatingToolbarsVisibility( bActive ); +} + +uno::Reference< ui::XUIElement > LayoutManager::implts_findElement( const rtl::OUString& aName ) +{ + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + parseResourceURL( aName, aElementType, aElementName ); + if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "menubar" )) + return m_xMenuBar; + else if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || ( m_aStatusBarElement.m_aName == aName )) + return m_aStatusBarElement.m_xUIElement; + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" )) + return m_aProgressBarElement.m_xUIElement; + + return uno::Reference< ui::XUIElement >(); +} + +UIElement& LayoutManager::impl_findElement( const rtl::OUString& aName ) +{ + static UIElement aEmptyElement; + + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + parseResourceURL( aName, aElementType, aElementName ); + if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || ( m_aStatusBarElement.m_aName == aName )) + return m_aStatusBarElement; + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" )) + return m_aProgressBarElement; + + return aEmptyElement; +} + +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->hasByName( aName ) && (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 ) + { + ui::DockingArea eDockingArea; + if ( aWindowState[n].Value >>= eDockingArea ) + rElementData.m_aDockedData.m_nDockedArea = sal_Int16( eDockingArea ); + } + else if ( aWindowState[n].Name == m_aPropDockPos ) + { + 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 ) + { + 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 ) + { + 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(); + + 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 ( beans::UnknownPropertyException ) + { + // Non-configurable elements should at least store their dimension/position + bPersistent = sal_True; + } + catch ( 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 ) ); + + 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; + + 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(); +} + +::Size LayoutManager::implts_getContainerWindowOutputSize() +{ + ::Size aContainerWinSize; + Window* pContainerWindow( 0 ); + + // Retrieve output size from container Window + vos::OGuard aGuard( Application::GetSolarMutex() ); + pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ); + if ( pContainerWindow ) + aContainerWinSize = pContainerWindow->GetOutputSizePixel(); + + return aContainerWinSize; +} + +Reference< XUIElement > LayoutManager::implts_createElement( const rtl::OUString& aName ) +{ + Reference< 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; +} + +void LayoutManager::implts_setVisibleState( sal_Bool bShow ) +{ + WriteGuard aWriteLock( m_aLock ); + m_aStatusBarElement.m_bMasterHide = !bShow; + aWriteLock.unlock(); + + implts_updateUIElementsVisibleState( bShow ); +} + +void LayoutManager::implts_updateUIElementsVisibleState( sal_Bool bSetVisible ) +{ + // notify listeners + uno::Any a; + if ( bSetVisible ) + implts_notifyListeners( frame::LayoutManagerEvents::VISIBLE, a ); + else + implts_notifyListeners( frame::LayoutManagerEvents::INVISIBLE, a ); + std::vector< Reference< awt::XWindow > > aWinVector; + + WriteGuard aWriteLock( m_aLock ); + Reference< XUIElement > xMenuBar( m_xMenuBar, UNO_QUERY ); + Reference< awt::XWindow > xContainerWindow( m_xContainerWindow ); + Reference< XComponent > xInplaceMenuBar( m_xInplaceMenuBar ); + MenuBarManager* pInplaceMenuBar( m_pInplaceMenuBar ); + aWriteLock.unlock(); + + bool bMustDoLayout(false); + 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(); + } + + SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow ); + if ( pSysWindow ) + { + if ( bSetVisible ) + pSysWindow->SetMenuBar( pMenuBar ); + else + pSysWindow->SetMenuBar( 0 ); + bMustDoLayout = true; + } + } + + // Hide/show the statusbar according to bSetVisible + if ( bSetVisible ) + bMustDoLayout = !implts_showStatusBar(); + else + bMustDoLayout = !implts_hideStatusBar(); + + aWriteLock.lock(); + uno::Reference< ui::XUIConfigurationListener > xThis( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager( m_pToolbarManager ); + aWriteLock.unlock(); + + if ( pToolbarManager ) + { + pToolbarManager->setVisible( bSetVisible ); + bMustDoLayout = pToolbarManager->isLayoutDirty(); + } + + if ( bMustDoLayout ) + implts_doLayout_notify( sal_False ); +} + +void LayoutManager::implts_setCurrentUIVisibility( sal_Bool bShow ) +{ + WriteGuard aWriteLock( m_aLock ); + 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(); + + implts_updateUIElementsVisibleState( bShow ); +} + +void LayoutManager::implts_destroyStatusBar() +{ + Reference< XComponent > xCompStatusBar; + + 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(); + + if ( xCompStatusBar.is() ) + xCompStatusBar->dispose(); + + implts_destroyProgressBar(); +} + +void LayoutManager::implts_createStatusBar( const rtl::OUString& aStatusBarName ) +{ + 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 ); + } + aWriteLock.unlock(); + + implts_createProgressBar(); +} + +void LayoutManager::implts_readStatusBarState( const rtl::OUString& rStatusBarName ) +{ + 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; + } +} + +void LayoutManager::implts_createProgressBar() +{ + Reference< XUIElement > xStatusBar; + Reference< XUIElement > xProgressBar; + Reference< XUIElement > xProgressBarBackup; + Reference< awt::XWindow > xContainerWindow; + + 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(); + + 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< awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY ); + pWrapper->setStatusBar( xWindow ); + } + else + { + Reference< 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< 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< 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< 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< awt::XWindow > xWindow; + if ( xStatusBar.is() ) + xWindow = Reference< 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< 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< awt::XWindow >( xStatusBar->getRealInterface(), UNO_QUERY ); + } + else if ( xProgressBar.is() ) + { + ProgressBarWrapper* pWrapper = (ProgressBarWrapper*)xProgressBar.get(); + if ( pWrapper ) + xWindow = pWrapper->getStatusBar(); + } + } + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + { + if ( !pWindow->IsVisible() ) + { + implts_setOffset( pWindow->GetSizePixel().Height() ); + pWindow->Show(); + implts_doLayout_notify( sal_False ); + } + return sal_True; + } + + return sal_False; +} + +sal_Bool LayoutManager::implts_hideProgressBar() +{ + Reference< XUIElement > xProgressBar; + Reference< 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< awt::XWindow > xStatusBar; + ProgressBarWrapper* pWrapper = (ProgressBarWrapper*)xProgressBar.get(); + if ( pWrapper ) + xWindow = pWrapper->getStatusBar(); + Reference< ui::XUIElement > xStatusBarElement = m_aStatusBarElement.m_xUIElement; + if ( xStatusBarElement.is() ) + xStatusBar = Reference< 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(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->IsVisible() && ( bHideStatusBar || bInternalStatusBar )) + { + implts_setOffset( 0 ); + pWindow->Hide(); + implts_doLayout_notify( sal_False ); + return sal_True; + } + + return sal_False; +} + +sal_Bool LayoutManager::implts_showStatusBar( sal_Bool bStoreState ) +{ + WriteGuard aWriteLock( m_aLock ); + Reference< ui::XUIElement > xStatusBar = m_aStatusBarElement.m_xUIElement; + if ( bStoreState ) + m_aStatusBarElement.m_bVisible = sal_True; + aWriteLock.unlock(); + + if ( xStatusBar.is() ) + { + Reference< awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY ); + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && !pWindow->IsVisible() ) + { + implts_setOffset( pWindow->GetSizePixel().Height() ); + pWindow->Show(); + implts_doLayout_notify( sal_False ); + return sal_True; + } + } + + return sal_False; +} + +sal_Bool LayoutManager::implts_hideStatusBar( sal_Bool bStoreState ) +{ + WriteGuard aWriteLock( m_aLock ); + Reference< ui::XUIElement > xStatusBar = m_aStatusBarElement.m_xUIElement; + if ( bStoreState ) + m_aStatusBarElement.m_bVisible = sal_False; + aWriteLock.unlock(); + + if ( xStatusBar.is() ) + { + Reference< awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY ); + + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->IsVisible() ) + { + implts_setOffset( 0 ); + pWindow->Hide(); + implts_doLayout_notify( sal_False ); + return sal_True; + } + } + + return sal_False; +} + +void LayoutManager::implts_setOffset( const sal_Int32 nBottomOffset ) +{ + ::Rectangle aOffsetRect; + setZeroRectangle( aOffsetRect ); + aOffsetRect.setHeight( nBottomOffset ); + + // make sure that the toolbar manager refernence/pointer is valid + uno::Reference< ui::XUIConfigurationListener > xThis( m_xToolbarManager ); + if ( xThis.is() ) + m_pToolbarManager->setDockingAreaOffsets( aOffsetRect ); +} + +void LayoutManager::implts_setInplaceMenuBar( const Reference< XIndexAccess >& xMergedMenuBar ) +throw (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 ); + + SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow ); + if ( pSysWindow ) + 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 (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() ); + SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow ); + if ( pSysWindow ) + { + 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(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ +} + +void SAL_CALL LayoutManager::attachFrame( const Reference< XFrame >& xFrame ) +throw (uno::RuntimeException) +{ + WriteGuard aWriteLock( m_aLock ); + m_xFrame = xFrame; +} + +void SAL_CALL LayoutManager::reset() +throw (RuntimeException) +{ + sal_Bool bComponentAttached( sal_False ); + + ReadGuard aReadLock( m_aLock ); + bComponentAttached = m_bComponentAttached; + aReadLock.unlock(); + + implts_reset( sal_True ); +} + +void SAL_CALL LayoutManager::setInplaceMenuBar( sal_Int64 ) +throw (uno::RuntimeException) +{ + OSL_ENSURE( sal_False, "This method is obsolete and should not be used!\n" ); +} + +void SAL_CALL LayoutManager::resetInplaceMenuBar() +throw (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 (uno::RuntimeException) +{ + implts_setInplaceMenuBar( xMergedMenuBar ); + + uno::Any a; + implts_notifyListeners( frame::LayoutManagerEvents::MERGEDMENUBAR, a ); + return sal_True; +} + +void SAL_CALL LayoutManager::removeMergedMenuBar() +throw (uno::RuntimeException) +{ + implts_resetInplaceMenuBar(); +} + +awt::Rectangle SAL_CALL LayoutManager::getCurrentDockingArea() +throw ( RuntimeException ) +{ + ReadGuard aReadLock( m_aLock ); + return m_aDockingArea; +} + +Reference< XDockingAreaAcceptor > SAL_CALL LayoutManager::getDockingAreaAcceptor() +throw (uno::RuntimeException) +{ + ReadGuard aReadLock( m_aLock ); + return m_xDockingAreaAcceptor; +} + +void SAL_CALL LayoutManager::setDockingAreaAcceptor( const Reference< 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< awt::XWindow > > oldDockingAreaWindows; + + uno::Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + + if ( !xDockingAreaAcceptor.is() ) + m_aAsyncLayoutTimer.Stop(); + + // Remove listener from old docking area acceptor + if ( m_xDockingAreaAcceptor.is() ) + { + Reference< awt::XWindow > xWindow( m_xDockingAreaAcceptor->getContainerWindow() ); + if ( xWindow.is() && ( m_xFrame->getContainerWindow() != m_xContainerWindow || !xDockingAreaAcceptor.is() ) ) + xWindow->removeWindowListener( Reference< awt::XWindowListener >( static_cast< OWeakObject * >( this ), UNO_QUERY )); + + m_aDockingArea = awt::Rectangle(); + if ( pToolbarManager ) + pToolbarManager->resetDockingArea(); + + Window* pContainerWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pContainerWindow ) + pContainerWindow->RemoveChildEventListener( LINK( this, LayoutManager, WindowEventListener ) ); + } + + Reference< ui::XDockingAreaAcceptor > xOldDockingAreaAcceptor( m_xDockingAreaAcceptor ); + m_xDockingAreaAcceptor = xDockingAreaAcceptor; + if ( m_xDockingAreaAcceptor.is() ) + { + m_aDockingArea = awt::Rectangle(); + m_xContainerWindow = m_xDockingAreaAcceptor->getContainerWindow(); + m_xContainerTopWindow.set( m_xContainerWindow, UNO_QUERY ); + m_xContainerWindow->addWindowListener( Reference< 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< 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(); + } + + uno::Reference< awt::XWindowPeer > xParent( m_xContainerWindow, UNO_QUERY ); + } + + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( xDockingAreaAcceptor.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + // 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() ) + { + // Reset docking area size for our old docking area acceptor + awt::Rectangle aEmptyRect; + xOldDockingAreaAcceptor->setDockingAreaSpace( aEmptyRect ); + } + + if ( xDockingAreaAcceptor.is() ) + { + if ( bAutomaticToolbars ) + { + lock(); + pToolbarManager->createStaticToolbars(); + unlock(); + } + implts_doLayout( sal_True, sal_False ); + } +} + +void LayoutManager::implts_reparentChildWindows() +{ + WriteGuard aWriteLock( m_aLock ); + UIElement aStatusBarElement = m_aStatusBarElement; + uno::Reference< awt::XWindow > xContainerWindow = m_xContainerWindow; + aWriteLock.unlock(); + + uno::Reference< awt::XWindow > xStatusBarWindow; + if ( aStatusBarElement.m_xUIElement.is() ) + { + try + { + xStatusBarWindow = Reference< awt::XWindow >( aStatusBarElement.m_xUIElement->getRealInterface(), UNO_QUERY ); + } + catch ( RuntimeException& ) { throw; } + catch ( Exception& ) {} + } + + if ( xStatusBarWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow ); + Window* pWindow = VCLUnoHelper::GetWindow( xStatusBarWindow ); + if ( pWindow && pContainerWindow ) + pWindow->SetParent( pContainerWindow ); + } + + implts_resetMenuBar(); + + aWriteLock.lock(); + uno::Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + if ( pToolbarManager ) + pToolbarManager->setParentWindow( uno::Reference< awt::XWindowPeer >( xContainerWindow, uno::UNO_QUERY )); + aWriteLock.unlock(); +} + +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 ) +{ + long nResult( 1 ); + + if ( pEvent && pEvent->ISA( VclWindowEvent )) + { + Window* pWindow = static_cast< VclWindowEvent* >(pEvent)->GetWindow(); + if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX ) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< ui::XUIConfigurationListener > xThis( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager( m_pToolbarManager ); + aReadLock.unlock(); + + if ( pToolbarManager ) + nResult = pToolbarManager->childWindowEvent( pEvent ); + } + } + + return nResult; +} + +void SAL_CALL LayoutManager::createElement( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::createElement" ); + + ReadGuard aReadLock( m_aLock ); + Reference< XFrame > xFrame = m_xFrame; + Reference< XURLTransformer > xURLTransformer = m_xURLTransformer; + sal_Bool bInPlaceMenu = m_bInplaceMenuSet; + aReadLock.unlock(); + + if ( !xFrame.is() ) + return; + + Reference< XModel > xModel( impl_getModelFromFrame( xFrame ) ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + + bool bMustBeLayouted( false ); + bool bNotify( false ); + + if ( m_xContainerWindow.is() && !implts_isPreviewModel( xModel ) ) // no UI elements on preview frames + { + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + parseResourceURL( aName, aElementType, aElementName ); + + if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ) && m_pToolbarManager != NULL ) + { + bNotify = m_pToolbarManager->createToolbar( aName ); + bMustBeLayouted = m_pToolbarManager->isLayoutDirty(); + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "menubar" )) + { + // PB 2004-12-15 #i38743# don't create a menubar if frame isn't top + if ( !bInPlaceMenu && !m_xMenuBar.is() && implts_isFrameOrWindowTop( xFrame )) + { + m_xMenuBar = implts_createElement( aName ); + if ( m_xMenuBar.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow ); + if ( pSysWindow ) + { + Reference< awt::XMenuBar > xMenuBar; + + Reference< XPropertySet > xPropSet( m_xMenuBar, UNO_QUERY ); + if ( xPropSet.is() ) + { + try + { + xPropSet->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "XMenuBar" ))) >>= xMenuBar; + } + catch ( beans::UnknownPropertyException ) {} + catch ( 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" )) + { + // Add layout manager as listener for docking and other window events + uno::Reference< uno::XInterface > xThis( static_cast< OWeakObject* >(this), 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 ); + } + } + + if ( bMustBeLayouted ) + implts_doLayout_notify( sal_True ); + + if ( bNotify ) + { + // UI element is invisible - provide information to listeners + implts_notifyListeners( 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 ); + + bool bMustBeLayouted( sal_False ); + bool bMustBeDestroyed( sal_False ); + bool bNotify( sal_False ); + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + Reference< XComponent > xComponent; + parseResourceURL( aName, aElementType, aElementName ); + + if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "menubar" )) + { + if ( !m_bInplaceMenuSet ) + { + impl_clearUpMenuBar(); + m_xMenuBar.clear(); + bNotify = true; + } + } + else if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || + ( m_aStatusBarElement.m_aName == aName )) + { + aWriteLock.unlock(); + implts_destroyStatusBar(); + bMustBeLayouted = true; + bNotify = true; + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" )) + { + aWriteLock.unlock(); + implts_createProgressBar(); + bMustBeLayouted = true; + bNotify = sal_True; + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ) && m_pToolbarManager != NULL ) + { + aWriteLock.unlock(); + bNotify = m_pToolbarManager->destroyToolbar( aName ); + bMustBeLayouted = m_pToolbarManager->isLayoutDirty(); + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" )) + { + uno::Reference< frame::XFrame > xFrame( m_xFrame ); + uno::Reference< lang::XMultiServiceFactory > xSMGR( m_xSMGR ); + aWriteLock.unlock(); + + impl_setDockingWindowVisibility( xSMGR, xFrame, aElementName, false ); + bMustBeLayouted = false; + bNotify = false; + } + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + if ( bMustBeDestroyed ) + { + if ( xComponent.is() ) + xComponent->dispose(); + bNotify = true; + } + + if ( bMustBeLayouted ) + doLayout(); + + if ( bNotify ) + implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_INVISIBLE, uno::makeAny( aName ) ); +} + +::sal_Bool SAL_CALL LayoutManager::requestElement( const ::rtl::OUString& rResourceURL ) +throw (uno::RuntimeException) +{ + bool bResult( false ); + bool bNotify( false ); + bool bDoLayout( false ); + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + parseResourceURL( rResourceURL, aElementType, aElementName ); + + WriteGuard aWriteLock( m_aLock ); + + ::rtl::OString aResName = rtl::OUStringToOString( aElementName, RTL_TEXTENCODING_ASCII_US ); + RTL_LOGFILE_CONTEXT_TRACE1( aLog, "framework (cd100003) Element %s requested.", aResName.getStr() ); + + if (( aElementType.equalsIgnoreAsciiCaseAscii( "statusbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "statusbar" )) || ( m_aStatusBarElement.m_aName == rResourceURL )) + { + implts_readStatusBarState( rResourceURL ); + if ( m_aStatusBarElement.m_bVisible && !m_aStatusBarElement.m_bMasterHide ) + { + aWriteLock.unlock(); + createElement( rResourceURL ); + + // 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# + uno::Reference< 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< awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY ); + Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow ) + { + pWindow->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); + bResult = true; + bNotify = true; + bDoLayout = true; + } + } + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" ) ) + { + aWriteLock.unlock(); + implts_showProgressBar(); + bResult = true; + bNotify = true; + bDoLayout = true; + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR ) && m_bVisible ) + { + bool bComponentAttached( m_aModuleIdentifier.getLength() > 0 ); + uno::Reference< uno::XInterface > xThis( m_xToolbarManager, uno::UNO_QUERY ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aWriteLock.unlock(); + + if ( pToolbarManager && bComponentAttached ) + { + bNotify = pToolbarManager->requestToolbar( rResourceURL ); + bDoLayout = true; + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" )) + { + uno::Reference< frame::XFrame > xFrame( m_xFrame ); + aWriteLock.unlock(); + + CreateDockingWindow( xFrame, aElementName ); + } + + if ( bNotify ) + implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_VISIBLE, uno::makeAny( rResourceURL ) ); + + return bResult; +} + +Reference< XUIElement > SAL_CALL LayoutManager::getElement( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + Reference< XUIElement > xUIElement = implts_findElement( aName ); + if ( !xUIElement.is() ) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< uno::XInterface > xThis( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager( m_pToolbarManager ); + aReadLock.unlock(); + + if ( pToolbarManager ) + xUIElement = pToolbarManager->getToolbar( aName ); + } + + return xUIElement; +} + +Sequence< Reference< ui::XUIElement > > SAL_CALL LayoutManager::getElements() +throw (uno::RuntimeException) +{ + ReadGuard aReadLock( m_aLock ); + uno::Reference< ui::XUIElement > xMenuBar( m_xMenuBar ); + uno::Reference< ui::XUIElement > xStatusBar( m_aStatusBarElement.m_xUIElement ); + uno::Reference< uno::XInterface > xThis( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager( m_pToolbarManager ); + aReadLock.unlock(); + + Sequence< Reference< ui::XUIElement > > aSeq; + if ( pToolbarManager ) + aSeq = pToolbarManager->getToolbars(); + + sal_Int32 nSize = aSeq.getLength(); + sal_Int32 nMenuBarIndex(-1); + sal_Int32 nStatusBarIndex(-1); + if ( xMenuBar.is() ) + { + nMenuBarIndex = nSize; + ++nSize; + } + if ( xStatusBar.is() ) + { + nStatusBarIndex = nSize; + ++nSize; + } + + aSeq.realloc(nSize); + if ( nMenuBarIndex >= 0 ) + aSeq[nMenuBarIndex] = xMenuBar; + if ( nStatusBarIndex >= 0 ) + aSeq[nStatusBarIndex] = xStatusBar; + + return aSeq; +} + +sal_Bool SAL_CALL LayoutManager::showElement( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::showElement" ); + + bool bResult( false ); + bool bNotify( false ); + bool bMustLayout( false ); + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + 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 && + implts_showStatusBar( sal_True )) + { + aWriteLock.unlock(); + + implts_writeWindowStateData( m_aStatusBarAlias, m_aStatusBarElement ); + bMustLayout = true; + bResult = true; + bNotify = true; + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" )) + { + bNotify = bResult = implts_showProgressBar(); + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< awt::XWindowListener > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + { + bNotify = pToolbarManager->showToolbar( aName ); + bMustLayout = pToolbarManager->isLayoutDirty(); + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" )) + { + ReadGuard aReadGuard( m_aLock ); + uno::Reference< frame::XFrame > xFrame( m_xFrame ); + uno::Reference< lang::XMultiServiceFactory > xSMGR( m_xSMGR ); + aReadGuard.unlock(); + + impl_setDockingWindowVisibility( xSMGR, xFrame, aElementName, true ); + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "toolpanel" )) + { + ReadGuard aReadGuard( m_aLock ); + uno::Reference< frame::XFrame > xFrame( m_xFrame ); + aReadGuard.unlock(); + ActivateToolPanel( m_xFrame, aName ); + } + + if ( bMustLayout ) + doLayout(); + + if ( bNotify ) + implts_notifyListeners( 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" ); + + bool bResult( false ); + bool bNotify( false ); + bool bMustLayout( false ); + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + 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() ) + { + m_bMenuVisible = sal_False; + + vos::OGuard aGuard( Application::GetSolarMutex() ); + SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow ); + if ( pSysWindow ) + { + MenuBar* pMenuBar = pSysWindow->GetMenuBar(); + if ( pMenuBar ) + { + pMenuBar->SetDisplayable( sal_False ); + bResult = true; + bNotify = 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 && + implts_hideStatusBar( sal_True )) + { + implts_writeWindowStateData( m_aStatusBarAlias, m_aStatusBarElement ); + bMustLayout = sal_True; + bNotify = sal_True; + bResult = sal_True; + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "progressbar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "progressbar" )) + { + bResult = bNotify = implts_hideProgressBar(); + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< uno::XInterface > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + bNotify = pToolbarManager->hideToolbar( aName ); + bMustLayout = pToolbarManager->isLayoutDirty(); + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" )) + { + ReadGuard aReadGuard( m_aLock ); + uno::Reference< frame::XFrame > xFrame( m_xFrame ); + uno::Reference< lang::XMultiServiceFactory > xSMGR( m_xSMGR ); + aReadGuard.unlock(); + + impl_setDockingWindowVisibility( xSMGR, xFrame, aElementName, false ); + } + + if ( bMustLayout ) + doLayout(); + + if ( bNotify ) + implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_INVISIBLE, uno::makeAny( aName ) ); + + return sal_False; +} + +sal_Bool SAL_CALL LayoutManager::dockWindow( const ::rtl::OUString& aName, DockingArea DockingArea, const awt::Point& Pos ) +throw (RuntimeException) +{ + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + parseResourceURL( aName, aElementType, aElementName ); + if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< uno::XInterface > xThis( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + { + pToolbarManager->dockToolbar( aName, DockingArea, Pos ); + if ( pToolbarManager->isLayoutDirty() ) + doLayout(); + } + } + return sal_False; +} + +::sal_Bool SAL_CALL LayoutManager::dockAllWindows( ::sal_Int16 /*nElementType*/ ) throw (uno::RuntimeException) +{ + ReadGuard aReadLock( m_aLock ); + bool bResult( false ); + uno::Reference< uno::XInterface > xThis( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + { + bResult = pToolbarManager->dockAllToolbars(); + if ( pToolbarManager->isLayoutDirty() ) + doLayout(); + } + return bResult; +} + +sal_Bool SAL_CALL LayoutManager::floatWindow( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + bool bResult( false ); + if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< uno::XInterface > xThis( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + { + bResult = pToolbarManager->floatToolbar( aName ); + if ( pToolbarManager->isLayoutDirty() ) + doLayout(); + } + } + return bResult; +} + +::sal_Bool SAL_CALL LayoutManager::lockWindow( const ::rtl::OUString& aName ) +throw (uno::RuntimeException) +{ + bool bResult( false ); + if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< uno::XInterface > xThis( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + { + bResult = pToolbarManager->lockToolbar( aName ); + if ( pToolbarManager->isLayoutDirty() ) + doLayout(); + } + } + return bResult; +} + +::sal_Bool SAL_CALL LayoutManager::unlockWindow( const ::rtl::OUString& aName ) +throw (uno::RuntimeException) +{ + bool bResult( false ); + if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< uno::XInterface > xThis( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + { + bResult = pToolbarManager->unlockToolbar( aName ); + if ( pToolbarManager->isLayoutDirty() ) + doLayout(); + } + } + return bResult; +} + +void SAL_CALL LayoutManager::setElementSize( const ::rtl::OUString& aName, const awt::Size& aSize ) +throw (RuntimeException) +{ + if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< uno::XInterface > xThis( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + { + pToolbarManager->setToolbarSize( aName, aSize ); + if ( pToolbarManager->isLayoutDirty() ) + doLayout(); + } + } +} + +void SAL_CALL LayoutManager::setElementPos( const ::rtl::OUString& aName, const awt::Point& aPos ) +throw (RuntimeException) +{ + if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager( m_pToolbarManager ); + aReadLock.unlock(); + + if ( pToolbarManager ) + { + pToolbarManager->setToolbarPos( aName, aPos ); + if ( pToolbarManager->isLayoutDirty() ) + doLayout(); + } + } +} + +void SAL_CALL LayoutManager::setElementPosSize( const ::rtl::OUString& aName, const awt::Point& aPos, const awt::Size& aSize ) +throw (RuntimeException) +{ + if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager( m_pToolbarManager ); + aReadLock.unlock(); + + if ( pToolbarManager ) + { + pToolbarManager->setToolbarPosSize( aName, aPos, aSize ); + if ( pToolbarManager->isLayoutDirty() ) + doLayout(); + } + } +} + +sal_Bool SAL_CALL LayoutManager::isElementVisible( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + + 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() ); + SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow ); + if ( pSysWindow ) + { + MenuBar* pMenuBar = pSysWindow->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< 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( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< frame::XLayoutManager > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + return pToolbarManager->isToolbarVisible( aName ); + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( "dockingwindow" )) + { + ReadGuard aReadGuard( m_aLock ); + uno::Reference< 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) +{ + if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< uno::XInterface > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + return pToolbarManager->isToolbarFloating( aName ); + } + + return sal_False; +} + +sal_Bool SAL_CALL LayoutManager::isElementDocked( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< uno::XInterface > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + return pToolbarManager->isToolbarDocked( aName ); + } + + return sal_False; +} + +::sal_Bool SAL_CALL LayoutManager::isElementLocked( const ::rtl::OUString& aName ) +throw (uno::RuntimeException) +{ + if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< uno::XInterface > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + return pToolbarManager->isToolbarLocked( aName ); + } + + return sal_False; +} + +awt::Size SAL_CALL LayoutManager::getElementSize( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< uno::XInterface > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + return pToolbarManager->getToolbarSize( aName ); + } + + return awt::Size(); +} + +awt::Point SAL_CALL LayoutManager::getElementPos( const ::rtl::OUString& aName ) +throw (RuntimeException) +{ + if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + ReadGuard aReadLock( m_aLock ); + uno::Reference< uno::XInterface > xToolbarManager( m_xToolbarManager, uno::UNO_QUERY ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( pToolbarManager ) + return pToolbarManager->getToolbarPos( aName ); + } + + return 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( 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( frame::LayoutManagerEvents::UNLOCK, a ); + + if ( bDoLayout ) + implts_doLayout_notify( sal_True ); +} + +void SAL_CALL LayoutManager::doLayout() +throw (RuntimeException) +{ + implts_doLayout_notify( sal_True ); +} + +//--------------------------------------------------------------------------------------------------------- +// ILayoutNotifications +//--------------------------------------------------------------------------------------------------------- +void LayoutManager::requestLayout( Hint eHint ) +{ + if ( eHint == HINT_TOOLBARSPACE_HAS_CHANGED ) + doLayout(); +} + +void LayoutManager::implts_doLayout_notify( sal_Bool bOuterResize ) +{ + bool bLayouted = implts_doLayout( false, bOuterResize ); + if ( bLayouted ) + implts_notifyListeners( frame::LayoutManagerEvents::LAYOUT, Any() ); +} + +sal_Bool LayoutManager::implts_doLayout( sal_Bool bForceRequestBorderSpace, sal_Bool bOuterResize ) +{ + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::implts_doLayout" ); + + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + ReadGuard aReadLock( m_aLock ); + + if ( !m_xFrame.is() || !m_bParentWindowVisible ) + return sal_False; + + bool bPreserveContentSize( m_bPreserveContentSize ); + bool bMustDoLayout( m_bMustDoLayout ); + bool bNoLock = ( m_nLockCount == 0 ); + awt::Rectangle aCurrBorderSpace( m_aDockingArea ); + Reference< awt::XWindow > xContainerWindow( m_xContainerWindow ); + Reference< awt::XTopWindow2 > xContainerTopWindow( m_xContainerTopWindow ); + Reference< awt::XWindow > xComponentWindow( m_xFrame->getComponentWindow() ); + Reference< XDockingAreaAcceptor > xDockingAreaAcceptor( m_xDockingAreaAcceptor ); + aReadLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + sal_Bool bLayouted( sal_False ); + + if ( bNoLock && xDockingAreaAcceptor.is() && xContainerWindow.is() && xComponentWindow.is() ) + { + bLayouted = sal_True; + + WriteGuard aWriteGuard( m_aLock ); + m_bDoLayout = sal_True; + aWriteGuard.unlock(); + + awt::Rectangle aDockSpace( implts_calcDockingAreaSizes() ); + awt::Rectangle aBorderSpace( aDockSpace ); + sal_Bool bGotRequestedBorderSpace( sal_True ); + + // We have to add the height of a possible status bar + aBorderSpace.Height += implts_getStatusBarSize().Height(); + + if ( !equalRectangles( aBorderSpace, aCurrBorderSpace ) || 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 + 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 ) + { + aWriteGuard.lock(); + m_aDockingArea = aBorderSpace; + m_bMustDoLayout = sal_False; + aWriteGuard.unlock(); + } + } + + if ( bGotRequestedBorderSpace ) + { + ::Size aContainerSize; + ::Size aStatusBarSize; + + // Interim solution to let the layout method within the + // toolbar layout manager. + implts_setOffset( implts_getStatusBarSize().Height() ); + m_pToolbarManager->setDockingArea( aDockSpace ); + + // Subtract status bar size from our container output size. Docking area windows + // don't contain the status bar! + aStatusBarSize = implts_getStatusBarSize(); + aContainerSize = implts_getContainerWindowOutputSize(); + aContainerSize.Height() -= aStatusBarSize.Height(); + + m_pToolbarManager->doLayout(aContainerSize); + + // Position the status bar + if ( aStatusBarSize.Height() > 0 ) + { + implts_setStatusBarPosSize( ::Point( 0, std::max(( aContainerSize.Height() ), long( 0 ))), + ::Size( aContainerSize.Width(),aStatusBarSize.Height() )); + } + + xDockingAreaAcceptor->setDockingAreaSpace( aBorderSpace ); + + aWriteGuard.lock(); + m_bDoLayout = sal_False; + aWriteGuard.unlock(); + } + } + + return bLayouted; +} + +sal_Bool LayoutManager::implts_resizeContainerWindow( const awt::Size& rContainerSize, + const awt::Point& rComponentPos ) +{ + 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(); + + // 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 whether 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, awt::PosSize::SIZE ); + // position the component window + xComponentWindow->setPosSize( rComponentPos.X, rComponentPos.Y, 0, 0, awt::PosSize::POS ); + return sal_True; +} + +void SAL_CALL LayoutManager::setVisible( sal_Bool bVisible ) +throw (uno::RuntimeException) +{ + WriteGuard aWriteLock( m_aLock ); + sal_Bool bWasVisible( m_bVisible ); + m_bVisible = bVisible; + aWriteLock.unlock(); + + if ( bWasVisible != bVisible ) + implts_setVisibleState( bVisible ); +} + +sal_Bool SAL_CALL LayoutManager::isVisible() +throw (uno::RuntimeException) +{ + ReadGuard aReadLock( m_aLock ); + return m_bVisible; +} + +::Size LayoutManager::implts_getStatusBarSize() +{ + ReadGuard aReadLock( m_aLock ); + bool bStatusBarVisible( isElementVisible( m_aStatusBarAlias )); + bool bProgressBarVisible( isElementVisible( m_aProgressBarAlias )); + bool bVisible( m_bVisible ); + Reference< XUIElement > xStatusBar( m_aStatusBarElement.m_xUIElement ); + Reference< XUIElement > xProgressBar( m_aProgressBarElement.m_xUIElement ); + + Reference< awt::XWindow > xWindow; + if ( bStatusBarVisible && bVisible && xStatusBar.is() ) + xWindow = Reference< 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() ) + { + awt::Rectangle aPosSize = xWindow->getPosSize(); + return ::Size( aPosSize.Width, aPosSize.Height ); + } + else + return ::Size(); +} + +awt::Rectangle LayoutManager::implts_calcDockingAreaSizes() +{ + ReadGuard aReadLock( m_aLock ); + Reference< awt::XWindow > xContainerWindow( m_xContainerWindow ); + Reference< XDockingAreaAcceptor > xDockingAreaAcceptor( m_xDockingAreaAcceptor ); + aReadLock.unlock(); + + awt::Rectangle aBorderSpace; + if ( xDockingAreaAcceptor.is() && xContainerWindow.is() ) + aBorderSpace = m_pToolbarManager->getDockingArea(); + + return aBorderSpace; +} + +void LayoutManager::implts_setDockingAreaWindowSizes( const awt::Rectangle& /*rBorderSpace*/ ) +{ + ReadGuard aReadLock( m_aLock ); + Reference< awt::XWindow > xContainerWindow( m_xContainerWindow ); + 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 ); + ::Size aStatusBarSize = implts_getStatusBarSize(); + + // 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() +{ + WriteGuard aWriteLock( m_aLock ); + bool bShowCloser( m_bMenuBarCloser ); + Reference< awt::XWindow > xContainerWindow( m_xContainerWindow ); + aWriteLock.unlock(); + + if ( xContainerWindow.is() ) + { + vos::OGuard aGuard( Application::GetSolarMutex() ); + + SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow ); + if ( pSysWindow ) + { + MenuBar* pMenuBar = pSysWindow->GetMenuBar(); + if ( pMenuBar ) + { + // TODO remove link on sal_False ?! + pMenuBar->ShowCloser( bShowCloser ); + pMenuBar->SetCloserHdl( LINK( this, LayoutManager, MenuBarClose )); + } + } + } +} + +sal_Bool LayoutManager::implts_resetMenuBar() +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + sal_Bool bMenuVisible( m_bMenuVisible ); + Reference< awt::XWindow > xContainerWindow( m_xContainerWindow ); + + MenuBar* pSetMenuBar = 0; + if ( m_xInplaceMenuBar.is() ) + pSetMenuBar = (MenuBar *)m_pInplaceMenuBar->GetMenuBar(); + else + { + MenuBarWrapper* pMenuBarWrapper = static_cast< MenuBarWrapper* >( m_xMenuBar.get() ); + if ( pMenuBarWrapper ) + pSetMenuBar = (MenuBar *)pMenuBarWrapper->GetMenuBarManager()->GetMenuBar(); + } + aWriteLock.unlock(); + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + + vos::OGuard aGuard( Application::GetSolarMutex() ); + SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow ); + if ( pSysWindow && bMenuVisible && pSetMenuBar ) + { + pSysWindow->SetMenuBar( pSetMenuBar ); + pSetMenuBar->SetDisplayable( sal_True ); + return sal_True; + } + + return sal_False; +} + +void LayoutManager::implts_setMenuBarCloser(sal_Bool bCloserState) +{ + WriteGuard aWriteLock( m_aLock ); + m_bMenuBarCloser = bCloserState; + aWriteLock.unlock(); + + implts_updateMenuBarClose(); +} + +IMPL_LINK( LayoutManager, MenuBarClose, MenuBar *, EMPTYARG ) +{ + ReadGuard aReadLock( m_aLock ); + uno::Reference< frame::XDispatchProvider > xProvider(m_xFrame, uno::UNO_QUERY); + uno::Reference< lang::XMultiServiceFactory > xSMGR = m_xSMGR; + aReadLock.unlock(); + + if ( !xProvider.is()) + return 0; + + uno::Reference< frame::XDispatchHelper > xDispatcher( + xSMGR->createInstance(SERVICENAME_DISPATCHHELPER), uno::UNO_QUERY_THROW); + + xDispatcher->executeDispatch( + xProvider, + ::rtl::OUString::createFromAscii(".uno:CloseWin"), + ::rtl::OUString::createFromAscii("_self"), + 0, + uno::Sequence< beans::PropertyValue >()); + + return 0; +} + +IMPL_LINK( LayoutManager, SettingsChanged, void*, EMPTYARG ) +{ + return 1; +} + +//--------------------------------------------------------------------------------------------------------- +// XLayoutManagerEventBroadcaster +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL LayoutManager::addLayoutManagerEventListener( const uno::Reference< frame::XLayoutManagerListener >& xListener ) +throw (uno::RuntimeException) +{ + m_aListenerContainer.addInterface( ::getCppuType( (const uno::Reference< frame::XLayoutManagerListener >*)NULL ), xListener ); +} + +void SAL_CALL LayoutManager::removeLayoutManagerEventListener( const uno::Reference< frame::XLayoutManagerListener >& xListener ) +throw (uno::RuntimeException) +{ + m_aListenerContainer.removeInterface( ::getCppuType( (const uno::Reference< frame::XLayoutManagerListener >*)NULL ), xListener ); +} + +void LayoutManager::implts_notifyListeners( short nEvent, uno::Any aInfoParam ) +{ + lang::EventObject aSource( static_cast< ::cppu::OWeakObject*>(this) ); + ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( ::getCppuType( ( const uno::Reference< frame::XLayoutManagerListener >*) NULL ) ); + if (pContainer!=NULL) + { + ::cppu::OInterfaceIteratorHelper pIterator(*pContainer); + while (pIterator.hasMoreElements()) + { + try + { + ((frame::XLayoutManagerListener*)pIterator.next())->layoutEvent( aSource, nEvent, aInfoParam ); + } + catch( uno::RuntimeException& ) + { + pIterator.remove(); + } + } + } +} + +//--------------------------------------------------------------------------------------------------------- +// XWindowListener +//--------------------------------------------------------------------------------------------------------- +void SAL_CALL LayoutManager::windowResized( const awt::WindowEvent& aEvent ) +throw( uno::RuntimeException ) +{ + /* SAFE AREA ----------------------------------------------------------------------------------------------- */ + WriteGuard aWriteLock( m_aLock ); + + if ( !m_xDockingAreaAcceptor.is() ) + return; + + // Request to set docking area space again. + awt::Rectangle aDockingArea( m_aDockingArea ); + Reference< XDockingAreaAcceptor > xDockingAreaAcceptor( m_xDockingAreaAcceptor ); + Reference< 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< awt::XWindow > xComponentWindow( m_xFrame->getComponentWindow() ); + if( xComponentWindow.is() == sal_True ) + { + uno::Reference< awt::XDevice > xDevice( m_xFrame->getContainerWindow(), uno::UNO_QUERY ); + + // Convert relativ size to output size. + awt::Rectangle aRectangle = m_xFrame->getContainerWindow()->getPosSize(); + awt::DeviceInfo aInfo = xDevice->getInfo(); + 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, awt::PosSize::POSSIZE ); + } + } +} + +void SAL_CALL LayoutManager::windowMoved( const awt::WindowEvent& ) throw( uno::RuntimeException ) +{ +} + +void SAL_CALL LayoutManager::windowShown( const lang::EventObject& aEvent ) throw( uno::RuntimeException ) +{ + ReadGuard aReadLock( m_aLock ); + Reference< awt::XWindow > xContainerWindow( m_xContainerWindow ); + bool bParentWindowVisible( m_bParentWindowVisible ); + aReadLock.unlock(); + + Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY ); + if ( xIfac == aEvent.Source ) + { + bool bSetVisible = false; + + WriteGuard aWriteLock( m_aLock ); + m_bParentWindowVisible = true; + bSetVisible = ( m_bParentWindowVisible != bParentWindowVisible ); + aWriteLock.unlock(); + + if ( bSetVisible ) + implts_updateUIElementsVisibleState( sal_True ); + } +} + +void SAL_CALL LayoutManager::windowHidden( const lang::EventObject& aEvent ) throw( uno::RuntimeException ) +{ + ReadGuard aReadLock( m_aLock ); + Reference< awt::XWindow > xContainerWindow( m_xContainerWindow ); + bool bParentWindowVisible( m_bParentWindowVisible ); + aReadLock.unlock(); + + Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY ); + if ( xIfac == aEvent.Source ) + { + bool bSetInvisible = false; + + WriteGuard aWriteLock( m_aLock ); + m_bParentWindowVisible = false; + bSetInvisible = ( m_bParentWindowVisible != bParentWindowVisible ); + aWriteLock.unlock(); + + if ( bSetInvisible ) + implts_updateUIElementsVisibleState( sal_False ); + } +} + +IMPL_LINK( LayoutManager, AsyncLayoutHdl, Timer *, EMPTYARG ) +{ + ReadGuard aReadLock( m_aLock ); + m_aAsyncLayoutTimer.Stop(); + + if( !m_xContainerWindow.is() ) + return 0; + + 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; +} + +//--------------------------------------------------------------------------------------------------------- +// 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)" ); + + WriteGuard aWriteLock( m_aLock ); + m_bComponentAttached = sal_True; + m_bMustDoLayout = sal_True; + aWriteLock.unlock(); + + 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)" ); + + WriteGuard aWriteLock( m_aLock ); + m_bActive = ( aEvent.Action == FrameAction_FRAME_UI_ACTIVATED ); + aWriteLock.unlock(); + + implts_toggleFloatingUIElementsVisibility( aEvent.Action == FrameAction_FRAME_UI_ACTIVATED ); + } + else if ( aEvent.Action == FrameAction_COMPONENT_DETACHING ) + { + RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::LayoutManager::frameAction (COMPONENT_DETACHING)" ); + + WriteGuard aWriteLock( m_aLock ); + m_bComponentAttached = sal_False; + aWriteLock.unlock(); + + implts_reset( sal_False ); + } +} + +// ______________________________________________ + +void SAL_CALL LayoutManager::disposing( const 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 ) ); + + // destroy all elements, it's possible that dettaching is NOT called! + implts_destroyElements(); + impl_clearUpMenuBar(); + m_xMenuBar.clear(); + if ( m_xInplaceMenuBar.is() ) + { + m_pInplaceMenuBar = 0; + m_xInplaceMenuBar->dispose(); + } + m_xInplaceMenuBar.clear(); + m_xContainerWindow.clear(); + m_xContainerTopWindow.clear(); + + // forward disposing call to toolbar manager + if ( m_pToolbarManager != NULL ) + m_pToolbarManager->disposing(rEvent); + + 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< 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. + uno::Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + if ( pToolbarManager ) + { + uno::Reference< awt::XWindowPeer > aEmptyWindowPeer; + pToolbarManager->setParentWindow( aEmptyWindowPeer ); + } + 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. + uno::Reference< frame::XLayoutManager > xThis( static_cast< ::cppu::OWeakObject* >(this), uno::UNO_QUERY ); + lang::EventObject aEvent( xThis ); + m_aListenerContainer.disposeAndClear( aEvent ); + } +} + +void SAL_CALL LayoutManager::elementInserted( const ui::ConfigurationEvent& Event ) throw (uno::RuntimeException) +{ + ReadGuard aReadLock( m_aLock ); + Reference< XFrame > xFrame( m_xFrame ); + Reference< ui::XUIConfigurationListener > xUICfgListener( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( xFrame.is() ) + { + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + bool bRefreshLayout(false); + + parseResourceURL( Event.ResourceURL, aElementType, aElementName ); + if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + if ( xUICfgListener.is() ) + { + xUICfgListener->elementInserted( Event ); + bRefreshLayout = pToolbarManager->isLayoutDirty(); + } + } + else if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_MENUBAR )) + { + Reference< XUIElement > xUIElement = implts_findElement( Event.ResourceURL ); + Reference< XUIElementSettings > xElementSettings( xUIElement, UNO_QUERY ); + if ( xElementSettings.is() ) + { + ::rtl::OUString aConfigSourcePropName( RTL_CONSTASCII_USTRINGPARAM( "ConfigurationSource" )); + uno::Reference< XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY ); + if ( xPropSet.is() ) + { + if ( Event.Source == uno::Reference< uno::XInterface >( m_xDocCfgMgr, uno::UNO_QUERY )) + xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( m_xDocCfgMgr )); + } + xElementSettings->updateSettings(); + } + } + + if ( bRefreshLayout ) + doLayout(); + } +} + +void SAL_CALL LayoutManager::elementRemoved( const ui::ConfigurationEvent& Event ) throw (uno::RuntimeException) +{ + ReadGuard aReadLock( m_aLock ); + Reference< frame::XFrame > xFrame( m_xFrame ); + Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager ); + Reference< awt::XWindow > xContainerWindow( m_xContainerWindow ); + Reference< ui::XUIElement > xMenuBar( m_xMenuBar ); + Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr ); + Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( xFrame.is() ) + { + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + bool bRefreshLayout(false); + + parseResourceURL( Event.ResourceURL, aElementType, aElementName ); + if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + if ( xToolbarManager.is() ) + { + xToolbarManager->elementRemoved( Event ); + bRefreshLayout = pToolbarManager->isLayoutDirty(); + } + } + else + { + Reference< XUIElement > xUIElement = implts_findElement( Event.ResourceURL ); + 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 >( xDocCfgMgr, UNO_QUERY )) + { + // document settings removed + if ( xModuleCfgMgr->hasSettings( Event.ResourceURL )) + { + xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( m_xModuleCfgMgr )); + xElementSettings->updateSettings(); + return; + } + } + + bNoSettings = true; + } + + // No settings anymore, element must be destroyed + if ( xContainerWindow.is() && bNoSettings ) + { + if ( aElementType.equalsIgnoreAsciiCaseAscii( "menubar" ) && aElementName.equalsIgnoreAsciiCaseAscii( "menubar" )) + { + SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow ); + if ( pSysWindow && !m_bInplaceMenuSet ) + pSysWindow->SetMenuBar( 0 ); + + Reference< XComponent > xComp( xMenuBar, UNO_QUERY ); + if ( xComp.is() ) + xComp->dispose(); + + WriteGuard aWriteLock( m_aLock ); + m_xMenuBar.clear(); + } + } + } + } + + if ( bRefreshLayout ) + doLayout(); + } +} + +void SAL_CALL LayoutManager::elementReplaced( const ui::ConfigurationEvent& Event ) throw (uno::RuntimeException) +{ + ReadGuard aReadLock( m_aLock ); + Reference< XFrame > xFrame( m_xFrame ); + Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + aReadLock.unlock(); + + if ( xFrame.is() ) + { + ::rtl::OUString aElementType; + ::rtl::OUString aElementName; + bool bRefreshLayout(false); + + parseResourceURL( Event.ResourceURL, aElementType, aElementName ); + if ( aElementType.equalsIgnoreAsciiCaseAscii( UIRESOURCETYPE_TOOLBAR )) + { + if ( xToolbarManager.is() ) + { + xToolbarManager->elementReplaced( Event ); + bRefreshLayout = pToolbarManager->isLayoutDirty(); + } + } + else + { + Reference< XUIElement > xUIElement = implts_findElement( Event.ResourceURL ); + 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 ( bRefreshLayout ) + doLayout(); + } +} + +//--------------------------------------------------------------------------------------------------------- +// OPropertySetHelper +//--------------------------------------------------------------------------------------------------------- +sal_Bool SAL_CALL LayoutManager::convertFastPropertyValue( Any& aConvertedValue, + Any& aOldValue, + sal_Int32 nHandle, + const Any& aValue ) throw( lang::IllegalArgumentException ) +{ + return LayoutManager_PBase::convertFastPropertyValue( aConvertedValue, aOldValue, nHandle, aValue ); +} + +void SAL_CALL LayoutManager::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, + const uno::Any& aValue ) throw( 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_False); + if (( aValue >>= bValue ) && bValue ) + { + ReadGuard aReadLock( m_aLock ); + Reference< ui::XUIConfigurationListener > xToolbarManager( m_xToolbarManager ); + ToolbarLayoutManager* pToolbarManager = m_pToolbarManager; + bool bAutomaticToolbars( m_bAutomaticToolbars ); + aReadLock.unlock(); + + if ( pToolbarManager ) + pToolbarManager->refreshToolbarsVisibility( bAutomaticToolbars ); + } + break; + } + + case LAYOUTMANAGER_PROPHANDLE_HIDECURRENTUI: + implts_setCurrentUIVisibility( !m_bHideCurrentUI ); + break; + default: break; + } +} + +void SAL_CALL LayoutManager::getFastPropertyValue( uno::Any& aValue, sal_Int32 nHandle ) const +{ + LayoutManager_PBase::getFastPropertyValue( aValue, nHandle ); +} + +::cppu::IPropertyArrayHelper& SAL_CALL LayoutManager::getInfoHelper() +{ + static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL; + + if( pInfoHelper == NULL ) + { + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + + if( pInfoHelper == NULL ) + { + uno::Sequence< beans::Property > aProperties; + describeProperties( aProperties ); + static ::cppu::OPropertyArrayHelper aInfoHelper( aProperties, sal_True ); + pInfoHelper = &aInfoHelper; + } + } + + return(*pInfoHelper); +} + +uno::Reference< beans::XPropertySetInfo > SAL_CALL LayoutManager::getPropertySetInfo() throw (uno::RuntimeException) +{ + static uno::Reference< beans::XPropertySetInfo >* pInfo = NULL; + + if( pInfo == NULL ) + { + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + + if( pInfo == NULL ) + { + static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + pInfo = &xInfo; + } + } + + return (*pInfo); +} + +} // namespace framework |