Avoid potential negative array index access to cached text.
[LibreOffice.git] / framework / source / layoutmanager / layoutmanager.cxx
blobb915e3f82a2665af9b019494113410aa19524a0b
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 <uielement/progressbarwrapper.hxx>
30 #include <uiconfiguration/globalsettings.hxx>
31 #include <uiconfiguration/windowstateproperties.hxx>
32 #include "toolbarlayoutmanager.hxx"
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 #include <com/sun/star/beans/PropertyAttribute.hpp>
36 #include <com/sun/star/frame/ModuleManager.hpp>
37 #include <com/sun/star/frame/XModel.hpp>
38 #include <com/sun/star/frame/FrameAction.hpp>
39 #include <com/sun/star/awt/PosSize.hpp>
40 #include <com/sun/star/awt/XDevice.hpp>
41 #include <com/sun/star/ui/theModuleUIConfigurationManagerSupplier.hpp>
42 #include <com/sun/star/ui/XUIConfigurationManagerSupplier.hpp>
43 #include <com/sun/star/ui/theWindowStateConfiguration.hpp>
44 #include <com/sun/star/ui/theUIElementFactoryManager.hpp>
45 #include <com/sun/star/container/XNameReplace.hpp>
46 #include <com/sun/star/container/XNameContainer.hpp>
47 #include <com/sun/star/frame/LayoutManagerEvents.hpp>
48 #include <com/sun/star/frame/XDispatchProvider.hpp>
49 #include <com/sun/star/frame/DispatchHelper.hpp>
50 #include <com/sun/star/lang/DisposedException.hpp>
51 #include <com/sun/star/util/URLTransformer.hpp>
53 #include <comphelper/lok.hxx>
54 #include <comphelper/propertyvalue.hxx>
55 #include <vcl/status.hxx>
56 #include <vcl/settings.hxx>
57 #include <vcl/window.hxx>
58 #include <vcl/svapp.hxx>
59 #include <toolkit/helper/vclunohelper.hxx>
60 #include <toolkit/awt/vclxmenu.hxx>
61 #include <comphelper/uno3.hxx>
62 #include <officecfg/Office/Compatibility.hxx>
64 #include <rtl/ref.hxx>
65 #include <sal/log.hxx>
66 #include <o3tl/string_view.hxx>
68 #include <algorithm>
70 // using namespace
71 using namespace ::com::sun::star;
72 using namespace ::com::sun::star::uno;
73 using namespace ::com::sun::star::beans;
74 using namespace ::com::sun::star::util;
75 using namespace ::com::sun::star::lang;
76 using namespace ::com::sun::star::container;
77 using namespace ::com::sun::star::ui;
78 using namespace ::com::sun::star::frame;
80 constexpr OUString STATUS_BAR_ALIAS = u"private:resource/statusbar/statusbar"_ustr;
82 namespace framework
85 IMPLEMENT_FORWARD_XTYPEPROVIDER2( LayoutManager, LayoutManager_Base, LayoutManager_PBase )
86 IMPLEMENT_FORWARD_XINTERFACE2( LayoutManager, LayoutManager_Base, LayoutManager_PBase )
88 LayoutManager::LayoutManager( const Reference< XComponentContext >& xContext ) :
89 ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >(m_aMutex)
90 , LayoutManager_PBase( *static_cast< ::cppu::OBroadcastHelper* >(this) )
91 , m_xContext( xContext )
92 , m_xURLTransformer( URLTransformer::create(xContext) )
93 , m_nLockCount( 0 )
94 , m_bInplaceMenuSet( false )
95 , m_bMenuVisible( true )
96 , m_bVisible( true )
97 , m_bParentWindowVisible( false )
98 , m_bMustDoLayout( true )
99 #if HAVE_FEATURE_DESKTOP
100 , m_bAutomaticToolbars( true )
101 #else
102 , m_bAutomaticToolbars( false )
103 #endif
104 , m_bHideCurrentUI( false )
105 , m_bGlobalSettings( false )
106 , m_bPreserveContentSize( false )
107 , m_bMenuBarCloseButton( false )
108 , m_xModuleManager( ModuleManager::create( xContext ))
109 , m_xUIElementFactoryManager( ui::theUIElementFactoryManager::get(xContext) )
110 , m_xPersistentWindowStateSupplier( ui::theWindowStateConfiguration::get( xContext ) )
111 , m_aAsyncLayoutTimer( "framework::LayoutManager m_aAsyncLayoutTimer" )
112 , m_aListenerContainer( m_aMutex )
114 // Initialize statusbar member
115 m_aStatusBarElement.m_aType = "statusbar";
116 m_aStatusBarElement.m_aName = STATUS_BAR_ALIAS;
118 if (!comphelper::LibreOfficeKit::isActive())
120 m_xToolbarManager = new ToolbarLayoutManager( xContext, Reference<XUIElementFactory>(m_xUIElementFactoryManager, UNO_QUERY_THROW), this );
123 m_aAsyncLayoutTimer.SetPriority( TaskPriority::HIGH_IDLE );
124 m_aAsyncLayoutTimer.SetTimeout( 50 );
125 m_aAsyncLayoutTimer.SetInvokeHandler( LINK( this, LayoutManager, AsyncLayoutHdl ) );
127 registerProperty( LAYOUTMANAGER_PROPNAME_ASCII_AUTOMATICTOOLBARS, LAYOUTMANAGER_PROPHANDLE_AUTOMATICTOOLBARS, css::beans::PropertyAttribute::TRANSIENT, &m_bAutomaticToolbars, cppu::UnoType<decltype(m_bAutomaticToolbars)>::get() );
128 registerProperty( LAYOUTMANAGER_PROPNAME_ASCII_HIDECURRENTUI, LAYOUTMANAGER_PROPHANDLE_HIDECURRENTUI, beans::PropertyAttribute::TRANSIENT, &m_bHideCurrentUI, cppu::UnoType<decltype(m_bHideCurrentUI)>::get() );
129 registerProperty( LAYOUTMANAGER_PROPNAME_ASCII_LOCKCOUNT, LAYOUTMANAGER_PROPHANDLE_LOCKCOUNT, beans::PropertyAttribute::TRANSIENT | beans::PropertyAttribute::READONLY, &m_nLockCount, cppu::UnoType<decltype(m_nLockCount)>::get() );
130 registerProperty( LAYOUTMANAGER_PROPNAME_MENUBARCLOSER, LAYOUTMANAGER_PROPHANDLE_MENUBARCLOSER, beans::PropertyAttribute::TRANSIENT, &m_bMenuBarCloseButton, cppu::UnoType<decltype(m_bMenuBarCloseButton)>::get() );
131 registerPropertyNoMember( LAYOUTMANAGER_PROPNAME_ASCII_REFRESHVISIBILITY, LAYOUTMANAGER_PROPHANDLE_REFRESHVISIBILITY, beans::PropertyAttribute::TRANSIENT, cppu::UnoType<bool>::get(), css::uno::Any(false) );
132 registerProperty( LAYOUTMANAGER_PROPNAME_ASCII_PRESERVE_CONTENT_SIZE, LAYOUTMANAGER_PROPHANDLE_PRESERVE_CONTENT_SIZE, beans::PropertyAttribute::TRANSIENT, &m_bPreserveContentSize, cppu::UnoType<decltype(m_bPreserveContentSize)>::get() );
133 registerPropertyNoMember( LAYOUTMANAGER_PROPNAME_ASCII_REFRESHTOOLTIP, LAYOUTMANAGER_PROPHANDLE_REFRESHTOOLTIP, beans::PropertyAttribute::TRANSIENT, cppu::UnoType<bool>::get(), css::uno::Any(false) );
136 LayoutManager::~LayoutManager()
138 m_aAsyncLayoutTimer.Stop();
139 setDockingAreaAcceptor(nullptr);
140 m_pGlobalSettings.reset();
143 void LayoutManager::implts_createMenuBar(const OUString& rMenuBarName)
145 SolarMutexGuard aWriteLock;
147 // Create a customized menu if compatibility mode is on
148 if (m_aModuleIdentifier == "com.sun.star.text.TextDocument" && officecfg::Office::Compatibility::View::MSCompatibleFormsMenu::get())
150 implts_createMSCompatibleMenuBar(rMenuBarName);
153 // Create the default menubar otherwise
154 if (m_bInplaceMenuSet || m_xMenuBar.is())
155 return;
157 m_xMenuBar.set( static_cast< MenuBarWrapper* >(implts_createElement( rMenuBarName ).get()) );
158 if ( !m_xMenuBar.is() )
159 return;
161 SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
162 if ( !pSysWindow )
163 return;
165 Reference< awt::XMenuBar > xMenuBar;
169 m_xMenuBar->getPropertyValue("XMenuBar") >>= xMenuBar;
171 catch (const beans::UnknownPropertyException&)
174 catch (const lang::WrappedTargetException&)
178 if ( !xMenuBar.is() )
179 return;
181 VCLXMenu* pAwtMenuBar = dynamic_cast<VCLXMenu*>( xMenuBar.get() );
182 if ( pAwtMenuBar )
184 MenuBar* pMenuBar = static_cast<MenuBar*>(pAwtMenuBar->GetMenu());
185 if ( pMenuBar )
187 pSysWindow->SetMenuBar(pMenuBar);
188 pMenuBar->SetDisplayable( m_bMenuVisible );
189 implts_updateMenuBarClose();
194 // Internal helper function
195 void LayoutManager::impl_clearUpMenuBar()
197 implts_lock();
199 // Clear up VCL menu bar to prepare shutdown
200 if ( m_xContainerWindow.is() )
202 SolarMutexGuard aGuard;
204 SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
205 if ( pSysWindow )
207 MenuBar* pSetMenuBar = nullptr;
208 if ( m_xInplaceMenuBar.is() )
209 pSetMenuBar = static_cast<MenuBar *>(m_xInplaceMenuBar->GetMenuBar());
210 else
212 Reference< awt::XMenuBar > xMenuBar;
214 if ( m_xMenuBar.is() )
218 m_xMenuBar->getPropertyValue("XMenuBar") >>= xMenuBar;
220 catch (const beans::UnknownPropertyException&)
223 catch (const lang::WrappedTargetException&)
228 VCLXMenu* pAwtMenuBar = dynamic_cast<VCLXMenu*>( xMenuBar.get() );
229 if ( pAwtMenuBar )
230 pSetMenuBar = static_cast<MenuBar*>(pAwtMenuBar->GetMenu());
233 MenuBar* pTopMenuBar = pSysWindow->GetMenuBar();
234 if ( pSetMenuBar == pTopMenuBar )
235 pSysWindow->SetMenuBar( nullptr );
239 // reset inplace menubar manager
240 VclPtr<Menu> pMenuBar;
241 if (m_xInplaceMenuBar.is())
243 pMenuBar = m_xInplaceMenuBar->GetMenuBar();
244 m_xInplaceMenuBar->dispose();
245 m_xInplaceMenuBar.clear();
247 pMenuBar.disposeAndClear();
248 m_bInplaceMenuSet = false;
250 if ( m_xMenuBar.is() )
252 m_xMenuBar->dispose();
253 m_xMenuBar.clear();
255 implts_unlock();
258 void LayoutManager::implts_lock()
260 SolarMutexGuard g;
261 ++m_nLockCount;
264 bool LayoutManager::implts_unlock()
266 SolarMutexGuard g;
267 m_nLockCount = std::max( m_nLockCount-1, static_cast<sal_Int32>(0) );
268 return ( m_nLockCount == 0 );
271 void LayoutManager::implts_reset( bool bAttached )
273 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
274 SolarMutexClearableGuard aReadLock;
275 Reference< XFrame > xFrame = m_xFrame;
276 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
277 Reference< XUIConfiguration > xModuleCfgMgr( m_xModuleCfgMgr, UNO_QUERY );
278 Reference< XUIConfiguration > xDocCfgMgr( m_xDocCfgMgr, UNO_QUERY );
279 Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
280 Reference< XComponentContext > xContext( m_xContext );
281 Reference< XNameAccess > xPersistentWindowStateSupplier( m_xPersistentWindowStateSupplier );
282 rtl::Reference<ToolbarLayoutManager> xToolbarManager( m_xToolbarManager );
283 OUString aModuleIdentifier( m_aModuleIdentifier );
284 bool bAutomaticToolbars( m_bAutomaticToolbars );
285 aReadLock.clear();
286 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
288 implts_lock();
290 Reference< XModel > xModel;
291 if ( xFrame.is() )
293 if ( bAttached )
295 OUString aOldModuleIdentifier( aModuleIdentifier );
298 aModuleIdentifier = m_xModuleManager->identify( xFrame );
300 catch( const Exception& ) {}
302 if ( !aModuleIdentifier.isEmpty() && aOldModuleIdentifier != aModuleIdentifier )
304 Reference< XModuleUIConfigurationManagerSupplier > xModuleCfgSupplier;
305 if ( xContext.is() )
306 xModuleCfgSupplier = theModuleUIConfigurationManagerSupplier::get( xContext );
308 if ( xModuleCfgMgr.is() )
312 // Remove listener to old module ui configuration manager
313 xModuleCfgMgr->removeConfigurationListener( Reference< XUIConfigurationListener >(this) );
315 catch (const Exception&)
322 // Add listener to new module ui configuration manager
323 xModuleCfgMgr.set( xModuleCfgSupplier->getUIConfigurationManager( aModuleIdentifier ), UNO_QUERY );
324 if ( xModuleCfgMgr.is() )
325 xModuleCfgMgr->addConfigurationListener( Reference< XUIConfigurationListener >(this) );
327 catch (const Exception&)
333 // Retrieve persistent window state reference for our new module
334 if ( xPersistentWindowStateSupplier.is() )
335 xPersistentWindowStateSupplier->getByName( aModuleIdentifier ) >>= xPersistentWindowState;
337 catch (const NoSuchElementException&)
340 catch (const WrappedTargetException&)
345 xModel = impl_getModelFromFrame( xFrame );
346 if ( xModel.is() )
348 Reference< XUIConfigurationManagerSupplier > xUIConfigurationManagerSupplier( xModel, UNO_QUERY );
349 if ( xUIConfigurationManagerSupplier.is() )
351 if ( xDocCfgMgr.is() )
355 // Remove listener to old ui configuration manager
356 xDocCfgMgr->removeConfigurationListener( Reference< XUIConfigurationListener >(this) );
358 catch (const Exception&)
365 xDocCfgMgr.set( xUIConfigurationManagerSupplier->getUIConfigurationManager(), UNO_QUERY );
366 if ( xDocCfgMgr.is() )
367 xDocCfgMgr->addConfigurationListener( Reference< XUIConfigurationListener >(this) );
369 catch (const Exception&)
375 else
377 // Remove configuration listeners before we can release our references
378 if ( xModuleCfgMgr.is() )
382 xModuleCfgMgr->removeConfigurationListener(
383 Reference< XUIConfigurationListener >(this) );
385 catch (const Exception&)
390 if ( xDocCfgMgr.is() )
394 xDocCfgMgr->removeConfigurationListener(
395 Reference< XUIConfigurationListener >(this) );
397 catch (const Exception&)
402 // Release references to our configuration managers as we currently don't have
403 // an attached module.
404 xModuleCfgMgr.clear();
405 xDocCfgMgr.clear();
406 xPersistentWindowState.clear();
407 aModuleIdentifier.clear();
410 Reference< XUIConfigurationManager > xModCfgMgr( xModuleCfgMgr, UNO_QUERY );
411 Reference< XUIConfigurationManager > xDokCfgMgr( xDocCfgMgr, UNO_QUERY );
413 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
414 SolarMutexClearableGuard aWriteLock;
415 m_aDockingArea = awt::Rectangle();
416 m_aModuleIdentifier = aModuleIdentifier;
417 m_xModuleCfgMgr = xModCfgMgr;
418 m_xDocCfgMgr = xDokCfgMgr;
419 m_xPersistentWindowState = xPersistentWindowState;
420 m_aStatusBarElement.m_bStateRead = false; // reset state to read data again!
421 aWriteLock.clear();
422 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
424 // reset/notify toolbar layout manager
425 if ( xToolbarManager.is() )
427 if ( bAttached )
429 xToolbarManager->attach( xFrame, xModCfgMgr, xDokCfgMgr, xPersistentWindowState );
430 uno::Reference< awt::XVclWindowPeer > xParent( xContainerWindow, UNO_QUERY );
431 xToolbarManager->setParentWindow( xParent );
432 if ( bAutomaticToolbars )
433 xToolbarManager->createStaticToolbars();
435 else
437 xToolbarManager->reset();
438 implts_destroyElements();
443 implts_unlock();
446 bool LayoutManager::implts_isEmbeddedLayoutManager() const
448 SolarMutexClearableGuard aReadLock;
449 Reference< XFrame > xFrame = m_xFrame;
450 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
451 aReadLock.clear();
453 Reference< awt::XWindow > xFrameContainerWindow = xFrame->getContainerWindow();
454 return xFrameContainerWindow != xContainerWindow;
457 void LayoutManager::implts_destroyElements()
459 SolarMutexResettableGuard aWriteLock;
460 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
461 aWriteLock.clear();
463 if ( pToolbarManager )
464 pToolbarManager->destroyToolbars();
466 implts_destroyStatusBar();
468 aWriteLock.reset();
469 impl_clearUpMenuBar();
470 aWriteLock.clear();
473 void LayoutManager::implts_toggleFloatingUIElementsVisibility( bool bActive )
475 SolarMutexClearableGuard aReadLock;
476 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
477 aReadLock.clear();
479 if ( pToolbarManager )
480 pToolbarManager->setFloatingToolbarsVisibility( bActive );
483 uno::Reference< ui::XUIElement > LayoutManager::implts_findElement( std::u16string_view aName )
485 OUString aElementType;
486 OUString aElementName;
488 parseResourceURL( aName, aElementType, aElementName );
489 if ( aElementType.equalsIgnoreAsciiCase("menubar") &&
490 aElementName.equalsIgnoreAsciiCase("menubar") )
491 return m_xMenuBar;
492 else if (( aElementType.equalsIgnoreAsciiCase("statusbar") &&
493 aElementName.equalsIgnoreAsciiCase("statusbar") ) ||
494 ( m_aStatusBarElement.m_aName == aName ))
495 return m_aStatusBarElement.m_xUIElement;
496 else if ( aElementType.equalsIgnoreAsciiCase("progressbar") &&
497 aElementName.equalsIgnoreAsciiCase("progressbar") )
498 return m_aProgressBarElement.m_xUIElement;
500 return uno::Reference< ui::XUIElement >();
503 bool LayoutManager::implts_readWindowStateData( const OUString& aName, UIElement& rElementData )
505 return readWindowStateData( aName, rElementData, m_xPersistentWindowState,
506 m_pGlobalSettings, m_bGlobalSettings, m_xContext );
509 bool LayoutManager::readWindowStateData( const OUString& aName, UIElement& rElementData,
510 const Reference< XNameAccess > &rPersistentWindowState,
511 std::unique_ptr<GlobalSettings> &rGlobalSettings, bool &bInGlobalSettings,
512 const Reference< XComponentContext > &rComponentContext )
514 if ( !rPersistentWindowState.is() )
515 return false;
517 bool bGetSettingsState( false );
519 SolarMutexClearableGuard aWriteLock;
520 bool bGlobalSettings( bInGlobalSettings );
521 if ( rGlobalSettings == nullptr )
523 rGlobalSettings.reset( new GlobalSettings( rComponentContext ) );
524 bGetSettingsState = true;
526 GlobalSettings* pGlobalSettings = rGlobalSettings.get();
527 aWriteLock.clear();
531 Sequence< PropertyValue > aWindowState;
532 if ( rPersistentWindowState->hasByName( aName ) && (rPersistentWindowState->getByName( aName ) >>= aWindowState) )
534 bool bValue( false );
535 for ( PropertyValue const & rProp : std::as_const(aWindowState) )
537 if ( rProp.Name == WINDOWSTATE_PROPERTY_DOCKED )
539 if ( rProp.Value >>= bValue )
540 rElementData.m_bFloating = !bValue;
542 else if ( rProp.Name == WINDOWSTATE_PROPERTY_VISIBLE )
544 if ( rProp.Value >>= bValue )
545 rElementData.m_bVisible = bValue;
547 else if ( rProp.Name == WINDOWSTATE_PROPERTY_DOCKINGAREA )
549 ui::DockingArea eDockingArea;
550 if ( rProp.Value >>= eDockingArea )
551 rElementData.m_aDockedData.m_nDockedArea = eDockingArea;
553 else if ( rProp.Name == WINDOWSTATE_PROPERTY_DOCKPOS )
555 awt::Point aPoint;
556 if (rProp.Value >>= aPoint)
558 //tdf#90256 repair these broken Docking positions
559 if (aPoint.X < 0)
560 aPoint.X = SAL_MAX_INT32;
561 if (aPoint.Y < 0)
562 aPoint.Y = SAL_MAX_INT32;
563 rElementData.m_aDockedData.m_aPos = aPoint;
566 else if ( rProp.Name == WINDOWSTATE_PROPERTY_POS )
568 awt::Point aPoint;
569 if ( rProp.Value >>= aPoint )
570 rElementData.m_aFloatingData.m_aPos = aPoint;
572 else if ( rProp.Name == WINDOWSTATE_PROPERTY_SIZE )
574 awt::Size aSize;
575 if ( rProp.Value >>= aSize )
576 rElementData.m_aFloatingData.m_aSize = aSize;
578 else if ( rProp.Name == WINDOWSTATE_PROPERTY_UINAME )
579 rProp.Value >>= rElementData.m_aUIName;
580 else if ( rProp.Name == WINDOWSTATE_PROPERTY_STYLE )
582 sal_Int32 nStyle = 0;
583 if ( rProp.Value >>= nStyle )
584 rElementData.m_nStyle = static_cast<ButtonType>( nStyle );
586 else if ( rProp.Name == WINDOWSTATE_PROPERTY_LOCKED )
588 if ( rProp.Value >>= bValue )
589 rElementData.m_aDockedData.m_bLocked = bValue;
591 else if ( rProp.Name == WINDOWSTATE_PROPERTY_CONTEXT )
593 if ( rProp.Value >>= bValue )
594 rElementData.m_bContextSensitive = bValue;
596 else if ( rProp.Name == WINDOWSTATE_PROPERTY_NOCLOSE )
598 if ( rProp.Value >>= bValue )
599 rElementData.m_bNoClose = bValue;
604 // oversteer values with global settings
605 if (bGetSettingsState || bGlobalSettings)
607 if ( pGlobalSettings->HasToolbarStatesInfo())
610 SolarMutexGuard aWriteLock2;
611 bInGlobalSettings = true;
614 uno::Any aValue;
615 if ( pGlobalSettings->GetToolbarStateInfo(
616 GlobalSettings::STATEINFO_LOCKED,
617 aValue ))
618 aValue >>= rElementData.m_aDockedData.m_bLocked;
619 if ( pGlobalSettings->GetToolbarStateInfo(
620 GlobalSettings::STATEINFO_DOCKED,
621 aValue ))
623 bool bValue;
624 if ( aValue >>= bValue )
625 rElementData.m_bFloating = !bValue;
630 const bool bDockingSupportCrippled = !StyleSettings::GetDockingFloatsSupported();
631 if (bDockingSupportCrippled)
632 rElementData.m_bFloating = false;
634 return true;
636 catch (const NoSuchElementException&)
640 return false;
643 void LayoutManager::implts_writeWindowStateData( const OUString& aName, const UIElement& rElementData )
645 SolarMutexClearableGuard aWriteLock;
646 Reference< XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
648 aWriteLock.clear();
650 bool bPersistent( false );
651 Reference< XPropertySet > xPropSet( rElementData.m_xUIElement, UNO_QUERY );
652 if ( xPropSet.is() )
656 // Check persistent flag of the user interface element
657 xPropSet->getPropertyValue("Persistent") >>= bPersistent;
659 catch (const beans::UnknownPropertyException&)
661 // Non-configurable elements should at least store their dimension/position
662 bPersistent = true;
664 catch (const lang::WrappedTargetException&)
669 if ( !(bPersistent && xPersistentWindowState.is()) )
670 return;
674 Sequence< PropertyValue > aWindowState{
675 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_DOCKED, !rElementData.m_bFloating),
676 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_VISIBLE, rElementData.m_bVisible),
677 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_DOCKINGAREA,
678 rElementData.m_aDockedData.m_nDockedArea),
679 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_DOCKPOS,
680 rElementData.m_aDockedData.m_aPos),
681 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_POS,
682 rElementData.m_aFloatingData.m_aPos),
683 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_SIZE,
684 rElementData.m_aFloatingData.m_aSize),
685 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_UINAME, rElementData.m_aUIName),
686 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_LOCKED,
687 rElementData.m_aDockedData.m_bLocked)
690 if ( xPersistentWindowState->hasByName( aName ))
692 Reference< XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY );
693 xReplace->replaceByName( aName, Any( aWindowState ));
695 else
697 Reference< XNameContainer > xInsert( xPersistentWindowState, uno::UNO_QUERY );
698 xInsert->insertByName( aName, Any( aWindowState ));
701 catch (const Exception&)
706 ::Size LayoutManager::implts_getContainerWindowOutputSize()
708 ::Size aContainerWinSize;
709 vcl::Window* pContainerWindow( nullptr );
711 // Retrieve output size from container Window
712 SolarMutexGuard aGuard;
713 pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
714 if ( pContainerWindow )
715 aContainerWinSize = pContainerWindow->GetOutputSizePixel();
717 return aContainerWinSize;
720 Reference< XUIElement > LayoutManager::implts_createElement( const OUString& aName )
722 Reference< ui::XUIElement > xUIElement;
724 SolarMutexGuard g;
725 Sequence< PropertyValue > aPropSeq{ comphelper::makePropertyValue("Frame", m_xFrame),
726 comphelper::makePropertyValue("Persistent", true) };
730 xUIElement = m_xUIElementFactoryManager->createUIElement( aName, aPropSeq );
732 catch (const NoSuchElementException&)
735 catch (const IllegalArgumentException&)
739 return xUIElement;
742 void LayoutManager::implts_setVisibleState( bool bShow )
745 SolarMutexGuard aWriteLock;
746 m_aStatusBarElement.m_bMasterHide = !bShow;
749 implts_updateUIElementsVisibleState( bShow );
752 void LayoutManager::implts_updateUIElementsVisibleState( bool bSetVisible )
754 // notify listeners
755 uno::Any a;
756 if ( bSetVisible )
757 implts_notifyListeners( frame::LayoutManagerEvents::VISIBLE, a );
758 else
759 implts_notifyListeners( frame::LayoutManagerEvents::INVISIBLE, a );
761 SolarMutexResettableGuard aWriteLock;
762 rtl::Reference< MenuBarWrapper > xMenuBar = m_xMenuBar;
763 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
764 rtl::Reference< MenuBarManager > xInplaceMenuBar( m_xInplaceMenuBar );
765 aWriteLock.clear();
767 if (( xMenuBar.is() || xInplaceMenuBar.is() ) && xContainerWindow.is() )
769 SolarMutexGuard aGuard;
771 MenuBar* pMenuBar( nullptr );
772 if ( xInplaceMenuBar.is() )
773 pMenuBar = static_cast<MenuBar *>(xInplaceMenuBar->GetMenuBar());
774 else
776 pMenuBar = static_cast<MenuBar *>(xMenuBar->GetMenuBarManager()->GetMenuBar());
779 SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow );
780 if ( pSysWindow )
782 if ( bSetVisible )
784 pSysWindow->SetMenuBar(pMenuBar);
786 else
787 pSysWindow->SetMenuBar( nullptr );
791 bool bMustDoLayout;
792 // Hide/show the statusbar according to bSetVisible
793 if ( bSetVisible )
794 bMustDoLayout = !implts_showStatusBar();
795 else
796 bMustDoLayout = !implts_hideStatusBar();
798 aWriteLock.reset();
799 ToolbarLayoutManager* pToolbarManager( m_xToolbarManager.get() );
800 aWriteLock.clear();
802 if ( pToolbarManager )
804 pToolbarManager->setVisible( bSetVisible );
805 bMustDoLayout = pToolbarManager->isLayoutDirty();
808 if ( bMustDoLayout )
809 implts_doLayout_notify( false );
812 void LayoutManager::implts_setCurrentUIVisibility( bool bShow )
815 SolarMutexGuard aWriteLock;
816 if (!bShow && m_aStatusBarElement.m_bVisible && m_aStatusBarElement.m_xUIElement.is())
817 m_aStatusBarElement.m_bMasterHide = true;
818 else if (bShow && m_aStatusBarElement.m_bVisible)
819 m_aStatusBarElement.m_bMasterHide = false;
822 implts_updateUIElementsVisibleState( bShow );
825 void LayoutManager::implts_destroyStatusBar()
827 Reference< XComponent > xCompStatusBar;
829 SolarMutexClearableGuard aWriteLock;
830 m_aStatusBarElement.m_aName.clear();
831 xCompStatusBar.set( m_aStatusBarElement.m_xUIElement, UNO_QUERY );
832 m_aStatusBarElement.m_xUIElement.clear();
833 aWriteLock.clear();
835 if ( xCompStatusBar.is() )
836 xCompStatusBar->dispose();
838 implts_destroyProgressBar();
841 void LayoutManager::implts_createStatusBar( const OUString& aStatusBarName )
844 SolarMutexGuard aWriteLock;
845 if (!m_aStatusBarElement.m_xUIElement.is())
847 implts_readStatusBarState(aStatusBarName);
848 m_aStatusBarElement.m_aName = aStatusBarName;
849 m_aStatusBarElement.m_xUIElement = implts_createElement(aStatusBarName);
853 implts_createProgressBar();
856 void LayoutManager::implts_readStatusBarState( const OUString& rStatusBarName )
858 SolarMutexGuard g;
859 if ( !m_aStatusBarElement.m_bStateRead )
861 // Read persistent data for status bar if not yet read!
862 if ( implts_readWindowStateData( rStatusBarName, m_aStatusBarElement ))
863 m_aStatusBarElement.m_bStateRead = true;
867 void LayoutManager::implts_createProgressBar()
869 Reference< XUIElement > xStatusBar;
870 Reference< XUIElement > xProgressBar;
871 rtl::Reference< ProgressBarWrapper > xProgressBarBackup;
872 Reference< awt::XWindow > xContainerWindow;
874 SolarMutexResettableGuard aWriteLock;
875 xStatusBar = m_aStatusBarElement.m_xUIElement;
876 xProgressBar = m_aProgressBarElement.m_xUIElement;
877 xProgressBarBackup = m_xProgressBarBackup;
878 m_xProgressBarBackup.clear();
879 xContainerWindow = m_xContainerWindow;
880 aWriteLock.clear();
882 bool bRecycled = xProgressBarBackup.is();
883 rtl::Reference<ProgressBarWrapper> pWrapper;
884 if ( bRecycled )
885 pWrapper = xProgressBarBackup.get();
886 else if ( xProgressBar.is() )
887 pWrapper = static_cast<ProgressBarWrapper*>(xProgressBar.get());
888 else
889 pWrapper = new ProgressBarWrapper();
891 if ( xStatusBar.is() )
893 Reference< awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY );
894 pWrapper->setStatusBar( xWindow );
896 else
898 Reference< awt::XWindow > xStatusBarWindow = pWrapper->getStatusBar();
900 SolarMutexGuard aGuard;
901 VclPtr<vcl::Window> pStatusBarWnd = VCLUnoHelper::GetWindow( xStatusBarWindow );
902 if ( !pStatusBarWnd )
904 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xContainerWindow );
905 if ( pWindow )
907 VclPtrInstance<StatusBar> pStatusBar( pWindow, WinBits( WB_LEFT | WB_3DLOOK ) );
908 Reference< awt::XWindow > xStatusBarWindow2( VCLUnoHelper::GetInterface( pStatusBar ));
909 pWrapper->setStatusBar( xStatusBarWindow2, true );
914 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
915 aWriteLock.reset();
916 m_aProgressBarElement.m_xUIElement = pWrapper;
917 aWriteLock.clear();
918 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
920 if ( bRecycled )
921 implts_showProgressBar();
924 void LayoutManager::implts_backupProgressBarWrapper()
926 SolarMutexGuard g;
928 if (m_xProgressBarBackup.is())
929 return;
931 // safe a backup copy of the current progress!
932 // This copy will be used automatically inside createProgressBar() which is called
933 // implicitly from implts_doLayout() .-)
934 m_xProgressBarBackup = static_cast<ProgressBarWrapper*>(m_aProgressBarElement.m_xUIElement.get());
936 // remove the relation between this old progress bar and our old status bar.
937 // Otherwise we work on disposed items ...
938 // The internal used ProgressBarWrapper can handle a NULL reference.
939 if ( m_xProgressBarBackup.is() )
940 m_xProgressBarBackup->setStatusBar( Reference< awt::XWindow >() );
942 // prevent us from dispose() the m_aProgressBarElement.m_xUIElement inside implts_reset()
943 m_aProgressBarElement.m_xUIElement.clear();
946 void LayoutManager::implts_destroyProgressBar()
948 // don't remove the progressbar in general
949 // We must reuse it if a new status bar is created later.
950 // Of course there exists one backup only.
951 // And further this backup will be released inside our dtor.
952 implts_backupProgressBarWrapper();
955 void LayoutManager::implts_setStatusBarPosSize( const ::Point& rPos, const ::Size& rSize )
957 Reference< XUIElement > xStatusBar;
958 Reference< XUIElement > xProgressBar;
959 Reference< awt::XWindow > xContainerWindow;
961 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
962 SolarMutexClearableGuard aReadLock;
963 xStatusBar = m_aStatusBarElement.m_xUIElement;
964 xProgressBar = m_aProgressBarElement.m_xUIElement;
965 xContainerWindow = m_xContainerWindow;
967 Reference< awt::XWindow > xWindow;
968 if ( xStatusBar.is() )
969 xWindow.set( xStatusBar->getRealInterface(), UNO_QUERY );
970 else if ( xProgressBar.is() )
972 ProgressBarWrapper* pWrapper = static_cast<ProgressBarWrapper*>(xProgressBar.get());
973 if ( pWrapper )
974 xWindow = pWrapper->getStatusBar();
976 aReadLock.clear();
977 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
979 if ( !xWindow.is() )
980 return;
982 SolarMutexGuard aGuard;
983 VclPtr<vcl::Window> pParentWindow = VCLUnoHelper::GetWindow( xContainerWindow );
984 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
985 if ( pParentWindow && ( pWindow && pWindow->GetType() == WindowType::STATUSBAR ))
987 vcl::Window* pOldParentWindow = pWindow->GetParent();
988 if ( pParentWindow != pOldParentWindow )
989 pWindow->SetParent( pParentWindow );
990 static_cast<StatusBar *>(pWindow.get())->SetPosSizePixel( rPos, rSize );
994 bool LayoutManager::implts_showProgressBar()
996 Reference< XUIElement > xStatusBar;
997 Reference< XUIElement > xProgressBar;
998 Reference< awt::XWindow > xWindow;
1000 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1001 SolarMutexGuard aWriteLock;
1002 xStatusBar = m_aStatusBarElement.m_xUIElement;
1003 xProgressBar = m_aProgressBarElement.m_xUIElement;
1004 bool bVisible( m_bVisible );
1006 m_aProgressBarElement.m_bVisible = true;
1007 if ( bVisible )
1009 if ( xStatusBar.is() && !m_aStatusBarElement.m_bMasterHide )
1011 xWindow.set( xStatusBar->getRealInterface(), UNO_QUERY );
1013 else if ( xProgressBar.is() )
1015 ProgressBarWrapper* pWrapper = static_cast<ProgressBarWrapper*>(xProgressBar.get());
1016 if ( pWrapper )
1017 xWindow = pWrapper->getStatusBar();
1021 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
1022 if ( pWindow )
1024 if ( !pWindow->IsVisible() )
1026 implts_setOffset( pWindow->GetSizePixel().Height() );
1027 pWindow->Show();
1028 implts_doLayout_notify( false );
1030 return true;
1033 return false;
1036 bool LayoutManager::implts_hideProgressBar()
1038 Reference< XUIElement > xProgressBar;
1039 Reference< awt::XWindow > xWindow;
1040 bool bHideStatusBar( false );
1042 SolarMutexGuard g;
1043 xProgressBar = m_aProgressBarElement.m_xUIElement;
1045 bool bInternalStatusBar( false );
1046 if ( xProgressBar.is() )
1048 Reference< awt::XWindow > xStatusBar;
1049 ProgressBarWrapper* pWrapper = static_cast<ProgressBarWrapper*>(xProgressBar.get());
1050 if ( pWrapper )
1051 xWindow = pWrapper->getStatusBar();
1052 Reference< ui::XUIElement > xStatusBarElement = m_aStatusBarElement.m_xUIElement;
1053 if ( xStatusBarElement.is() )
1054 xStatusBar.set( xStatusBarElement->getRealInterface(), UNO_QUERY );
1055 bInternalStatusBar = xStatusBar != xWindow;
1057 m_aProgressBarElement.m_bVisible = false;
1058 implts_readStatusBarState( STATUS_BAR_ALIAS );
1059 bHideStatusBar = !m_aStatusBarElement.m_bVisible;
1061 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
1062 if ( pWindow && pWindow->IsVisible() && ( bHideStatusBar || bInternalStatusBar ))
1064 implts_setOffset( 0 );
1065 pWindow->Hide();
1066 implts_doLayout_notify( false );
1067 return true;
1070 return false;
1073 bool LayoutManager::implts_showStatusBar( bool bStoreState )
1075 SolarMutexClearableGuard aWriteLock;
1076 Reference< ui::XUIElement > xStatusBar = m_aStatusBarElement.m_xUIElement;
1077 if ( bStoreState )
1078 m_aStatusBarElement.m_bVisible = true;
1079 aWriteLock.clear();
1081 if ( xStatusBar.is() )
1083 Reference< awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY );
1085 SolarMutexGuard aGuard;
1086 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
1087 if ( pWindow && !pWindow->IsVisible() )
1089 implts_setOffset( pWindow->GetSizePixel().Height() );
1090 pWindow->Show();
1091 implts_doLayout_notify( false );
1092 return true;
1096 return false;
1099 bool LayoutManager::implts_hideStatusBar( bool bStoreState )
1101 SolarMutexClearableGuard aWriteLock;
1102 Reference< ui::XUIElement > xStatusBar = m_aStatusBarElement.m_xUIElement;
1103 if ( bStoreState )
1104 m_aStatusBarElement.m_bVisible = false;
1105 aWriteLock.clear();
1107 if ( xStatusBar.is() )
1109 Reference< awt::XWindow > xWindow( xStatusBar->getRealInterface(), UNO_QUERY );
1111 SolarMutexGuard aGuard;
1112 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
1113 if ( pWindow && pWindow->IsVisible() )
1115 implts_setOffset( 0 );
1116 pWindow->Hide();
1117 implts_doLayout_notify( false );
1118 return true;
1122 return false;
1125 void LayoutManager::implts_setOffset( const sal_Int32 nBottomOffset )
1127 if ( m_xToolbarManager.is() )
1128 m_xToolbarManager->setDockingAreaOffsets({ 0, 0, 0, nBottomOffset });
1131 void LayoutManager::implts_setInplaceMenuBar( const Reference< XIndexAccess >& xMergedMenuBar )
1133 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1134 SolarMutexClearableGuard aWriteLock;
1136 if ( m_bInplaceMenuSet )
1137 return;
1139 SolarMutexGuard aGuard;
1141 // Reset old inplace menubar!
1142 VclPtr<Menu> pOldMenuBar;
1143 if (m_xInplaceMenuBar.is())
1145 pOldMenuBar = m_xInplaceMenuBar->GetMenuBar();
1146 m_xInplaceMenuBar->dispose();
1147 m_xInplaceMenuBar.clear();
1149 pOldMenuBar.disposeAndClear();
1151 m_bInplaceMenuSet = false;
1153 if ( m_xFrame.is() && m_xContainerWindow.is() )
1155 Reference< XDispatchProvider > xDispatchProvider;
1157 VclPtr<MenuBar> pMenuBar = VclPtr<MenuBar>::Create();
1158 m_xInplaceMenuBar = new MenuBarManager( m_xContext, m_xFrame, m_xURLTransformer, xDispatchProvider, OUString(), pMenuBar, true );
1159 m_xInplaceMenuBar->SetItemContainer( xMergedMenuBar );
1161 SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
1162 if ( pSysWindow )
1163 pSysWindow->SetMenuBar(pMenuBar);
1165 m_bInplaceMenuSet = true;
1168 aWriteLock.clear();
1169 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1171 implts_updateMenuBarClose();
1174 void LayoutManager::implts_resetInplaceMenuBar()
1176 SolarMutexGuard g;
1177 m_bInplaceMenuSet = false;
1179 if ( m_xContainerWindow.is() )
1181 SolarMutexGuard aGuard;
1182 SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
1183 if ( pSysWindow )
1185 if ( m_xMenuBar )
1186 pSysWindow->SetMenuBar(static_cast<MenuBar *>(m_xMenuBar->GetMenuBarManager()->GetMenuBar()));
1187 else
1188 pSysWindow->SetMenuBar(nullptr);
1192 // Remove inplace menu bar
1193 VclPtr<Menu> pMenuBar;
1194 if (m_xInplaceMenuBar.is())
1196 pMenuBar = m_xInplaceMenuBar->GetMenuBar();
1197 m_xInplaceMenuBar->dispose();
1198 m_xInplaceMenuBar.clear();
1200 pMenuBar.disposeAndClear();
1203 void SAL_CALL LayoutManager::attachFrame( const Reference< XFrame >& xFrame )
1205 SolarMutexGuard g;
1206 m_xFrame = xFrame;
1209 void SAL_CALL LayoutManager::reset()
1211 implts_reset( true );
1214 // XMenuBarMergingAcceptor
1216 sal_Bool SAL_CALL LayoutManager::setMergedMenuBar(
1217 const Reference< XIndexAccess >& xMergedMenuBar )
1219 implts_setInplaceMenuBar( xMergedMenuBar );
1221 uno::Any a;
1222 implts_notifyListeners( frame::LayoutManagerEvents::MERGEDMENUBAR, a );
1223 return true;
1226 void SAL_CALL LayoutManager::removeMergedMenuBar()
1228 implts_resetInplaceMenuBar();
1231 awt::Rectangle SAL_CALL LayoutManager::getCurrentDockingArea()
1233 SolarMutexGuard g;
1234 return m_aDockingArea;
1237 Reference< XDockingAreaAcceptor > SAL_CALL LayoutManager::getDockingAreaAcceptor()
1239 SolarMutexGuard g;
1240 return m_xDockingAreaAcceptor;
1243 void SAL_CALL LayoutManager::setDockingAreaAcceptor( const Reference< ui::XDockingAreaAcceptor >& xDockingAreaAcceptor )
1245 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1246 SolarMutexClearableGuard aWriteLock;
1248 if (( m_xDockingAreaAcceptor == xDockingAreaAcceptor ) || !m_xFrame.is() )
1249 return;
1251 // IMPORTANT: Be sure to stop layout timer if don't have a docking area acceptor!
1252 if ( !xDockingAreaAcceptor.is() )
1253 m_aAsyncLayoutTimer.Stop();
1255 bool bAutomaticToolbars( m_bAutomaticToolbars );
1257 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1259 if ( !xDockingAreaAcceptor.is() )
1260 m_aAsyncLayoutTimer.Stop();
1262 // Remove listener from old docking area acceptor
1263 if ( m_xDockingAreaAcceptor.is() )
1265 Reference< awt::XWindow > xWindow( m_xDockingAreaAcceptor->getContainerWindow() );
1266 if ( xWindow.is() && ( m_xFrame->getContainerWindow() != m_xContainerWindow || !xDockingAreaAcceptor.is() ) )
1267 xWindow->removeWindowListener( Reference< awt::XWindowListener >(this) );
1269 m_aDockingArea = awt::Rectangle();
1270 if ( pToolbarManager )
1271 pToolbarManager->resetDockingArea();
1273 VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( xWindow );
1274 if ( pContainerWindow )
1275 pContainerWindow->RemoveChildEventListener( LINK( this, LayoutManager, WindowEventListener ) );
1278 m_xDockingAreaAcceptor = xDockingAreaAcceptor;
1279 if ( m_xDockingAreaAcceptor.is() )
1281 m_aDockingArea = awt::Rectangle();
1282 m_xContainerWindow = m_xDockingAreaAcceptor->getContainerWindow();
1283 m_xContainerTopWindow.set( m_xContainerWindow, UNO_QUERY );
1284 m_xContainerWindow->addWindowListener( Reference< awt::XWindowListener >(this) );
1286 // we always must keep a connection to the window of our frame for resize events
1287 if ( m_xContainerWindow != m_xFrame->getContainerWindow() )
1288 m_xFrame->getContainerWindow()->addWindowListener( Reference< awt::XWindowListener >(this) );
1290 // #i37884# set initial visibility state - in the plugin case the container window is already shown
1291 // and we get no notification anymore
1293 VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
1294 if( pContainerWindow )
1295 m_bParentWindowVisible = pContainerWindow->IsVisible();
1299 aWriteLock.clear();
1300 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1302 if ( xDockingAreaAcceptor.is() )
1304 SolarMutexGuard aGuard;
1306 // Add layout manager as listener to get notifications about toolbar button activities
1307 VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
1308 if ( pContainerWindow )
1309 pContainerWindow->AddChildEventListener( LINK( this, LayoutManager, WindowEventListener ) );
1311 // We have now a new container window, reparent all child windows!
1312 implts_reparentChildWindows();
1314 else
1315 implts_destroyElements(); // remove all elements
1317 if ( pToolbarManager && xDockingAreaAcceptor.is() )
1319 if ( bAutomaticToolbars )
1321 lock();
1322 pToolbarManager->createStaticToolbars();
1323 unlock();
1325 implts_doLayout( true, false );
1329 void LayoutManager::implts_reparentChildWindows()
1331 SolarMutexResettableGuard aWriteLock;
1332 UIElement aStatusBarElement = m_aStatusBarElement;
1333 uno::Reference< awt::XWindow > xContainerWindow = m_xContainerWindow;
1334 aWriteLock.clear();
1336 uno::Reference< awt::XWindow > xStatusBarWindow;
1337 if ( aStatusBarElement.m_xUIElement.is() )
1341 xStatusBarWindow.set( aStatusBarElement.m_xUIElement->getRealInterface(), UNO_QUERY );
1343 catch (const RuntimeException&)
1345 throw;
1347 catch (const Exception&)
1352 if ( xStatusBarWindow.is() )
1354 SolarMutexGuard aGuard;
1355 VclPtr<vcl::Window> pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
1356 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xStatusBarWindow );
1357 if ( pWindow && pContainerWindow )
1358 pWindow->SetParent( pContainerWindow );
1361 implts_resetMenuBar();
1363 aWriteLock.reset();
1364 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1365 if ( pToolbarManager )
1366 pToolbarManager->setParentWindow( uno::Reference< awt::XVclWindowPeer >( xContainerWindow, uno::UNO_QUERY ));
1367 aWriteLock.clear();
1370 uno::Reference< ui::XUIElement > LayoutManager::implts_createDockingWindow( const OUString& aElementName )
1372 Reference< XUIElement > xUIElement = implts_createElement( aElementName );
1373 return xUIElement;
1376 IMPL_LINK( LayoutManager, WindowEventListener, VclWindowEvent&, rEvent, void )
1378 vcl::Window* pWindow = rEvent.GetWindow();
1379 if ( pWindow && pWindow->GetType() == WindowType::TOOLBOX )
1381 SolarMutexClearableGuard aReadLock;
1382 ToolbarLayoutManager* pToolbarManager( m_xToolbarManager.get() );
1383 aReadLock.clear();
1385 if ( pToolbarManager )
1386 pToolbarManager->childWindowEvent( &rEvent );
1390 void SAL_CALL LayoutManager::createElement( const OUString& aName )
1392 SAL_INFO( "fwk", "LayoutManager::createElement " << aName );
1394 SolarMutexClearableGuard aReadLock;
1395 Reference< XFrame > xFrame = m_xFrame;
1396 aReadLock.clear();
1398 if ( !xFrame.is() )
1399 return;
1401 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1402 SolarMutexClearableGuard aWriteLock;
1404 bool bMustBeLayouted( false );
1405 bool bNotify( false );
1407 bool bPreviewFrame;
1408 if (m_xToolbarManager.is())
1409 // Assumes that we created the ToolbarLayoutManager with our frame, if
1410 // not then we're somewhat fouled up ...
1411 bPreviewFrame = m_xToolbarManager->isPreviewFrame();
1412 else
1414 Reference< XModel > xModel( impl_getModelFromFrame( xFrame ) );
1415 bPreviewFrame = implts_isPreviewModel( xModel );
1418 if ( m_xContainerWindow.is() && !bPreviewFrame ) // no UI elements on preview frames
1420 OUString aElementType;
1421 OUString aElementName;
1423 parseResourceURL( aName, aElementType, aElementName );
1425 if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ) && m_xToolbarManager.is() )
1427 bNotify = m_xToolbarManager->createToolbar( aName );
1428 bMustBeLayouted = m_xToolbarManager->isLayoutDirty();
1430 else if ( aElementType.equalsIgnoreAsciiCase("menubar") &&
1431 aElementName.equalsIgnoreAsciiCase("menubar") &&
1432 implts_isFrameOrWindowTop(xFrame) )
1434 implts_createMenuBar( aName );
1435 if (m_bMenuVisible)
1436 bNotify = true;
1438 aWriteLock.clear();
1440 else if ( aElementType.equalsIgnoreAsciiCase("statusbar") &&
1441 ( implts_isFrameOrWindowTop(xFrame) || implts_isEmbeddedLayoutManager() ))
1443 implts_createStatusBar( aName );
1444 bNotify = true;
1446 else if ( aElementType.equalsIgnoreAsciiCase("progressbar") &&
1447 aElementName.equalsIgnoreAsciiCase("progressbar") &&
1448 implts_isFrameOrWindowTop(xFrame) )
1450 implts_createProgressBar();
1451 bNotify = true;
1453 else if ( aElementType.equalsIgnoreAsciiCase("dockingwindow"))
1455 // Add layout manager as listener for docking and other window events
1456 uno::Reference< uno::XInterface > xThis( static_cast< OWeakObject* >(this), uno::UNO_QUERY );
1457 uno::Reference< ui::XUIElement > xUIElement( implts_createDockingWindow( aName ));
1459 if ( xUIElement.is() )
1461 impl_addWindowListeners( xThis, xUIElement );
1464 // The docking window is created by a factory method located in the sfx2 library.
1465 // CreateDockingWindow( xFrame, aElementName );
1469 if ( bMustBeLayouted )
1470 implts_doLayout_notify( true );
1472 if ( bNotify )
1474 // UI element is invisible - provide information to listeners
1475 implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_VISIBLE, uno::Any( aName ) );
1479 void SAL_CALL LayoutManager::destroyElement( const OUString& aName )
1481 SAL_INFO( "fwk", "LayoutManager::destroyElement " << aName );
1483 bool bMustBeLayouted(false);
1484 bool bNotify(false);
1485 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1487 SolarMutexClearableGuard aWriteLock;
1489 OUString aElementType;
1490 OUString aElementName;
1492 parseResourceURL(aName, aElementType, aElementName);
1494 if (aElementType.equalsIgnoreAsciiCase("menubar")
1495 && aElementName.equalsIgnoreAsciiCase("menubar"))
1497 if (!m_bInplaceMenuSet)
1499 impl_clearUpMenuBar();
1500 m_xMenuBar.clear();
1501 bNotify = true;
1504 else if ((aElementType.equalsIgnoreAsciiCase("statusbar")
1505 && aElementName.equalsIgnoreAsciiCase("statusbar"))
1506 || (m_aStatusBarElement.m_aName == aName))
1508 aWriteLock.clear();
1509 implts_destroyStatusBar();
1510 bMustBeLayouted = true;
1511 bNotify = true;
1513 else if (aElementType.equalsIgnoreAsciiCase("progressbar")
1514 && aElementName.equalsIgnoreAsciiCase("progressbar"))
1516 aWriteLock.clear();
1517 implts_createProgressBar();
1518 bMustBeLayouted = true;
1519 bNotify = true;
1521 else if (aElementType.equalsIgnoreAsciiCase(UIRESOURCETYPE_TOOLBAR)
1522 && m_xToolbarManager.is())
1524 aWriteLock.clear();
1525 bNotify = m_xToolbarManager->destroyToolbar(aName);
1526 bMustBeLayouted = m_xToolbarManager->isLayoutDirty();
1528 else if (aElementType.equalsIgnoreAsciiCase("dockingwindow"))
1530 uno::Reference<frame::XFrame> xFrame(m_xFrame);
1531 uno::Reference<XComponentContext> xContext(m_xContext);
1532 aWriteLock.clear();
1534 impl_setDockingWindowVisibility(xContext, xFrame, aElementName, false);
1535 bMustBeLayouted = false;
1536 bNotify = false;
1539 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1541 if ( bMustBeLayouted )
1542 doLayout();
1544 if ( bNotify )
1545 implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_INVISIBLE, uno::Any( aName ) );
1548 sal_Bool SAL_CALL LayoutManager::requestElement( const OUString& rResourceURL )
1550 bool bResult( false );
1551 bool bNotify( false );
1552 OUString aElementType;
1553 OUString aElementName;
1555 parseResourceURL( rResourceURL, aElementType, aElementName );
1557 SolarMutexClearableGuard aWriteLock;
1559 OString aResName = OUStringToOString( aElementName, RTL_TEXTENCODING_ASCII_US );
1560 SAL_INFO( "fwk", "LayoutManager::requestElement " << aResName );
1562 if (( aElementType.equalsIgnoreAsciiCase("statusbar") &&
1563 aElementName.equalsIgnoreAsciiCase("statusbar") ) ||
1564 ( m_aStatusBarElement.m_aName == rResourceURL ))
1566 implts_readStatusBarState( rResourceURL );
1567 if ( m_aStatusBarElement.m_bVisible && !m_aStatusBarElement.m_bMasterHide )
1569 aWriteLock.clear();
1570 createElement( rResourceURL );
1572 // There are some situation where we are not able to create an element.
1573 // Therefore we have to check the reference before further action.
1574 // See #i70019#
1575 uno::Reference< ui::XUIElement > xUIElement( m_aStatusBarElement.m_xUIElement );
1576 if ( xUIElement.is() )
1578 // we need VCL here to pass special flags to Show()
1579 SolarMutexGuard aGuard;
1580 Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), UNO_QUERY );
1581 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
1582 if ( pWindow )
1584 pWindow->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
1585 bResult = true;
1586 bNotify = true;
1591 else if ( aElementType.equalsIgnoreAsciiCase("progressbar") &&
1592 aElementName.equalsIgnoreAsciiCase("progressbar") )
1594 aWriteLock.clear();
1595 implts_showProgressBar();
1596 bResult = true;
1597 bNotify = true;
1599 else if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ) && m_bVisible )
1601 bool bComponentAttached( !m_aModuleIdentifier.isEmpty() );
1602 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1603 aWriteLock.clear();
1605 if ( pToolbarManager && bComponentAttached )
1607 bNotify = pToolbarManager->requestToolbar( rResourceURL );
1610 else if ( aElementType.equalsIgnoreAsciiCase("dockingwindow"))
1612 uno::Reference< frame::XFrame > xFrame( m_xFrame );
1613 aWriteLock.clear();
1615 CreateDockingWindow( xFrame, aElementName );
1618 if ( bNotify )
1619 implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_VISIBLE, uno::Any( rResourceURL ) );
1621 return bResult;
1624 Reference< XUIElement > SAL_CALL LayoutManager::getElement( const OUString& aName )
1626 Reference< XUIElement > xUIElement = implts_findElement( aName );
1627 if ( !xUIElement.is() )
1629 SolarMutexClearableGuard aReadLock;
1630 ToolbarLayoutManager* pToolbarManager( m_xToolbarManager.get() );
1631 aReadLock.clear();
1633 if ( pToolbarManager )
1634 xUIElement = pToolbarManager->getToolbar( aName );
1637 return xUIElement;
1640 Sequence< Reference< ui::XUIElement > > SAL_CALL LayoutManager::getElements()
1642 SolarMutexClearableGuard aReadLock;
1643 rtl::Reference< MenuBarWrapper > xMenuBar( m_xMenuBar );
1644 uno::Reference< ui::XUIElement > xStatusBar( m_aStatusBarElement.m_xUIElement );
1645 ToolbarLayoutManager* pToolbarManager( m_xToolbarManager.get() );
1646 aReadLock.clear();
1648 Sequence< Reference< ui::XUIElement > > aSeq;
1649 if ( pToolbarManager )
1650 aSeq = pToolbarManager->getToolbars();
1652 sal_Int32 nSize = aSeq.getLength();
1653 sal_Int32 nMenuBarIndex(-1);
1654 sal_Int32 nStatusBarIndex(-1);
1655 if ( xMenuBar.is() )
1657 nMenuBarIndex = nSize;
1658 ++nSize;
1660 if ( xStatusBar.is() )
1662 nStatusBarIndex = nSize;
1663 ++nSize;
1666 aSeq.realloc(nSize);
1667 auto pSeq = aSeq.getArray();
1668 if ( nMenuBarIndex >= 0 )
1669 pSeq[nMenuBarIndex] = xMenuBar;
1670 if ( nStatusBarIndex >= 0 )
1671 pSeq[nStatusBarIndex] = xStatusBar;
1673 return aSeq;
1676 sal_Bool SAL_CALL LayoutManager::showElement( const OUString& aName )
1678 bool bResult( false );
1679 bool bNotify( false );
1680 bool bMustLayout( false );
1681 OUString aElementType;
1682 OUString aElementName;
1684 parseResourceURL( aName, aElementType, aElementName );
1686 OString aResName = OUStringToOString( aElementName, RTL_TEXTENCODING_ASCII_US );
1687 SAL_INFO( "fwk", "LayoutManager::showElement " << aResName );
1689 if ( aElementType.equalsIgnoreAsciiCase("menubar") &&
1690 aElementName.equalsIgnoreAsciiCase("menubar") )
1693 SolarMutexGuard aWriteLock;
1694 m_bMenuVisible = true;
1697 bResult = implts_resetMenuBar();
1698 bNotify = bResult;
1700 else if (( aElementType.equalsIgnoreAsciiCase("statusbar") &&
1701 aElementName.equalsIgnoreAsciiCase("statusbar") ) ||
1702 ( m_aStatusBarElement.m_aName == aName ))
1704 SolarMutexClearableGuard aWriteLock;
1705 if ( m_aStatusBarElement.m_xUIElement.is() && !m_aStatusBarElement.m_bMasterHide &&
1706 implts_showStatusBar( true ))
1708 aWriteLock.clear();
1710 implts_writeWindowStateData( STATUS_BAR_ALIAS, m_aStatusBarElement );
1711 bMustLayout = true;
1712 bResult = true;
1713 bNotify = true;
1716 else if ( aElementType.equalsIgnoreAsciiCase("progressbar") &&
1717 aElementName.equalsIgnoreAsciiCase("progressbar") )
1719 bNotify = bResult = implts_showProgressBar();
1721 else if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
1723 SolarMutexClearableGuard aReadLock;
1724 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1725 aReadLock.clear();
1727 if ( pToolbarManager )
1729 bNotify = pToolbarManager->showToolbar( aName );
1730 bMustLayout = pToolbarManager->isLayoutDirty();
1733 else if ( aElementType.equalsIgnoreAsciiCase("dockingwindow"))
1735 SolarMutexClearableGuard aReadGuard;
1736 uno::Reference< frame::XFrame > xFrame( m_xFrame );
1737 uno::Reference< XComponentContext > xContext( m_xContext );
1738 aReadGuard.clear();
1740 impl_setDockingWindowVisibility( xContext, xFrame, aElementName, true );
1743 if ( bMustLayout )
1744 doLayout();
1746 if ( bNotify )
1747 implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_VISIBLE, uno::Any( aName ) );
1749 return bResult;
1752 sal_Bool SAL_CALL LayoutManager::hideElement( const OUString& aName )
1754 bool bNotify( false );
1755 bool bMustLayout( false );
1756 OUString aElementType;
1757 OUString aElementName;
1759 parseResourceURL( aName, aElementType, aElementName );
1760 OString aResName = OUStringToOString( aElementName, RTL_TEXTENCODING_ASCII_US );
1761 SAL_INFO( "fwk", "LayoutManager::hideElement " << aResName );
1763 if ( aElementType.equalsIgnoreAsciiCase("menubar") &&
1764 aElementName.equalsIgnoreAsciiCase("menubar") )
1766 SolarMutexGuard g;
1768 if ( m_xContainerWindow.is() )
1770 m_bMenuVisible = false;
1772 SolarMutexGuard aGuard;
1773 SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
1774 if ( pSysWindow )
1776 MenuBar* pMenuBar = pSysWindow->GetMenuBar();
1777 if ( pMenuBar )
1779 pMenuBar->SetDisplayable( false );
1780 bNotify = true;
1785 else if (( aElementType.equalsIgnoreAsciiCase("statusbar") &&
1786 aElementName.equalsIgnoreAsciiCase("statusbar") ) ||
1787 ( m_aStatusBarElement.m_aName == aName ))
1789 SolarMutexGuard g;
1790 if ( m_aStatusBarElement.m_xUIElement.is() && !m_aStatusBarElement.m_bMasterHide &&
1791 implts_hideStatusBar( true ))
1793 implts_writeWindowStateData( STATUS_BAR_ALIAS, m_aStatusBarElement );
1794 bMustLayout = true;
1795 bNotify = true;
1798 else if ( aElementType.equalsIgnoreAsciiCase("progressbar") &&
1799 aElementName.equalsIgnoreAsciiCase("progressbar") )
1801 bNotify = implts_hideProgressBar();
1803 else if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
1805 SolarMutexClearableGuard aReadLock;
1806 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1807 aReadLock.clear();
1809 if ( pToolbarManager )
1811 bNotify = pToolbarManager->hideToolbar( aName );
1812 bMustLayout = pToolbarManager->isLayoutDirty();
1815 else if ( aElementType.equalsIgnoreAsciiCase("dockingwindow"))
1817 SolarMutexClearableGuard aReadGuard;
1818 uno::Reference< frame::XFrame > xFrame( m_xFrame );
1819 uno::Reference< XComponentContext > xContext( m_xContext );
1820 aReadGuard.clear();
1822 impl_setDockingWindowVisibility( xContext, xFrame, aElementName, false );
1825 if ( bMustLayout )
1826 doLayout();
1828 if ( bNotify )
1829 implts_notifyListeners( frame::LayoutManagerEvents::UIELEMENT_INVISIBLE, uno::Any( aName ) );
1831 return false;
1834 sal_Bool SAL_CALL LayoutManager::dockWindow( const OUString& aName, DockingArea DockingArea, const awt::Point& Pos )
1836 OUString aElementType;
1837 OUString aElementName;
1839 parseResourceURL( aName, aElementType, aElementName );
1840 if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
1842 SolarMutexClearableGuard aReadLock;
1843 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1844 aReadLock.clear();
1846 if ( pToolbarManager )
1848 pToolbarManager->dockToolbar( aName, DockingArea, Pos );
1849 if ( pToolbarManager->isLayoutDirty() )
1850 doLayout();
1853 return false;
1856 sal_Bool SAL_CALL LayoutManager::dockAllWindows( ::sal_Int16 /*nElementType*/ )
1858 SolarMutexClearableGuard aReadLock;
1859 bool bResult( false );
1860 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1861 aReadLock.clear();
1863 if ( pToolbarManager )
1865 bResult = pToolbarManager->dockAllToolbars();
1866 if ( pToolbarManager->isLayoutDirty() )
1867 doLayout();
1869 return bResult;
1872 sal_Bool SAL_CALL LayoutManager::floatWindow( const OUString& aName )
1874 bool bResult( false );
1875 if ( o3tl::equalsIgnoreAsciiCase(getElementTypeFromResourceURL( aName ), UIRESOURCETYPE_TOOLBAR ))
1877 SolarMutexClearableGuard aReadLock;
1878 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1879 aReadLock.clear();
1881 if ( pToolbarManager )
1883 bResult = pToolbarManager->floatToolbar( aName );
1884 if ( pToolbarManager->isLayoutDirty() )
1885 doLayout();
1888 return bResult;
1891 sal_Bool SAL_CALL LayoutManager::lockWindow( const OUString& aName )
1893 bool bResult( false );
1894 if ( o3tl::equalsIgnoreAsciiCase(getElementTypeFromResourceURL( aName ), UIRESOURCETYPE_TOOLBAR ))
1896 SolarMutexClearableGuard aReadLock;
1897 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1898 aReadLock.clear();
1900 if ( pToolbarManager )
1902 bResult = pToolbarManager->lockToolbar( aName );
1903 if ( pToolbarManager->isLayoutDirty() )
1904 doLayout();
1907 return bResult;
1910 sal_Bool SAL_CALL LayoutManager::unlockWindow( const OUString& aName )
1912 bool bResult( false );
1913 if ( o3tl::equalsIgnoreAsciiCase(getElementTypeFromResourceURL( aName ), UIRESOURCETYPE_TOOLBAR ))
1915 SolarMutexClearableGuard aReadLock;
1916 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1917 aReadLock.clear();
1919 if ( pToolbarManager )
1921 bResult = pToolbarManager->unlockToolbar( aName );
1922 if ( pToolbarManager->isLayoutDirty() )
1923 doLayout();
1926 return bResult;
1929 void SAL_CALL LayoutManager::setElementSize( const OUString& aName, const awt::Size& aSize )
1931 if ( !o3tl::equalsIgnoreAsciiCase(getElementTypeFromResourceURL( aName ), UIRESOURCETYPE_TOOLBAR ))
1932 return;
1934 SolarMutexClearableGuard aReadLock;
1935 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
1936 aReadLock.clear();
1938 if ( pToolbarManager )
1940 pToolbarManager->setToolbarSize( aName, aSize );
1941 if ( pToolbarManager->isLayoutDirty() )
1942 doLayout();
1946 void SAL_CALL LayoutManager::setElementPos( const OUString& aName, const awt::Point& aPos )
1948 if ( !o3tl::equalsIgnoreAsciiCase(getElementTypeFromResourceURL( aName ), UIRESOURCETYPE_TOOLBAR ))
1949 return;
1951 SolarMutexClearableGuard aReadLock;
1952 ToolbarLayoutManager* pToolbarManager( m_xToolbarManager.get() );
1953 aReadLock.clear();
1955 if ( pToolbarManager )
1957 pToolbarManager->setToolbarPos( aName, aPos );
1958 if ( pToolbarManager->isLayoutDirty() )
1959 doLayout();
1963 void SAL_CALL LayoutManager::setElementPosSize( const OUString& aName, const awt::Point& aPos, const awt::Size& aSize )
1965 if ( !o3tl::equalsIgnoreAsciiCase(getElementTypeFromResourceURL( aName ), UIRESOURCETYPE_TOOLBAR ))
1966 return;
1968 SolarMutexClearableGuard aReadLock;
1969 ToolbarLayoutManager* pToolbarManager( m_xToolbarManager.get() );
1970 aReadLock.clear();
1972 if ( pToolbarManager )
1974 pToolbarManager->setToolbarPosSize( aName, aPos, aSize );
1975 if ( pToolbarManager->isLayoutDirty() )
1976 doLayout();
1980 sal_Bool SAL_CALL LayoutManager::isElementVisible( const OUString& aName )
1982 OUString aElementType;
1983 OUString aElementName;
1985 parseResourceURL( aName, aElementType, aElementName );
1986 if ( aElementType.equalsIgnoreAsciiCase("menubar") &&
1987 aElementName.equalsIgnoreAsciiCase("menubar") )
1989 SolarMutexResettableGuard aReadLock;
1990 if ( m_xContainerWindow.is() )
1992 aReadLock.clear();
1994 SolarMutexGuard aGuard;
1995 SystemWindow* pSysWindow = getTopSystemWindow( m_xContainerWindow );
1996 if ( pSysWindow )
1998 MenuBar* pMenuBar = pSysWindow->GetMenuBar();
1999 if ( pMenuBar && pMenuBar->IsDisplayable() )
2000 return true;
2002 else
2004 aReadLock.reset();
2005 return m_bMenuVisible;
2009 else if (( aElementType.equalsIgnoreAsciiCase("statusbar") &&
2010 aElementName.equalsIgnoreAsciiCase("statusbar") ) ||
2011 ( m_aStatusBarElement.m_aName == aName ))
2013 if ( m_aStatusBarElement.m_xUIElement.is() )
2015 Reference< awt::XWindow > xWindow( m_aStatusBarElement.m_xUIElement->getRealInterface(), UNO_QUERY );
2016 if ( xWindow.is() )
2018 SolarMutexGuard g;
2019 VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow );
2020 if ( pWindow && pWindow->IsVisible() )
2021 return true;
2022 else
2023 return false;
2027 else if ( aElementType.equalsIgnoreAsciiCase("progressbar") &&
2028 aElementName.equalsIgnoreAsciiCase("progressbar") )
2030 if ( m_aProgressBarElement.m_xUIElement.is() )
2031 return m_aProgressBarElement.m_bVisible;
2033 else if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
2035 SolarMutexClearableGuard aReadLock;
2036 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2037 aReadLock.clear();
2039 if ( pToolbarManager )
2040 return pToolbarManager->isToolbarVisible( aName );
2042 else if ( aElementType.equalsIgnoreAsciiCase("dockingwindow"))
2044 SolarMutexClearableGuard aReadGuard;
2045 uno::Reference< frame::XFrame > xFrame( m_xFrame );
2046 aReadGuard.clear();
2048 return IsDockingWindowVisible( xFrame, aElementName );
2051 return false;
2054 sal_Bool SAL_CALL LayoutManager::isElementFloating( const OUString& aName )
2056 if ( o3tl::equalsIgnoreAsciiCase(getElementTypeFromResourceURL( aName ), UIRESOURCETYPE_TOOLBAR ))
2058 SolarMutexClearableGuard aReadLock;
2059 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2060 aReadLock.clear();
2062 if ( pToolbarManager )
2063 return pToolbarManager->isToolbarFloating( aName );
2066 return false;
2069 sal_Bool SAL_CALL LayoutManager::isElementDocked( const OUString& aName )
2071 if ( o3tl::equalsIgnoreAsciiCase(getElementTypeFromResourceURL( aName ), UIRESOURCETYPE_TOOLBAR ))
2073 SolarMutexClearableGuard aReadLock;
2074 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2075 aReadLock.clear();
2077 if ( pToolbarManager )
2078 return pToolbarManager->isToolbarDocked( aName );
2081 return false;
2084 sal_Bool SAL_CALL LayoutManager::isElementLocked( const OUString& aName )
2086 if ( o3tl::equalsIgnoreAsciiCase(getElementTypeFromResourceURL( aName ), UIRESOURCETYPE_TOOLBAR ))
2088 SolarMutexClearableGuard aReadLock;
2089 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2090 aReadLock.clear();
2092 if ( pToolbarManager )
2093 return pToolbarManager->isToolbarLocked( aName );
2096 return false;
2099 awt::Size SAL_CALL LayoutManager::getElementSize( const OUString& aName )
2101 if ( o3tl::equalsIgnoreAsciiCase(getElementTypeFromResourceURL( aName ), UIRESOURCETYPE_TOOLBAR ))
2103 SolarMutexClearableGuard aReadLock;
2104 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2105 aReadLock.clear();
2107 if ( pToolbarManager )
2108 return pToolbarManager->getToolbarSize( aName );
2111 return awt::Size();
2114 awt::Point SAL_CALL LayoutManager::getElementPos( const OUString& aName )
2116 if ( o3tl::equalsIgnoreAsciiCase(getElementTypeFromResourceURL( aName ), UIRESOURCETYPE_TOOLBAR ))
2118 SolarMutexClearableGuard aReadLock;
2119 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2120 aReadLock.clear();
2122 if ( pToolbarManager )
2123 return pToolbarManager->getToolbarPos( aName );
2126 return awt::Point();
2129 void SAL_CALL LayoutManager::lock()
2131 implts_lock();
2133 SolarMutexClearableGuard aReadLock;
2134 sal_Int32 nLockCount( m_nLockCount );
2135 aReadLock.clear();
2137 SAL_INFO( "fwk", "LayoutManager::lock " << reinterpret_cast<sal_Int64>(this) << " - " << nLockCount );
2139 Any a( nLockCount );
2140 implts_notifyListeners( frame::LayoutManagerEvents::LOCK, a );
2143 void SAL_CALL LayoutManager::unlock()
2145 bool bDoLayout( implts_unlock() );
2147 SolarMutexClearableGuard aReadLock;
2148 sal_Int32 nLockCount( m_nLockCount );
2149 aReadLock.clear();
2151 SAL_INFO( "fwk", "LayoutManager::unlock " << reinterpret_cast<sal_Int64>(this) << " - " << nLockCount);
2153 // conform to documentation: unlock with lock count == 0 means force a layout
2156 SolarMutexGuard aWriteLock;
2157 if (bDoLayout)
2158 m_aAsyncLayoutTimer.Stop();
2161 Any a( nLockCount );
2162 implts_notifyListeners( frame::LayoutManagerEvents::UNLOCK, a );
2164 if ( bDoLayout )
2165 implts_doLayout_notify( true );
2168 void SAL_CALL LayoutManager::doLayout()
2170 implts_doLayout_notify( true );
2173 // ILayoutNotifications
2175 void LayoutManager::requestLayout()
2177 doLayout();
2180 void LayoutManager::implts_doLayout_notify( bool bOuterResize )
2182 bool bLayouted = implts_doLayout( false, bOuterResize );
2183 if ( bLayouted )
2184 implts_notifyListeners( frame::LayoutManagerEvents::LAYOUT, Any() );
2187 bool LayoutManager::implts_doLayout( bool bForceRequestBorderSpace, bool bOuterResize )
2189 SAL_INFO( "fwk", "LayoutManager::implts_doLayout" );
2191 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2192 SolarMutexClearableGuard aReadLock;
2194 if ( !m_xFrame.is() || !m_bParentWindowVisible )
2195 return false;
2197 bool bPreserveContentSize( m_bPreserveContentSize );
2198 bool bMustDoLayout( m_bMustDoLayout );
2199 bool bNoLock = ( m_nLockCount == 0 );
2200 awt::Rectangle aCurrBorderSpace( m_aDockingArea );
2201 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2202 Reference< awt::XTopWindow2 > xContainerTopWindow( m_xContainerTopWindow );
2203 Reference< awt::XWindow > xComponentWindow;
2204 try {
2205 xComponentWindow = m_xFrame->getComponentWindow();
2206 } catch (css::lang::DisposedException &) {
2207 // There can be a race between one thread calling Frame::dispose
2208 // (framework/source/services/frame.cxx) -> Frame::disableLayoutManager
2209 // -> LayoutManager::attachFrame(null) setting m_xFrame to null, and
2210 // the main thread firing the timer-triggered
2211 // LayoutManager::AsyncLayoutHdl -> LayoutManager::implts_doLayout and
2212 // calling into the in-dispose m_xFrame here, so silently ignore a
2213 // DisposedException here:
2214 return false;
2216 Reference< XDockingAreaAcceptor > xDockingAreaAcceptor( m_xDockingAreaAcceptor );
2217 aReadLock.clear();
2218 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2220 bool bLayouted( false );
2222 if ( bNoLock && xDockingAreaAcceptor.is() && xContainerWindow.is() && xComponentWindow.is() )
2224 bLayouted = true;
2226 awt::Rectangle aDockSpace( implts_calcDockingAreaSizes() );
2227 awt::Rectangle aBorderSpace( aDockSpace );
2228 bool bGotRequestedBorderSpace( true );
2230 // We have to add the height of a possible status bar
2231 aBorderSpace.Height += implts_getStatusBarSize().Height();
2233 if ( !equalRectangles( aBorderSpace, aCurrBorderSpace ) || bForceRequestBorderSpace || bMustDoLayout )
2235 // we always resize the content window (instead of the complete container window) if we're not set up
2236 // to (attempt to) preserve the content window's size
2237 if ( bOuterResize && !bPreserveContentSize )
2238 bOuterResize = false;
2240 // maximized windows can resized their content window only, not their container window
2241 if ( bOuterResize && xContainerTopWindow.is() && xContainerTopWindow->getIsMaximized() )
2242 bOuterResize = false;
2244 // if the component window does not have a size (yet), then we can't use it to calc the container
2245 // window size
2246 awt::Rectangle aComponentRect = xComponentWindow->getPosSize();
2247 if ( bOuterResize && ( aComponentRect.Width == 0 ) && ( aComponentRect.Height == 0 ) )
2248 bOuterResize = false;
2250 bGotRequestedBorderSpace = false;
2251 if ( bOuterResize )
2253 Reference< awt::XDevice > xDevice( xContainerWindow, uno::UNO_QUERY );
2254 awt::DeviceInfo aContainerInfo = xDevice->getInfo();
2256 awt::Size aRequestedSize( aComponentRect.Width + aContainerInfo.LeftInset + aContainerInfo.RightInset + aBorderSpace.X + aBorderSpace.Width,
2257 aComponentRect.Height + aContainerInfo.TopInset + aContainerInfo.BottomInset + aBorderSpace.Y + aBorderSpace.Height );
2258 awt::Point aComponentPos( aBorderSpace.X, aBorderSpace.Y );
2260 bGotRequestedBorderSpace = implts_resizeContainerWindow( aRequestedSize, aComponentPos );
2263 // if we did not do a container window resize, or it failed, then use the DockingAcceptor as usual
2264 if ( !bGotRequestedBorderSpace )
2265 bGotRequestedBorderSpace = xDockingAreaAcceptor->requestDockingAreaSpace( aBorderSpace );
2267 if ( bGotRequestedBorderSpace )
2269 SolarMutexGuard aWriteGuard;
2270 m_aDockingArea = aBorderSpace;
2271 m_bMustDoLayout = false;
2275 if ( bGotRequestedBorderSpace )
2277 ::Size aContainerSize;
2278 ::Size aStatusBarSize;
2280 // Interim solution to let the layout method within the
2281 // toolbar layout manager.
2282 implts_setOffset( implts_getStatusBarSize().Height() );
2283 if ( m_xToolbarManager.is() )
2284 m_xToolbarManager->setDockingArea( aDockSpace );
2286 // Subtract status bar size from our container output size. Docking area windows
2287 // don't contain the status bar!
2288 aStatusBarSize = implts_getStatusBarSize();
2289 aContainerSize = implts_getContainerWindowOutputSize();
2290 aContainerSize.AdjustHeight( -(aStatusBarSize.Height()) );
2292 if ( m_xToolbarManager.is() )
2293 m_xToolbarManager->doLayout(aContainerSize);
2295 // Position the status bar
2296 if ( aStatusBarSize.Height() > 0 )
2298 implts_setStatusBarPosSize( ::Point( 0, std::max(( aContainerSize.Height() ), tools::Long( 0 ))),
2299 ::Size( aContainerSize.Width(),aStatusBarSize.Height() ));
2302 xDockingAreaAcceptor->setDockingAreaSpace( aBorderSpace );
2306 return bLayouted;
2309 bool LayoutManager::implts_resizeContainerWindow( const awt::Size& rContainerSize,
2310 const awt::Point& rComponentPos )
2312 SolarMutexClearableGuard aReadLock;
2313 Reference< awt::XWindow > xContainerWindow = m_xContainerWindow;
2314 Reference< awt::XTopWindow2 > xContainerTopWindow = m_xContainerTopWindow;
2315 Reference< awt::XWindow > xComponentWindow = m_xFrame->getComponentWindow();
2316 aReadLock.clear();
2318 // calculate the maximum size we have for the container window
2319 sal_Int32 nDisplay = xContainerTopWindow->getDisplay();
2320 AbsoluteScreenPixelRectangle aWorkArea = Application::GetScreenPosSizePixel( nDisplay );
2322 if (!aWorkArea.IsEmpty())
2324 if (( rContainerSize.Width > aWorkArea.GetWidth() ) || ( rContainerSize.Height > aWorkArea.GetHeight() ))
2325 return false;
2326 // Strictly, this is not correct. If we have a multi-screen display (css.awt.DisplayAccess.MultiDisplay == true),
2327 // the "effective work area" would be much larger than the work area of a single display, since we could in theory
2328 // position the container window across multiple screens.
2329 // However, this should suffice as a heuristics here ... (nobody really wants to check whether the different screens are
2330 // stacked horizontally or vertically, whether their work areas can really be combined, or are separated by non-work-areas,
2331 // and the like ... right?)
2334 // resize our container window
2335 xContainerWindow->setPosSize( 0, 0, rContainerSize.Width, rContainerSize.Height, awt::PosSize::SIZE );
2336 // position the component window
2337 xComponentWindow->setPosSize( rComponentPos.X, rComponentPos.Y, 0, 0, awt::PosSize::POS );
2338 return true;
2341 void SAL_CALL LayoutManager::setVisible( sal_Bool bVisible )
2343 SolarMutexClearableGuard aWriteLock;
2344 bool bWasVisible( m_bVisible );
2345 m_bVisible = bVisible;
2346 aWriteLock.clear();
2348 if ( bWasVisible != bool(bVisible) )
2349 implts_setVisibleState( bVisible );
2352 sal_Bool SAL_CALL LayoutManager::isVisible()
2354 SolarMutexGuard g;
2355 return m_bVisible;
2358 ::Size LayoutManager::implts_getStatusBarSize()
2360 SolarMutexClearableGuard aReadLock;
2361 bool bStatusBarVisible( isElementVisible( STATUS_BAR_ALIAS ));
2362 bool bProgressBarVisible( isElementVisible( "private:resource/progressbar/progressbar" ));
2363 bool bVisible( m_bVisible );
2364 Reference< XUIElement > xStatusBar( m_aStatusBarElement.m_xUIElement );
2365 Reference< XUIElement > xProgressBar( m_aProgressBarElement.m_xUIElement );
2367 Reference< awt::XWindow > xWindow;
2368 if ( bStatusBarVisible && bVisible && xStatusBar.is() )
2369 xWindow.set( xStatusBar->getRealInterface(), UNO_QUERY );
2370 else if ( xProgressBar.is() && !xStatusBar.is() && bProgressBarVisible )
2372 ProgressBarWrapper* pWrapper = static_cast<ProgressBarWrapper*>(xProgressBar.get());
2373 if ( pWrapper )
2374 xWindow = pWrapper->getStatusBar();
2376 aReadLock.clear();
2378 if ( xWindow.is() )
2380 awt::Rectangle aPosSize = xWindow->getPosSize();
2381 return ::Size( aPosSize.Width, aPosSize.Height );
2383 else
2384 return ::Size();
2387 awt::Rectangle LayoutManager::implts_calcDockingAreaSizes()
2389 SolarMutexClearableGuard aReadLock;
2390 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2391 Reference< XDockingAreaAcceptor > xDockingAreaAcceptor( m_xDockingAreaAcceptor );
2392 aReadLock.clear();
2394 awt::Rectangle aBorderSpace;
2395 if ( m_xToolbarManager.is() && xDockingAreaAcceptor.is() && xContainerWindow.is() )
2396 aBorderSpace = m_xToolbarManager->getDockingArea();
2398 return aBorderSpace;
2401 void LayoutManager::implts_setDockingAreaWindowSizes()
2403 SolarMutexClearableGuard aReadLock;
2404 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2405 aReadLock.clear();
2407 uno::Reference< awt::XDevice > xDevice( xContainerWindow, uno::UNO_QUERY );
2408 // Convert relative size to output size.
2409 awt::Rectangle aRectangle = xContainerWindow->getPosSize();
2410 awt::DeviceInfo aInfo = xDevice->getInfo();
2411 awt::Size aContainerClientSize( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset,
2412 aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
2413 ::Size aStatusBarSize = implts_getStatusBarSize();
2415 // Position the status bar
2416 if ( aStatusBarSize.Height() > 0 )
2418 implts_setStatusBarPosSize( ::Point( 0, std::max(( aContainerClientSize.Height - aStatusBarSize.Height() ), tools::Long( 0 ))),
2419 ::Size( aContainerClientSize.Width, aStatusBarSize.Height() ));
2423 void LayoutManager::implts_updateMenuBarClose()
2425 SolarMutexClearableGuard aWriteLock;
2426 bool bShowCloseButton( m_bMenuBarCloseButton );
2427 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2428 aWriteLock.clear();
2430 if ( !xContainerWindow.is() )
2431 return;
2433 SolarMutexGuard aGuard;
2435 SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow );
2436 if ( pSysWindow )
2438 MenuBar* pMenuBar = pSysWindow->GetMenuBar();
2439 if ( pMenuBar )
2441 // TODO remove link on sal_False ?!
2442 pMenuBar->ShowCloseButton(bShowCloseButton);
2443 pMenuBar->SetCloseButtonClickHdl(LINK(this, LayoutManager, MenuBarClose));
2448 bool LayoutManager::implts_resetMenuBar()
2450 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2451 SolarMutexGuard aWriteLock;
2452 bool bMenuVisible( m_bMenuVisible );
2453 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2455 MenuBar* pSetMenuBar = nullptr;
2456 if ( m_xInplaceMenuBar.is() )
2457 pSetMenuBar = static_cast<MenuBar *>(m_xInplaceMenuBar->GetMenuBar());
2458 else if ( m_xMenuBar )
2459 pSetMenuBar = static_cast<MenuBar*>(m_xMenuBar->GetMenuBarManager()->GetMenuBar());
2461 SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow );
2462 if ( pSysWindow && bMenuVisible && pSetMenuBar )
2464 pSysWindow->SetMenuBar(pSetMenuBar);
2465 pSetMenuBar->SetDisplayable( true );
2466 return true;
2469 return false;
2472 void LayoutManager::implts_createMSCompatibleMenuBar( const OUString& aName )
2474 SolarMutexGuard aWriteLock;
2476 // Find Form menu in the original menubar
2477 m_xMenuBar.set( static_cast< MenuBarWrapper* >(implts_createElement( aName ).get()) );
2478 uno::Reference< container::XIndexReplace > xMenuIndex(m_xMenuBar->getSettings(true), UNO_QUERY);
2480 sal_Int32 nFormsMenu = -1;
2481 for (sal_Int32 nIndex = 0; nIndex < xMenuIndex->getCount(); ++nIndex)
2483 uno::Sequence< beans::PropertyValue > aProps;
2484 xMenuIndex->getByIndex( nIndex ) >>= aProps;
2485 OUString aCommand;
2486 for ( beans::PropertyValue const & rProp : std::as_const(aProps) )
2488 if (rProp.Name == "CommandURL")
2490 rProp.Value >>= aCommand;
2491 break;
2495 if (aCommand == ".uno:FormatFormMenu")
2496 nFormsMenu = nIndex;
2498 assert(nFormsMenu != -1);
2500 // Create the MS compatible Form menu
2501 css::uno::Reference< css::ui::XUIElement > xFormsMenu = implts_createElement( "private:resource/menubar/mscompatibleformsmenu" );
2502 if(!xFormsMenu.is())
2503 return;
2505 // Merge the MS compatible Form menu into the menubar
2506 uno::Reference< XUIElementSettings > xFormsMenuSettings(xFormsMenu, UNO_QUERY);
2507 uno::Reference< container::XIndexAccess > xFormsMenuIndex(xFormsMenuSettings->getSettings(true));
2509 assert(xFormsMenuIndex->getCount() >= 1);
2510 uno::Sequence< beans::PropertyValue > aNewFormsMenu;
2511 xFormsMenuIndex->getByIndex( 0 ) >>= aNewFormsMenu;
2512 xMenuIndex->replaceByIndex(nFormsMenu, uno::Any(aNewFormsMenu));
2514 setMergedMenuBar( xMenuIndex );
2516 // Clear up the temporal forms menubar
2517 Reference< XComponent > xFormsMenuComp( xFormsMenu, UNO_QUERY );
2518 if ( xFormsMenuComp.is() )
2519 xFormsMenuComp->dispose();
2520 xFormsMenu.clear();
2523 IMPL_LINK_NOARG(LayoutManager, MenuBarClose, void*, void)
2525 SolarMutexClearableGuard aReadLock;
2526 uno::Reference< frame::XDispatchProvider > xProvider(m_xFrame, uno::UNO_QUERY);
2527 uno::Reference< XComponentContext > xContext( m_xContext );
2528 aReadLock.clear();
2530 if ( !xProvider.is())
2531 return;
2533 uno::Reference< frame::XDispatchHelper > xDispatcher = frame::DispatchHelper::create( xContext );
2535 xDispatcher->executeDispatch(
2536 xProvider,
2537 ".uno:CloseWin",
2538 "_self",
2540 uno::Sequence< beans::PropertyValue >());
2543 // XLayoutManagerEventBroadcaster
2545 void SAL_CALL LayoutManager::addLayoutManagerEventListener( const uno::Reference< frame::XLayoutManagerListener >& xListener )
2547 m_aListenerContainer.addInterface( cppu::UnoType<frame::XLayoutManagerListener>::get(), xListener );
2550 void SAL_CALL LayoutManager::removeLayoutManagerEventListener( const uno::Reference< frame::XLayoutManagerListener >& xListener )
2552 m_aListenerContainer.removeInterface( cppu::UnoType<frame::XLayoutManagerListener>::get(), xListener );
2555 void LayoutManager::implts_notifyListeners(short nEvent, const uno::Any& rInfoParam)
2557 comphelper::OInterfaceContainerHelper2* pContainer = m_aListenerContainer.getContainer( cppu::UnoType<frame::XLayoutManagerListener>::get());
2558 if (pContainer==nullptr)
2559 return;
2561 lang::EventObject aSource( static_cast< ::cppu::OWeakObject*>(this) );
2562 comphelper::OInterfaceIteratorHelper2 pIterator(*pContainer);
2563 while (pIterator.hasMoreElements())
2567 static_cast<frame::XLayoutManagerListener*>(pIterator.next())->layoutEvent(aSource, nEvent, rInfoParam);
2569 catch( const uno::RuntimeException& )
2571 pIterator.remove();
2576 // XWindowListener
2578 void SAL_CALL LayoutManager::windowResized( const awt::WindowEvent& aEvent )
2580 SolarMutexGuard g;
2581 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2583 Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY );
2584 if ( xIfac == aEvent.Source && m_bVisible )
2586 // We have to call our resize handler at least once synchronously, as some
2587 // application modules need this. So we have to check if this is the first
2588 // call after the async layout time expired.
2589 m_bMustDoLayout = true;
2590 if ( !m_aAsyncLayoutTimer.IsActive() )
2592 m_aAsyncLayoutTimer.Invoke();
2593 if ( m_nLockCount == 0 )
2594 m_aAsyncLayoutTimer.Start();
2597 else if ( m_xFrame.is() && aEvent.Source == m_xFrame->getContainerWindow() )
2599 // the container window of my DockingAreaAcceptor is not the same as of my frame
2600 // I still have to resize my frames' window as nobody else will do it
2601 Reference< awt::XWindow > xComponentWindow( m_xFrame->getComponentWindow() );
2602 if( xComponentWindow.is() )
2604 uno::Reference< awt::XDevice > xDevice( m_xFrame->getContainerWindow(), uno::UNO_QUERY );
2606 // Convert relative size to output size.
2607 awt::Rectangle aRectangle = m_xFrame->getContainerWindow()->getPosSize();
2608 awt::DeviceInfo aInfo = xDevice->getInfo();
2609 awt::Size aSize( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
2610 aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
2612 // Resize our component window.
2613 xComponentWindow->setPosSize( 0, 0, aSize.Width, aSize.Height, awt::PosSize::POSSIZE );
2618 void SAL_CALL LayoutManager::windowMoved( const awt::WindowEvent& )
2622 void SAL_CALL LayoutManager::windowShown( const lang::EventObject& aEvent )
2624 SolarMutexClearableGuard aReadLock;
2625 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2626 bool bParentWindowVisible( m_bParentWindowVisible );
2627 aReadLock.clear();
2629 Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY );
2630 if ( xIfac == aEvent.Source )
2632 SolarMutexClearableGuard aWriteLock;
2633 m_bParentWindowVisible = true;
2634 bool bSetVisible = ( m_bParentWindowVisible != bParentWindowVisible );
2635 aWriteLock.clear();
2637 if ( bSetVisible )
2638 implts_updateUIElementsVisibleState( true );
2642 void SAL_CALL LayoutManager::windowHidden( const lang::EventObject& aEvent )
2644 SolarMutexClearableGuard aReadLock;
2645 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2646 bool bParentWindowVisible( m_bParentWindowVisible );
2647 aReadLock.clear();
2649 Reference< XInterface > xIfac( xContainerWindow, UNO_QUERY );
2650 if ( xIfac == aEvent.Source )
2652 SolarMutexClearableGuard aWriteLock;
2653 m_bParentWindowVisible = false;
2654 bool bSetInvisible = ( m_bParentWindowVisible != bParentWindowVisible );
2655 aWriteLock.clear();
2657 if ( bSetInvisible )
2658 implts_updateUIElementsVisibleState( false );
2662 IMPL_LINK_NOARG(LayoutManager, AsyncLayoutHdl, Timer *, void)
2665 SolarMutexGuard aReadLock;
2667 if (!m_xContainerWindow.is())
2668 return;
2671 implts_setDockingAreaWindowSizes();
2672 implts_doLayout( true, false );
2675 // XFrameActionListener
2677 void SAL_CALL LayoutManager::frameAction( const FrameActionEvent& aEvent )
2679 if (( aEvent.Action == FrameAction_COMPONENT_ATTACHED ) || ( aEvent.Action == FrameAction_COMPONENT_REATTACHED ))
2681 SAL_INFO( "fwk", "LayoutManager::frameAction (COMPONENT_ATTACHED|REATTACHED)" );
2684 SolarMutexGuard aWriteLock;
2685 m_bMustDoLayout = true;
2688 implts_reset( true );
2689 implts_doLayout( true, false );
2690 implts_doLayout( true, true );
2692 else if (( aEvent.Action == FrameAction_FRAME_UI_ACTIVATED ) || ( aEvent.Action == FrameAction_FRAME_UI_DEACTIVATING ))
2694 SAL_INFO( "fwk", "LayoutManager::frameAction (FRAME_UI_ACTIVATED|DEACTIVATING)" );
2696 implts_toggleFloatingUIElementsVisibility( aEvent.Action == FrameAction_FRAME_UI_ACTIVATED );
2698 else if ( aEvent.Action == FrameAction_COMPONENT_DETACHING )
2700 SAL_INFO( "fwk", "LayoutManager::frameAction (COMPONENT_DETACHING)" );
2702 implts_reset( false );
2706 void SAL_CALL LayoutManager::disposing( const lang::EventObject& rEvent )
2708 bool bDisposeAndClear( false );
2710 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2712 SolarMutexGuard aWriteLock;
2714 if (rEvent.Source == Reference<XInterface>(m_xFrame, UNO_QUERY))
2716 // Our frame gets disposed, release all our references that depends on a working frame reference.
2718 setDockingAreaAcceptor(Reference<ui::XDockingAreaAcceptor>());
2720 // destroy all elements, it's possible that detaching is NOT called!
2721 implts_destroyElements();
2722 impl_clearUpMenuBar();
2723 m_xMenuBar.clear();
2724 VclPtr<Menu> pMenuBar;
2725 if (m_xInplaceMenuBar.is())
2727 pMenuBar = m_xInplaceMenuBar->GetMenuBar();
2728 m_xInplaceMenuBar->dispose();
2729 m_xInplaceMenuBar.clear();
2731 pMenuBar.disposeAndClear();
2732 m_xContainerWindow.clear();
2733 m_xContainerTopWindow.clear();
2735 // forward disposing call to toolbar manager
2736 if (m_xToolbarManager.is())
2737 m_xToolbarManager->disposing(rEvent);
2739 if (m_xModuleCfgMgr.is())
2743 Reference<XUIConfiguration> xModuleCfgMgr(m_xModuleCfgMgr, UNO_QUERY);
2744 xModuleCfgMgr->removeConfigurationListener(Reference<XUIConfigurationListener>(this));
2746 catch (const Exception&)
2751 if (m_xDocCfgMgr.is())
2755 Reference<XUIConfiguration> xDocCfgMgr(m_xDocCfgMgr, UNO_QUERY);
2756 xDocCfgMgr->removeConfigurationListener(Reference<XUIConfigurationListener>(this));
2758 catch (const Exception&)
2763 m_xDocCfgMgr.clear();
2764 m_xModuleCfgMgr.clear();
2765 m_xFrame.clear();
2766 m_pGlobalSettings.reset();
2768 bDisposeAndClear = true;
2770 else if (rEvent.Source == Reference<XInterface>(m_xContainerWindow, UNO_QUERY))
2772 // Our container window gets disposed. Remove all user interface elements.
2773 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
2774 if (pToolbarManager)
2776 uno::Reference<awt::XVclWindowPeer> aEmptyWindowPeer;
2777 pToolbarManager->setParentWindow(aEmptyWindowPeer);
2779 impl_clearUpMenuBar();
2780 m_xMenuBar.clear();
2781 VclPtr<Menu> pMenuBar;
2782 if (m_xInplaceMenuBar.is())
2784 pMenuBar = m_xInplaceMenuBar->GetMenuBar();
2785 m_xInplaceMenuBar->dispose();
2786 m_xInplaceMenuBar.clear();
2788 pMenuBar.disposeAndClear();
2789 m_xContainerWindow.clear();
2790 m_xContainerTopWindow.clear();
2792 else if (rEvent.Source == Reference<XInterface>(m_xDocCfgMgr, UNO_QUERY))
2793 m_xDocCfgMgr.clear();
2794 else if (rEvent.Source == Reference<XInterface>(m_xModuleCfgMgr, UNO_QUERY))
2795 m_xModuleCfgMgr.clear();
2797 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2799 // Send disposing to our listener when we have lost our frame.
2800 if ( bDisposeAndClear )
2802 // Send message to all listener and forget her references.
2803 uno::Reference< frame::XLayoutManager > xThis(this);
2804 lang::EventObject aEvent( xThis );
2805 m_aListenerContainer.disposeAndClear( aEvent );
2809 void SAL_CALL LayoutManager::elementInserted( const ui::ConfigurationEvent& Event )
2811 SolarMutexClearableGuard aReadLock;
2812 Reference< XFrame > xFrame( m_xFrame );
2813 rtl::Reference< ToolbarLayoutManager > xToolbarManager( m_xToolbarManager );
2814 aReadLock.clear();
2816 if ( !xFrame.is() )
2817 return;
2819 OUString aElementType;
2820 OUString aElementName;
2821 bool bRefreshLayout(false);
2823 parseResourceURL( Event.ResourceURL, aElementType, aElementName );
2824 if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
2826 if ( xToolbarManager.is() )
2828 xToolbarManager->elementInserted( Event );
2829 bRefreshLayout = xToolbarManager->isLayoutDirty();
2832 else if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_MENUBAR ))
2834 Reference< XUIElement > xUIElement = implts_findElement( Event.ResourceURL );
2835 Reference< XUIElementSettings > xElementSettings( xUIElement, UNO_QUERY );
2836 if ( xElementSettings.is() )
2838 uno::Reference< XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY );
2839 if ( xPropSet.is() )
2841 if ( Event.Source == uno::Reference< uno::XInterface >( m_xDocCfgMgr, uno::UNO_QUERY ))
2842 xPropSet->setPropertyValue( "ConfigurationSource", Any( m_xDocCfgMgr ));
2844 xElementSettings->updateSettings();
2848 if ( bRefreshLayout )
2849 doLayout();
2852 void SAL_CALL LayoutManager::elementRemoved( const ui::ConfigurationEvent& Event )
2854 SolarMutexClearableGuard aReadLock;
2855 Reference< frame::XFrame > xFrame( m_xFrame );
2856 rtl::Reference< ToolbarLayoutManager > xToolbarManager( m_xToolbarManager );
2857 Reference< awt::XWindow > xContainerWindow( m_xContainerWindow );
2858 rtl::Reference< MenuBarWrapper > xMenuBar( m_xMenuBar );
2859 Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr );
2860 Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr );
2861 aReadLock.clear();
2863 if ( !xFrame.is() )
2864 return;
2866 OUString aElementType;
2867 OUString aElementName;
2868 bool bRefreshLayout(false);
2870 parseResourceURL( Event.ResourceURL, aElementType, aElementName );
2871 if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
2873 if ( xToolbarManager.is() )
2875 xToolbarManager->elementRemoved( Event );
2876 bRefreshLayout = xToolbarManager->isLayoutDirty();
2879 else
2881 Reference< XUIElement > xUIElement = implts_findElement( Event.ResourceURL );
2882 Reference< XUIElementSettings > xElementSettings( xUIElement, UNO_QUERY );
2883 if ( xElementSettings.is() )
2885 bool bNoSettings( false );
2886 OUString aConfigSourcePropName( "ConfigurationSource" );
2887 Reference< XInterface > xElementCfgMgr;
2888 Reference< XPropertySet > xPropSet( xElementSettings, UNO_QUERY );
2890 if ( xPropSet.is() )
2891 xPropSet->getPropertyValue( aConfigSourcePropName ) >>= xElementCfgMgr;
2893 if ( !xElementCfgMgr.is() )
2894 return;
2896 // Check if the same UI configuration manager has changed => check further
2897 if ( Event.Source == xElementCfgMgr )
2899 // Same UI configuration manager where our element has its settings
2900 if ( Event.Source == Reference< XInterface >( xDocCfgMgr, UNO_QUERY ))
2902 // document settings removed
2903 if ( xModuleCfgMgr->hasSettings( Event.ResourceURL ))
2905 xPropSet->setPropertyValue( aConfigSourcePropName, Any( m_xModuleCfgMgr ));
2906 xElementSettings->updateSettings();
2907 return;
2911 bNoSettings = true;
2914 // No settings anymore, element must be destroyed
2915 if ( xContainerWindow.is() && bNoSettings )
2917 if ( aElementType.equalsIgnoreAsciiCase("menubar") &&
2918 aElementName.equalsIgnoreAsciiCase("menubar") )
2920 SystemWindow* pSysWindow = getTopSystemWindow( xContainerWindow );
2921 if ( pSysWindow && !m_bInplaceMenuSet )
2922 pSysWindow->SetMenuBar( nullptr );
2924 if ( xMenuBar.is() )
2925 xMenuBar->dispose();
2927 SolarMutexGuard g;
2928 m_xMenuBar.clear();
2934 if ( bRefreshLayout )
2935 doLayout();
2938 void SAL_CALL LayoutManager::elementReplaced( const ui::ConfigurationEvent& Event )
2940 SolarMutexClearableGuard aReadLock;
2941 Reference< XFrame > xFrame( m_xFrame );
2942 rtl::Reference< ToolbarLayoutManager > xToolbarManager( m_xToolbarManager );
2943 aReadLock.clear();
2945 if ( !xFrame.is() )
2946 return;
2948 OUString aElementType;
2949 OUString aElementName;
2950 bool bRefreshLayout(false);
2952 parseResourceURL( Event.ResourceURL, aElementType, aElementName );
2953 if ( aElementType.equalsIgnoreAsciiCase( UIRESOURCETYPE_TOOLBAR ))
2955 if ( xToolbarManager.is() )
2957 xToolbarManager->elementReplaced( Event );
2958 bRefreshLayout = xToolbarManager->isLayoutDirty();
2961 else
2963 Reference< XUIElement > xUIElement = implts_findElement( Event.ResourceURL );
2964 Reference< XUIElementSettings > xElementSettings( xUIElement, UNO_QUERY );
2965 if ( xElementSettings.is() )
2967 Reference< XInterface > xElementCfgMgr;
2968 Reference< XPropertySet > xPropSet( xElementSettings, UNO_QUERY );
2970 if ( xPropSet.is() )
2971 xPropSet->getPropertyValue( "ConfigurationSource" ) >>= xElementCfgMgr;
2973 if ( !xElementCfgMgr.is() )
2974 return;
2976 // Check if the same UI configuration manager has changed => update settings
2977 if ( Event.Source == xElementCfgMgr )
2978 xElementSettings->updateSettings();
2982 if ( bRefreshLayout )
2983 doLayout();
2986 void SAL_CALL LayoutManager::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle,
2987 const uno::Any& aValue )
2989 if ( (nHandle != LAYOUTMANAGER_PROPHANDLE_REFRESHVISIBILITY) && (nHandle != LAYOUTMANAGER_PROPHANDLE_REFRESHTOOLTIP) )
2990 LayoutManager_PBase::setFastPropertyValue_NoBroadcast( nHandle, aValue );
2992 switch( nHandle )
2994 case LAYOUTMANAGER_PROPHANDLE_MENUBARCLOSER:
2995 implts_updateMenuBarClose();
2996 break;
2998 case LAYOUTMANAGER_PROPHANDLE_REFRESHVISIBILITY:
3000 bool bValue(false);
3001 if (( aValue >>= bValue ) && bValue )
3003 SolarMutexClearableGuard aReadLock;
3004 ToolbarLayoutManager* pToolbarManager = m_xToolbarManager.get();
3005 bool bAutomaticToolbars( m_bAutomaticToolbars );
3006 aReadLock.clear();
3008 if ( pToolbarManager )
3009 pToolbarManager->refreshToolbarsVisibility( bAutomaticToolbars );
3011 break;
3014 case LAYOUTMANAGER_PROPHANDLE_HIDECURRENTUI:
3015 implts_setCurrentUIVisibility( !m_bHideCurrentUI );
3016 break;
3018 case LAYOUTMANAGER_PROPHANDLE_REFRESHTOOLTIP:
3019 if (m_xToolbarManager.is())
3020 m_xToolbarManager->updateToolbarsTips();
3021 break;
3023 default: break;
3027 namespace detail
3029 class InfoHelperBuilder
3031 private:
3032 std::unique_ptr<::cppu::OPropertyArrayHelper> m_pInfoHelper;
3033 public:
3034 explicit InfoHelperBuilder(const LayoutManager &rManager)
3036 uno::Sequence< beans::Property > aProperties;
3037 rManager.describeProperties(aProperties);
3038 m_pInfoHelper.reset( new ::cppu::OPropertyArrayHelper(aProperties, true) );
3040 InfoHelperBuilder(const InfoHelperBuilder&) = delete;
3041 InfoHelperBuilder& operator=(const InfoHelperBuilder&) = delete;
3043 ::cppu::OPropertyArrayHelper& getHelper() { return *m_pInfoHelper; }
3047 ::cppu::IPropertyArrayHelper& SAL_CALL LayoutManager::getInfoHelper()
3049 static detail::InfoHelperBuilder INFO(*this);
3050 return INFO.getHelper();
3053 uno::Reference< beans::XPropertySetInfo > SAL_CALL LayoutManager::getPropertySetInfo()
3055 static uno::Reference< beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
3057 return xInfo;
3060 } // namespace framework
3062 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
3063 com_sun_star_comp_framework_LayoutManager_get_implementation(
3064 css::uno::XComponentContext *context,
3065 css::uno::Sequence<css::uno::Any> const &)
3067 return cppu::acquire(new framework::LayoutManager(context));
3070 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */