Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / framework / source / layoutmanager / layoutmanager.cxx
blob3283798bd7e38d8912dd763536db10ddd1e6fdb6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <memory>
21 #include <config_feature_desktop.h>
23 #include <properties.h>
24 #include <services/layoutmanager.hxx>
25 #include "helpers.hxx"
27 #include <framework/sfxhelperfunctions.hxx>
28 #include <uielement/menubarwrapper.hxx>
29 #include <framework/addonsoptions.hxx>
30 #include <toolkit/helper/convert.hxx>
31 #include <uielement/progressbarwrapper.hxx>
32 #include <uiconfiguration/globalsettings.hxx>
33 #include <uiconfiguration/windowstateproperties.hxx>
34 #include "toolbarlayoutmanager.hxx"
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/beans/PropertyAttribute.hpp>
38 #include <com/sun/star/frame/ModuleManager.hpp>
39 #include <com/sun/star/frame/XModel.hpp>
40 #include <com/sun/star/frame/FrameAction.hpp>
41 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
42 #include <com/sun/star/awt/XTopWindow.hpp>
43 #include <com/sun/star/awt/XSystemDependentMenuPeer.hpp>
44 #include <com/sun/star/lang/SystemDependent.hpp>
45 #include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
46 #include <com/sun/star/awt/PosSize.hpp>
47 #include <com/sun/star/awt/XDevice.hpp>
48 #include <com/sun/star/awt/XSystemDependentWindowPeer.hpp>
49 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
50 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
51 #include <com/sun/star/ui/UIElementType.hpp>
52 #include <com/sun/star/ui/theWindowStateConfiguration.hpp>
53 #include <com/sun/star/ui/theUIElementFactoryManager.hpp>
54 #include <com/sun/star/container/XNameReplace.hpp>
55 #include <com/sun/star/container/XNameContainer.hpp>
56 #include <com/sun/star/frame/LayoutManagerEvents.hpp>
57 #include <com/sun/star/frame/XDispatchProvider.hpp>
58 #include <com/sun/star/frame/DispatchHelper.hpp>
59 #include <com/sun/star/lang/DisposedException.hpp>
60 #include <com/sun/star/util/URLTransformer.hpp>
62 #include <comphelper/lok.hxx>
63 #include <svtools/imgdef.hxx>
64 #include <tools/diagnose_ex.h>
65 #include <vcl/status.hxx>
66 #include <vcl/settings.hxx>
67 #include <vcl/window.hxx>
68 #include <vcl/dockingarea.hxx>
69 #include <vcl/svapp.hxx>
70 #include <vcl/i18nhelp.hxx>
71 #include <vcl/wall.hxx>
72 #include <toolkit/helper/vclunohelper.hxx>
73 #include <toolkit/awt/vclxwindow.hxx>
74 #include <toolkit/awt/vclxmenu.hxx>
75 #include <comphelper/uno3.hxx>
76 #include <rtl/instance.hxx>
77 #include <unotools/cmdoptions.hxx>
78 #include <unotools/compatibilityviewoptions.hxx>
80 #include <rtl/ref.hxx>
81 #include <rtl/strbuf.hxx>
82 #include <sal/log.hxx>
84 #include <algorithm>
86 // using namespace
87 using namespace ::com::sun::star;
88 using namespace ::com::sun::star::uno;
89 using namespace ::com::sun::star::beans;
90 using namespace ::com::sun::star::util;
91 using namespace ::com::sun::star::lang;
92 using namespace ::com::sun::star::container;
93 using namespace ::com::sun::star::ui;
94 using namespace ::com::sun::star::frame;
96 static const char STATUS_BAR_ALIAS[] = "private:resource/statusbar/statusbar";
98 namespace framework
101 IMPLEMENT_FORWARD_XTYPEPROVIDER2( LayoutManager, LayoutManager_Base, LayoutManager_PBase )
102 IMPLEMENT_FORWARD_XINTERFACE2( LayoutManager, LayoutManager_Base, LayoutManager_PBase )
104 LayoutManager::LayoutManager( const Reference< XComponentContext >& xContext ) : LayoutManager_Base()
105 , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >(m_aMutex)
106 , LayoutManager_PBase( *static_cast< ::cppu::OBroadcastHelper* >(this) )
107 , m_xContext( xContext )
108 , m_xURLTransformer( URLTransformer::create(xContext) )
109 , m_nLockCount( 0 )
110 , m_bInplaceMenuSet( false )
111 , m_bMenuVisible( true )
112 , m_bVisible( true )
113 , m_bParentWindowVisible( false )
114 , m_bMustDoLayout( true )
115 #if HAVE_FEATURE_DESKTOP
116 , m_bAutomaticToolbars( true )
117 #else
118 , m_bAutomaticToolbars( false )
119 #endif
120 , m_bHideCurrentUI( false )
121 , m_bGlobalSettings( false )
122 , m_bPreserveContentSize( false )
123 , m_bMenuBarCloseButton( false )
124 , m_xModuleManager( ModuleManager::create( xContext ))
125 , m_xUIElementFactoryManager( ui::theUIElementFactoryManager::get(xContext) )
126 , m_xPersistentWindowStateSupplier( ui::theWindowStateConfiguration::get( xContext ) )
127 , m_aListenerContainer( m_aMutex )
129 // Initialize statusbar member
130 m_aStatusBarElement.m_aType = "statusbar";
131 m_aStatusBarElement.m_aName = STATUS_BAR_ALIAS;
133 if (!comphelper::LibreOfficeKit::isActive())
135 m_xToolbarManager = new ToolbarLayoutManager( xContext, Reference<XUIElementFactory>(m_xUIElementFactoryManager, UNO_QUERY_THROW), this );
138 m_aAsyncLayoutTimer.SetPriority( TaskPriority::HIGH_IDLE );
139 m_aAsyncLayoutTimer.SetTimeout( 50 );
140 m_aAsyncLayoutTimer.SetInvokeHandler( LINK( this, LayoutManager, AsyncLayoutHdl ) );
141 m_aAsyncLayoutTimer.SetDebugName( "framework::LayoutManager m_aAsyncLayoutTimer" );
143 registerProperty( LAYOUTMANAGER_PROPNAME_ASCII_AUTOMATICTOOLBARS, LAYOUTMANAGER_PROPHANDLE_AUTOMATICTOOLBARS, css::beans::PropertyAttribute::TRANSIENT, &m_bAutomaticToolbars, cppu::UnoType<decltype(m_bAutomaticToolbars)>::get() );
144 registerProperty( LAYOUTMANAGER_PROPNAME_ASCII_HIDECURRENTUI, LAYOUTMANAGER_PROPHANDLE_HIDECURRENTUI, beans::PropertyAttribute::TRANSIENT, &m_bHideCurrentUI, cppu::UnoType<decltype(m_bHideCurrentUI)>::get() );
145 registerProperty( LAYOUTMANAGER_PROPNAME_ASCII_LOCKCOUNT, LAYOUTMANAGER_PROPHANDLE_LOCKCOUNT, beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY, &m_nLockCount, cppu::UnoType<decltype(m_nLockCount)>::get() );
146 registerProperty( LAYOUTMANAGER_PROPNAME_MENUBARCLOSER, LAYOUTMANAGER_PROPHANDLE_MENUBARCLOSER, beans::PropertyAttribute::TRANSIENT, &m_bMenuBarCloseButton, cppu::UnoType<decltype(m_bMenuBarCloseButton)>::get() );
147 registerPropertyNoMember( LAYOUTMANAGER_PROPNAME_ASCII_REFRESHVISIBILITY, LAYOUTMANAGER_PROPHANDLE_REFRESHVISIBILITY, beans::PropertyAttribute::TRANSIENT, cppu::UnoType<bool>::get(), css::uno::Any(false) );
148 registerProperty( LAYOUTMANAGER_PROPNAME_ASCII_PRESERVE_CONTENT_SIZE, LAYOUTMANAGER_PROPHANDLE_PRESERVE_CONTENT_SIZE, beans::PropertyAttribute::TRANSIENT, &m_bPreserveContentSize, cppu::UnoType<decltype(m_bPreserveContentSize)>::get() );
151 LayoutManager::~LayoutManager()
153 m_aAsyncLayoutTimer.Stop();
154 setDockingAreaAcceptor(nullptr);
155 m_pGlobalSettings.reset();
158 void LayoutManager::implts_createMenuBar(const OUString& rMenuBarName)
160 SolarMutexGuard aWriteLock;
162 // Create a customized menu if compatibility mode is on
163 SvtCompatibilityViewOptions aCompOptions;
164 if( aCompOptions.HasMSOCompatibleFormsMenu() && m_aModuleIdentifier == "com.sun.star.text.TextDocument" )
166 implts_createMSCompatibleMenuBar(rMenuBarName);
169 // Create the default menubar otherwise
170 if (!m_bInplaceMenuSet && !m_xMenuBar.is())
172 m_xMenuBar = implts_createElement( rMenuBarName );
173 if ( m_xMenuBar.is() )
175 SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
176 if ( pSysWindow )
178 Reference< awt::XMenuBar > xMenuBar;
180 Reference< XPropertySet > xPropSet( m_xMenuBar, UNO_QUERY );
181 if ( xPropSet.is() )
185 xPropSet->getPropertyValue("XMenuBar") >>= xMenuBar;
187 catch (const beans::UnknownPropertyException&)
190 catch (const lang::WrappedTargetException&)
195 if ( xMenuBar.is() )
197 VCLXMenu* pAwtMenuBar = comphelper::getUnoTunnelImplementation<VCLXMenu>( xMenuBar );
198 if ( pAwtMenuBar )
200 MenuBar* pMenuBar = static_cast<MenuBar*>(pAwtMenuBar->GetMenu());
201 if ( pMenuBar )
203 pSysWindow->SetMenuBar(pMenuBar);
204 pMenuBar->SetDisplayable( m_bMenuVisible );
205 implts_updateMenuBarClose();
214 // Internal helper function
215 void LayoutManager::impl_clearUpMenuBar()
217 implts_lock();
219 // Clear up VCL menu bar to prepare shutdown
220 if ( m_xContainerWindow.is() )
222 SolarMutexGuard aGuard;
224 SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
225 if ( pSysWindow )
227 MenuBar* pSetMenuBar = nullptr;
228 if ( m_xInplaceMenuBar.is() )
229 pSetMenuBar = static_cast<MenuBar *>(m_xInplaceMenuBar->GetMenuBar());
230 else
232 Reference< awt::XMenuBar > xMenuBar;
234 Reference< XPropertySet > xPropSet( m_xMenuBar, UNO_QUERY );
235 if ( xPropSet.is() )
239 xPropSet->getPropertyValue("XMenuBar") >>= xMenuBar;
241 catch (const beans::UnknownPropertyException&)
244 catch (const lang::WrappedTargetException&)
249 VCLXMenu* pAwtMenuBar = comphelper::getUnoTunnelImplementation<VCLXMenu>( xMenuBar );
250 if ( pAwtMenuBar )
251 pSetMenuBar = static_cast<MenuBar*>(pAwtMenuBar->GetMenu());
254 MenuBar* pTopMenuBar = pSysWindow->GetMenuBar();
255 if ( pSetMenuBar == pTopMenuBar )
256 pSysWindow->SetMenuBar( nullptr );
260 // reset inplace menubar manager
261 VclPtr<Menu> pMenuBar;
262 if (m_xInplaceMenuBar.is())
264 pMenuBar = m_xInplaceMenuBar->GetMenuBar();
265 m_xInplaceMenuBar->dispose();
266 m_xInplaceMenuBar.clear();
268 pMenuBar.disposeAndClear();
269 m_bInplaceMenuSet = false;
271 Reference< XComponent > xComp( m_xMenuBar, UNO_QUERY );
272 if ( xComp.is() )
273 xComp->dispose();
274 m_xMenuBar.clear();
275 implts_unlock();
278 void LayoutManager::implts_lock()
280 SolarMutexGuard g;
281 ++m_nLockCount;
284 bool LayoutManager::implts_unlock()
286 SolarMutexGuard g;
287 m_nLockCount = std::max( m_nLockCount-1, static_cast<sal_Int32>(0) );
288 return ( m_nLockCount == 0 );
291 void LayoutManager::implts_reset( bool bAttached )
293 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
294 SolarMutexClearableGuard aReadLock;
295 Reference< XFrame > xFrame = m_xFrame;
296 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
297 Reference< XUIConfiguration > xModuleCfgMgr( m_xModuleCfgMgr, UNO_QUERY );
298 Reference< XUIConfiguration > xDocCfgMgr( m_xDocCfgMgr, UNO_QUERY );
299 Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
300 Reference< XComponentContext > xContext( m_xContext );
301 Reference< XNameAccess > xPersistentWindowStateSupplier( m_xPersistentWindowStateSupplier );
302 rtl::Reference<ToolbarLayoutManager> xToolbarManager( m_xToolbarManager );
303 OUString aModuleIdentifier( m_aModuleIdentifier );
304 bool bAutomaticToolbars( m_bAutomaticToolbars );
305 aReadLock.clear();
306 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
308 implts_lock();
310 Reference< XModel > xModel;
311 if ( xFrame.is() )
313 if ( bAttached )
315 OUString aOldModuleIdentifier( aModuleIdentifier );
318 aModuleIdentifier = m_xModuleManager->identify( xFrame );
320 catch( const Exception& ) {}
322 if ( !aModuleIdentifier.isEmpty() && aOldModuleIdentifier != aModuleIdentifier )
324 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier;
325 if ( xContext.is() )
326 xModuleCfgSupplier = theModuleUIConfigurationManagerSupplier::get( xContext );
328 if ( xModuleCfgMgr.is() )
332 // Remove listener to old module ui configuration manager
333 xModuleCfgMgr->removeConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
335 catch (const Exception&)
342 // Add listener to new module ui configuration manager
343 xModuleCfgMgr.set( xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier ), UNO_QUERY );
344 if ( xModuleCfgMgr.is() )
345 xModuleCfgMgr->addConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
347 catch (const Exception&)
353 // Retrieve persistent window state reference for our new module
354 if ( xPersistentWindowStateSupplier.is() )
355 xPersistentWindowStateSupplier->getByName( aModuleIdentifier ) >>= xPersistentWindowState;
357 catch (const NoSuchElementException&)
360 catch (const WrappedTargetException&)
365 xModel = impl_getModelFromFrame( xFrame );
366 if ( xModel.is() )
368 Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier( xModel, UNO_QUERY );
369 if ( xUIConfigurationManagerSupplier.is() )
371 if ( xDocCfgMgr.is() )
375 // Remove listener to old ui configuration manager
376 xDocCfgMgr->removeConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
378 catch (const Exception&)
385 xDocCfgMgr.set( xUIConfigurationManagerSupplier->getUIConfigurationManager(), UNO_QUERY );
386 if ( xDocCfgMgr.is() )
387 xDocCfgMgr->addConfigurationListener( Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
389 catch (const Exception&)
395 else
397 // Remove configuration listeners before we can release our references
398 if ( xModuleCfgMgr.is() )
402 xModuleCfgMgr->removeConfigurationListener(
403 Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
405 catch (const Exception&)
410 if ( xDocCfgMgr.is() )
414 xDocCfgMgr->removeConfigurationListener(
415 Reference< XUIConfigurationListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
417 catch (const Exception&)
422 // Release references to our configuration managers as we currently don't have
423 // an attached module.
424 xModuleCfgMgr.clear();
425 xDocCfgMgr.clear();
426 xPersistentWindowState.clear();
427 aModuleIdentifier.clear();
430 Reference< XUIConfigurationManager > xModCfgMgr( xModuleCfgMgr, UNO_QUERY );
431 Reference< XUIConfigurationManager > xDokCfgMgr( xDocCfgMgr, UNO_QUERY );
433 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
434 SolarMutexClearableGuard aWriteLock;
435 m_aDockingArea = awt::Rectangle();
436 m_aModuleIdentifier = aModuleIdentifier;
437 m_xModuleCfgMgr = xModCfgMgr;
438 m_xDocCfgMgr = xDokCfgMgr;
439 m_xPersistentWindowState = xPersistentWindowState;
440 m_aStatusBarElement.m_bStateRead = false; // reset state to read data again!
441 aWriteLock.clear();
442 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
444 // reset/notify toolbar layout manager
445 if ( xToolbarManager.is() )
447 if ( bAttached )
449 xToolbarManager->attach( xFrame, xModCfgMgr, xDokCfgMgr, xPersistentWindowState );
450 uno::Reference< awt::XWindowPeer > xParent( xContainerWindow, UNO_QUERY );
451 xToolbarManager->setParentWindow( xParent );
452 if ( bAutomaticToolbars )
453 xToolbarManager->createStaticToolbars();
455 else
457 xToolbarManager->reset();
458 implts_destroyElements();
463 implts_unlock();
466 bool LayoutManager::implts_isEmbeddedLayoutManager() const
468 SolarMutexClearableGuard aReadLock;
469 Reference< XFrame > xFrame = m_xFrame;
470 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
471 aReadLock.clear();
473 Reference< awt::XWindow > xFrameContainerWindow = xFrame->getContainerWindow();
474 return xFrameContainerWindow != xContainerWindow;
477 void LayoutManager::implts_destroyElements()
479 SolarMutexResettableGuard aWriteLock;
480 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
481 aWriteLock.clear();
483 if ( pToolbarManager )
484 pToolbarManager->destroyToolbars();
486 implts_destroyStatusBar();
488 aWriteLock.reset();
489 impl_clearUpMenuBar();
490 aWriteLock.clear();
493 void LayoutManager::implts_toggleFloatingUIElementsVisibility( bool bActive )
495 SolarMutexClearableGuard aReadLock;
496 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
497 aReadLock.clear();
499 if ( pToolbarManager )
500 pToolbarManager->setFloatingToolbarsVisibility( bActive );
503 uno::Reference< ui::XUIElement > LayoutManager::implts_findElement( const OUString& aName )
505 OUString aElementType;
506 OUString aElementName;
508 parseResourceURL( aName, aElementType, aElementName );
509 if ( aElementType.equalsIgnoreAsciiCase("menubar") &&
510 aElementName.equalsIgnoreAsciiCase("menubar") )
511 return m_xMenuBar;
512 else if (( aElementType.equalsIgnoreAsciiCase("statusbar") &&
513 aElementName.equalsIgnoreAsciiCase("statusbar") ) ||
514 ( m_aStatusBarElement.m_aName == aName ))
515 return m_aStatusBarElement.m_xUIElement;
516 else if ( aElementType.equalsIgnoreAsciiCase("progressbar") &&
517 aElementName.equalsIgnoreAsciiCase("progressbar") )
518 return m_aProgressBarElement.m_xUIElement;
520 return uno::Reference< ui::XUIElement >();
523 bool LayoutManager::implts_readWindowStateData( const OUString& aName, UIElement& rElementData )
525 return readWindowStateData( aName, rElementData, m_xPersistentWindowState,
526 m_pGlobalSettings, m_bGlobalSettings, m_xContext );
529 bool LayoutManager::readWindowStateData( const OUString& aName, UIElement& rElementData,
530 const Reference< XNameAccess > &rPersistentWindowState,
531 std::unique_ptr<GlobalSettings> &rGlobalSettings, bool &bInGlobalSettings,
532 const Reference< XComponentContext > &rComponentContext )
534 if ( rPersistentWindowState.is() )
536 bool bGetSettingsState( false );
538 SolarMutexClearableGuard aWriteLock;
539 bool bGlobalSettings( bInGlobalSettings );
540 if ( rGlobalSettings == nullptr )
542 rGlobalSettings.reset( new GlobalSettings( rComponentContext ) );
543 bGetSettingsState = true;
545 GlobalSettings* pGlobalSettings = rGlobalSettings.get();
546 aWriteLock.clear();
550 Sequence< PropertyValue > aWindowState;
551 if ( rPersistentWindowState->hasByName( aName ) && (rPersistentWindowState->getByName( aName ) >>= aWindowState) )
553 bool bValue( false );
554 for ( sal_Int32 n = 0; n < aWindowState.getLength(); n++ )
556 if ( aWindowState[n].Name == WINDOWSTATE_PROPERTY_DOCKED )
558 if ( aWindowState[n].Value >>= bValue )
559 rElementData.m_bFloating = !bValue;
561 else if ( aWindowState[n].Name == WINDOWSTATE_PROPERTY_VISIBLE )
563 if ( aWindowState[n].Value >>= bValue )
564 rElementData.m_bVisible = bValue;
566 else if ( aWindowState[n].Name == WINDOWSTATE_PROPERTY_DOCKINGAREA )
568 ui::DockingArea eDockingArea;
569 if ( aWindowState[n].Value >>= eDockingArea )
570 rElementData.m_aDockedData.m_nDockedArea = eDockingArea;
572 else if ( aWindowState[n].Name == WINDOWSTATE_PROPERTY_DOCKPOS )
574 awt::Point aPoint;
575 if (aWindowState[n].Value >>= aPoint)
577 //tdf#90256 repair these broken Docking positions
578 if (aPoint.X < 0)
579 aPoint.X = SAL_MAX_INT32;
580 if (aPoint.Y < 0)
581 aPoint.Y = SAL_MAX_INT32;
582 rElementData.m_aDockedData.m_aPos = aPoint;
585 else if ( aWindowState[n].Name == WINDOWSTATE_PROPERTY_POS )
587 awt::Point aPoint;
588 if ( aWindowState[n].Value >>= aPoint )
589 rElementData.m_aFloatingData.m_aPos = aPoint;
591 else if ( aWindowState[n].Name == WINDOWSTATE_PROPERTY_SIZE )
593 awt::Size aSize;
594 if ( aWindowState[n].Value >>= aSize )
595 rElementData.m_aFloatingData.m_aSize = aSize;
597 else if ( aWindowState[n].Name == WINDOWSTATE_PROPERTY_UINAME )
598 aWindowState[n].Value >>= rElementData.m_aUIName;
599 else if ( aWindowState[n].Name == WINDOWSTATE_PROPERTY_STYLE )
601 sal_Int32 nStyle = 0;
602 if ( aWindowState[n].Value >>= nStyle )
603 rElementData.m_nStyle = static_cast<ButtonType>( nStyle );
605 else if ( aWindowState[n].Name == WINDOWSTATE_PROPERTY_LOCKED )
607 if ( aWindowState[n].Value >>= bValue )
608 rElementData.m_aDockedData.m_bLocked = bValue;
610 else if ( aWindowState[n].Name == WINDOWSTATE_PROPERTY_CONTEXT )
612 if ( aWindowState[n].Value >>= bValue )
613 rElementData.m_bContextSensitive = bValue;
615 else if ( aWindowState[n].Name == WINDOWSTATE_PROPERTY_NOCLOSE )
617 if ( aWindowState[n].Value >>= bValue )
618 rElementData.m_bNoClose = bValue;
623 // oversteer values with global settings
624 if (bGetSettingsState || bGlobalSettings)
626 if ( pGlobalSettings->HasToolbarStatesInfo())
629 SolarMutexGuard aWriteLock2;
630 bInGlobalSettings = true;
633 uno::Any aValue;
634 if ( pGlobalSettings->GetToolbarStateInfo(
635 GlobalSettings::STATEINFO_LOCKED,
636 aValue ))
637 aValue >>= rElementData.m_aDockedData.m_bLocked;
638 if ( pGlobalSettings->GetToolbarStateInfo(
639 GlobalSettings::STATEINFO_DOCKED,
640 aValue ))
642 bool bValue;
643 if ( aValue >>= bValue )
644 rElementData.m_bFloating = !bValue;
649 const bool bDockingSupportCrippled = !StyleSettings::GetDockingFloatsSupported();
650 if (bDockingSupportCrippled)
651 rElementData.m_bFloating = false;
653 return true;
655 catch (const NoSuchElementException&)
660 return false;
663 void LayoutManager::implts_writeWindowStateData( const OUString& aName, const UIElement& rElementData )
665 SolarMutexClearableGuard aWriteLock;
666 Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
668 aWriteLock.clear();
670 bool bPersistent( false );
671 Reference< XPropertySet > xPropSet( rElementData.m_xUIElement, UNO_QUERY );
672 if ( xPropSet.is() )
676 // Check persistent flag of the user interface element
677 xPropSet->getPropertyValue("Persistent") >>= bPersistent;
679 catch (const beans::UnknownPropertyException&)
681 // Non-configurable elements should at least store their dimension/position
682 bPersistent = true;
684 catch (const lang::WrappedTargetException&)
689 if ( bPersistent && xPersistentWindowState.is() )
693 Sequence< PropertyValue > aWindowState( 8 );
695 aWindowState[0].Name = WINDOWSTATE_PROPERTY_DOCKED;
696 aWindowState[0].Value <<= !rElementData.m_bFloating;
697 aWindowState[1].Name = WINDOWSTATE_PROPERTY_VISIBLE;
698 aWindowState[1].Value <<= rElementData.m_bVisible;
700 aWindowState[2].Name = WINDOWSTATE_PROPERTY_DOCKINGAREA;
701 aWindowState[2].Value <<= rElementData.m_aDockedData.m_nDockedArea;
703 aWindowState[3].Name = WINDOWSTATE_PROPERTY_DOCKPOS;
704 aWindowState[3].Value <<= rElementData.m_aDockedData.m_aPos;
706 aWindowState[4].Name = WINDOWSTATE_PROPERTY_POS;
707 aWindowState[4].Value <<= rElementData.m_aFloatingData.m_aPos;
709 aWindowState[5].Name = WINDOWSTATE_PROPERTY_SIZE;
710 aWindowState[5].Value <<= rElementData.m_aFloatingData.m_aSize;
711 aWindowState[6].Name = WINDOWSTATE_PROPERTY_UINAME;
712 aWindowState[6].Value <<= rElementData.m_aUIName;
713 aWindowState[7].Name = WINDOWSTATE_PROPERTY_LOCKED;
714 aWindowState[7].Value <<= rElementData.m_aDockedData.m_bLocked;
716 if ( xPersistentWindowState->hasByName( aName ))
718 Reference< XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY );
719 xReplace->replaceByName( aName, makeAny( aWindowState ));
721 else
723 Reference< XNameContainer > xInsert( xPersistentWindowState, uno::UNO_QUERY );
724 xInsert->insertByName( aName, makeAny( aWindowState ));
727 catch (const Exception&)
733 ::Size LayoutManager::implts_getContainerWindowOutputSize()
735 ::Size aContainerWinSize;
736 vcl::Window* pContainerWindow( nullptr );
738 // Retrieve output size from container Window
739 SolarMutexGuard aGuard;
740 pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow ).get();
741 if ( pContainerWindow )
742 aContainerWinSize = pContainerWindow->GetOutputSizePixel();
744 return aContainerWinSize;
747 Reference< XUIElement > LayoutManager::implts_createElement( const OUString& aName )
749 Reference< ui::XUIElement > xUIElement;
751 SolarMutexGuard g;
752 Sequence< PropertyValue > aPropSeq( 2 );
753 aPropSeq[0].Name = "Frame";
754 aPropSeq[0].Value <<= m_xFrame;
755 aPropSeq[1].Name = "Persistent";
756 aPropSeq[1].Value <<= true;
760 xUIElement = m_xUIElementFactoryManager->createUIElement( aName, aPropSeq );
762 catch (const NoSuchElementException&)
765 catch (const IllegalArgumentException&)
769 return xUIElement;
772 void LayoutManager::implts_setVisibleState( bool bShow )
775 SolarMutexGuard aWriteLock;
776 m_aStatusBarElement.m_bMasterHide = !bShow;
779 implts_updateUIElementsVisibleState( bShow );
782 void LayoutManager::implts_updateUIElementsVisibleState( bool bSetVisible )
784 // notify listeners
785 uno::Any a;
786 if ( bSetVisible )
787 implts_notifyListeners( frame::LayoutManagerEvents::VISIBLE, a );
788 else
789 implts_notifyListeners( frame::LayoutManagerEvents::INVISIBLE, a );
791 SolarMutexResettableGuard aWriteLock;
792 Reference< XUIElement > xMenuBar = m_xMenuBar;
793 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
794 rtl::Reference< MenuBarManager > xInplaceMenuBar( m_xInplaceMenuBar );
795 aWriteLock.clear();
797 if (( xMenuBar.is() || xInplaceMenuBar.is() ) && xContainerWindow.is() )
799 SolarMutexGuard aGuard;
801 MenuBar* pMenuBar( nullptr );
802 if ( xInplaceMenuBar.is() )
803 pMenuBar = static_cast<MenuBar *>(xInplaceMenuBar->GetMenuBar());
804 else
806 MenuBarWrapper* pMenuBarWrapper = static_cast< MenuBarWrapper* >(xMenuBar.get());
807 pMenuBar = static_cast<MenuBar *>(pMenuBarWrapper->GetMenuBarManager()->GetMenuBar());
810 SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow );
811 if ( pSysWindow )
813 if ( bSetVisible )
815 pSysWindow->SetMenuBar(pMenuBar);
817 else
818 pSysWindow->SetMenuBar( nullptr );
822 bool bMustDoLayout;
823 // Hide/show the statusbar according to bSetVisible
824 if ( bSetVisible )
825 bMustDoLayout = !implts_showStatusBar();
826 else
827 bMustDoLayout = !implts_hideStatusBar();
829 aWriteLock.reset();
830 ToolbarLayoutManager* pToolbarManager( m_xToolbarManager.get() );
831 aWriteLock.clear();
833 if ( pToolbarManager )
835 pToolbarManager->setVisible( bSetVisible );
836 bMustDoLayout = pToolbarManager->isLayoutDirty();
839 if ( bMustDoLayout )
840 implts_doLayout_notify( false );
843 void LayoutManager::implts_setCurrentUIVisibility( bool bShow )
846 SolarMutexGuard aWriteLock;
847 if (!bShow && m_aStatusBarElement.m_bVisible && m_aStatusBarElement.m_xUIElement.is())
848 m_aStatusBarElement.m_bMasterHide = true;
849 else if (bShow && m_aStatusBarElement.m_bVisible)
850 m_aStatusBarElement.m_bMasterHide = false;
853 implts_updateUIElementsVisibleState( bShow );
856 void LayoutManager::implts_destroyStatusBar()
858 Reference< XComponent > xCompStatusBar;
860 SolarMutexClearableGuard aWriteLock;
861 m_aStatusBarElement.m_aName.clear();
862 xCompStatusBar.set( m_aStatusBarElement.m_xUIElement, UNO_QUERY );
863 m_aStatusBarElement.m_xUIElement.clear();
864 aWriteLock.clear();
866 if ( xCompStatusBar.is() )
867 xCompStatusBar->dispose();
869 implts_destroyProgressBar();
872 void LayoutManager::implts_createStatusBar( const OUString& aStatusBarName )
875 SolarMutexGuard aWriteLock;
876 if (!m_aStatusBarElement.m_xUIElement.is())
878 implts_readStatusBarState(aStatusBarName);
879 m_aStatusBarElement.m_aName = aStatusBarName;
880 m_aStatusBarElement.m_xUIElement = implts_createElement(aStatusBarName);
884 implts_createProgressBar();
887 void LayoutManager::implts_readStatusBarState( const OUString& rStatusBarName )
889 SolarMutexGuard g;
890 if ( !m_aStatusBarElement.m_bStateRead )
892 // Read persistent data for status bar if not yet read!
893 if ( implts_readWindowStateData( rStatusBarName, m_aStatusBarElement ))
894 m_aStatusBarElement.m_bStateRead = true;
898 void LayoutManager::implts_createProgressBar()
900 Reference< XUIElement > xStatusBar;
901 Reference< XUIElement > xProgressBar;
902 Reference< XUIElement > xProgressBarBackup;
903 Reference< awt::XWindow > xContainerWindow;
905 SolarMutexResettableGuard aWriteLock;
906 xStatusBar = m_aStatusBarElement.m_xUIElement;
907 xProgressBar = m_aProgressBarElement.m_xUIElement;
908 xProgressBarBackup = m_xProgressBarBackup;
909 m_xProgressBarBackup.clear();
910 xContainerWindow = m_xContainerWindow;
911 aWriteLock.clear();
913 bool bRecycled = xProgressBarBackup.is();
914 ProgressBarWrapper* pWrapper = nullptr;
915 if ( bRecycled )
916 pWrapper = static_cast<ProgressBarWrapper*>(xProgressBarBackup.get());
917 else if ( xProgressBar.is() )
918 pWrapper = static_cast<ProgressBarWrapper*>(xProgressBar.get());
919 else
920 pWrapper = new ProgressBarWrapper();
922 if ( xStatusBar.is() )
924 Reference< awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY );
925 pWrapper->setStatusBar( xWindow );
927 else
929 Reference< awt::XWindow > xStatusBarWindow = pWrapper->getStatusBar();
931 SolarMutexGuard aGuard;
932 VclPtr<vcl::Window> pStatusBarWnd = VCLUnoHelper::GetWindow( xStatusBarWindow );
933 if ( !pStatusBarWnd )
935 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xContainerWindow );
936 if ( pWindow )
938 VclPtrInstance<StatusBar> pStatusBar( pWindow, WinBits( WB_LEFT | WB_3DLOOK ) );
939 Reference< awt::XWindow > xStatusBarWindow2( VCLUnoHelper::GetInterface( pStatusBar ));
940 pWrapper->setStatusBar( xStatusBarWindow2, true );
945 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
946 aWriteLock.reset();
947 m_aProgressBarElement.m_xUIElement.set( static_cast< cppu::OWeakObject* >( pWrapper ), UNO_QUERY );
948 aWriteLock.clear();
949 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
951 if ( bRecycled )
952 implts_showProgressBar();
955 void LayoutManager::implts_backupProgressBarWrapper()
957 SolarMutexGuard g;
959 if (m_xProgressBarBackup.is())
960 return;
962 // safe a backup copy of the current progress!
963 // This copy will be used automatically inside createProgressBar() which is called
964 // implicitly from implts_doLayout() .-)
965 m_xProgressBarBackup = m_aProgressBarElement.m_xUIElement;
967 // remove the relation between this old progress bar and our old status bar.
968 // Otherwise we work on disposed items ...
969 // The internal used ProgressBarWrapper can handle a NULL reference.
970 if ( m_xProgressBarBackup.is() )
972 ProgressBarWrapper* pWrapper = static_cast<ProgressBarWrapper*>(m_xProgressBarBackup.get());
973 if ( pWrapper )
974 pWrapper->setStatusBar( Reference< awt::XWindow >() );
977 // prevent us from dispose() the m_aProgressBarElement.m_xUIElement inside implts_reset()
978 m_aProgressBarElement.m_xUIElement.clear();
981 void LayoutManager::implts_destroyProgressBar()
983 // don't remove the progressbar in general
984 // We must reuse it if a new status bar is created later.
985 // Of course there exists one backup only.
986 // And further this backup will be released inside our dtor.
987 implts_backupProgressBarWrapper();
990 void LayoutManager::implts_setStatusBarPosSize( const ::Point& rPos, const ::Size& rSize )
992 Reference< XUIElement > xStatusBar;
993 Reference< XUIElement > xProgressBar;
994 Reference< awt::XWindow > xContainerWindow;
996 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
997 SolarMutexClearableGuard aReadLock;
998 xStatusBar = m_aStatusBarElement.m_xUIElement;
999 xProgressBar = m_aProgressBarElement.m_xUIElement;
1000 xContainerWindow = m_xContainerWindow;
1002 Reference< awt::XWindow > xWindow;
1003 if ( xStatusBar.is() )
1004 xWindow.set( xStatusBar->getRealInterface(), UNO_QUERY );
1005 else if ( xProgressBar.is() )
1007 ProgressBarWrapper* pWrapper = static_cast<ProgressBarWrapper*>(xProgressBar.get());
1008 if ( pWrapper )
1009 xWindow = pWrapper->getStatusBar();
1011 aReadLock.clear();
1012 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1014 if ( xWindow.is() )
1016 SolarMutexGuard aGuard;
1017 VclPtr<vcl::Window> pParentWindow = VCLUnoHelper::GetWindow( xContainerWindow );
1018 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
1019 if ( pParentWindow && ( pWindow && pWindow->GetType() == WindowType::STATUSBAR ))
1021 vcl::Window* pOldParentWindow = pWindow->GetParent();
1022 if ( pParentWindow != pOldParentWindow )
1023 pWindow->SetParent( pParentWindow );
1024 static_cast<StatusBar *>(pWindow.get())->SetPosSizePixel( rPos, rSize );
1029 bool LayoutManager::implts_showProgressBar()
1031 Reference< XUIElement > xStatusBar;
1032 Reference< XUIElement > xProgressBar;
1033 Reference< awt::XWindow > xWindow;
1035 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1036 SolarMutexGuard aWriteLock;
1037 xStatusBar = m_aStatusBarElement.m_xUIElement;
1038 xProgressBar = m_aProgressBarElement.m_xUIElement;
1039 bool bVisible( m_bVisible );
1041 m_aProgressBarElement.m_bVisible = true;
1042 if ( bVisible )
1044 if ( xStatusBar.is() && !m_aStatusBarElement.m_bMasterHide )
1046 xWindow.set( xStatusBar->getRealInterface(), UNO_QUERY );
1048 else if ( xProgressBar.is() )
1050 ProgressBarWrapper* pWrapper = static_cast<ProgressBarWrapper*>(xProgressBar.get());
1051 if ( pWrapper )
1052 xWindow = pWrapper->getStatusBar();
1056 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
1057 if ( pWindow )
1059 if ( !pWindow->IsVisible() )
1061 implts_setOffset( pWindow->GetSizePixel().Height() );
1062 pWindow->Show();
1063 implts_doLayout_notify( false );
1065 return true;
1068 return false;
1071 bool LayoutManager::implts_hideProgressBar()
1073 Reference< XUIElement > xProgressBar;
1074 Reference< awt::XWindow > xWindow;
1075 bool bHideStatusBar( false );
1077 SolarMutexGuard g;
1078 xProgressBar = m_aProgressBarElement.m_xUIElement;
1080 bool bInternalStatusBar( false );
1081 if ( xProgressBar.is() )
1083 Reference< awt::XWindow > xStatusBar;
1084 ProgressBarWrapper* pWrapper = static_cast<ProgressBarWrapper*>(xProgressBar.get());
1085 if ( pWrapper )
1086 xWindow = pWrapper->getStatusBar();
1087 Reference< ui::XUIElement > xStatusBarElement = m_aStatusBarElement.m_xUIElement;
1088 if ( xStatusBarElement.is() )
1089 xStatusBar.set( xStatusBarElement->getRealInterface(), UNO_QUERY );
1090 bInternalStatusBar = xStatusBar != xWindow;
1092 m_aProgressBarElement.m_bVisible = false;
1093 implts_readStatusBarState( STATUS_BAR_ALIAS );
1094 bHideStatusBar = !m_aStatusBarElement.m_bVisible;
1096 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
1097 if ( pWindow && pWindow->IsVisible() && ( bHideStatusBar || bInternalStatusBar ))
1099 implts_setOffset( 0 );
1100 pWindow->Hide();
1101 implts_doLayout_notify( false );
1102 return true;
1105 return false;
1108 bool LayoutManager::implts_showStatusBar( bool bStoreState )
1110 SolarMutexClearableGuard aWriteLock;
1111 Reference< ui::XUIElement > xStatusBar = m_aStatusBarElement.m_xUIElement;
1112 if ( bStoreState )
1113 m_aStatusBarElement.m_bVisible = true;
1114 aWriteLock.clear();
1116 if ( xStatusBar.is() )
1118 Reference< awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY );
1120 SolarMutexGuard aGuard;
1121 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
1122 if ( pWindow && !pWindow->IsVisible() )
1124 implts_setOffset( pWindow->GetSizePixel().Height() );
1125 pWindow->Show();
1126 implts_doLayout_notify( false );
1127 return true;
1131 return false;
1134 bool LayoutManager::implts_hideStatusBar( bool bStoreState )
1136 SolarMutexClearableGuard aWriteLock;
1137 Reference< ui::XUIElement > xStatusBar = m_aStatusBarElement.m_xUIElement;
1138 if ( bStoreState )
1139 m_aStatusBarElement.m_bVisible = false;
1140 aWriteLock.clear();
1142 if ( xStatusBar.is() )
1144 Reference< awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY );
1146 SolarMutexGuard aGuard;
1147 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
1148 if ( pWindow && pWindow->IsVisible() )
1150 implts_setOffset( 0 );
1151 pWindow->Hide();
1152 implts_doLayout_notify( false );
1153 return true;
1157 return false;
1160 void LayoutManager::implts_setOffset( const sal_Int32 nBottomOffset )
1162 ::tools::Rectangle aOffsetRect;
1163 setZeroRectangle( aOffsetRect );
1164 aOffsetRect.setHeight( nBottomOffset );
1166 if ( m_xToolbarManager.is() )
1167 m_xToolbarManager->setDockingAreaOffsets( aOffsetRect );
1170 void LayoutManager::implts_setInplaceMenuBar( const Reference< XIndexAccess >& xMergedMenuBar )
1172 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1173 SolarMutexClearableGuard aWriteLock;
1175 if ( !m_bInplaceMenuSet )
1177 SolarMutexGuard aGuard;
1179 // Reset old inplace menubar!
1180 VclPtr<Menu> pOldMenuBar;
1181 if (m_xInplaceMenuBar.is())
1183 pOldMenuBar = m_xInplaceMenuBar->GetMenuBar();
1184 m_xInplaceMenuBar->dispose();
1185 m_xInplaceMenuBar.clear();
1187 pOldMenuBar.disposeAndClear();
1189 m_bInplaceMenuSet = false;
1191 if ( m_xFrame.is() && m_xContainerWindow.is() )
1193 Reference< XDispatchProvider > xDispatchProvider;
1195 VclPtr<MenuBar> pMenuBar = VclPtr<MenuBar>::Create();
1196 m_xInplaceMenuBar = new MenuBarManager( m_xContext, m_xFrame, m_xURLTransformer, xDispatchProvider, OUString(), pMenuBar, true );
1197 m_xInplaceMenuBar->SetItemContainer( xMergedMenuBar );
1199 SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
1200 if ( pSysWindow )
1201 pSysWindow->SetMenuBar(pMenuBar);
1203 m_bInplaceMenuSet = true;
1206 aWriteLock.clear();
1207 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1209 implts_updateMenuBarClose();
1213 void LayoutManager::implts_resetInplaceMenuBar()
1215 SolarMutexGuard g;
1216 m_bInplaceMenuSet = false;
1218 if ( m_xContainerWindow.is() )
1220 SolarMutexGuard aGuard;
1221 MenuBarWrapper* pMenuBarWrapper = static_cast< MenuBarWrapper* >(m_xMenuBar.get());
1222 SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
1223 if ( pSysWindow )
1225 if ( pMenuBarWrapper )
1226 pSysWindow->SetMenuBar(static_cast<MenuBar *>(pMenuBarWrapper->GetMenuBarManager()->GetMenuBar()));
1227 else
1228 pSysWindow->SetMenuBar(nullptr);
1232 // Remove inplace menu bar
1233 VclPtr<Menu> pMenuBar;
1234 if (m_xInplaceMenuBar.is())
1236 pMenuBar = m_xInplaceMenuBar->GetMenuBar();
1237 m_xInplaceMenuBar->dispose();
1238 m_xInplaceMenuBar.clear();
1240 pMenuBar.disposeAndClear();
1243 void SAL_CALL LayoutManager::attachFrame( const Reference< XFrame >& xFrame )
1245 SolarMutexGuard g;
1246 m_xFrame = xFrame;
1249 void SAL_CALL LayoutManager::reset()
1251 implts_reset( true );
1254 // XMenuBarMergingAcceptor
1256 sal_Bool SAL_CALL LayoutManager::setMergedMenuBar(
1257 const Reference< XIndexAccess >& xMergedMenuBar )
1259 implts_setInplaceMenuBar( xMergedMenuBar );
1261 uno::Any a;
1262 implts_notifyListeners( frame::LayoutManagerEvents::MERGEDMENUBAR, a );
1263 return true;
1266 void SAL_CALL LayoutManager::removeMergedMenuBar()
1268 implts_resetInplaceMenuBar();
1271 awt::Rectangle SAL_CALL LayoutManager::getCurrentDockingArea()
1273 SolarMutexGuard g;
1274 return m_aDockingArea;
1277 Reference< XDockingAreaAcceptor > SAL_CALL LayoutManager::getDockingAreaAcceptor()
1279 SolarMutexGuard g;
1280 return m_xDockingAreaAcceptor;
1283 void SAL_CALL LayoutManager::setDockingAreaAcceptor( const Reference< ui::XDockingAreaAcceptor >& xDockingAreaAcceptor )
1285 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1286 SolarMutexClearableGuard aWriteLock;
1288 if (( m_xDockingAreaAcceptor == xDockingAreaAcceptor ) || !m_xFrame.is() )
1289 return;
1291 // IMPORTANT: Be sure to stop layout timer if don't have a docking area acceptor!
1292 if ( !xDockingAreaAcceptor.is() )
1293 m_aAsyncLayoutTimer.Stop();
1295 bool bAutomaticToolbars( m_bAutomaticToolbars );
1297 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1299 if ( !xDockingAreaAcceptor.is() )
1300 m_aAsyncLayoutTimer.Stop();
1302 // Remove listener from old docking area acceptor
1303 if ( m_xDockingAreaAcceptor.is() )
1305 Reference< awt::XWindow > xWindow( m_xDockingAreaAcceptor->getContainerWindow() );
1306 if ( xWindow.is() && ( m_xFrame->getContainerWindow() != m_xContainerWindow || !xDockingAreaAcceptor.is() ) )
1307 xWindow->removeWindowListener( Reference< awt::XWindowListener >( static_cast< OWeakObject * >( this ), UNO_QUERY ));
1309 m_aDockingArea = awt::Rectangle();
1310 if ( pToolbarManager )
1311 pToolbarManager->resetDockingArea();
1313 VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( xWindow );
1314 if ( pContainerWindow )
1315 pContainerWindow->RemoveChildEventListener( LINK( this, LayoutManager, WindowEventListener ) );
1318 m_xDockingAreaAcceptor = xDockingAreaAcceptor;
1319 if ( m_xDockingAreaAcceptor.is() )
1321 m_aDockingArea = awt::Rectangle();
1322 m_xContainerWindow = m_xDockingAreaAcceptor->getContainerWindow();
1323 m_xContainerTopWindow.set( m_xContainerWindow, UNO_QUERY );
1324 m_xContainerWindow->addWindowListener( Reference< awt::XWindowListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
1326 // we always must keep a connection to the window of our frame for resize events
1327 if ( m_xContainerWindow != m_xFrame->getContainerWindow() )
1328 m_xFrame->getContainerWindow()->addWindowListener( Reference< awt::XWindowListener >( static_cast< OWeakObject* >( this ), UNO_QUERY ));
1330 // #i37884# set initial visibility state - in the plugin case the container window is already shown
1331 // and we get no notification anymore
1333 VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
1334 if( pContainerWindow )
1335 m_bParentWindowVisible = pContainerWindow->IsVisible();
1339 aWriteLock.clear();
1340 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1342 if ( xDockingAreaAcceptor.is() )
1344 SolarMutexGuard aGuard;
1346 // Add layout manager as listener to get notifications about toolbar button activities
1347 VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
1348 if ( pContainerWindow )
1349 pContainerWindow->AddChildEventListener( LINK( this, LayoutManager, WindowEventListener ) );
1351 // We have now a new container window, reparent all child windows!
1352 implts_reparentChildWindows();
1354 else
1355 implts_destroyElements(); // remove all elements
1357 if ( pToolbarManager && xDockingAreaAcceptor.is() )
1359 if ( bAutomaticToolbars )
1361 lock();
1362 pToolbarManager->createStaticToolbars();
1363 unlock();
1365 implts_doLayout( true, false );
1369 void LayoutManager::implts_reparentChildWindows()
1371 SolarMutexResettableGuard aWriteLock;
1372 UIElement aStatusBarElement = m_aStatusBarElement;
1373 uno::Reference< awt::XWindow > xContainerWindow = m_xContainerWindow;
1374 aWriteLock.clear();
1376 uno::Reference< awt::XWindow > xStatusBarWindow;
1377 if ( aStatusBarElement.m_xUIElement.is() )
1381 xStatusBarWindow.set( aStatusBarElement.m_xUIElement->getRealInterface(), UNO_QUERY );
1383 catch (const RuntimeException&)
1385 throw;
1387 catch (const Exception&)
1392 if ( xStatusBarWindow.is() )
1394 SolarMutexGuard aGuard;
1395 VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
1396 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xStatusBarWindow );
1397 if ( pWindow && pContainerWindow )
1398 pWindow->SetParent( pContainerWindow );
1401 implts_resetMenuBar();
1403 aWriteLock.reset();
1404 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1405 if ( pToolbarManager )
1406 pToolbarManager->setParentWindow( uno::Reference< awt::XWindowPeer >( xContainerWindow, uno::UNO_QUERY ));
1407 aWriteLock.clear();
1410 uno::Reference< ui::XUIElement > LayoutManager::implts_createDockingWindow( const OUString& aElementName )
1412 Reference< XUIElement > xUIElement = implts_createElement( aElementName );
1413 return xUIElement;
1416 IMPL_LINK( LayoutManager, WindowEventListener, VclWindowEvent&, rEvent, void )
1418 vcl::Window* pWindow = rEvent.GetWindow();
1419 if ( pWindow && pWindow->GetType() == WindowType::TOOLBOX )
1421 SolarMutexClearableGuard aReadLock;
1422 ToolbarLayoutManager* pToolbarManager( m_xToolbarManager.get() );
1423 aReadLock.clear();
1425 if ( pToolbarManager )
1426 pToolbarManager->childWindowEvent( &rEvent );
1430 void SAL_CALL LayoutManager::createElement( const OUString& aName )
1432 SAL_INFO( "fwk", "framework (cd100003) ::LayoutManager::createElement" );
1434 SolarMutexClearableGuard aReadLock;
1435 Reference< XFrame > xFrame = m_xFrame;
1436 aReadLock.clear();
1438 if ( !xFrame.is() )
1439 return;
1441 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1442 SolarMutexClearableGuard aWriteLock;
1444 bool bMustBeLayouted( false );
1445 bool bNotify( false );
1447 bool bPreviewFrame;
1448 if (m_xToolbarManager.is())
1449 // Assumes that we created the ToolbarLayoutManager with our frame, if
1450 // not then we're somewhat fouled up ...
1451 bPreviewFrame = m_xToolbarManager->isPreviewFrame();
1452 else
1454 Reference< XModel > xModel( impl_getModelFromFrame( xFrame ) );
1455 bPreviewFrame = implts_isPreviewModel( xModel );
1458 if ( m_xContainerWindow.is() && !bPreviewFrame ) // no UI elements on preview frames
1460 OUString aElementType;
1461 OUString aElementName;
1463 parseResourceURL( aName, aElementType, aElementName );
1465 if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ) && m_xToolbarManager.is() )
1467 bNotify = m_xToolbarManager->createToolbar( aName );
1468 bMustBeLayouted = m_xToolbarManager->isLayoutDirty();
1470 else if ( aElementType.equalsIgnoreAsciiCase("menubar") &&
1471 aElementName.equalsIgnoreAsciiCase("menubar") &&
1472 implts_isFrameOrWindowTop(xFrame) )
1474 implts_createMenuBar( aName );
1475 if (m_bMenuVisible)
1476 bNotify = true;
1478 aWriteLock.clear();
1480 else if ( aElementType.equalsIgnoreAsciiCase("statusbar") &&
1481 ( implts_isFrameOrWindowTop(xFrame) || implts_isEmbeddedLayoutManager() ))
1483 implts_createStatusBar( aName );
1484 bNotify = true;
1486 else if ( aElementType.equalsIgnoreAsciiCase("progressbar") &&
1487 aElementName.equalsIgnoreAsciiCase("progressbar") &&
1488 implts_isFrameOrWindowTop(xFrame) )
1490 implts_createProgressBar();
1491 bNotify = true;
1493 else if ( aElementType.equalsIgnoreAsciiCase("dockingwindow"))
1495 // Add layout manager as listener for docking and other window events
1496 uno::Reference< uno::XInterface > xThis( static_cast< OWeakObject* >(this), uno::UNO_QUERY );
1497 uno::Reference< ui::XUIElement > xUIElement( implts_createDockingWindow( aName ));
1499 if ( xUIElement.is() )
1501 impl_addWindowListeners( xThis, xUIElement );
1504 // The docking window is created by a factory method located in the sfx2 library.
1505 // CreateDockingWindow( xFrame, aElementName );
1509 if ( bMustBeLayouted )
1510 implts_doLayout_notify( true );
1512 if ( bNotify )
1514 // UI element is invisible - provide information to listeners
1515 implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_VISIBLE, uno::makeAny( aName ) );
1519 void SAL_CALL LayoutManager::destroyElement( const OUString& aName )
1521 SAL_INFO( "fwk", "framework (cd100003) ::LayoutManager::destroyElement" );
1523 bool bMustBeLayouted(false);
1524 bool bNotify(false);
1525 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1527 SolarMutexClearableGuard aWriteLock;
1529 OUString aElementType;
1530 OUString aElementName;
1532 parseResourceURL(aName, aElementType, aElementName);
1534 if (aElementType.equalsIgnoreAsciiCase("menubar")
1535 && aElementName.equalsIgnoreAsciiCase("menubar"))
1537 if (!m_bInplaceMenuSet)
1539 impl_clearUpMenuBar();
1540 m_xMenuBar.clear();
1541 bNotify = true;
1544 else if ((aElementType.equalsIgnoreAsciiCase("statusbar")
1545 && aElementName.equalsIgnoreAsciiCase("statusbar"))
1546 || (m_aStatusBarElement.m_aName == aName))
1548 aWriteLock.clear();
1549 implts_destroyStatusBar();
1550 bMustBeLayouted = true;
1551 bNotify = true;
1553 else if (aElementType.equalsIgnoreAsciiCase("progressbar")
1554 && aElementName.equalsIgnoreAsciiCase("progressbar"))
1556 aWriteLock.clear();
1557 implts_createProgressBar();
1558 bMustBeLayouted = true;
1559 bNotify = true;
1561 else if (aElementType.equalsIgnoreAsciiCase(UIRESOURCETYPE_TOOLBAR)
1562 && m_xToolbarManager.is())
1564 aWriteLock.clear();
1565 bNotify = m_xToolbarManager->destroyToolbar(aName);
1566 bMustBeLayouted = m_xToolbarManager->isLayoutDirty();
1568 else if (aElementType.equalsIgnoreAsciiCase("dockingwindow"))
1570 uno::Reference<frame::XFrame> xFrame(m_xFrame);
1571 uno::Reference<XComponentContext> xContext(m_xContext);
1572 aWriteLock.clear();
1574 impl_setDockingWindowVisibility(xContext, xFrame, aElementName, false);
1575 bMustBeLayouted = false;
1576 bNotify = false;
1579 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1581 if ( bMustBeLayouted )
1582 doLayout();
1584 if ( bNotify )
1585 implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_INVISIBLE, uno::makeAny( aName ) );
1588 sal_Bool SAL_CALL LayoutManager::requestElement( const OUString& rResourceURL )
1590 bool bResult( false );
1591 bool bNotify( false );
1592 OUString aElementType;
1593 OUString aElementName;
1595 parseResourceURL( rResourceURL, aElementType, aElementName );
1597 SolarMutexClearableGuard aWriteLock;
1599 OString aResName = OUStringToOString( aElementName, RTL_TEXTENCODING_ASCII_US );
1600 SAL_INFO( "fwk", "framework (cd100003) Element " << aResName << " requested." );
1602 if (( aElementType.equalsIgnoreAsciiCase("statusbar") &&
1603 aElementName.equalsIgnoreAsciiCase("statusbar") ) ||
1604 ( m_aStatusBarElement.m_aName == rResourceURL ))
1606 implts_readStatusBarState( rResourceURL );
1607 if ( m_aStatusBarElement.m_bVisible && !m_aStatusBarElement.m_bMasterHide )
1609 aWriteLock.clear();
1610 createElement( rResourceURL );
1612 // There are some situation where we are not able to create an element.
1613 // Therefore we have to check the reference before further action.
1614 // See #i70019#
1615 uno::Reference< ui::XUIElement > xUIElement( m_aStatusBarElement.m_xUIElement );
1616 if ( xUIElement.is() )
1618 // we need VCL here to pass special flags to Show()
1619 SolarMutexGuard aGuard;
1620 Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY );
1621 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
1622 if ( pWindow )
1624 pWindow->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
1625 bResult = true;
1626 bNotify = true;
1631 else if ( aElementType.equalsIgnoreAsciiCase("progressbar") &&
1632 aElementName.equalsIgnoreAsciiCase("progressbar") )
1634 aWriteLock.clear();
1635 implts_showProgressBar();
1636 bResult = true;
1637 bNotify = true;
1639 else if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ) && m_bVisible )
1641 bool bComponentAttached( !m_aModuleIdentifier.isEmpty() );
1642 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1643 aWriteLock.clear();
1645 if ( pToolbarManager && bComponentAttached )
1647 bNotify = pToolbarManager->requestToolbar( rResourceURL );
1650 else if ( aElementType.equalsIgnoreAsciiCase("dockingwindow"))
1652 uno::Reference< frame::XFrame > xFrame( m_xFrame );
1653 aWriteLock.clear();
1655 CreateDockingWindow( xFrame, aElementName );
1658 if ( bNotify )
1659 implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_VISIBLE, uno::makeAny( rResourceURL ) );
1661 return bResult;
1664 Reference< XUIElement > SAL_CALL LayoutManager::getElement( const OUString& aName )
1666 Reference< XUIElement > xUIElement = implts_findElement( aName );
1667 if ( !xUIElement.is() )
1669 SolarMutexClearableGuard aReadLock;
1670 ToolbarLayoutManager* pToolbarManager( m_xToolbarManager.get() );
1671 aReadLock.clear();
1673 if ( pToolbarManager )
1674 xUIElement = pToolbarManager->getToolbar( aName );
1677 return xUIElement;
1680 Sequence< Reference< ui::XUIElement > > SAL_CALL LayoutManager::getElements()
1682 SolarMutexClearableGuard aReadLock;
1683 uno::Reference< ui::XUIElement > xMenuBar( m_xMenuBar );
1684 uno::Reference< ui::XUIElement > xStatusBar( m_aStatusBarElement.m_xUIElement );
1685 ToolbarLayoutManager* pToolbarManager( m_xToolbarManager.get() );
1686 aReadLock.clear();
1688 Sequence< Reference< ui::XUIElement > > aSeq;
1689 if ( pToolbarManager )
1690 aSeq = pToolbarManager->getToolbars();
1692 sal_Int32 nSize = aSeq.getLength();
1693 sal_Int32 nMenuBarIndex(-1);
1694 sal_Int32 nStatusBarIndex(-1);
1695 if ( xMenuBar.is() )
1697 nMenuBarIndex = nSize;
1698 ++nSize;
1700 if ( xStatusBar.is() )
1702 nStatusBarIndex = nSize;
1703 ++nSize;
1706 aSeq.realloc(nSize);
1707 if ( nMenuBarIndex >= 0 )
1708 aSeq[nMenuBarIndex] = xMenuBar;
1709 if ( nStatusBarIndex >= 0 )
1710 aSeq[nStatusBarIndex] = xStatusBar;
1712 return aSeq;
1715 sal_Bool SAL_CALL LayoutManager::showElement( const OUString& aName )
1717 SAL_INFO( "fwk", "framework (cd100003) ::LayoutManager::showElement" );
1719 bool bResult( false );
1720 bool bNotify( false );
1721 bool bMustLayout( false );
1722 OUString aElementType;
1723 OUString aElementName;
1725 parseResourceURL( aName, aElementType, aElementName );
1727 OString aResName = OUStringToOString( aElementName, RTL_TEXTENCODING_ASCII_US );
1728 SAL_INFO( "fwk", "framework (cd100003) Element " << aResName );
1730 if ( aElementType.equalsIgnoreAsciiCase("menubar") &&
1731 aElementName.equalsIgnoreAsciiCase("menubar") )
1734 SolarMutexGuard aWriteLock;
1735 m_bMenuVisible = true;
1738 bResult = implts_resetMenuBar();
1739 bNotify = bResult;
1741 else if (( aElementType.equalsIgnoreAsciiCase("statusbar") &&
1742 aElementName.equalsIgnoreAsciiCase("statusbar") ) ||
1743 ( m_aStatusBarElement.m_aName == aName ))
1745 SolarMutexClearableGuard aWriteLock;
1746 if ( m_aStatusBarElement.m_xUIElement.is() && !m_aStatusBarElement.m_bMasterHide &&
1747 implts_showStatusBar( true ))
1749 aWriteLock.clear();
1751 implts_writeWindowStateData( STATUS_BAR_ALIAS, m_aStatusBarElement );
1752 bMustLayout = true;
1753 bResult = true;
1754 bNotify = true;
1757 else if ( aElementType.equalsIgnoreAsciiCase("progressbar") &&
1758 aElementName.equalsIgnoreAsciiCase("progressbar") )
1760 bNotify = bResult = implts_showProgressBar();
1762 else if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
1764 SolarMutexClearableGuard aReadLock;
1765 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1766 aReadLock.clear();
1768 if ( pToolbarManager )
1770 bNotify = pToolbarManager->showToolbar( aName );
1771 bMustLayout = pToolbarManager->isLayoutDirty();
1774 else if ( aElementType.equalsIgnoreAsciiCase("dockingwindow"))
1776 SolarMutexClearableGuard aReadGuard;
1777 uno::Reference< frame::XFrame > xFrame( m_xFrame );
1778 uno::Reference< XComponentContext > xContext( m_xContext );
1779 aReadGuard.clear();
1781 impl_setDockingWindowVisibility( xContext, xFrame, aElementName, true );
1784 if ( bMustLayout )
1785 doLayout();
1787 if ( bNotify )
1788 implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_VISIBLE, uno::makeAny( aName ) );
1790 return bResult;
1793 sal_Bool SAL_CALL LayoutManager::hideElement( const OUString& aName )
1795 SAL_INFO( "fwk", "framework (cd100003) ::LayoutManager::hideElement" );
1797 bool bNotify( false );
1798 bool bMustLayout( false );
1799 OUString aElementType;
1800 OUString aElementName;
1802 parseResourceURL( aName, aElementType, aElementName );
1803 OString aResName = OUStringToOString( aElementName, RTL_TEXTENCODING_ASCII_US );
1804 SAL_INFO( "fwk", "framework (cd100003) Element " << aResName );
1806 if ( aElementType.equalsIgnoreAsciiCase("menubar") &&
1807 aElementName.equalsIgnoreAsciiCase("menubar") )
1809 SolarMutexGuard g;
1811 if ( m_xContainerWindow.is() )
1813 m_bMenuVisible = false;
1815 SolarMutexGuard aGuard;
1816 SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
1817 if ( pSysWindow )
1819 MenuBar* pMenuBar = pSysWindow->GetMenuBar();
1820 if ( pMenuBar )
1822 pMenuBar->SetDisplayable( false );
1823 bNotify = true;
1828 else if (( aElementType.equalsIgnoreAsciiCase("statusbar") &&
1829 aElementName.equalsIgnoreAsciiCase("statusbar") ) ||
1830 ( m_aStatusBarElement.m_aName == aName ))
1832 SolarMutexGuard g;
1833 if ( m_aStatusBarElement.m_xUIElement.is() && !m_aStatusBarElement.m_bMasterHide &&
1834 implts_hideStatusBar( true ))
1836 implts_writeWindowStateData( STATUS_BAR_ALIAS, m_aStatusBarElement );
1837 bMustLayout = true;
1838 bNotify = true;
1841 else if ( aElementType.equalsIgnoreAsciiCase("progressbar") &&
1842 aElementName.equalsIgnoreAsciiCase("progressbar") )
1844 bNotify = implts_hideProgressBar();
1846 else if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
1848 SolarMutexClearableGuard aReadLock;
1849 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1850 aReadLock.clear();
1852 if ( pToolbarManager )
1854 bNotify = pToolbarManager->hideToolbar( aName );
1855 bMustLayout = pToolbarManager->isLayoutDirty();
1858 else if ( aElementType.equalsIgnoreAsciiCase("dockingwindow"))
1860 SolarMutexClearableGuard aReadGuard;
1861 uno::Reference< frame::XFrame > xFrame( m_xFrame );
1862 uno::Reference< XComponentContext > xContext( m_xContext );
1863 aReadGuard.clear();
1865 impl_setDockingWindowVisibility( xContext, xFrame, aElementName, false );
1868 if ( bMustLayout )
1869 doLayout();
1871 if ( bNotify )
1872 implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_INVISIBLE, uno::makeAny( aName ) );
1874 return false;
1877 sal_Bool SAL_CALL LayoutManager::dockWindow( const OUString& aName, DockingArea DockingArea, const awt::Point& Pos )
1879 OUString aElementType;
1880 OUString aElementName;
1882 parseResourceURL( aName, aElementType, aElementName );
1883 if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
1885 SolarMutexClearableGuard aReadLock;
1886 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1887 aReadLock.clear();
1889 if ( pToolbarManager )
1891 pToolbarManager->dockToolbar( aName, DockingArea, Pos );
1892 if ( pToolbarManager->isLayoutDirty() )
1893 doLayout();
1896 return false;
1899 sal_Bool SAL_CALL LayoutManager::dockAllWindows( ::sal_Int16 /*nElementType*/ )
1901 SolarMutexClearableGuard aReadLock;
1902 bool bResult( false );
1903 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1904 aReadLock.clear();
1906 if ( pToolbarManager )
1908 bResult = pToolbarManager->dockAllToolbars();
1909 if ( pToolbarManager->isLayoutDirty() )
1910 doLayout();
1912 return bResult;
1915 sal_Bool SAL_CALL LayoutManager::floatWindow( const OUString& aName )
1917 bool bResult( false );
1918 if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
1920 SolarMutexClearableGuard aReadLock;
1921 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1922 aReadLock.clear();
1924 if ( pToolbarManager )
1926 bResult = pToolbarManager->floatToolbar( aName );
1927 if ( pToolbarManager->isLayoutDirty() )
1928 doLayout();
1931 return bResult;
1934 sal_Bool SAL_CALL LayoutManager::lockWindow( const OUString& aName )
1936 bool bResult( false );
1937 if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
1939 SolarMutexClearableGuard aReadLock;
1940 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1941 aReadLock.clear();
1943 if ( pToolbarManager )
1945 bResult = pToolbarManager->lockToolbar( aName );
1946 if ( pToolbarManager->isLayoutDirty() )
1947 doLayout();
1950 return bResult;
1953 sal_Bool SAL_CALL LayoutManager::unlockWindow( const OUString& aName )
1955 bool bResult( false );
1956 if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
1958 SolarMutexClearableGuard aReadLock;
1959 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1960 aReadLock.clear();
1962 if ( pToolbarManager )
1964 bResult = pToolbarManager->unlockToolbar( aName );
1965 if ( pToolbarManager->isLayoutDirty() )
1966 doLayout();
1969 return bResult;
1972 void SAL_CALL LayoutManager::setElementSize( const OUString& aName, const awt::Size& aSize )
1974 if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
1976 SolarMutexClearableGuard aReadLock;
1977 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1978 aReadLock.clear();
1980 if ( pToolbarManager )
1982 pToolbarManager->setToolbarSize( aName, aSize );
1983 if ( pToolbarManager->isLayoutDirty() )
1984 doLayout();
1989 void SAL_CALL LayoutManager::setElementPos( const OUString& aName, const awt::Point& aPos )
1991 if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
1993 SolarMutexClearableGuard aReadLock;
1994 ToolbarLayoutManager* pToolbarManager( m_xToolbarManager.get() );
1995 aReadLock.clear();
1997 if ( pToolbarManager )
1999 pToolbarManager->setToolbarPos( aName, aPos );
2000 if ( pToolbarManager->isLayoutDirty() )
2001 doLayout();
2006 void SAL_CALL LayoutManager::setElementPosSize( const OUString& aName, const awt::Point& aPos, const awt::Size& aSize )
2008 if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
2010 SolarMutexClearableGuard aReadLock;
2011 ToolbarLayoutManager* pToolbarManager( m_xToolbarManager.get() );
2012 aReadLock.clear();
2014 if ( pToolbarManager )
2016 pToolbarManager->setToolbarPosSize( aName, aPos, aSize );
2017 if ( pToolbarManager->isLayoutDirty() )
2018 doLayout();
2023 sal_Bool SAL_CALL LayoutManager::isElementVisible( const OUString& aName )
2025 OUString aElementType;
2026 OUString aElementName;
2028 parseResourceURL( aName, aElementType, aElementName );
2029 if ( aElementType.equalsIgnoreAsciiCase("menubar") &&
2030 aElementName.equalsIgnoreAsciiCase("menubar") )
2032 SolarMutexResettableGuard aReadLock;
2033 if ( m_xContainerWindow.is() )
2035 aReadLock.clear();
2037 SolarMutexGuard aGuard;
2038 SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
2039 if ( pSysWindow )
2041 MenuBar* pMenuBar = pSysWindow->GetMenuBar();
2042 if ( pMenuBar && pMenuBar->IsDisplayable() )
2043 return true;
2045 else
2047 aReadLock.reset();
2048 return m_bMenuVisible;
2052 else if (( aElementType.equalsIgnoreAsciiCase("statusbar") &&
2053 aElementName.equalsIgnoreAsciiCase("statusbar") ) ||
2054 ( m_aStatusBarElement.m_aName == aName ))
2056 if ( m_aStatusBarElement.m_xUIElement.is() )
2058 Reference< awt::XWindow > xWindow( m_aStatusBarElement.m_xUIElement->getRealInterface(), UNO_QUERY );
2059 if ( xWindow.is() )
2061 SolarMutexGuard g;
2062 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
2063 if ( pWindow && pWindow->IsVisible() )
2064 return true;
2065 else
2066 return false;
2070 else if ( aElementType.equalsIgnoreAsciiCase("progressbar") &&
2071 aElementName.equalsIgnoreAsciiCase("progressbar") )
2073 if ( m_aProgressBarElement.m_xUIElement.is() )
2074 return m_aProgressBarElement.m_bVisible;
2076 else if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
2078 SolarMutexClearableGuard aReadLock;
2079 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2080 aReadLock.clear();
2082 if ( pToolbarManager )
2083 return pToolbarManager->isToolbarVisible( aName );
2085 else if ( aElementType.equalsIgnoreAsciiCase("dockingwindow"))
2087 SolarMutexClearableGuard aReadGuard;
2088 uno::Reference< frame::XFrame > xFrame( m_xFrame );
2089 aReadGuard.clear();
2091 return IsDockingWindowVisible( xFrame, aElementName );
2094 return false;
2097 sal_Bool SAL_CALL LayoutManager::isElementFloating( const OUString& aName )
2099 if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
2101 SolarMutexClearableGuard aReadLock;
2102 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2103 aReadLock.clear();
2105 if ( pToolbarManager )
2106 return pToolbarManager->isToolbarFloating( aName );
2109 return false;
2112 sal_Bool SAL_CALL LayoutManager::isElementDocked( const OUString& aName )
2114 if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
2116 SolarMutexClearableGuard aReadLock;
2117 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2118 aReadLock.clear();
2120 if ( pToolbarManager )
2121 return pToolbarManager->isToolbarDocked( aName );
2124 return false;
2127 sal_Bool SAL_CALL LayoutManager::isElementLocked( const OUString& aName )
2129 if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
2131 SolarMutexClearableGuard aReadLock;
2132 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2133 aReadLock.clear();
2135 if ( pToolbarManager )
2136 return pToolbarManager->isToolbarLocked( aName );
2139 return false;
2142 awt::Size SAL_CALL LayoutManager::getElementSize( const OUString& aName )
2144 if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
2146 SolarMutexClearableGuard aReadLock;
2147 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2148 aReadLock.clear();
2150 if ( pToolbarManager )
2151 return pToolbarManager->getToolbarSize( aName );
2154 return awt::Size();
2157 awt::Point SAL_CALL LayoutManager::getElementPos( const OUString& aName )
2159 if ( getElementTypeFromResourceURL( aName ).equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
2161 SolarMutexClearableGuard aReadLock;
2162 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2163 aReadLock.clear();
2165 if ( pToolbarManager )
2166 return pToolbarManager->getToolbarPos( aName );
2169 return awt::Point();
2172 void SAL_CALL LayoutManager::lock()
2174 implts_lock();
2176 SolarMutexClearableGuard aReadLock;
2177 sal_Int32 nLockCount( m_nLockCount );
2178 aReadLock.clear();
2180 SAL_INFO( "fwk", "framework (cd100003) ::LayoutManager::lock lockCount=" << nLockCount );
2181 #ifdef DBG_UTIL
2182 SAL_INFO( "fwk", "LayoutManager::lock " << reinterpret_cast<sal_Int64>(this) << " - " << nLockCount );
2183 #endif
2185 Any a( nLockCount );
2186 implts_notifyListeners( frame::LayoutManagerEvents::LOCK, a );
2189 void SAL_CALL LayoutManager::unlock()
2191 bool bDoLayout( implts_unlock() );
2193 SolarMutexClearableGuard aReadLock;
2194 sal_Int32 nLockCount( m_nLockCount );
2195 aReadLock.clear();
2197 SAL_INFO( "fwk", "framework (cd100003) ::LayoutManager::unlock lockCount=" << nLockCount );
2198 #ifdef DBG_UTIL
2199 SAL_INFO( "fwk", "LayoutManager::unlock " << reinterpret_cast<sal_Int64>(this) << " - " << nLockCount);
2200 #endif
2201 // conform to documentation: unlock with lock count == 0 means force a layout
2204 SolarMutexGuard aWriteLock;
2205 if (bDoLayout)
2206 m_aAsyncLayoutTimer.Stop();
2209 Any a( nLockCount );
2210 implts_notifyListeners( frame::LayoutManagerEvents::UNLOCK, a );
2212 if ( bDoLayout )
2213 implts_doLayout_notify( true );
2216 void SAL_CALL LayoutManager::doLayout()
2218 implts_doLayout_notify( true );
2221 // ILayoutNotifications
2223 void LayoutManager::requestLayout()
2225 doLayout();
2228 void LayoutManager::implts_doLayout_notify( bool bOuterResize )
2230 bool bLayouted = implts_doLayout( false, bOuterResize );
2231 if ( bLayouted )
2232 implts_notifyListeners( frame::LayoutManagerEvents::LAYOUT, Any() );
2235 bool LayoutManager::implts_doLayout( bool bForceRequestBorderSpace, bool bOuterResize )
2237 SAL_INFO( "fwk", "framework (cd100003) ::LayoutManager::implts_doLayout" );
2239 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2240 SolarMutexClearableGuard aReadLock;
2242 if ( !m_xFrame.is() || !m_bParentWindowVisible )
2243 return false;
2245 bool bPreserveContentSize( m_bPreserveContentSize );
2246 bool bMustDoLayout( m_bMustDoLayout );
2247 bool bNoLock = ( m_nLockCount == 0 );
2248 awt::Rectangle aCurrBorderSpace( m_aDockingArea );
2249 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2250 Reference< awt::XTopWindow2 > xContainerTopWindow( m_xContainerTopWindow );
2251 Reference< awt::XWindow > xComponentWindow;
2252 try {
2253 xComponentWindow = m_xFrame->getComponentWindow();
2254 } catch (css::lang::DisposedException &) {
2255 // There can be a race between one thread calling Frame::dispose
2256 // (framework/source/services/frame.cxx) -> Frame::disableLayoutManager
2257 // -> LayoutManager::attachFrame(null) setting m_xFrame to null, and
2258 // the main thread firing the timer-triggered
2259 // LayoutManager::AsyncLayoutHdl -> LayoutManager::implts_doLayout and
2260 // calling into the in-dispose m_xFrame here, so silently ignore a
2261 // DisposedException here:
2262 return false;
2264 Reference< XDockingAreaAcceptor > xDockingAreaAcceptor( m_xDockingAreaAcceptor );
2265 aReadLock.clear();
2266 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2268 bool bLayouted( false );
2270 if ( bNoLock && xDockingAreaAcceptor.is() && xContainerWindow.is() && xComponentWindow.is() )
2272 bLayouted = true;
2274 awt::Rectangle aDockSpace( implts_calcDockingAreaSizes() );
2275 awt::Rectangle aBorderSpace( aDockSpace );
2276 bool bGotRequestedBorderSpace( true );
2278 // We have to add the height of a possible status bar
2279 aBorderSpace.Height += implts_getStatusBarSize().Height();
2281 if ( !equalRectangles( aBorderSpace, aCurrBorderSpace ) || bForceRequestBorderSpace || bMustDoLayout )
2283 // we always resize the content window (instead of the complete container window) if we're not set up
2284 // to (attempt to) preserve the content window's size
2285 if ( bOuterResize && !bPreserveContentSize )
2286 bOuterResize = false;
2288 // maximized windows can resized their content window only, not their container window
2289 if ( bOuterResize && xContainerTopWindow.is() && xContainerTopWindow->getIsMaximized() )
2290 bOuterResize = false;
2292 // if the component window does not have a size (yet), then we can't use it to calc the container
2293 // window size
2294 awt::Rectangle aComponentRect = xComponentWindow->getPosSize();
2295 if ( bOuterResize && ( aComponentRect.Width == 0 ) && ( aComponentRect.Height == 0 ) )
2296 bOuterResize = false;
2298 bGotRequestedBorderSpace = false;
2299 if ( bOuterResize )
2301 Reference< awt::XDevice > xDevice( xContainerWindow, uno::UNO_QUERY );
2302 awt::DeviceInfo aContainerInfo = xDevice->getInfo();
2304 awt::Size aRequestedSize( aComponentRect.Width + aContainerInfo.LeftInset + aContainerInfo.RightInset + aBorderSpace.X + aBorderSpace.Width,
2305 aComponentRect.Height + aContainerInfo.TopInset + aContainerInfo.BottomInset + aBorderSpace.Y + aBorderSpace.Height );
2306 awt::Point aComponentPos( aBorderSpace.X, aBorderSpace.Y );
2308 bGotRequestedBorderSpace = implts_resizeContainerWindow( aRequestedSize, aComponentPos );
2311 // if we did not do a container window resize, or it failed, then use the DockingAcceptor as usual
2312 if ( !bGotRequestedBorderSpace )
2313 bGotRequestedBorderSpace = xDockingAreaAcceptor->requestDockingAreaSpace( aBorderSpace );
2315 if ( bGotRequestedBorderSpace )
2317 SolarMutexGuard aWriteGuard;
2318 m_aDockingArea = aBorderSpace;
2319 m_bMustDoLayout = false;
2323 if ( bGotRequestedBorderSpace )
2325 ::Size aContainerSize;
2326 ::Size aStatusBarSize;
2328 // Interim solution to let the layout method within the
2329 // toolbar layout manager.
2330 implts_setOffset( implts_getStatusBarSize().Height() );
2331 if ( m_xToolbarManager.is() )
2332 m_xToolbarManager->setDockingArea( aDockSpace );
2334 // Subtract status bar size from our container output size. Docking area windows
2335 // don't contain the status bar!
2336 aStatusBarSize = implts_getStatusBarSize();
2337 aContainerSize = implts_getContainerWindowOutputSize();
2338 aContainerSize.AdjustHeight( -(aStatusBarSize.Height()) );
2340 if ( m_xToolbarManager.is() )
2341 m_xToolbarManager->doLayout(aContainerSize);
2343 // Position the status bar
2344 if ( aStatusBarSize.Height() > 0 )
2346 implts_setStatusBarPosSize( ::Point( 0, std::max(( aContainerSize.Height() ), long( 0 ))),
2347 ::Size( aContainerSize.Width(),aStatusBarSize.Height() ));
2350 xDockingAreaAcceptor->setDockingAreaSpace( aBorderSpace );
2354 return bLayouted;
2357 bool LayoutManager::implts_resizeContainerWindow( const awt::Size& rContainerSize,
2358 const awt::Point& rComponentPos )
2360 SolarMutexClearableGuard aReadLock;
2361 Reference< awt::XWindow > xContainerWindow = m_xContainerWindow;
2362 Reference< awt::XTopWindow2 > xContainerTopWindow = m_xContainerTopWindow;
2363 Reference< awt::XWindow > xComponentWindow = m_xFrame->getComponentWindow();
2364 aReadLock.clear();
2366 // calculate the maximum size we have for the container window
2367 sal_Int32 nDisplay = xContainerTopWindow->getDisplay();
2368 tools::Rectangle aWorkArea = Application::GetScreenPosSizePixel( nDisplay );
2370 if (( aWorkArea.GetWidth() > 0 ) && ( aWorkArea.GetHeight() > 0 ))
2372 if (( rContainerSize.Width > aWorkArea.GetWidth() ) || ( rContainerSize.Height > aWorkArea.GetHeight() ))
2373 return false;
2374 // Strictly, this is not correct. If we have a multi-screen display (css.awt.DisplayAccess.MultiDisplay == true),
2375 // the "effective work area" would be much larger than the work area of a single display, since we could in theory
2376 // position the container window across multiple screens.
2377 // However, this should suffice as a heuristics here ... (nobody really wants to check whether the different screens are
2378 // stacked horizontally or vertically, whether their work areas can really be combined, or are separated by non-work-areas,
2379 // and the like ... right?)
2382 // resize our container window
2383 xContainerWindow->setPosSize( 0, 0, rContainerSize.Width, rContainerSize.Height, awt::PosSize::SIZE );
2384 // position the component window
2385 xComponentWindow->setPosSize( rComponentPos.X, rComponentPos.Y, 0, 0, awt::PosSize::POS );
2386 return true;
2389 void SAL_CALL LayoutManager::setVisible( sal_Bool bVisible )
2391 SolarMutexClearableGuard aWriteLock;
2392 bool bWasVisible( m_bVisible );
2393 m_bVisible = bVisible;
2394 aWriteLock.clear();
2396 if ( bWasVisible != bool(bVisible) )
2397 implts_setVisibleState( bVisible );
2400 sal_Bool SAL_CALL LayoutManager::isVisible()
2402 SolarMutexGuard g;
2403 return m_bVisible;
2406 ::Size LayoutManager::implts_getStatusBarSize()
2408 SolarMutexClearableGuard aReadLock;
2409 bool bStatusBarVisible( isElementVisible( STATUS_BAR_ALIAS ));
2410 bool bProgressBarVisible( isElementVisible( "private:resource/progressbar/progressbar" ));
2411 bool bVisible( m_bVisible );
2412 Reference< XUIElement > xStatusBar( m_aStatusBarElement.m_xUIElement );
2413 Reference< XUIElement > xProgressBar( m_aProgressBarElement.m_xUIElement );
2415 Reference< awt::XWindow > xWindow;
2416 if ( bStatusBarVisible && bVisible && xStatusBar.is() )
2417 xWindow.set( xStatusBar->getRealInterface(), UNO_QUERY );
2418 else if ( xProgressBar.is() && !xStatusBar.is() && bProgressBarVisible )
2420 ProgressBarWrapper* pWrapper = static_cast<ProgressBarWrapper*>(xProgressBar.get());
2421 if ( pWrapper )
2422 xWindow = pWrapper->getStatusBar();
2424 aReadLock.clear();
2426 if ( xWindow.is() )
2428 awt::Rectangle aPosSize = xWindow->getPosSize();
2429 return ::Size( aPosSize.Width, aPosSize.Height );
2431 else
2432 return ::Size();
2435 awt::Rectangle LayoutManager::implts_calcDockingAreaSizes()
2437 SolarMutexClearableGuard aReadLock;
2438 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2439 Reference< XDockingAreaAcceptor > xDockingAreaAcceptor( m_xDockingAreaAcceptor );
2440 aReadLock.clear();
2442 awt::Rectangle aBorderSpace;
2443 if ( m_xToolbarManager.is() && xDockingAreaAcceptor.is() && xContainerWindow.is() )
2444 aBorderSpace = m_xToolbarManager->getDockingArea();
2446 return aBorderSpace;
2449 void LayoutManager::implts_setDockingAreaWindowSizes()
2451 SolarMutexClearableGuard aReadLock;
2452 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2453 aReadLock.clear();
2455 uno::Reference< awt::XDevice > xDevice( xContainerWindow, uno::UNO_QUERY );
2456 // Convert relative size to output size.
2457 awt::Rectangle aRectangle = xContainerWindow->getPosSize();
2458 awt::DeviceInfo aInfo = xDevice->getInfo();
2459 awt::Size aContainerClientSize( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset,
2460 aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
2461 ::Size aStatusBarSize = implts_getStatusBarSize();
2463 // Position the status bar
2464 if ( aStatusBarSize.Height() > 0 )
2466 implts_setStatusBarPosSize( ::Point( 0, std::max(( aContainerClientSize.Height - aStatusBarSize.Height() ), long( 0 ))),
2467 ::Size( aContainerClientSize.Width, aStatusBarSize.Height() ));
2471 void LayoutManager::implts_updateMenuBarClose()
2473 SolarMutexClearableGuard aWriteLock;
2474 bool bShowCloseButton( m_bMenuBarCloseButton );
2475 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2476 aWriteLock.clear();
2478 if ( xContainerWindow.is() )
2480 SolarMutexGuard aGuard;
2482 SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow );
2483 if ( pSysWindow )
2485 MenuBar* pMenuBar = pSysWindow->GetMenuBar();
2486 if ( pMenuBar )
2488 // TODO remove link on sal_False ?!
2489 pMenuBar->ShowCloseButton(bShowCloseButton);
2490 pMenuBar->SetCloseButtonClickHdl(LINK(this, LayoutManager, MenuBarClose));
2496 bool LayoutManager::implts_resetMenuBar()
2498 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2499 SolarMutexGuard aWriteLock;
2500 bool bMenuVisible( m_bMenuVisible );
2501 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2503 MenuBar* pSetMenuBar = nullptr;
2504 if ( m_xInplaceMenuBar.is() )
2505 pSetMenuBar = static_cast<MenuBar *>(m_xInplaceMenuBar->GetMenuBar());
2506 else
2508 MenuBarWrapper* pMenuBarWrapper = static_cast< MenuBarWrapper* >( m_xMenuBar.get() );
2509 if ( pMenuBarWrapper )
2510 pSetMenuBar = static_cast<MenuBar*>(pMenuBarWrapper->GetMenuBarManager()->GetMenuBar());
2513 SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow );
2514 if ( pSysWindow && bMenuVisible && pSetMenuBar )
2516 pSysWindow->SetMenuBar(pSetMenuBar);
2517 pSetMenuBar->SetDisplayable( true );
2518 return true;
2521 return false;
2524 void LayoutManager::implts_createMSCompatibleMenuBar( const OUString& aName )
2526 SolarMutexGuard aWriteLock;
2528 // Find Form menu in the original menubar
2529 m_xMenuBar = implts_createElement( aName );
2530 uno::Reference< XUIElementSettings > xMenuBarSettings(m_xMenuBar, UNO_QUERY);
2531 uno::Reference< container::XIndexReplace > xMenuIndex(xMenuBarSettings->getSettings(true), UNO_QUERY);
2533 sal_Int32 nFormsMenu = -1;
2534 for (sal_Int32 nIndex = 0; nIndex < xMenuIndex->getCount(); ++nIndex)
2536 uno::Sequence< beans::PropertyValue > aProps;
2537 xMenuIndex->getByIndex( nIndex ) >>= aProps;
2538 OUString aCommand;
2539 for (sal_Int32 nSeqInd = 0; nSeqInd < aProps.getLength(); ++nSeqInd)
2541 if (aProps[nSeqInd].Name == "CommandURL")
2543 aProps[nSeqInd].Value >>= aCommand;
2544 break;
2548 if (aCommand == ".uno:FormatFormMenu")
2549 nFormsMenu = nIndex;
2551 assert(nFormsMenu != -1);
2553 // Create the MS compatible Form menu
2554 css::uno::Reference< css::ui::XUIElement > xFormsMenu = implts_createElement( "private:resource/menubar/mscompatibleformsmenu" );
2555 if(!xFormsMenu.is())
2556 return;
2558 // Merge the MS compatible Form menu into the menubar
2559 uno::Reference< XUIElementSettings > xFormsMenuSettings(xFormsMenu, UNO_QUERY);
2560 uno::Reference< container::XIndexAccess > xFormsMenuIndex(xFormsMenuSettings->getSettings(true));
2562 assert(xFormsMenuIndex->getCount() >= 1);
2563 uno::Sequence< beans::PropertyValue > aNewFormsMenu;
2564 xFormsMenuIndex->getByIndex( 0 ) >>= aNewFormsMenu;
2565 xMenuIndex->replaceByIndex(nFormsMenu, uno::makeAny(aNewFormsMenu));
2567 setMergedMenuBar( xMenuIndex );
2569 // Clear up the temporal forms menubar
2570 Reference< XComponent > xFormsMenuComp( xFormsMenu, UNO_QUERY );
2571 if ( xFormsMenuComp.is() )
2572 xFormsMenuComp->dispose();
2573 xFormsMenu.clear();
2576 IMPL_LINK_NOARG(LayoutManager, MenuBarClose, void*, void)
2578 SolarMutexClearableGuard aReadLock;
2579 uno::Reference< frame::XDispatchProvider > xProvider(m_xFrame, uno::UNO_QUERY);
2580 uno::Reference< XComponentContext > xContext( m_xContext );
2581 aReadLock.clear();
2583 if ( !xProvider.is())
2584 return;
2586 uno::Reference< frame::XDispatchHelper > xDispatcher = frame::DispatchHelper::create( xContext );
2588 xDispatcher->executeDispatch(
2589 xProvider,
2590 ".uno:CloseWin",
2591 "_self",
2593 uno::Sequence< beans::PropertyValue >());
2596 // XLayoutManagerEventBroadcaster
2598 void SAL_CALL LayoutManager::addLayoutManagerEventListener( const uno::Reference< frame::XLayoutManagerListener >& xListener )
2600 m_aListenerContainer.addInterface( cppu::UnoType<frame::XLayoutManagerListener>::get(), xListener );
2603 void SAL_CALL LayoutManager::removeLayoutManagerEventListener( const uno::Reference< frame::XLayoutManagerListener >& xListener )
2605 m_aListenerContainer.removeInterface( cppu::UnoType<frame::XLayoutManagerListener>::get(), xListener );
2608 void LayoutManager::implts_notifyListeners(short nEvent, const uno::Any& rInfoParam)
2610 lang::EventObject aSource( static_cast< ::cppu::OWeakObject*>(this) );
2611 ::cppu::OInterfaceContainerHelper* pContainer = m_aListenerContainer.getContainer( cppu::UnoType<frame::XLayoutManagerListener>::get());
2612 if (pContainer!=nullptr)
2614 ::cppu::OInterfaceIteratorHelper pIterator(*pContainer);
2615 while (pIterator.hasMoreElements())
2619 static_cast<frame::XLayoutManagerListener*>(pIterator.next())->layoutEvent(aSource, nEvent, rInfoParam);
2621 catch( const uno::RuntimeException& )
2623 pIterator.remove();
2629 // XWindowListener
2631 void SAL_CALL LayoutManager::windowResized( const awt::WindowEvent& aEvent )
2633 SolarMutexGuard g;
2634 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2636 Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY );
2637 if ( xIfac == aEvent.Source && m_bVisible )
2639 // We have to call our resize handler at least once synchronously, as some
2640 // application modules need this. So we have to check if this is the first
2641 // call after the async layout time expired.
2642 m_bMustDoLayout = true;
2643 if ( !m_aAsyncLayoutTimer.IsActive() )
2645 m_aAsyncLayoutTimer.Invoke();
2646 if ( m_nLockCount == 0 )
2647 m_aAsyncLayoutTimer.Start();
2650 else if ( m_xFrame.is() && aEvent.Source == m_xFrame->getContainerWindow() )
2652 // the container window of my DockingAreaAcceptor is not the same as of my frame
2653 // I still have to resize my frames' window as nobody else will do it
2654 Reference< awt::XWindow > xComponentWindow( m_xFrame->getComponentWindow() );
2655 if( xComponentWindow.is() )
2657 uno::Reference< awt::XDevice > xDevice( m_xFrame->getContainerWindow(), uno::UNO_QUERY );
2659 // Convert relative size to output size.
2660 awt::Rectangle aRectangle = m_xFrame->getContainerWindow()->getPosSize();
2661 awt::DeviceInfo aInfo = xDevice->getInfo();
2662 awt::Size aSize( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
2663 aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
2665 // Resize our component window.
2666 xComponentWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, awt::PosSize::POSSIZE );
2671 void SAL_CALL LayoutManager::windowMoved( const awt::WindowEvent& )
2675 void SAL_CALL LayoutManager::windowShown( const lang::EventObject& aEvent )
2677 SolarMutexClearableGuard aReadLock;
2678 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2679 bool bParentWindowVisible( m_bParentWindowVisible );
2680 aReadLock.clear();
2682 Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY );
2683 if ( xIfac == aEvent.Source )
2685 SolarMutexClearableGuard aWriteLock;
2686 m_bParentWindowVisible = true;
2687 bool bSetVisible = ( m_bParentWindowVisible != bParentWindowVisible );
2688 aWriteLock.clear();
2690 if ( bSetVisible )
2691 implts_updateUIElementsVisibleState( true );
2695 void SAL_CALL LayoutManager::windowHidden( const lang::EventObject& aEvent )
2697 SolarMutexClearableGuard aReadLock;
2698 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2699 bool bParentWindowVisible( m_bParentWindowVisible );
2700 aReadLock.clear();
2702 Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY );
2703 if ( xIfac == aEvent.Source )
2705 SolarMutexClearableGuard aWriteLock;
2706 m_bParentWindowVisible = false;
2707 bool bSetInvisible = ( m_bParentWindowVisible != bParentWindowVisible );
2708 aWriteLock.clear();
2710 if ( bSetInvisible )
2711 implts_updateUIElementsVisibleState( false );
2715 IMPL_LINK_NOARG(LayoutManager, AsyncLayoutHdl, Timer *, void)
2718 SolarMutexGuard aReadLock;
2720 if (!m_xContainerWindow.is())
2721 return;
2724 implts_setDockingAreaWindowSizes();
2725 implts_doLayout( true, false );
2728 // XFrameActionListener
2730 void SAL_CALL LayoutManager::frameAction( const FrameActionEvent& aEvent )
2732 if (( aEvent.Action == FrameAction_COMPONENT_ATTACHED ) || ( aEvent.Action == FrameAction_COMPONENT_REATTACHED ))
2734 SAL_INFO( "fwk", "framework (cd100003) ::LayoutManager::frameAction (COMPONENT_ATTACHED|REATTACHED)" );
2737 SolarMutexGuard aWriteLock;
2738 m_bMustDoLayout = true;
2741 implts_reset( true );
2742 implts_doLayout( true, false );
2743 implts_doLayout( true, true );
2745 else if (( aEvent.Action == FrameAction_FRAME_UI_ACTIVATED ) || ( aEvent.Action == FrameAction_FRAME_UI_DEACTIVATING ))
2747 SAL_INFO( "fwk", "framework (cd100003) ::LayoutManager::frameAction (FRAME_UI_ACTIVATED|DEACTIVATING)" );
2749 implts_toggleFloatingUIElementsVisibility( aEvent.Action == FrameAction_FRAME_UI_ACTIVATED );
2751 else if ( aEvent.Action == FrameAction_COMPONENT_DETACHING )
2753 SAL_INFO( "fwk", "framework (cd100003) ::LayoutManager::frameAction (COMPONENT_DETACHING)" );
2755 implts_reset( false );
2759 void SAL_CALL LayoutManager::disposing( const lang::EventObject& rEvent )
2761 bool bDisposeAndClear( false );
2763 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2765 SolarMutexGuard aWriteLock;
2767 if (rEvent.Source == Reference<XInterface>(m_xFrame, UNO_QUERY))
2769 // Our frame gets disposed, release all our references that depends on a working frame reference.
2771 setDockingAreaAcceptor(Reference<ui::XDockingAreaAcceptor>());
2773 // destroy all elements, it's possible that detaching is NOT called!
2774 implts_destroyElements();
2775 impl_clearUpMenuBar();
2776 m_xMenuBar.clear();
2777 VclPtr<Menu> pMenuBar;
2778 if (m_xInplaceMenuBar.is())
2780 pMenuBar = m_xInplaceMenuBar->GetMenuBar();
2781 m_xInplaceMenuBar->dispose();
2782 m_xInplaceMenuBar.clear();
2784 pMenuBar.disposeAndClear();
2785 m_xContainerWindow.clear();
2786 m_xContainerTopWindow.clear();
2788 // forward disposing call to toolbar manager
2789 if (m_xToolbarManager.is())
2790 m_xToolbarManager->disposing(rEvent);
2792 if (m_xModuleCfgMgr.is())
2796 Reference<XUIConfiguration> xModuleCfgMgr(m_xModuleCfgMgr, UNO_QUERY);
2797 xModuleCfgMgr->removeConfigurationListener(Reference<XUIConfigurationListener>(
2798 static_cast<OWeakObject*>(this), UNO_QUERY));
2800 catch (const Exception&)
2805 if (m_xDocCfgMgr.is())
2809 Reference<XUIConfiguration> xDocCfgMgr(m_xDocCfgMgr, UNO_QUERY);
2810 xDocCfgMgr->removeConfigurationListener(Reference<XUIConfigurationListener>(
2811 static_cast<OWeakObject*>(this), UNO_QUERY));
2813 catch (const Exception&)
2818 m_xDocCfgMgr.clear();
2819 m_xModuleCfgMgr.clear();
2820 m_xFrame.clear();
2821 m_pGlobalSettings.reset();
2823 bDisposeAndClear = true;
2825 else if (rEvent.Source == Reference<XInterface>(m_xContainerWindow, UNO_QUERY))
2827 // Our container window gets disposed. Remove all user interface elements.
2828 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2829 if (pToolbarManager)
2831 uno::Reference<awt::XWindowPeer> aEmptyWindowPeer;
2832 pToolbarManager->setParentWindow(aEmptyWindowPeer);
2834 impl_clearUpMenuBar();
2835 m_xMenuBar.clear();
2836 VclPtr<Menu> pMenuBar;
2837 if (m_xInplaceMenuBar.is())
2839 pMenuBar = m_xInplaceMenuBar->GetMenuBar();
2840 m_xInplaceMenuBar->dispose();
2841 m_xInplaceMenuBar.clear();
2843 pMenuBar.disposeAndClear();
2844 m_xContainerWindow.clear();
2845 m_xContainerTopWindow.clear();
2847 else if (rEvent.Source == Reference<XInterface>(m_xDocCfgMgr, UNO_QUERY))
2848 m_xDocCfgMgr.clear();
2849 else if (rEvent.Source == Reference<XInterface>(m_xModuleCfgMgr, UNO_QUERY))
2850 m_xModuleCfgMgr.clear();
2852 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2854 // Send disposing to our listener when we have lost our frame.
2855 if ( bDisposeAndClear )
2857 // Send message to all listener and forget her references.
2858 uno::Reference< frame::XLayoutManager > xThis( static_cast< ::cppu::OWeakObject* >(this), uno::UNO_QUERY );
2859 lang::EventObject aEvent( xThis );
2860 m_aListenerContainer.disposeAndClear( aEvent );
2864 void SAL_CALL LayoutManager::elementInserted( const ui::ConfigurationEvent& Event )
2866 SolarMutexClearableGuard aReadLock;
2867 Reference< XFrame > xFrame( m_xFrame );
2868 rtl::Reference< ToolbarLayoutManager > xToolbarManager( m_xToolbarManager );
2869 aReadLock.clear();
2871 if ( xFrame.is() )
2873 OUString aElementType;
2874 OUString aElementName;
2875 bool bRefreshLayout(false);
2877 parseResourceURL( Event.ResourceURL, aElementType, aElementName );
2878 if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
2880 if ( xToolbarManager.is() )
2882 xToolbarManager->elementInserted( Event );
2883 bRefreshLayout = xToolbarManager->isLayoutDirty();
2886 else if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_MENUBAR ))
2888 Reference< XUIElement > xUIElement = implts_findElement( Event.ResourceURL );
2889 Reference< XUIElementSettings > xElementSettings( xUIElement, UNO_QUERY );
2890 if ( xElementSettings.is() )
2892 uno::Reference< XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY );
2893 if ( xPropSet.is() )
2895 if ( Event.Source == uno::Reference< uno::XInterface >( m_xDocCfgMgr, uno::UNO_QUERY ))
2896 xPropSet->setPropertyValue( "ConfigurationSource", makeAny( m_xDocCfgMgr ));
2898 xElementSettings->updateSettings();
2902 if ( bRefreshLayout )
2903 doLayout();
2907 void SAL_CALL LayoutManager::elementRemoved( const ui::ConfigurationEvent& Event )
2909 SolarMutexClearableGuard aReadLock;
2910 Reference< frame::XFrame > xFrame( m_xFrame );
2911 rtl::Reference< ToolbarLayoutManager > xToolbarManager( m_xToolbarManager );
2912 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2913 Reference< ui::XUIElement > xMenuBar( m_xMenuBar );
2914 Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr );
2915 Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr );
2916 aReadLock.clear();
2918 if ( xFrame.is() )
2920 OUString aElementType;
2921 OUString aElementName;
2922 bool bRefreshLayout(false);
2924 parseResourceURL( Event.ResourceURL, aElementType, aElementName );
2925 if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
2927 if ( xToolbarManager.is() )
2929 xToolbarManager->elementRemoved( Event );
2930 bRefreshLayout = xToolbarManager->isLayoutDirty();
2933 else
2935 Reference< XUIElement > xUIElement = implts_findElement( Event.ResourceURL );
2936 Reference< XUIElementSettings > xElementSettings( xUIElement, UNO_QUERY );
2937 if ( xElementSettings.is() )
2939 bool bNoSettings( false );
2940 OUString aConfigSourcePropName( "ConfigurationSource" );
2941 Reference< XInterface > xElementCfgMgr;
2942 Reference< XPropertySet > xPropSet( xElementSettings, UNO_QUERY );
2944 if ( xPropSet.is() )
2945 xPropSet->getPropertyValue( aConfigSourcePropName ) >>= xElementCfgMgr;
2947 if ( !xElementCfgMgr.is() )
2948 return;
2950 // Check if the same UI configuration manager has changed => check further
2951 if ( Event.Source == xElementCfgMgr )
2953 // Same UI configuration manager where our element has its settings
2954 if ( Event.Source == Reference< XInterface >( xDocCfgMgr, UNO_QUERY ))
2956 // document settings removed
2957 if ( xModuleCfgMgr->hasSettings( Event.ResourceURL ))
2959 xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( m_xModuleCfgMgr ));
2960 xElementSettings->updateSettings();
2961 return;
2965 bNoSettings = true;
2968 // No settings anymore, element must be destroyed
2969 if ( xContainerWindow.is() && bNoSettings )
2971 if ( aElementType.equalsIgnoreAsciiCase("menubar") &&
2972 aElementName.equalsIgnoreAsciiCase("menubar") )
2974 SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow );
2975 if ( pSysWindow && !m_bInplaceMenuSet )
2976 pSysWindow->SetMenuBar( nullptr );
2978 Reference< XComponent > xComp( xMenuBar, UNO_QUERY );
2979 if ( xComp.is() )
2980 xComp->dispose();
2982 SolarMutexGuard g;
2983 m_xMenuBar.clear();
2989 if ( bRefreshLayout )
2990 doLayout();
2994 void SAL_CALL LayoutManager::elementReplaced( const ui::ConfigurationEvent& Event )
2996 SolarMutexClearableGuard aReadLock;
2997 Reference< XFrame > xFrame( m_xFrame );
2998 rtl::Reference< ToolbarLayoutManager > xToolbarManager( m_xToolbarManager );
2999 aReadLock.clear();
3001 if ( xFrame.is() )
3003 OUString aElementType;
3004 OUString aElementName;
3005 bool bRefreshLayout(false);
3007 parseResourceURL( Event.ResourceURL, aElementType, aElementName );
3008 if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
3010 if ( xToolbarManager.is() )
3012 xToolbarManager->elementReplaced( Event );
3013 bRefreshLayout = xToolbarManager->isLayoutDirty();
3016 else
3018 Reference< XUIElement > xUIElement = implts_findElement( Event.ResourceURL );
3019 Reference< XUIElementSettings > xElementSettings( xUIElement, UNO_QUERY );
3020 if ( xElementSettings.is() )
3022 Reference< XInterface > xElementCfgMgr;
3023 Reference< XPropertySet > xPropSet( xElementSettings, UNO_QUERY );
3025 if ( xPropSet.is() )
3026 xPropSet->getPropertyValue( "ConfigurationSource" ) >>= xElementCfgMgr;
3028 if ( !xElementCfgMgr.is() )
3029 return;
3031 // Check if the same UI configuration manager has changed => update settings
3032 if ( Event.Source == xElementCfgMgr )
3033 xElementSettings->updateSettings();
3037 if ( bRefreshLayout )
3038 doLayout();
3042 void SAL_CALL LayoutManager::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle,
3043 const uno::Any& aValue )
3045 if ( nHandle != LAYOUTMANAGER_PROPHANDLE_REFRESHVISIBILITY )
3046 LayoutManager_PBase::setFastPropertyValue_NoBroadcast( nHandle, aValue );
3048 switch( nHandle )
3050 case LAYOUTMANAGER_PROPHANDLE_MENUBARCLOSER:
3051 implts_updateMenuBarClose();
3052 break;
3054 case LAYOUTMANAGER_PROPHANDLE_REFRESHVISIBILITY:
3056 bool bValue(false);
3057 if (( aValue >>= bValue ) && bValue )
3059 SolarMutexClearableGuard aReadLock;
3060 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
3061 bool bAutomaticToolbars( m_bAutomaticToolbars );
3062 aReadLock.clear();
3064 if ( pToolbarManager )
3065 pToolbarManager->refreshToolbarsVisibility( bAutomaticToolbars );
3067 break;
3070 case LAYOUTMANAGER_PROPHANDLE_HIDECURRENTUI:
3071 implts_setCurrentUIVisibility( !m_bHideCurrentUI );
3072 break;
3073 default: break;
3077 namespace detail
3079 class InfoHelperBuilder
3081 private:
3082 std::unique_ptr<::cppu::OPropertyArrayHelper> m_pInfoHelper;
3083 public:
3084 explicit InfoHelperBuilder(const LayoutManager &rManager)
3086 uno::Sequence< beans::Property > aProperties;
3087 rManager.describeProperties(aProperties);
3088 m_pInfoHelper.reset( new ::cppu::OPropertyArrayHelper(aProperties, true) );
3090 InfoHelperBuilder(const InfoHelperBuilder&) = delete;
3091 InfoHelperBuilder& operator=(const InfoHelperBuilder&) = delete;
3093 ::cppu::OPropertyArrayHelper& getHelper() { return *m_pInfoHelper; }
3096 namespace
3098 struct theInfoHelper :
3099 public rtl::StaticWithArg< detail::InfoHelperBuilder, LayoutManager,
3100 theInfoHelper >
3105 ::cppu::IPropertyArrayHelper& SAL_CALL LayoutManager::getInfoHelper()
3107 return theInfoHelper::get(*this).getHelper();
3110 uno::Reference< beans::XPropertySetInfo > SAL_CALL LayoutManager::getPropertySetInfo()
3112 static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
3114 return xInfo;
3117 } // namespace framework
3119 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
3120 com_sun_star_comp_framework_LayoutManager_get_implementation(
3121 css::uno::XComponentContext *context,
3122 css::uno::Sequence<css::uno::Any> const &)
3124 return cppu::acquire(new framework::LayoutManager(context));
3127 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */