/************************************************************************* * * 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 * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include // interface includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // other includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // 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(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->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( 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 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