1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 "toolbarlayoutmanager.hxx"
21 #include <uiconfiguration/windowstateproperties.hxx>
22 #include <uielement/addonstoolbarwrapper.hxx>
23 #include "helpers.hxx"
24 #include <services/layoutmanager.hxx>
25 #include <strings.hrc>
26 #include <classes/fwkresid.hxx>
28 #include <com/sun/star/awt/PosSize.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/ui/UIElementType.hpp>
31 #include <com/sun/star/container/XNameReplace.hpp>
32 #include <com/sun/star/container/XNameContainer.hpp>
33 #include <com/sun/star/ui/XUIElementSettings.hpp>
34 #include <com/sun/star/ui/XUIFunctionListener.hpp>
36 #include <comphelper/propertyvalue.hxx>
37 #include <cppuhelper/queryinterface.hxx>
38 #include <o3tl/string_view.hxx>
39 #include <unotools/cmdoptions.hxx>
40 #include <toolkit/helper/vclunohelper.hxx>
41 #include <toolkit/helper/convert.hxx>
43 #include <vcl/i18nhelp.hxx>
44 #include <vcl/dockingarea.hxx>
45 #include <vcl/settings.hxx>
46 #include <vcl/svapp.hxx>
47 #include <sal/log.hxx>
48 #include <tools/gen.hxx>
51 using namespace ::com::sun::star
;
56 ToolbarLayoutManager::ToolbarLayoutManager(
57 uno::Reference
< uno::XComponentContext
> xContext
,
58 uno::Reference
< ui::XUIElementFactory
> xUIElementFactory
,
59 LayoutManager
* pParentLayouter
):
60 m_xContext(std::move( xContext
)),
61 m_xUIElementFactoryManager(std::move( xUIElementFactory
)),
62 m_pParentLayouter( pParentLayouter
),
63 m_aDockingArea(0, 0, 0, 0),
64 m_aDockingAreaOffsets(0, 0, 0, 0),
65 m_eDockOperation( DOCKOP_ON_COLROW
),
66 m_ePreviewDetection( PREVIEWFRAME_UNKNOWN
),
67 m_bComponentAttached( false ),
68 m_bLayoutDirty( false ),
69 m_bGlobalSettings( false ),
70 m_bDockingInProgress( false ),
71 m_bLayoutInProgress( false ),
72 m_bToolbarCreation( false )
76 ToolbarLayoutManager::~ToolbarLayoutManager()
78 m_pGlobalSettings
.reset();
79 m_pAddonOptions
.reset();
84 void SAL_CALL
ToolbarLayoutManager::acquire() noexcept
86 OWeakObject::acquire();
89 void SAL_CALL
ToolbarLayoutManager::release() noexcept
91 OWeakObject::release();
94 uno::Any SAL_CALL
ToolbarLayoutManager::queryInterface( const uno::Type
& rType
)
96 uno::Any a
= ::cppu::queryInterface( rType
,
97 static_cast< awt::XDockableWindowListener
* >(this),
98 static_cast< ui::XUIConfigurationListener
* >(this),
99 static_cast< awt::XWindowListener
* >(this));
104 return OWeakObject::queryInterface( rType
);
107 void SAL_CALL
ToolbarLayoutManager::disposing( const lang::EventObject
& aEvent
)
109 if ( aEvent
.Source
== m_xFrame
)
111 // Reset all internal references
113 implts_destroyDockingAreaWindows();
117 awt::Rectangle
ToolbarLayoutManager::getDockingArea()
119 SolarMutexResettableGuard aWriteLock
;
120 tools::Rectangle
aNewDockingArea( m_aDockingArea
);
123 if ( isLayoutDirty() )
124 aNewDockingArea
= implts_calcDockingArea();
127 m_aDockingArea
= aNewDockingArea
;
130 return putRectangleValueToAWT(aNewDockingArea
);
133 void ToolbarLayoutManager::setDockingArea( const awt::Rectangle
& rDockingArea
)
136 m_aDockingArea
= putAWTToRectangle( rDockingArea
);
137 m_bLayoutDirty
= true;
140 void ToolbarLayoutManager::implts_setDockingAreaWindowSizes( const awt::Rectangle
& rBorderSpace
)
142 SolarMutexClearableGuard aReadLock
;
143 tools::Rectangle aDockOffsets
= m_aDockingAreaOffsets
;
144 uno::Reference
< awt::XWindow2
> xContainerWindow( m_xContainerWindow
);
145 uno::Reference
< awt::XWindow
> xTopDockAreaWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_TOP
)] );
146 uno::Reference
< awt::XWindow
> xBottomDockAreaWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_BOTTOM
)] );
147 uno::Reference
< awt::XWindow
> xLeftDockAreaWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_LEFT
)] );
148 uno::Reference
< awt::XWindow
> xRightDockAreaWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_RIGHT
)] );
151 uno::Reference
< awt::XDevice
> xDevice( xContainerWindow
, uno::UNO_QUERY
);
153 // Convert relative size to output size.
154 awt::Rectangle aRectangle
= xContainerWindow
->getPosSize();
155 awt::DeviceInfo aInfo
= xDevice
->getInfo();
156 awt::Size
aContainerClientSize( aRectangle
.Width
- aInfo
.LeftInset
- aInfo
.RightInset
,
157 aRectangle
.Height
- aInfo
.TopInset
- aInfo
.BottomInset
);
158 tools::Long aStatusBarHeight
= aDockOffsets
.GetHeight();
160 sal_Int32
nLeftRightDockingAreaHeight( aContainerClientSize
.Height
);
161 if ( rBorderSpace
.Y
>= 0 )
163 // Top docking area window
164 xTopDockAreaWindow
->setPosSize( 0, 0, aContainerClientSize
.Width
, rBorderSpace
.Y
, awt::PosSize::POSSIZE
);
165 xTopDockAreaWindow
->setVisible( true );
166 nLeftRightDockingAreaHeight
-= rBorderSpace
.Y
;
169 if ( rBorderSpace
.Height
>= 0 )
171 // Bottom docking area window
172 sal_Int32 nBottomPos
= std::max( sal_Int32( aContainerClientSize
.Height
- rBorderSpace
.Height
- aStatusBarHeight
+ 1 ), sal_Int32( 0 ));
173 sal_Int32 nHeight
= ( nBottomPos
== 0 ) ? 0 : rBorderSpace
.Height
;
175 xBottomDockAreaWindow
->setPosSize( 0, nBottomPos
, aContainerClientSize
.Width
, nHeight
, awt::PosSize::POSSIZE
);
176 xBottomDockAreaWindow
->setVisible( true );
177 nLeftRightDockingAreaHeight
-= nHeight
- 1;
180 nLeftRightDockingAreaHeight
-= aStatusBarHeight
;
181 if ( rBorderSpace
.X
>= 0 || nLeftRightDockingAreaHeight
> 0 )
183 // Left docking area window
184 // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority!
185 sal_Int32 nHeight
= std::max
<sal_Int32
>( 0, nLeftRightDockingAreaHeight
);
187 xLeftDockAreaWindow
->setPosSize( 0, rBorderSpace
.Y
, rBorderSpace
.X
, nHeight
, awt::PosSize::POSSIZE
);
188 xLeftDockAreaWindow
->setVisible( true );
190 if ( rBorderSpace
.Width
>= 0 || nLeftRightDockingAreaHeight
> 0 )
192 // Right docking area window
193 // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority!
194 sal_Int32 nLeftPos
= std::max
<sal_Int32
>( 0, aContainerClientSize
.Width
- rBorderSpace
.Width
);
195 sal_Int32 nHeight
= std::max
<sal_Int32
>( 0, nLeftRightDockingAreaHeight
);
196 sal_Int32 nWidth
= ( nLeftPos
== 0 ) ? 0 : rBorderSpace
.Width
;
198 xRightDockAreaWindow
->setPosSize( nLeftPos
, rBorderSpace
.Y
, nWidth
, nHeight
, awt::PosSize::POSSIZE
);
199 xRightDockAreaWindow
->setVisible( true );
204 void ToolbarLayoutManager::doLayout(const ::Size
& aContainerSize
)
206 SolarMutexResettableGuard aWriteLock
;
207 bool bLayoutInProgress( m_bLayoutInProgress
);
208 m_bLayoutInProgress
= true;
209 awt::Rectangle aDockingArea
= putRectangleValueToAWT( m_aDockingArea
);
212 if ( bLayoutInProgress
)
215 // Retrieve row/column dependent data from all docked user-interface elements
216 for ( sal_Int32 i
= 0; i
< DOCKINGAREAS_COUNT
; i
++ )
218 bool bReverse( isReverseOrderDockingArea( i
));
219 std::vector
< SingleRowColumnWindowData
> aRowColumnsWindowData
;
221 implts_getDockingAreaElementInfos( static_cast<ui::DockingArea
>(i
), aRowColumnsWindowData
);
223 sal_Int32
nOffset( 0 );
224 const sal_uInt32 nCount
= aRowColumnsWindowData
.size();
225 for ( sal_uInt32 j
= 0; j
< nCount
; ++j
)
227 sal_uInt32 nIndex
= bReverse
? nCount
-j
-1 : j
;
228 implts_calcWindowPosSizeOnSingleRowColumn( i
, nOffset
, aRowColumnsWindowData
[nIndex
], aContainerSize
);
229 nOffset
+= aRowColumnsWindowData
[j
].nStaticSize
;
233 implts_setDockingAreaWindowSizes( aDockingArea
);
236 m_bLayoutDirty
= false;
237 m_bLayoutInProgress
= false;
241 bool ToolbarLayoutManager::implts_isParentWindowVisible() const
244 bool bVisible( false );
245 if ( m_xContainerWindow
.is() )
246 bVisible
= m_xContainerWindow
->isVisible();
251 tools::Rectangle
ToolbarLayoutManager::implts_calcDockingArea()
253 SolarMutexClearableGuard aReadLock
;
254 UIElementVector
aWindowVector( m_aUIElements
);
257 tools::Rectangle aBorderSpace
;
258 sal_Int32
nCurrRowColumn( 0 );
259 sal_Int32
nCurrPos( 0 );
260 ui::DockingArea
nCurrDockingArea( ui::DockingArea_DOCKINGAREA_TOP
);
261 std::vector
< sal_Int32
> aRowColumnSizes
[DOCKINGAREAS_COUNT
];
263 // initialize rectangle with zero values!
264 aBorderSpace
.setWidth(0);
265 aBorderSpace
.setHeight(0);
267 aRowColumnSizes
[static_cast<int>(nCurrDockingArea
)].clear();
268 aRowColumnSizes
[static_cast<int>(nCurrDockingArea
)].push_back( 0 );
270 for (auto const& window
: aWindowVector
)
272 if ( window
.m_xUIElement
.is() )
274 uno::Reference
< awt::XWindow
> xWindow( window
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
275 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
276 if ( xWindow
.is() && xDockWindow
.is() )
278 SolarMutexGuard aGuard
;
280 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( xWindow
);
281 if ( pWindow
&& !xDockWindow
->isFloating() && window
.m_bVisible
&& !window
.m_bMasterHide
)
283 awt::Rectangle aPosSize
= xWindow
->getPosSize();
284 if ( window
.m_aDockedData
.m_nDockedArea
!= nCurrDockingArea
)
286 nCurrDockingArea
= window
.m_aDockedData
.m_nDockedArea
;
289 aRowColumnSizes
[static_cast<int>(nCurrDockingArea
)].clear();
290 aRowColumnSizes
[static_cast<int>(nCurrDockingArea
)].push_back( 0 );
293 if ( window
.m_aDockedData
.m_nDockedArea
== nCurrDockingArea
)
295 if ( isHorizontalDockingArea( window
.m_aDockedData
.m_nDockedArea
))
297 if ( window
.m_aDockedData
.m_aPos
.Y
> nCurrPos
)
300 nCurrPos
= window
.m_aDockedData
.m_aPos
.Y
;
301 aRowColumnSizes
[static_cast<int>(nCurrDockingArea
)].push_back( 0 );
304 if ( aPosSize
.Height
> aRowColumnSizes
[static_cast<int>(nCurrDockingArea
)][nCurrRowColumn
] )
305 aRowColumnSizes
[static_cast<int>(nCurrDockingArea
)][nCurrRowColumn
] = aPosSize
.Height
;
309 if ( window
.m_aDockedData
.m_aPos
.X
> nCurrPos
)
312 nCurrPos
= window
.m_aDockedData
.m_aPos
.X
;
313 aRowColumnSizes
[static_cast<int>(nCurrDockingArea
)].push_back( 0 );
316 if ( aPosSize
.Width
> aRowColumnSizes
[static_cast<int>(nCurrDockingArea
)][nCurrRowColumn
] )
317 aRowColumnSizes
[static_cast<int>(nCurrDockingArea
)][nCurrRowColumn
] = aPosSize
.Width
;
325 // Sum up max heights from every row/column
326 if ( !aWindowVector
.empty() )
328 for ( sal_Int32 i
= 0; i
<= sal_Int32(ui::DockingArea_DOCKINGAREA_RIGHT
); i
++ )
330 sal_Int32
nSize( 0 );
331 const sal_uInt32 nCount
= aRowColumnSizes
[i
].size();
332 for ( sal_uInt32 j
= 0; j
< nCount
; j
++ )
333 nSize
+= aRowColumnSizes
[i
][j
];
335 if ( i
== sal_Int32(ui::DockingArea_DOCKINGAREA_TOP
) )
336 aBorderSpace
.SetTop( nSize
);
337 else if ( i
== sal_Int32(ui::DockingArea_DOCKINGAREA_BOTTOM
) )
338 aBorderSpace
.SetBottom( nSize
);
339 else if ( i
== sal_Int32(ui::DockingArea_DOCKINGAREA_LEFT
) )
340 aBorderSpace
.SetLeft( nSize
);
342 aBorderSpace
.SetRight( nSize
);
349 void ToolbarLayoutManager::reset()
352 SolarMutexGuard aWriteLock
;
353 m_xModuleCfgMgr
.clear();
354 m_xDocCfgMgr
.clear();
355 m_ePreviewDetection
= PREVIEWFRAME_UNKNOWN
;
356 m_bComponentAttached
= false;
363 void ToolbarLayoutManager::attach(
364 const uno::Reference
< frame::XFrame
>& xFrame
,
365 const uno::Reference
< ui::XUIConfigurationManager
>& xModuleCfgMgr
,
366 const uno::Reference
< ui::XUIConfigurationManager
>& xDocCfgMgr
,
367 const uno::Reference
< container::XNameAccess
>& xPersistentWindowState
)
369 // reset toolbar manager if we lose our current frame
370 if ( m_xFrame
.is() && m_xFrame
!= xFrame
)
375 m_xModuleCfgMgr
= xModuleCfgMgr
;
376 m_xDocCfgMgr
= xDocCfgMgr
;
377 m_xPersistentWindowState
= xPersistentWindowState
;
378 m_bComponentAttached
= true;
381 bool ToolbarLayoutManager::isPreviewFrame()
384 if (m_ePreviewDetection
== PREVIEWFRAME_UNKNOWN
)
386 uno::Reference
< frame::XFrame
> xFrame( m_xFrame
);
388 uno::Reference
< frame::XModel
> xModel( impl_getModelFromFrame( xFrame
));
390 m_ePreviewDetection
= (implts_isPreviewModel( xModel
) ? PREVIEWFRAME_YES
: PREVIEWFRAME_NO
);
392 return m_ePreviewDetection
== PREVIEWFRAME_YES
;
395 void ToolbarLayoutManager::createStaticToolbars()
398 implts_createCustomToolBars();
399 implts_createAddonsToolBars();
400 implts_createNonContextSensitiveToolBars();
401 implts_sortUIElements();
404 bool ToolbarLayoutManager::requestToolbar( const OUString
& rResourceURL
)
406 if (isPreviewFrame())
407 return false; // no toolbars for preview frame!
409 bool bNotify( false );
410 bool bMustCallCreate( false );
411 uno::Reference
< ui::XUIElement
> xUIElement
;
413 UIElement aRequestedToolbar
= impl_findToolbar( rResourceURL
);
414 if ( aRequestedToolbar
.m_aName
!= rResourceURL
)
416 bMustCallCreate
= true;
417 aRequestedToolbar
.m_aName
= rResourceURL
;
418 aRequestedToolbar
.m_aType
= UIRESOURCETYPE_TOOLBAR
;
419 aRequestedToolbar
.m_xUIElement
= xUIElement
;
420 implts_readWindowStateData( rResourceURL
, aRequestedToolbar
);
423 xUIElement
= aRequestedToolbar
.m_xUIElement
;
424 if ( !xUIElement
.is() )
425 bMustCallCreate
= true;
427 bool bCreateOrShowToolbar( aRequestedToolbar
.m_bVisible
&& !aRequestedToolbar
.m_bMasterHide
);
429 if ( bCreateOrShowToolbar
)
430 bNotify
= bMustCallCreate
? createToolbar( rResourceURL
) : showToolbar( rResourceURL
);
435 bool ToolbarLayoutManager::createToolbar( const OUString
& rResourceURL
)
437 bool bNotify( false );
439 uno::Reference
<frame::XFrame
> xFrame
;
440 uno::Reference
<awt::XWindow2
> xContainerWindow
;
442 SolarMutexGuard aReadLock
;
443 xFrame
.set(m_xFrame
);
444 xContainerWindow
.set(m_xContainerWindow
);
447 if ( !xFrame
.is() || !xContainerWindow
.is() )
450 UIElement aToolbarElement
= implts_findToolbar( rResourceURL
);
451 if ( !aToolbarElement
.m_xUIElement
.is() )
453 uno::Reference
< ui::XUIElement
> xUIElement
;
455 uno::Sequence
< beans::PropertyValue
> aPropSeq
{
456 comphelper::makePropertyValue("Frame", xFrame
),
457 comphelper::makePropertyValue("Persistent", true)
459 uno::Reference
<ui::XUIElementFactory
> xUIElementFactory
;
461 SolarMutexGuard aReadLock
;
462 xUIElementFactory
.set(m_xUIElementFactoryManager
);
465 implts_setToolbarCreation();
468 if ( xUIElementFactory
.is() )
469 xUIElement
= xUIElementFactory
->createUIElement( rResourceURL
, aPropSeq
);
471 catch (const container::NoSuchElementException
&)
474 catch (const lang::IllegalArgumentException
&)
477 implts_setToolbarCreation( false );
479 if ( xUIElement
.is() )
481 uno::Reference
< awt::XWindow
> xWindow( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
482 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
483 if ( xDockWindow
.is() && xWindow
.is() )
487 xDockWindow
->addDockableWindowListener( uno::Reference
< awt::XDockableWindowListener
>(this) );
488 xWindow
->addWindowListener( uno::Reference
< awt::XWindowListener
>(this) );
489 xDockWindow
->enableDocking( true );
491 catch (const uno::Exception
&)
496 bool bVisible
= false;
497 bool bFloating
= false;
499 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
501 SolarMutexClearableGuard aWriteLock
;
503 UIElement
& rElement
= impl_findToolbar(rResourceURL
);
504 if (rElement
.m_xUIElement
.is())
506 // somebody else must have created it while we released
507 // the SolarMutex - just dispose our new instance and
508 // do nothing. (We have to dispose either the new or the
509 // existing m_xUIElement.)
511 uno::Reference
<lang::XComponent
> const xC(xUIElement
, uno::UNO_QUERY
);
515 if (!rElement
.m_aName
.isEmpty())
517 // Reuse a local entry so we are able to use the latest
518 // UI changes for this document.
519 implts_setElementData(rElement
, xDockWindow
);
520 rElement
.m_xUIElement
= xUIElement
;
521 bVisible
= rElement
.m_bVisible
;
522 bFloating
= rElement
.m_bFloating
;
526 // Create new UI element and try to read its state data
527 UIElement
aNewToolbar(rResourceURL
, UIRESOURCETYPE_TOOLBAR
, xUIElement
);
528 implts_readWindowStateData(rResourceURL
, aNewToolbar
);
529 implts_setElementData(aNewToolbar
, xDockWindow
);
530 implts_insertToolbar(aNewToolbar
);
531 bVisible
= aNewToolbar
.m_bVisible
;
532 bFloating
= rElement
.m_bFloating
;
535 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
537 // set toolbar menu style according to customize command state
538 SvtCommandOptions aCmdOptions
;
540 SolarMutexGuard aGuard
;
541 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( xWindow
);
542 if ( pWindow
&& pWindow
->GetType() == WindowType::TOOLBOX
)
544 ToolBox
* pToolbar
= static_cast<ToolBox
*>(pWindow
.get());
545 ToolBoxMenuType nMenuType
= pToolbar
->GetMenuType();
546 if ( aCmdOptions
.LookupDisabled( "ConfigureDialog" ))
547 pToolbar
->SetMenuType( nMenuType
& ~ToolBoxMenuType::Customize
);
549 pToolbar
->SetMenuType( nMenuType
| ToolBoxMenuType::Customize
);
553 implts_sortUIElements();
555 if ( bVisible
&& !bFloating
)
556 implts_setLayoutDirty();
563 bool ToolbarLayoutManager::destroyToolbar( std::u16string_view rResourceURL
)
565 uno::Reference
< lang::XComponent
> xComponent
;
567 bool bNotify( false );
568 bool bMustBeSorted( false );
569 bool bMustLayouted( false );
570 bool bMustBeDestroyed( !o3tl::starts_with(rResourceURL
, u
"private:resource/toolbar/addon_") );
573 SolarMutexGuard aWriteLock
;
574 for (auto & elem
: m_aUIElements
)
576 if (elem
.m_aName
== rResourceURL
)
578 xComponent
.set(elem
.m_xUIElement
, uno::UNO_QUERY
);
579 if (bMustBeDestroyed
)
580 elem
.m_xUIElement
.clear();
582 elem
.m_bVisible
= false;
588 uno::Reference
< ui::XUIElement
> xUIElement( xComponent
, uno::UNO_QUERY
);
589 if ( xUIElement
.is() )
591 uno::Reference
< awt::XWindow
> xWindow( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
592 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
594 if ( bMustBeDestroyed
)
599 xWindow
->removeWindowListener( uno::Reference
< awt::XWindowListener
>(this) );
601 catch (const uno::Exception
&)
607 if ( xDockWindow
.is() )
608 xDockWindow
->removeDockableWindowListener( uno::Reference
< awt::XDockableWindowListener
>(this) );
610 catch (const uno::Exception
&)
617 xWindow
->setVisible( false );
621 if ( !xDockWindow
->isFloating() )
622 bMustLayouted
= true;
623 bMustBeSorted
= true;
626 if ( bMustBeDestroyed
)
628 if ( xComponent
.is() )
629 xComponent
->dispose();
634 implts_setLayoutDirty();
637 implts_sortUIElements();
642 void ToolbarLayoutManager::destroyToolbars()
644 UIElementVector aUIElementVector
;
645 implts_getUIElementVectorCopy( aUIElementVector
);
648 SolarMutexGuard aWriteLock
;
649 m_aUIElements
.clear();
650 m_bLayoutDirty
= true;
653 for (auto const& elem
: aUIElementVector
)
655 uno::Reference
< lang::XComponent
> xComponent( elem
.m_xUIElement
, uno::UNO_QUERY
);
656 if ( xComponent
.is() )
657 xComponent
->dispose();
661 bool ToolbarLayoutManager::showToolbar( std::u16string_view rResourceURL
)
663 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
665 SolarMutexGuard aGuard
;
666 vcl::Window
* pWindow
= getWindowFromXUIElement( aUIElement
.m_xUIElement
);
668 // Addons appear to need to be populated at start, but we don't
669 // want to populate them with (scaled) images until later.
670 AddonsToolBarWrapper
*pAddOns
;
671 pAddOns
= dynamic_cast<AddonsToolBarWrapper
*>( aUIElement
.m_xUIElement
.get());
673 pAddOns
->populateImages();
677 if ( !aUIElement
.m_bFloating
)
678 implts_setLayoutDirty();
680 pWindow
->Show( true, ShowFlags::NoFocusChange
| ShowFlags::NoActivate
);
682 aUIElement
.m_bVisible
= true;
683 implts_writeWindowStateData( aUIElement
);
684 implts_setToolbar( aUIElement
);
685 implts_sortUIElements();
692 bool ToolbarLayoutManager::hideToolbar( std::u16string_view rResourceURL
)
694 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
696 SolarMutexGuard aGuard
;
697 vcl::Window
* pWindow
= getWindowFromXUIElement( aUIElement
.m_xUIElement
);
700 pWindow
->Show( false );
701 if ( !aUIElement
.m_bFloating
)
702 implts_setLayoutDirty();
704 aUIElement
.m_bVisible
= false;
705 implts_writeWindowStateData( aUIElement
);
706 implts_setToolbar( aUIElement
);
713 void ToolbarLayoutManager::refreshToolbarsVisibility( bool bAutomaticToolbars
)
715 UIElementVector aUIElementVector
;
717 if ( !bAutomaticToolbars
)
720 implts_getUIElementVectorCopy( aUIElementVector
);
722 UIElement aUIElement
;
723 SolarMutexGuard aGuard
;
724 for (auto const& elem
: aUIElementVector
)
726 if ( implts_readWindowStateData( elem
.m_aName
, aUIElement
) &&
727 ( elem
.m_bVisible
!= aUIElement
.m_bVisible
) && !elem
.m_bMasterHide
)
730 UIElement
& rUIElement
= impl_findToolbar( elem
.m_aName
);
731 if ( rUIElement
.m_aName
== elem
.m_aName
)
733 rUIElement
.m_bVisible
= aUIElement
.m_bVisible
;
734 implts_setLayoutDirty();
740 void ToolbarLayoutManager::setFloatingToolbarsVisibility( bool bVisible
)
742 UIElementVector aUIElementVector
;
743 implts_getUIElementVectorCopy( aUIElementVector
);
745 SolarMutexGuard aGuard
;
746 for (auto const& elem
: aUIElementVector
)
748 vcl::Window
* pWindow
= getWindowFromXUIElement( elem
.m_xUIElement
);
749 if ( pWindow
&& elem
.m_bFloating
)
753 if ( elem
.m_bVisible
&& !elem
.m_bMasterHide
)
754 pWindow
->Show( true, ShowFlags::NoFocusChange
| ShowFlags::NoActivate
);
757 pWindow
->Show( false );
762 void ToolbarLayoutManager::setVisible( bool bVisible
)
764 UIElementVector aUIElementVector
;
765 implts_getUIElementVectorCopy( aUIElementVector
);
767 SolarMutexGuard aGuard
;
768 for (auto & elem
: aUIElementVector
)
770 if (!elem
.m_bFloating
)
772 elem
.m_bMasterHide
= !bVisible
;
773 implts_setToolbar(elem
);
774 implts_setLayoutDirty();
777 vcl::Window
* pWindow
= getWindowFromXUIElement( elem
.m_xUIElement
);
780 bool bSetVisible( elem
.m_bVisible
&& bVisible
);
785 if ( elem
.m_bFloating
)
786 pWindow
->Show(true, ShowFlags::NoFocusChange
| ShowFlags::NoActivate
);
795 bool ToolbarLayoutManager::dockToolbar( std::u16string_view rResourceURL
, ui::DockingArea eDockingArea
, const awt::Point
& aPos
)
797 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
799 if ( !aUIElement
.m_xUIElement
.is() )
804 uno::Reference
< awt::XWindow
> xWindow( aUIElement
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
805 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
806 if ( xDockWindow
.is() )
808 if ( eDockingArea
!= ui::DockingArea_DOCKINGAREA_DEFAULT
)
809 aUIElement
.m_aDockedData
.m_nDockedArea
= eDockingArea
;
811 if ( !isDefaultPos( aPos
))
812 aUIElement
.m_aDockedData
.m_aPos
= aPos
;
814 if ( !xDockWindow
->isFloating() )
816 vcl::Window
* pWindow( nullptr );
817 ToolBox
* pToolBox( nullptr );
820 SolarMutexGuard aGuard
;
821 pWindow
= VCLUnoHelper::GetWindow( xWindow
);
822 if ( pWindow
&& pWindow
->GetType() == WindowType::TOOLBOX
)
824 pToolBox
= static_cast<ToolBox
*>(pWindow
);
826 // We have to set the alignment of the toolbox. It's possible that the toolbox is moved from a
827 // horizontal to a vertical docking area!
828 pToolBox
->SetAlign( ImplConvertAlignment( aUIElement
.m_aDockedData
.m_nDockedArea
));
832 if ( hasDefaultPosValue( aUIElement
.m_aDockedData
.m_aPos
))
834 // Docking on its default position without a preset position -
835 // we have to find a good place for it.
838 SolarMutexGuard aGuard
;
841 aSize
= pToolBox
->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIElement
.m_aDockedData
.m_nDockedArea
) );
843 aSize
= pWindow
->GetSizePixel();
848 implts_findNextDockingPos(aUIElement
.m_aDockedData
.m_nDockedArea
, aSize
, aDockPos
, aPixelPos
);
849 aUIElement
.m_aDockedData
.m_aPos
= aDockPos
;
853 implts_setToolbar( aUIElement
);
855 if ( xDockWindow
->isFloating() )
857 // ATTENTION: This will call toggleFloatingMode() via notifications which
858 // sets the floating member of the UIElement correctly!
859 xDockWindow
->setFloatingMode( false );
863 implts_writeWindowStateData( aUIElement
);
864 implts_sortUIElements();
866 if ( aUIElement
.m_bVisible
)
867 implts_setLayoutDirty();
872 catch (const lang::DisposedException
&)
879 bool ToolbarLayoutManager::dockAllToolbars()
881 std::vector
< OUString
> aToolBarNameVector
;
884 SolarMutexGuard aReadLock
;
885 for (auto const& elem
: m_aUIElements
)
887 if (elem
.m_aType
== "toolbar" && elem
.m_xUIElement
.is() && elem
.m_bFloating
889 aToolBarNameVector
.push_back(elem
.m_aName
);
894 const sal_uInt32 nCount
= aToolBarNameVector
.size();
895 for ( sal_uInt32 i
= 0; i
< nCount
; ++i
)
898 aPoint
.X
= aPoint
.Y
= SAL_MAX_INT32
;
899 bResult
&= dockToolbar( aToolBarNameVector
[i
], ui::DockingArea_DOCKINGAREA_DEFAULT
, aPoint
);
905 void ToolbarLayoutManager::childWindowEvent( VclSimpleEvent
const * pEvent
)
907 // To enable toolbar controllers to change their image when a sub-toolbar function
908 // is activated, we need this mechanism. We have NO connection between these toolbars
910 auto pWindowEvent
= dynamic_cast< const VclWindowEvent
* >(pEvent
);
914 if ( pEvent
->GetId() == VclEventId::ToolboxSelect
)
916 OUString aToolbarName
;
918 ToolBox
* pToolBox
= getToolboxPtr( pWindowEvent
->GetWindow() );
922 aToolbarName
= retrieveToolbarNameFromHelpURL( pToolBox
);
923 ToolBoxItemId nId
= pToolBox
->GetCurItemId();
924 if ( nId
> ToolBoxItemId(0) )
925 aCommand
= pToolBox
->GetItemCommand( nId
);
928 if ( !aToolbarName
.isEmpty() && !aCommand
.isEmpty() )
930 SolarMutexClearableGuard aReadLock
;
931 ::std::vector
< uno::Reference
< ui::XUIFunctionListener
> > aListenerArray
;
933 for (auto const& elem
: m_aUIElements
)
935 if ( elem
.m_xUIElement
.is() )
937 uno::Reference
< ui::XUIFunctionListener
> xListener( elem
.m_xUIElement
, uno::UNO_QUERY
);
938 if ( xListener
.is() )
939 aListenerArray
.push_back( xListener
);
944 const sal_uInt32 nCount
= aListenerArray
.size();
945 for ( sal_uInt32 i
= 0; i
< nCount
; ++i
)
949 aListenerArray
[i
]->functionExecute( aToolbarName
, aCommand
);
951 catch (const uno::RuntimeException
&)
955 catch (const uno::Exception
&)
961 else if ( pEvent
->GetId() == VclEventId::ToolboxFormatChanged
)
963 if ( !implts_isToolbarCreationActive() )
965 ToolBox
* pToolBox
= getToolboxPtr( pWindowEvent
->GetWindow() );
968 OUString aToolbarName
= retrieveToolbarNameFromHelpURL( pToolBox
);
969 if ( !aToolbarName
.isEmpty() )
971 OUString aToolbarUrl
= "private:resource/toolbar/" + aToolbarName
;
973 UIElement aToolbar
= implts_findToolbar( aToolbarUrl
);
974 if ( aToolbar
.m_xUIElement
.is() && !aToolbar
.m_bFloating
)
976 implts_setLayoutDirty();
977 m_pParentLayouter
->requestLayout();
985 void ToolbarLayoutManager::resetDockingArea()
987 SolarMutexClearableGuard aReadLock
;
988 uno::Reference
< awt::XWindow
> xTopDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_TOP
)] );
989 uno::Reference
< awt::XWindow
> xLeftDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_LEFT
)] );
990 uno::Reference
< awt::XWindow
> xRightDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_RIGHT
)] );
991 uno::Reference
< awt::XWindow
> xBottomDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_BOTTOM
)] );
994 if ( xTopDockingWindow
.is() )
995 xTopDockingWindow
->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE
);
996 if ( xLeftDockingWindow
.is() )
997 xLeftDockingWindow
->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE
);
998 if ( xRightDockingWindow
.is() )
999 xRightDockingWindow
->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE
);
1000 if ( xBottomDockingWindow
.is() )
1001 xBottomDockingWindow
->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE
);
1004 void ToolbarLayoutManager::setParentWindow(
1005 const uno::Reference
< awt::XVclWindowPeer
>& xParentWindow
)
1007 static const char DOCKINGAREASTRING
[] = "dockingarea";
1009 uno::Reference
< awt::XWindow
> xTopDockWindow( createToolkitWindow( m_xContext
, xParentWindow
, DOCKINGAREASTRING
), uno::UNO_QUERY
);
1010 uno::Reference
< awt::XWindow
> xLeftDockWindow( createToolkitWindow( m_xContext
, xParentWindow
, DOCKINGAREASTRING
), uno::UNO_QUERY
);
1011 uno::Reference
< awt::XWindow
> xRightDockWindow( createToolkitWindow( m_xContext
, xParentWindow
, DOCKINGAREASTRING
), uno::UNO_QUERY
);
1012 uno::Reference
< awt::XWindow
> xBottomDockWindow( createToolkitWindow( m_xContext
, xParentWindow
, DOCKINGAREASTRING
), uno::UNO_QUERY
);
1015 SolarMutexGuard aWriteLock
;
1016 m_xContainerWindow
.set(xParentWindow
, uno::UNO_QUERY
);
1017 m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_TOP
)] = xTopDockWindow
;
1018 m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_LEFT
)] = xLeftDockWindow
;
1019 m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_RIGHT
)] = xRightDockWindow
;
1020 m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_BOTTOM
)] = xBottomDockWindow
;
1023 if ( xParentWindow
.is() )
1025 SolarMutexGuard aGuard
;
1026 VclPtr
< ::DockingAreaWindow
> pWindow
= dynamic_cast< ::DockingAreaWindow
* >(VCLUnoHelper::GetWindow( xTopDockWindow
) );
1028 pWindow
->SetAlign( WindowAlign::Top
);
1029 pWindow
= dynamic_cast< ::DockingAreaWindow
* >(VCLUnoHelper::GetWindow( xBottomDockWindow
) );
1031 pWindow
->SetAlign( WindowAlign::Bottom
);
1032 pWindow
= dynamic_cast< ::DockingAreaWindow
* >(VCLUnoHelper::GetWindow( xLeftDockWindow
) );
1034 pWindow
->SetAlign( WindowAlign::Left
);
1035 pWindow
= dynamic_cast< ::DockingAreaWindow
* >(VCLUnoHelper::GetWindow( xRightDockWindow
) );
1037 pWindow
->SetAlign( WindowAlign::Right
);
1038 implts_reparentToolbars();
1047 void ToolbarLayoutManager::setDockingAreaOffsets( const ::tools::Rectangle
& rOffsets
)
1050 m_aDockingAreaOffsets
= rOffsets
;
1051 m_bLayoutDirty
= true;
1054 OUString
ToolbarLayoutManager::implts_generateGenericAddonToolbarTitle( sal_Int32 nNumber
) const
1056 OUString
aAddonGenericTitle(FwkResId(STR_TOOLBAR_TITLE_ADDON
));
1057 const vcl::I18nHelper
& rI18nHelper
= Application::GetSettings().GetUILocaleI18nHelper();
1059 OUString aNumStr
= rI18nHelper
.GetNum( nNumber
, 0, false, false );
1060 aAddonGenericTitle
= aAddonGenericTitle
.replaceFirst( "%num%", aNumStr
);
1062 return aAddonGenericTitle
;
1065 void ToolbarLayoutManager::implts_createAddonsToolBars()
1067 SolarMutexClearableGuard aWriteLock
;
1068 if ( !m_pAddonOptions
)
1069 m_pAddonOptions
.reset( new AddonsOptions
);
1071 uno::Reference
< ui::XUIElementFactory
> xUIElementFactory( m_xUIElementFactoryManager
);
1072 uno::Reference
< frame::XFrame
> xFrame( m_xFrame
);
1075 if (isPreviewFrame())
1076 return; // no addon toolbars for preview frame!
1078 uno::Sequence
< uno::Sequence
< beans::PropertyValue
> > aAddonToolBarData
;
1079 uno::Reference
< ui::XUIElement
> xUIElement
;
1081 sal_uInt32 nCount
= m_pAddonOptions
->GetAddonsToolBarCount();
1083 uno::Sequence
< beans::PropertyValue
> aPropSeq( 2 );
1084 auto pPropSeq
= aPropSeq
.getArray();
1085 pPropSeq
[0].Name
= "Frame";
1086 pPropSeq
[0].Value
<<= xFrame
;
1087 pPropSeq
[1].Name
= "ConfigurationData";
1088 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
1090 OUString
aAddonToolBarName( "private:resource/toolbar/addon_" +
1091 m_pAddonOptions
->GetAddonsToolbarResourceName(i
) );
1092 aAddonToolBarData
= m_pAddonOptions
->GetAddonsToolBarPart( i
);
1093 pPropSeq
[1].Value
<<= aAddonToolBarData
;
1095 UIElement aElement
= implts_findToolbar( aAddonToolBarName
);
1098 // It's now possible that we are called more than once. Be sure to not create
1099 // add-on toolbars more than once!
1100 if ( aElement
.m_xUIElement
.is() )
1105 xUIElement
= xUIElementFactory
->createUIElement( aAddonToolBarName
, aPropSeq
);
1106 if ( xUIElement
.is() )
1108 uno::Reference
< awt::XDockableWindow
> xDockWindow( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
1109 if ( xDockWindow
.is() )
1113 xDockWindow
->addDockableWindowListener( uno::Reference
< awt::XDockableWindowListener
>(this) );
1114 xDockWindow
->enableDocking( true );
1115 uno::Reference
< awt::XWindow
> xWindow( xDockWindow
, uno::UNO_QUERY
);
1117 xWindow
->addWindowListener( uno::Reference
< awt::XWindowListener
>(this) );
1119 catch (const uno::Exception
&)
1124 OUString aGenericAddonTitle
= implts_generateGenericAddonToolbarTitle( i
+1 );
1126 if ( !aElement
.m_aName
.isEmpty() )
1128 // Reuse a local entry so we are able to use the latest
1129 // UI changes for this document.
1130 implts_setElementData( aElement
, xDockWindow
);
1131 aElement
.m_xUIElement
= xUIElement
;
1132 if ( aElement
.m_aUIName
.isEmpty() )
1134 aElement
.m_aUIName
= aGenericAddonTitle
;
1135 implts_writeWindowStateData( aElement
);
1140 // Create new UI element and try to read its state data
1141 UIElement
aNewToolbar( aAddonToolBarName
, "toolbar", xUIElement
);
1142 aNewToolbar
.m_bFloating
= true;
1143 implts_readWindowStateData( aAddonToolBarName
, aNewToolbar
);
1144 implts_setElementData( aNewToolbar
, xDockWindow
);
1145 if ( aNewToolbar
.m_aUIName
.isEmpty() )
1147 aNewToolbar
.m_aUIName
= aGenericAddonTitle
;
1148 implts_writeWindowStateData( aNewToolbar
);
1150 implts_insertToolbar( aNewToolbar
);
1153 uno::Reference
< awt::XWindow
> xWindow( xDockWindow
, uno::UNO_QUERY
);
1156 // Set generic title for add-on toolbar
1157 SolarMutexGuard aGuard
;
1158 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( xWindow
);
1159 if ( pWindow
->GetText().isEmpty() )
1160 pWindow
->SetText( aGenericAddonTitle
);
1161 if ( pWindow
->GetType() == WindowType::TOOLBOX
)
1163 ToolBox
* pToolbar
= static_cast<ToolBox
*>(pWindow
.get());
1164 pToolbar
->SetMenuType();
1169 catch (const container::NoSuchElementException
&)
1172 catch (const lang::IllegalArgumentException
&)
1178 void ToolbarLayoutManager::implts_createCustomToolBars()
1180 SolarMutexClearableGuard aReadLock
;
1181 if ( !m_bComponentAttached
)
1184 uno::Reference
< frame::XFrame
> xFrame( m_xFrame
);
1185 uno::Reference
< ui::XUIConfigurationManager
> xModuleCfgMgr
= m_xModuleCfgMgr
;
1186 uno::Reference
< ui::XUIConfigurationManager
> xDocCfgMgr
= m_xDocCfgMgr
;
1192 if (isPreviewFrame())
1193 return; // no custom toolbars for preview frame!
1195 uno::Sequence
< uno::Sequence
< beans::PropertyValue
> > aTbxSeq
;
1196 if ( xDocCfgMgr
.is() )
1198 aTbxSeq
= xDocCfgMgr
->getUIElementsInfo( ui::UIElementType::TOOLBAR
);
1199 implts_createCustomToolBars( aTbxSeq
); // first create all document based toolbars
1201 if ( xModuleCfgMgr
.is() )
1203 aTbxSeq
= xModuleCfgMgr
->getUIElementsInfo( ui::UIElementType::TOOLBAR
);
1204 implts_createCustomToolBars( aTbxSeq
); // second create module based toolbars
1208 void ToolbarLayoutManager::implts_createNonContextSensitiveToolBars()
1210 SolarMutexClearableGuard aReadLock
;
1212 if ( !m_xPersistentWindowState
.is() || !m_xFrame
.is() || !m_bComponentAttached
)
1215 uno::Reference
< container::XNameAccess
> xPersistentWindowState( m_xPersistentWindowState
);
1218 if (isPreviewFrame())
1221 std::vector
< OUString
> aMakeVisibleToolbars
;
1225 const uno::Sequence
< OUString
> aToolbarNames
= xPersistentWindowState
->getElementNames();
1227 if ( aToolbarNames
.hasElements() )
1229 OUString aElementType
;
1230 OUString aElementName
;
1232 aMakeVisibleToolbars
.reserve(aToolbarNames
.getLength());
1236 for ( OUString
const & aName
: aToolbarNames
)
1238 parseResourceURL( aName
, aElementType
, aElementName
);
1240 // Check that we only create:
1241 // - Toolbars (the statusbar is also member of the persistent window state)
1242 // - Not custom toolbars, there are created with their own method (implts_createCustomToolbars)
1243 if ( aElementType
.equalsIgnoreAsciiCase("toolbar") &&
1244 aElementName
.indexOf( "custom_" ) == -1 )
1246 UIElement aNewToolbar
= implts_findToolbar( aName
);
1247 bool bFound
= ( aNewToolbar
.m_aName
== aName
);
1249 implts_readWindowStateData( aName
, aNewToolbar
);
1251 if ( aNewToolbar
.m_bVisible
&& !aNewToolbar
.m_bContextSensitive
)
1254 implts_insertToolbar( aNewToolbar
);
1255 aMakeVisibleToolbars
.push_back( aName
);
1261 catch (const uno::RuntimeException
&)
1265 catch (const uno::Exception
&)
1269 for (auto const& rURL
: aMakeVisibleToolbars
)
1271 requestToolbar(rURL
);
1275 void ToolbarLayoutManager::implts_createCustomToolBars( const uno::Sequence
< uno::Sequence
< beans::PropertyValue
> >& aTbxSeqSeq
)
1277 for ( const uno::Sequence
< beans::PropertyValue
>& rTbxSeq
: aTbxSeqSeq
)
1279 OUString aTbxResName
;
1281 for ( const beans::PropertyValue
& rProp
: rTbxSeq
)
1283 if ( rProp
.Name
== "ResourceURL" )
1284 rProp
.Value
>>= aTbxResName
;
1285 else if ( rProp
.Name
== "UIName" )
1286 rProp
.Value
>>= aTbxTitle
;
1289 // Only create custom toolbars. Their name have to start with "custom_"!
1290 if ( !aTbxResName
.isEmpty() && ( aTbxResName
.indexOf( "custom_" ) != -1 ) )
1291 implts_createCustomToolBar( aTbxResName
, aTbxTitle
);
1295 void ToolbarLayoutManager::implts_createCustomToolBar( const OUString
& aTbxResName
, const OUString
& aTitle
)
1297 if ( aTbxResName
.isEmpty() )
1300 if ( !createToolbar( aTbxResName
) )
1301 SAL_WARN("fwk.uielement", "ToolbarLayoutManager cannot create custom toolbar");
1303 uno::Reference
< ui::XUIElement
> xUIElement
= getToolbar( aTbxResName
);
1305 if ( !aTitle
.isEmpty() && xUIElement
.is() )
1307 SolarMutexGuard aGuard
;
1309 vcl::Window
* pWindow
= getWindowFromXUIElement( xUIElement
);
1311 pWindow
->SetText( aTitle
);
1315 void ToolbarLayoutManager::implts_reparentToolbars()
1317 SolarMutexClearableGuard aWriteLock
;
1318 UIElementVector aUIElementVector
= m_aUIElements
;
1319 VclPtr
<vcl::Window
> pContainerWindow
= VCLUnoHelper::GetWindow( m_xContainerWindow
);
1320 VclPtr
<vcl::Window
> pTopDockWindow
= VCLUnoHelper::GetWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_TOP
)] );
1321 VclPtr
<vcl::Window
> pBottomDockWindow
= VCLUnoHelper::GetWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_BOTTOM
)] );
1322 VclPtr
<vcl::Window
> pLeftDockWindow
= VCLUnoHelper::GetWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_LEFT
)] );
1323 VclPtr
<vcl::Window
> pRightDockWindow
= VCLUnoHelper::GetWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_RIGHT
)] );
1326 SolarMutexGuard aGuard
;
1327 if ( !pContainerWindow
)
1330 for (auto const& elem
: aUIElementVector
)
1332 uno::Reference
< ui::XUIElement
> xUIElement( elem
.m_xUIElement
);
1333 if ( xUIElement
.is() )
1335 uno::Reference
< awt::XWindow
> xWindow
;
1338 // We have to retrieve the window reference with try/catch as it is
1339 // possible that all elements have been disposed!
1340 xWindow
.set( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
1342 catch (const uno::RuntimeException
&)
1346 catch (const uno::Exception
&)
1350 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( xWindow
);
1353 // Reparent our child windows according to their current state.
1354 if ( elem
.m_bFloating
)
1355 pWindow
->SetParent( pContainerWindow
);
1358 if ( elem
.m_aDockedData
.m_nDockedArea
== ui::DockingArea_DOCKINGAREA_TOP
)
1359 pWindow
->SetParent( pTopDockWindow
);
1360 else if ( elem
.m_aDockedData
.m_nDockedArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
)
1361 pWindow
->SetParent( pBottomDockWindow
);
1362 else if ( elem
.m_aDockedData
.m_nDockedArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
1363 pWindow
->SetParent( pLeftDockWindow
);
1365 pWindow
->SetParent( pRightDockWindow
);
1372 void ToolbarLayoutManager::implts_setToolbarCreation( bool bStart
)
1375 m_bToolbarCreation
= bStart
;
1378 bool ToolbarLayoutManager::implts_isToolbarCreationActive()
1381 return m_bToolbarCreation
;
1384 void ToolbarLayoutManager::implts_setElementData( UIElement
& rElement
, const uno::Reference
< awt::XDockableWindow
>& rDockWindow
)
1386 SolarMutexClearableGuard aReadLock
;
1387 bool bShowElement( rElement
.m_bVisible
&& !rElement
.m_bMasterHide
&& implts_isParentWindowVisible() );
1390 uno::Reference
< awt::XWindow2
> xWindow( rDockWindow
, uno::UNO_QUERY
);
1392 vcl::Window
* pWindow( nullptr );
1393 ToolBox
* pToolBox( nullptr );
1395 if ( !(rDockWindow
.is() && xWindow
.is()) )
1399 SolarMutexGuard aGuard
;
1400 pWindow
= VCLUnoHelper::GetWindow( xWindow
);
1403 OUString aText
= pWindow
->GetText();
1404 if ( aText
.isEmpty() )
1405 pWindow
->SetText( rElement
.m_aUIName
);
1406 if ( rElement
.m_bNoClose
)
1407 pWindow
->SetStyle( pWindow
->GetStyle() & ~WB_CLOSEABLE
);
1408 if ( pWindow
->GetType() == WindowType::TOOLBOX
)
1409 pToolBox
= static_cast<ToolBox
*>(pWindow
);
1413 pToolBox
->SetButtonType( rElement
.m_nStyle
);
1414 if ( rElement
.m_bNoClose
)
1415 pToolBox
->SetFloatStyle( pToolBox
->GetFloatStyle() & ~WB_CLOSEABLE
);
1419 if ( rElement
.m_bFloating
)
1423 SolarMutexGuard aGuard
;
1424 OUString aText
= pWindow
->GetText();
1425 if ( aText
.isEmpty() )
1426 pWindow
->SetText( rElement
.m_aUIName
);
1429 awt::Point
aPos(rElement
.m_aFloatingData
.m_aPos
);
1430 bool bWriteData( false );
1431 bool bUndefPos
= hasDefaultPosValue( rElement
.m_aFloatingData
.m_aPos
);
1432 bool bSetSize
= ( rElement
.m_aFloatingData
.m_aSize
.Width
!= 0 &&
1433 rElement
.m_aFloatingData
.m_aSize
.Height
!= 0 );
1434 rDockWindow
->setFloatingMode( true );
1437 aPos
= implts_findNextCascadeFloatingPos();
1438 rElement
.m_aFloatingData
.m_aPos
= aPos
; // set new cascaded position
1443 xWindow
->setOutputSize(rElement
.m_aFloatingData
.m_aSize
);
1448 // set an optimal initial floating size
1449 SolarMutexGuard aGuard
;
1450 ::Size
aSize( pToolBox
->CalcFloatingWindowSizePixel() );
1451 pToolBox
->SetOutputSizePixel( aSize
);
1455 // #i60882# IMPORTANT: Set position after size as it is
1456 // possible that we position some part of the toolbar
1457 // outside of the desktop. A default constructed toolbar
1458 // always has one line. Now VCL automatically
1459 // position the toolbar back into the desktop. Therefore
1460 // we resize the toolbar with the new (wrong) position.
1461 // To fix this problem we have to set the size BEFORE the
1463 xWindow
->setPosSize( aPos
.X
, aPos
.Y
, 0, 0, awt::PosSize::POS
);
1466 implts_writeWindowStateData( rElement
);
1467 if ( bShowElement
&& pWindow
)
1469 SolarMutexGuard aGuard
;
1470 pWindow
->Show( true, ShowFlags::NoFocusChange
| ShowFlags::NoActivate
);
1475 bool bSetSize( false );
1481 SolarMutexGuard aGuard
;
1482 pToolBox
->SetAlign( ImplConvertAlignment(rElement
.m_aDockedData
.m_nDockedArea
) );
1483 pToolBox
->SetLineCount( 1 );
1484 rDockWindow
->setFloatingMode( false );
1485 if ( rElement
.m_aDockedData
.m_bLocked
)
1486 rDockWindow
->lock();
1487 aSize
= pToolBox
->CalcWindowSizePixel();
1490 if ( isDefaultPos( rElement
.m_aDockedData
.m_aPos
))
1492 awt::Point aDockPos
;
1493 implts_findNextDockingPos( rElement
.m_aDockedData
.m_nDockedArea
, aSize
, aDockPos
, aPixelPos
);
1494 rElement
.m_aDockedData
.m_aPos
= aDockPos
;
1498 xWindow
->setPosSize( aPixelPos
.X(), aPixelPos
.Y(), 0, 0, awt::PosSize::POS
);
1500 xWindow
->setOutputSize( AWTSize( aSize
) );
1504 SolarMutexGuard aGuard
;
1505 if ( !bShowElement
)
1511 void ToolbarLayoutManager::implts_destroyDockingAreaWindows()
1513 SolarMutexClearableGuard aWriteLock
;
1514 uno::Reference
< awt::XWindow
> xTopDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_TOP
)] );
1515 uno::Reference
< awt::XWindow
> xLeftDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_LEFT
)] );
1516 uno::Reference
< awt::XWindow
> xRightDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_RIGHT
)] );
1517 uno::Reference
< awt::XWindow
> xBottomDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_BOTTOM
)] );
1518 m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_TOP
)].clear();
1519 m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_LEFT
)].clear();
1520 m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_RIGHT
)].clear();
1521 m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_BOTTOM
)].clear();
1525 xTopDockingWindow
->dispose();
1526 xLeftDockingWindow
->dispose();
1527 xRightDockingWindow
->dispose();
1528 xBottomDockingWindow
->dispose();
1531 // persistence methods
1533 bool ToolbarLayoutManager::implts_readWindowStateData( const OUString
& aName
, UIElement
& rElementData
)
1535 return LayoutManager::readWindowStateData( aName
, rElementData
, m_xPersistentWindowState
,
1536 m_pGlobalSettings
, m_bGlobalSettings
, m_xContext
);
1539 void ToolbarLayoutManager::implts_writeWindowStateData( const UIElement
& rElementData
)
1541 SolarMutexClearableGuard aWriteLock
;
1542 uno::Reference
< container::XNameAccess
> xPersistentWindowState( m_xPersistentWindowState
);
1545 bool bPersistent( false );
1546 uno::Reference
< beans::XPropertySet
> xPropSet( rElementData
.m_xUIElement
, uno::UNO_QUERY
);
1547 if ( xPropSet
.is() )
1551 // Check persistent flag of the user interface element
1552 xPropSet
->getPropertyValue("Persistent") >>= bPersistent
;
1554 catch (const beans::UnknownPropertyException
&)
1556 bPersistent
= true; // Non-configurable elements should at least store their dimension/position
1558 catch (const lang::WrappedTargetException
&)
1563 if ( !(bPersistent
&& xPersistentWindowState
.is()) )
1568 uno::Sequence
<beans::PropertyValue
> aWindowState
{
1569 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_DOCKED
, !rElementData
.m_bFloating
),
1570 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_VISIBLE
, rElementData
.m_bVisible
),
1571 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_DOCKINGAREA
,
1572 rElementData
.m_aDockedData
.m_nDockedArea
),
1573 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_DOCKPOS
,
1574 rElementData
.m_aDockedData
.m_aPos
),
1575 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_POS
,
1576 rElementData
.m_aFloatingData
.m_aPos
),
1577 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_SIZE
,
1578 rElementData
.m_aFloatingData
.m_aSize
),
1579 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_UINAME
, rElementData
.m_aUIName
),
1580 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_LOCKED
,
1581 rElementData
.m_aDockedData
.m_bLocked
),
1582 comphelper::makePropertyValue(WINDOWSTATE_PROPERTY_STYLE
,
1583 static_cast<sal_uInt16
>(rElementData
.m_nStyle
))
1586 OUString aName
= rElementData
.m_aName
;
1587 if ( xPersistentWindowState
->hasByName( aName
))
1589 uno::Reference
< container::XNameReplace
> xReplace( xPersistentWindowState
, uno::UNO_QUERY
);
1590 xReplace
->replaceByName( aName
, uno::Any( aWindowState
));
1594 uno::Reference
< container::XNameContainer
> xInsert( xPersistentWindowState
, uno::UNO_QUERY
);
1595 xInsert
->insertByName( aName
, uno::Any( aWindowState
));
1598 catch (const uno::Exception
&)
1603 /******************************************************************************
1604 LOOKUP PART FOR TOOLBARS
1605 ******************************************************************************/
1607 UIElement
& ToolbarLayoutManager::impl_findToolbar( std::u16string_view aName
)
1609 static UIElement aEmptyElement
;
1612 for (auto & elem
: m_aUIElements
)
1614 if ( elem
.m_aName
== aName
)
1618 return aEmptyElement
;
1621 UIElement
ToolbarLayoutManager::implts_findToolbar( std::u16string_view aName
)
1624 return impl_findToolbar( aName
);
1627 UIElement
ToolbarLayoutManager::implts_findToolbar( const uno::Reference
< uno::XInterface
>& xToolbar
)
1632 for (auto const& elem
: m_aUIElements
)
1634 if ( elem
.m_xUIElement
.is() )
1636 uno::Reference
< uno::XInterface
> xIfac( elem
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
1637 if ( xIfac
== xToolbar
)
1648 uno::Reference
< awt::XWindow
> ToolbarLayoutManager::implts_getXWindow( std::u16string_view aName
)
1650 uno::Reference
< awt::XWindow
> xWindow
;
1653 for (auto const& elem
: m_aUIElements
)
1655 if ( elem
.m_aName
== aName
&& elem
.m_xUIElement
.is() )
1657 xWindow
.set( elem
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
1665 vcl::Window
* ToolbarLayoutManager::implts_getWindow( std::u16string_view aName
)
1667 uno::Reference
< awt::XWindow
> xWindow
= implts_getXWindow( aName
);
1668 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( xWindow
);
1673 bool ToolbarLayoutManager::implts_insertToolbar( const UIElement
& rUIElement
)
1675 UIElement aTempData
;
1676 bool bFound( false );
1677 bool bResult( false );
1679 aTempData
= implts_findToolbar( rUIElement
.m_aName
);
1680 if ( aTempData
.m_aName
== rUIElement
.m_aName
)
1686 m_aUIElements
.push_back( rUIElement
);
1693 void ToolbarLayoutManager::implts_setToolbar( const UIElement
& rUIElement
)
1696 UIElement
& rData
= impl_findToolbar( rUIElement
.m_aName
);
1697 if ( rData
.m_aName
== rUIElement
.m_aName
)
1700 m_aUIElements
.push_back( rUIElement
);
1703 /******************************************************************************
1704 LAYOUT CODE PART FOR TOOLBARS
1705 ******************************************************************************/
1707 awt::Point
ToolbarLayoutManager::implts_findNextCascadeFloatingPos()
1709 const sal_Int32 nHotZoneX
= 50;
1710 const sal_Int32 nHotZoneY
= 50;
1711 const sal_Int32 nCascadeIndentX
= 15;
1712 const sal_Int32 nCascadeIndentY
= 15;
1714 SolarMutexClearableGuard aReadLock
;
1715 uno::Reference
< awt::XWindow2
> xContainerWindow( m_xContainerWindow
);
1716 uno::Reference
< awt::XWindow
> xTopDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_TOP
)] );
1717 uno::Reference
< awt::XWindow
> xLeftDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_LEFT
)] );
1720 awt::Point
aStartPos( nCascadeIndentX
, nCascadeIndentY
);
1721 awt::Point
aCurrPos( aStartPos
);
1723 if ( xContainerWindow
.is() )
1725 SolarMutexGuard aGuard
;
1726 VclPtr
<vcl::Window
> pContainerWindow
= VCLUnoHelper::GetWindow( xContainerWindow
);
1727 if ( pContainerWindow
)
1728 aStartPos
= AWTPoint(pContainerWindow
->OutputToScreenPixel(VCLPoint(aStartPos
)));
1731 // Determine size of top and left docking area
1732 awt::Rectangle
aTopRect( xTopDockingWindow
->getPosSize() );
1733 awt::Rectangle
aLeftRect( xLeftDockingWindow
->getPosSize() );
1735 aStartPos
.X
+= aLeftRect
.Width
+ nCascadeIndentX
;
1736 aStartPos
.Y
+= aTopRect
.Height
+ nCascadeIndentY
;
1737 aCurrPos
= aStartPos
;
1739 // Try to find a cascaded position for the new floating window
1740 for (auto const& elem
: m_aUIElements
)
1742 if ( elem
.m_xUIElement
.is() )
1744 uno::Reference
< awt::XDockableWindow
> xDockWindow( elem
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
1745 uno::Reference
< awt::XWindow
> xWindow( xDockWindow
, uno::UNO_QUERY
);
1746 if ( xDockWindow
.is() && xDockWindow
->isFloating() )
1748 SolarMutexGuard aGuard
;
1749 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( xWindow
);
1750 if ( pWindow
&& pWindow
->IsVisible() )
1752 awt::Rectangle aFloatRect
= xWindow
->getPosSize();
1753 if ((( aFloatRect
.X
- nHotZoneX
) <= aCurrPos
.X
) &&
1754 ( aFloatRect
.X
>= aCurrPos
.X
) &&
1755 (( aFloatRect
.Y
- nHotZoneY
) <= aCurrPos
.Y
) &&
1756 ( aFloatRect
.Y
>= aCurrPos
.Y
))
1758 aCurrPos
.X
= aFloatRect
.X
+ nCascadeIndentX
;
1759 aCurrPos
.Y
= aFloatRect
.Y
+ nCascadeIndentY
;
1769 void ToolbarLayoutManager::implts_sortUIElements()
1773 std::stable_sort( m_aUIElements
.begin(), m_aUIElements
.end()); // first created element should first
1775 // We have to reset our temporary flags.
1776 for (auto & elem
: m_aUIElements
)
1777 elem
.m_bUserActive
= false;
1780 void ToolbarLayoutManager::implts_getUIElementVectorCopy( UIElementVector
& rCopy
)
1783 rCopy
= m_aUIElements
;
1786 ::Size
ToolbarLayoutManager::implts_getTopBottomDockingAreaSizes()
1789 uno::Reference
< awt::XWindow
> xTopDockingAreaWindow
;
1790 uno::Reference
< awt::XWindow
> xBottomDockingAreaWindow
;
1793 SolarMutexGuard aReadLock
;
1794 xTopDockingAreaWindow
= m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_TOP
)];
1795 xBottomDockingAreaWindow
= m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_BOTTOM
)];
1798 if ( xTopDockingAreaWindow
.is() )
1799 aSize
.setWidth( xTopDockingAreaWindow
->getPosSize().Height
);
1800 if ( xBottomDockingAreaWindow
.is() )
1801 aSize
.setHeight( xBottomDockingAreaWindow
->getPosSize().Height
);
1806 void ToolbarLayoutManager::implts_getDockingAreaElementInfos( ui::DockingArea eDockingArea
, std::vector
< SingleRowColumnWindowData
>& rRowColumnsWindowData
)
1808 std::vector
< UIElement
> aWindowVector
;
1810 if (( eDockingArea
< ui::DockingArea_DOCKINGAREA_TOP
) || ( eDockingArea
> ui::DockingArea_DOCKINGAREA_RIGHT
))
1811 eDockingArea
= ui::DockingArea_DOCKINGAREA_TOP
;
1813 uno::Reference
< awt::XWindow
> xDockAreaWindow
;
1815 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1817 SolarMutexGuard aReadLock
;
1818 aWindowVector
.reserve(m_aUIElements
.size());
1819 xDockAreaWindow
= m_xDockAreaWindows
[static_cast<int>(eDockingArea
)];
1820 for (auto const& elem
: m_aUIElements
)
1822 if (elem
.m_aDockedData
.m_nDockedArea
== eDockingArea
&& elem
.m_bVisible
)
1824 uno::Reference
<ui::XUIElement
> xUIElement(elem
.m_xUIElement
);
1825 if (xUIElement
.is())
1827 uno::Reference
<awt::XWindow
> xWindow(xUIElement
->getRealInterface(),
1829 uno::Reference
<awt::XDockableWindow
> xDockWindow(xWindow
, uno::UNO_QUERY
);
1830 if (xDockWindow
.is())
1832 if (!elem
.m_bFloating
)
1835 aWindowVector
.push_back(elem
);
1840 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow(xWindow
);
1841 DockingManager
* pDockMgr
= vcl::Window::GetDockingManager();
1842 if (pDockMgr
!= nullptr)
1844 SystemWindow
* pFloatingWindow
= pDockMgr
->GetFloatingWindow(pWindow
);
1845 if (pFloatingWindow
)
1847 // update the position data of the floating window
1848 if (pFloatingWindow
->UpdatePositionData())
1850 awt::Rectangle aTmpRect
= xWindow
->getPosSize();
1851 UIElement uiElem
= elem
;
1852 uiElem
.m_aFloatingData
.m_aPos
1853 = awt::Point(aTmpRect
.X
, aTmpRect
.Y
);
1854 implts_setToolbar(uiElem
);
1855 implts_writeWindowStateData(uiElem
);
1865 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1867 rRowColumnsWindowData
.clear();
1869 // Collect data from windows that are on the same row/column
1871 sal_Int32
nIndex( 0 );
1872 sal_Int32
nLastPos( 0 );
1873 sal_Int32
nCurrPos( -1 );
1874 sal_Int32
nLastRowColPixelPos( 0 );
1875 awt::Rectangle aDockAreaRect
;
1877 if ( xDockAreaWindow
.is() )
1878 aDockAreaRect
= xDockAreaWindow
->getPosSize();
1880 if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
1881 nLastRowColPixelPos
= 0;
1882 else if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
)
1883 nLastRowColPixelPos
= aDockAreaRect
.Height
;
1884 else if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
1885 nLastRowColPixelPos
= 0;
1887 nLastRowColPixelPos
= aDockAreaRect
.Width
;
1889 const sal_uInt32 nCount
= aWindowVector
.size();
1890 for ( j
= 0; j
< sal_Int32( nCount
); j
++ )
1892 const UIElement
& rElement
= aWindowVector
[j
];
1893 uno::Reference
< awt::XWindow
> xWindow
;
1894 uno::Reference
< ui::XUIElement
> xUIElement( rElement
.m_xUIElement
);
1895 awt::Rectangle aPosSize
;
1897 if ( !lcl_checkUIElement(xUIElement
,aPosSize
,xWindow
) )
1899 if ( isHorizontalDockingArea( eDockingArea
))
1901 if ( nCurrPos
== -1 )
1903 nCurrPos
= rElement
.m_aDockedData
.m_aPos
.Y
;
1906 SingleRowColumnWindowData aRowColumnWindowData
;
1907 aRowColumnWindowData
.nRowColumn
= nCurrPos
;
1908 rRowColumnsWindowData
.push_back( aRowColumnWindowData
);
1911 sal_Int32
nSpace( 0 );
1912 if ( rElement
.m_aDockedData
.m_aPos
.Y
!= nCurrPos
)
1914 if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
1915 nLastRowColPixelPos
+= rRowColumnsWindowData
[nIndex
].nStaticSize
;
1917 nLastRowColPixelPos
-= rRowColumnsWindowData
[nIndex
].nStaticSize
;
1920 nCurrPos
= rElement
.m_aDockedData
.m_aPos
.Y
;
1921 SingleRowColumnWindowData aRowColumnWindowData
;
1922 aRowColumnWindowData
.nRowColumn
= nCurrPos
;
1923 rRowColumnsWindowData
.push_back( aRowColumnWindowData
);
1926 // Calc space before an element and store it
1927 nSpace
= ( rElement
.m_aDockedData
.m_aPos
.X
- nLastPos
);
1928 if ( rElement
.m_aDockedData
.m_aPos
.X
>= nLastPos
)
1930 rRowColumnsWindowData
[nIndex
].nSpace
+= nSpace
;
1931 nLastPos
= rElement
.m_aDockedData
.m_aPos
.X
+ aPosSize
.Width
;
1936 nLastPos
+= aPosSize
.Width
;
1938 rRowColumnsWindowData
[nIndex
].aRowColumnSpace
.push_back( nSpace
);
1940 rRowColumnsWindowData
[nIndex
].aRowColumnWindows
.push_back( xWindow
);
1941 rRowColumnsWindowData
[nIndex
].aUIElementNames
.push_back( rElement
.m_aName
);
1942 rRowColumnsWindowData
[nIndex
].aRowColumnWindowSizes
.emplace_back(
1943 rElement
.m_aDockedData
.m_aPos
.X
,
1944 rElement
.m_aDockedData
.m_aPos
.Y
,
1947 if ( rRowColumnsWindowData
[nIndex
].nStaticSize
< aPosSize
.Height
)
1948 rRowColumnsWindowData
[nIndex
].nStaticSize
= aPosSize
.Height
;
1949 if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
1950 rRowColumnsWindowData
[nIndex
].aRowColumnRect
= awt::Rectangle( 0, nLastRowColPixelPos
,
1951 aDockAreaRect
.Width
, aPosSize
.Height
);
1953 rRowColumnsWindowData
[nIndex
].aRowColumnRect
= awt::Rectangle( 0, ( nLastRowColPixelPos
- aPosSize
.Height
),
1954 aDockAreaRect
.Width
, aPosSize
.Height
);
1955 rRowColumnsWindowData
[nIndex
].nVarSize
+= aPosSize
.Width
+ nSpace
;
1959 if ( nCurrPos
== -1 )
1961 nCurrPos
= rElement
.m_aDockedData
.m_aPos
.X
;
1964 SingleRowColumnWindowData aRowColumnWindowData
;
1965 aRowColumnWindowData
.nRowColumn
= nCurrPos
;
1966 rRowColumnsWindowData
.push_back( aRowColumnWindowData
);
1969 sal_Int32
nSpace( 0 );
1970 if ( rElement
.m_aDockedData
.m_aPos
.X
!= nCurrPos
)
1972 if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
1973 nLastRowColPixelPos
+= rRowColumnsWindowData
[nIndex
].nStaticSize
;
1975 nLastRowColPixelPos
-= rRowColumnsWindowData
[nIndex
].nStaticSize
;
1978 nCurrPos
= rElement
.m_aDockedData
.m_aPos
.X
;
1979 SingleRowColumnWindowData aRowColumnWindowData
;
1980 aRowColumnWindowData
.nRowColumn
= nCurrPos
;
1981 rRowColumnsWindowData
.push_back( aRowColumnWindowData
);
1984 // Calc space before an element and store it
1985 nSpace
= ( rElement
.m_aDockedData
.m_aPos
.Y
- nLastPos
);
1986 if ( rElement
.m_aDockedData
.m_aPos
.Y
> nLastPos
)
1988 rRowColumnsWindowData
[nIndex
].nSpace
+= nSpace
;
1989 nLastPos
= rElement
.m_aDockedData
.m_aPos
.Y
+ aPosSize
.Height
;
1994 nLastPos
+= aPosSize
.Height
;
1996 rRowColumnsWindowData
[nIndex
].aRowColumnSpace
.push_back( nSpace
);
1998 rRowColumnsWindowData
[nIndex
].aRowColumnWindows
.push_back( xWindow
);
1999 rRowColumnsWindowData
[nIndex
].aUIElementNames
.push_back( rElement
.m_aName
);
2000 rRowColumnsWindowData
[nIndex
].aRowColumnWindowSizes
.emplace_back(
2001 rElement
.m_aDockedData
.m_aPos
.X
,
2002 rElement
.m_aDockedData
.m_aPos
.Y
,
2005 if ( rRowColumnsWindowData
[nIndex
].nStaticSize
< aPosSize
.Width
)
2006 rRowColumnsWindowData
[nIndex
].nStaticSize
= aPosSize
.Width
;
2007 if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
2008 rRowColumnsWindowData
[nIndex
].aRowColumnRect
= awt::Rectangle( nLastRowColPixelPos
, 0,
2009 aPosSize
.Width
, aDockAreaRect
.Height
);
2011 rRowColumnsWindowData
[nIndex
].aRowColumnRect
= awt::Rectangle( ( nLastRowColPixelPos
- aPosSize
.Width
), 0,
2012 aPosSize
.Width
, aDockAreaRect
.Height
);
2013 rRowColumnsWindowData
[nIndex
].nVarSize
+= aPosSize
.Height
+ nSpace
;
2018 void ToolbarLayoutManager::implts_getDockingAreaElementInfoOnSingleRowCol( ui::DockingArea eDockingArea
, sal_Int32 nRowCol
, SingleRowColumnWindowData
& rRowColumnWindowData
)
2020 std::vector
< UIElement
> aWindowVector
;
2022 if (( eDockingArea
< ui::DockingArea_DOCKINGAREA_TOP
) || ( eDockingArea
> ui::DockingArea_DOCKINGAREA_RIGHT
))
2023 eDockingArea
= ui::DockingArea_DOCKINGAREA_TOP
;
2025 bool bHorzDockArea
= isHorizontalDockingArea( eDockingArea
);
2027 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2029 SolarMutexGuard aReadLock
;
2030 for (auto const& elem
: m_aUIElements
)
2032 if (elem
.m_aDockedData
.m_nDockedArea
== eDockingArea
)
2034 bool bSameRowCol
= bHorzDockArea
? (elem
.m_aDockedData
.m_aPos
.Y
== nRowCol
)
2035 : (elem
.m_aDockedData
.m_aPos
.X
== nRowCol
);
2036 uno::Reference
<ui::XUIElement
> xUIElement(elem
.m_xUIElement
);
2038 if (bSameRowCol
&& xUIElement
.is())
2040 uno::Reference
<awt::XWindow
> xWindow(xUIElement
->getRealInterface(),
2044 SolarMutexGuard aGuard
;
2045 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow(xWindow
);
2046 uno::Reference
<awt::XDockableWindow
> xDockWindow(xWindow
, uno::UNO_QUERY
);
2047 if (pWindow
&& elem
.m_bVisible
&& xDockWindow
.is() && !elem
.m_bFloating
)
2048 aWindowVector
.push_back(elem
); // docked windows
2054 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2056 // Initialize structure
2057 rRowColumnWindowData
.aUIElementNames
.clear();
2058 rRowColumnWindowData
.aRowColumnWindows
.clear();
2059 rRowColumnWindowData
.aRowColumnWindowSizes
.clear();
2060 rRowColumnWindowData
.aRowColumnSpace
.clear();
2061 rRowColumnWindowData
.nVarSize
= 0;
2062 rRowColumnWindowData
.nStaticSize
= 0;
2063 rRowColumnWindowData
.nSpace
= 0;
2064 rRowColumnWindowData
.nRowColumn
= nRowCol
;
2066 // Collect data from windows that are on the same row/column
2068 sal_Int32
nLastPos( 0 );
2070 const sal_uInt32 nCount
= aWindowVector
.size();
2071 for ( j
= 0; j
< sal_Int32( nCount
); j
++ )
2073 const UIElement
& rElement
= aWindowVector
[j
];
2074 uno::Reference
< awt::XWindow
> xWindow
;
2075 uno::Reference
< ui::XUIElement
> xUIElement( rElement
.m_xUIElement
);
2076 awt::Rectangle aPosSize
;
2077 if ( !lcl_checkUIElement(xUIElement
,aPosSize
,xWindow
) )
2081 if ( isHorizontalDockingArea( eDockingArea
))
2083 nSpace
= ( rElement
.m_aDockedData
.m_aPos
.X
- nLastPos
);
2085 // Calc space before an element and store it
2086 if ( rElement
.m_aDockedData
.m_aPos
.X
> nLastPos
)
2087 rRowColumnWindowData
.nSpace
+= nSpace
;
2091 nLastPos
= rElement
.m_aDockedData
.m_aPos
.X
+ aPosSize
.Width
;
2093 rRowColumnWindowData
.aRowColumnWindowSizes
.emplace_back(
2094 rElement
.m_aDockedData
.m_aPos
.X
, rElement
.m_aDockedData
.m_aPos
.Y
,
2095 aPosSize
.Width
, aPosSize
.Height
);
2096 if ( rRowColumnWindowData
.nStaticSize
< aPosSize
.Height
)
2097 rRowColumnWindowData
.nStaticSize
= aPosSize
.Height
;
2098 rRowColumnWindowData
.nVarSize
+= aPosSize
.Width
;
2102 // Calc space before an element and store it
2103 nSpace
= ( rElement
.m_aDockedData
.m_aPos
.Y
- nLastPos
);
2104 if ( rElement
.m_aDockedData
.m_aPos
.Y
> nLastPos
)
2105 rRowColumnWindowData
.nSpace
+= nSpace
;
2109 nLastPos
= rElement
.m_aDockedData
.m_aPos
.Y
+ aPosSize
.Height
;
2111 rRowColumnWindowData
.aRowColumnWindowSizes
.emplace_back(
2112 rElement
.m_aDockedData
.m_aPos
.X
, rElement
.m_aDockedData
.m_aPos
.Y
,
2113 aPosSize
.Width
, aPosSize
.Height
);
2114 if ( rRowColumnWindowData
.nStaticSize
< aPosSize
.Width
)
2115 rRowColumnWindowData
.nStaticSize
= aPosSize
.Width
;
2116 rRowColumnWindowData
.nVarSize
+= aPosSize
.Height
;
2119 rRowColumnWindowData
.aUIElementNames
.push_back( rElement
.m_aName
);
2120 rRowColumnWindowData
.aRowColumnWindows
.push_back( xWindow
);
2121 rRowColumnWindowData
.aRowColumnSpace
.push_back( nSpace
);
2122 rRowColumnWindowData
.nVarSize
+= nSpace
;
2126 ::tools::Rectangle
ToolbarLayoutManager::implts_getWindowRectFromRowColumn(
2127 ui::DockingArea DockingArea
,
2128 const SingleRowColumnWindowData
& rRowColumnWindowData
,
2129 const ::Point
& rMousePos
,
2130 std::u16string_view rExcludeElementName
)
2132 ::tools::Rectangle aWinRect
;
2134 if (( DockingArea
< ui::DockingArea_DOCKINGAREA_TOP
) || ( DockingArea
> ui::DockingArea_DOCKINGAREA_RIGHT
))
2135 DockingArea
= ui::DockingArea_DOCKINGAREA_TOP
;
2137 if ( rRowColumnWindowData
.aRowColumnWindows
.empty() )
2141 SolarMutexClearableGuard aReadLock
;
2142 VclPtr
<vcl::Window
> pContainerWindow( VCLUnoHelper::GetWindow( m_xContainerWindow
));
2143 VclPtr
<vcl::Window
> pDockingAreaWindow( VCLUnoHelper::GetWindow( m_xDockAreaWindows
[static_cast<int>(DockingArea
)] ));
2146 // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect
2147 SolarMutexGuard aGuard
;
2149 // Retrieve output size from container Window
2150 if ( pDockingAreaWindow
&& pContainerWindow
)
2152 const sal_uInt32 nCount
= rRowColumnWindowData
.aRowColumnWindows
.size();
2153 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
2155 awt::Rectangle aWindowRect
= rRowColumnWindowData
.aRowColumnWindows
[i
]->getPosSize();
2156 ::tools::Rectangle
aRect( aWindowRect
.X
, aWindowRect
.Y
, aWindowRect
.X
+aWindowRect
.Width
, aWindowRect
.Y
+aWindowRect
.Height
);
2157 aRect
.SetPos( pContainerWindow
->ScreenToOutputPixel( pDockingAreaWindow
->OutputToScreenPixel( aRect
.TopLeft() )));
2158 if ( aRect
.Contains( rMousePos
))
2160 // Check if we have found the excluded element. If yes, we have to provide an empty rectangle.
2161 // We prevent that a toolbar cannot be moved when the mouse pointer is inside its own rectangle!
2162 if ( rExcludeElementName
!= rRowColumnWindowData
.aUIElementNames
[i
] )
2174 ::tools::Rectangle
ToolbarLayoutManager::implts_determineFrontDockingRect(
2175 ui::DockingArea eDockingArea
,
2177 const ::tools::Rectangle
& rDockedElementRect
,
2178 std::u16string_view rMovedElementName
,
2179 const ::tools::Rectangle
& rMovedElementRect
)
2181 SingleRowColumnWindowData aRowColumnWindowData
;
2183 bool bHorzDockArea( isHorizontalDockingArea( eDockingArea
));
2184 implts_getDockingAreaElementInfoOnSingleRowCol( eDockingArea
, nRowCol
, aRowColumnWindowData
);
2185 if ( aRowColumnWindowData
.aRowColumnWindows
.empty() )
2186 return rMovedElementRect
;
2189 sal_Int32
nSpace( 0 );
2190 ::tools::Rectangle
aFrontDockingRect( rMovedElementRect
);
2191 const sal_uInt32 nCount
= aRowColumnWindowData
.aRowColumnWindows
.size();
2192 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
2194 if ( bHorzDockArea
)
2196 if ( aRowColumnWindowData
.aRowColumnWindowSizes
[i
].X
>= rDockedElementRect
.Left() )
2198 nSpace
+= aRowColumnWindowData
.aRowColumnSpace
[i
];
2201 else if ( aRowColumnWindowData
.aUIElementNames
[i
] == rMovedElementName
)
2202 nSpace
+= aRowColumnWindowData
.aRowColumnWindowSizes
[i
].Width
+
2203 aRowColumnWindowData
.aRowColumnSpace
[i
];
2209 if ( aRowColumnWindowData
.aRowColumnWindowSizes
[i
].Y
>= rDockedElementRect
.Top() )
2211 nSpace
+= aRowColumnWindowData
.aRowColumnSpace
[i
];
2214 else if ( aRowColumnWindowData
.aUIElementNames
[i
] == rMovedElementName
)
2215 nSpace
+= aRowColumnWindowData
.aRowColumnWindowSizes
[i
].Height
+
2216 aRowColumnWindowData
.aRowColumnSpace
[i
];
2224 sal_Int32 nMove
= std::min( nSpace
, static_cast<sal_Int32
>(aFrontDockingRect
.getOpenWidth()) );
2225 if ( bHorzDockArea
)
2226 aFrontDockingRect
.Move( -nMove
, 0 );
2228 aFrontDockingRect
.Move( 0, -nMove
);
2231 return aFrontDockingRect
;
2235 void ToolbarLayoutManager::implts_findNextDockingPos( ui::DockingArea DockingArea
, const ::Size
& aUIElementSize
, awt::Point
& rVirtualPos
, ::Point
& rPixelPos
)
2237 SolarMutexClearableGuard aReadLock
;
2238 if (( DockingArea
< ui::DockingArea_DOCKINGAREA_TOP
) || ( DockingArea
> ui::DockingArea_DOCKINGAREA_RIGHT
))
2239 DockingArea
= ui::DockingArea_DOCKINGAREA_TOP
;
2240 uno::Reference
< awt::XWindow
> xDockingWindow( m_xDockAreaWindows
[static_cast<int>(DockingArea
)] );
2241 ::Size aDockingWinSize
;
2243 // Retrieve output size from container Window
2244 vcl::Window
* pDockingWindow
= VCLUnoHelper::GetWindow( xDockingWindow
);
2245 if ( pDockingWindow
)
2246 aDockingWinSize
= pDockingWindow
->GetOutputSizePixel();
2249 sal_Int32
nFreeRowColPixelPos( 0 );
2250 sal_Int32
nMaxSpace( 0 );
2251 sal_Int32
nNeededSpace( 0 );
2252 sal_Int32
nTopDockingAreaSize( 0 );
2254 if ( isHorizontalDockingArea( DockingArea
))
2256 nMaxSpace
= aDockingWinSize
.Width();
2257 nNeededSpace
= aUIElementSize
.Width();
2261 nMaxSpace
= aDockingWinSize
.Height();
2262 nNeededSpace
= aUIElementSize
.Height();
2263 nTopDockingAreaSize
= implts_getTopBottomDockingAreaSizes().Width();
2266 std::vector
< SingleRowColumnWindowData
> aRowColumnsWindowData
;
2268 implts_getDockingAreaElementInfos( DockingArea
, aRowColumnsWindowData
);
2269 sal_Int32
nPixelPos( 0 );
2270 const sal_uInt32 nCount
= aRowColumnsWindowData
.size();
2271 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
2273 SingleRowColumnWindowData
& rRowColumnWindowData
= aRowColumnsWindowData
[i
];
2275 if (( DockingArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
) ||
2276 ( DockingArea
== ui::DockingArea_DOCKINGAREA_RIGHT
))
2277 nPixelPos
+= rRowColumnWindowData
.nStaticSize
;
2279 if ((( nMaxSpace
- rRowColumnWindowData
.nVarSize
) >= nNeededSpace
) ||
2280 ( rRowColumnWindowData
.nSpace
>= nNeededSpace
))
2282 // Check current row where we can find the needed space
2283 sal_Int32
nCurrPos( 0 );
2284 const sal_uInt32 nWindowSizesCount
= rRowColumnWindowData
.aRowColumnWindowSizes
.size();
2285 for ( sal_uInt32 j
= 0; j
< nWindowSizesCount
; j
++ )
2287 awt::Rectangle rRect
= rRowColumnWindowData
.aRowColumnWindowSizes
[j
];
2288 sal_Int32
& rSpace
= rRowColumnWindowData
.aRowColumnSpace
[j
];
2289 if ( isHorizontalDockingArea( DockingArea
))
2291 if ( rSpace
>= nNeededSpace
)
2293 rVirtualPos
= awt::Point( nCurrPos
, rRowColumnWindowData
.nRowColumn
);
2294 if ( DockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
2295 rPixelPos
= ::Point( nCurrPos
, nPixelPos
);
2297 rPixelPos
= ::Point( nCurrPos
, aDockingWinSize
.Height() - nPixelPos
);
2300 nCurrPos
= rRect
.X
+ rRect
.Width
;
2304 if ( rSpace
>= nNeededSpace
)
2306 rVirtualPos
= awt::Point( rRowColumnWindowData
.nRowColumn
, nCurrPos
);
2307 if ( DockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
2308 rPixelPos
= ::Point( nPixelPos
, nTopDockingAreaSize
+ nCurrPos
);
2310 rPixelPos
= ::Point( aDockingWinSize
.Width() - nPixelPos
, nTopDockingAreaSize
+ nCurrPos
);
2313 nCurrPos
= rRect
.Y
+ rRect
.Height
;
2317 if (( nCurrPos
+ nNeededSpace
) <= nMaxSpace
)
2319 if ( isHorizontalDockingArea( DockingArea
))
2321 rVirtualPos
= awt::Point( nCurrPos
, rRowColumnWindowData
.nRowColumn
);
2322 if ( DockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
2323 rPixelPos
= ::Point( nCurrPos
, nPixelPos
);
2325 rPixelPos
= ::Point( nCurrPos
, aDockingWinSize
.Height() - nPixelPos
);
2330 rVirtualPos
= awt::Point( rRowColumnWindowData
.nRowColumn
, nCurrPos
);
2331 if ( DockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
2332 rPixelPos
= ::Point( nPixelPos
, nTopDockingAreaSize
+ nCurrPos
);
2334 rPixelPos
= ::Point( aDockingWinSize
.Width() - nPixelPos
, nTopDockingAreaSize
+ nCurrPos
);
2340 if (( DockingArea
== ui::DockingArea_DOCKINGAREA_TOP
) || ( DockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
))
2341 nPixelPos
+= rRowColumnWindowData
.nStaticSize
;
2344 sal_Int32
nNextFreeRowCol( 0 );
2345 sal_Int32 nRowColumnsCount
= aRowColumnsWindowData
.size();
2346 if ( nRowColumnsCount
> 0 )
2347 nNextFreeRowCol
= aRowColumnsWindowData
[nRowColumnsCount
-1].nRowColumn
+1;
2349 nNextFreeRowCol
= 0;
2351 if ( nNextFreeRowCol
== 0 )
2353 if ( DockingArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
)
2354 nFreeRowColPixelPos
= aDockingWinSize
.Height() - aUIElementSize
.Height();
2355 else if ( DockingArea
== ui::DockingArea_DOCKINGAREA_RIGHT
)
2356 nFreeRowColPixelPos
= aDockingWinSize
.Width() - aUIElementSize
.Width();
2359 if ( isHorizontalDockingArea( DockingArea
))
2361 rVirtualPos
= awt::Point( 0, nNextFreeRowCol
);
2362 if ( DockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
2363 rPixelPos
= ::Point( 0, nFreeRowColPixelPos
);
2365 rPixelPos
= ::Point( 0, aDockingWinSize
.Height() - nFreeRowColPixelPos
);
2369 rVirtualPos
= awt::Point( nNextFreeRowCol
, 0 );
2370 rPixelPos
= ::Point( aDockingWinSize
.Width() - nFreeRowColPixelPos
, 0 );
2374 void ToolbarLayoutManager::implts_calcWindowPosSizeOnSingleRowColumn(
2375 sal_Int32 nDockingArea
,
2377 SingleRowColumnWindowData
& rRowColumnWindowData
,
2378 const ::Size
& rContainerSize
)
2381 sal_Int32
nRCSpace( rRowColumnWindowData
.nSpace
);
2382 sal_Int32
nContainerClientSize(0);
2384 if ( rRowColumnWindowData
.aRowColumnWindows
.empty() )
2387 if ( isHorizontalDockingArea( nDockingArea
))
2389 nContainerClientSize
= rContainerSize
.Width();
2390 nDiff
= nContainerClientSize
- rRowColumnWindowData
.nVarSize
;
2394 sal_Int32 nTopDockingAreaSize
= implts_getTopBottomDockingAreaSizes().Width();
2395 sal_Int32 nBottomDockingAreaSize
= implts_getTopBottomDockingAreaSizes().Height();
2396 nContainerClientSize
= ( rContainerSize
.Height() - nTopDockingAreaSize
- nBottomDockingAreaSize
);
2397 nDiff
= nContainerClientSize
- rRowColumnWindowData
.nVarSize
;
2400 const sal_uInt32 nCount
= rRowColumnWindowData
.aRowColumnWindowSizes
.size();
2401 if (( nDiff
< 0 ) && ( nRCSpace
> 0 ))
2403 // First we try to reduce the size of blank space before/behind docked windows
2404 sal_Int32 i
= nCount
- 1;
2407 sal_Int32 nSpace
= rRowColumnWindowData
.aRowColumnSpace
[i
];
2408 if ( nSpace
>= -nDiff
)
2410 if ( isHorizontalDockingArea( nDockingArea
))
2412 // Try to move this and all user elements behind with the calculated difference
2413 for ( sal_uInt32 j
= i
; j
< nCount
; j
++ )
2414 rRowColumnWindowData
.aRowColumnWindowSizes
[j
].X
+= nDiff
;
2418 // Try to move this and all user elements behind with the calculated difference
2419 for ( sal_uInt32 j
= i
; j
< nCount
; j
++ )
2420 rRowColumnWindowData
.aRowColumnWindowSizes
[j
].Y
+= nDiff
;
2426 else if ( nSpace
> 0 )
2428 if ( isHorizontalDockingArea( nDockingArea
))
2430 // Try to move this and all user elements behind with the calculated difference
2431 for ( sal_uInt32 j
= i
; j
< nCount
; j
++ )
2432 rRowColumnWindowData
.aRowColumnWindowSizes
[j
].X
-= nSpace
;
2436 // Try to move this and all user elements behind with the calculated difference
2437 for ( sal_uInt32 j
= i
; j
< nCount
; j
++ )
2438 rRowColumnWindowData
.aRowColumnWindowSizes
[j
].Y
-= nSpace
;
2446 // Check if we have to reduce further
2449 // Now we have to reduce the size of certain docked windows
2450 sal_Int32 i
= sal_Int32( nCount
- 1 );
2453 awt::Rectangle
& rWinRect
= rRowColumnWindowData
.aRowColumnWindowSizes
[i
];
2456 SolarMutexGuard aGuard
;
2458 uno::Reference
< awt::XWindow
> xWindow
= rRowColumnWindowData
.aRowColumnWindows
[i
];
2459 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( xWindow
);
2460 if ( pWindow
&& pWindow
->GetType() == WindowType::TOOLBOX
)
2461 aMinSize
= static_cast<ToolBox
*>(pWindow
.get())->CalcMinimumWindowSizePixel();
2464 if ( !aMinSize
.IsEmpty() )
2466 if ( isHorizontalDockingArea( nDockingArea
))
2468 sal_Int32 nMaxReducation
= rWinRect
.Width
- aMinSize
.Width();
2469 if ( nMaxReducation
>= -nDiff
)
2471 rWinRect
.Width
= rWinRect
.Width
+ nDiff
;
2476 rWinRect
.Width
= aMinSize
.Width();
2477 nDiff
+= nMaxReducation
;
2480 // Try to move this and all user elements behind with the calculated difference
2481 for ( sal_uInt32 j
= i
; j
< nCount
; j
++ )
2482 rRowColumnWindowData
.aRowColumnWindowSizes
[j
].X
+= nDiff
;
2486 sal_Int32 nMaxReducation
= rWinRect
.Height
- aMinSize
.Height();
2487 if ( nMaxReducation
>= -nDiff
)
2489 rWinRect
.Height
= rWinRect
.Height
+ nDiff
;
2494 rWinRect
.Height
= aMinSize
.Height();
2495 nDiff
+= nMaxReducation
;
2498 // Try to move this and all user elements behind with the calculated difference
2499 for ( sal_uInt32 j
= i
; j
< nCount
; j
++ )
2500 rRowColumnWindowData
.aRowColumnWindowSizes
[j
].Y
+= nDiff
;
2511 SolarMutexClearableGuard aReadLock
;
2512 VclPtr
<vcl::Window
> pDockAreaWindow
= VCLUnoHelper::GetWindow( m_xDockAreaWindows
[nDockingArea
] );
2515 sal_Int32
nCurrPos( 0 );
2517 SolarMutexGuard aGuard
;
2518 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
2520 uno::Reference
< awt::XWindow
> xWindow
= rRowColumnWindowData
.aRowColumnWindows
[i
];
2521 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( xWindow
);
2522 vcl::Window
* pOldParentWindow
= pWindow
->GetParent();
2524 if ( pDockAreaWindow
!= pOldParentWindow
)
2525 pWindow
->SetParent( pDockAreaWindow
);
2527 awt::Rectangle aWinRect
= rRowColumnWindowData
.aRowColumnWindowSizes
[i
];
2528 if ( isHorizontalDockingArea( nDockingArea
))
2530 if ( aWinRect
.X
< nCurrPos
)
2531 aWinRect
.X
= nCurrPos
;
2532 pWindow
->SetPosSizePixel( ::Point( aWinRect
.X
, nOffset
), ::Size( aWinRect
.Width
, rRowColumnWindowData
.nStaticSize
));
2533 pWindow
->Show( true, ShowFlags::NoFocusChange
| ShowFlags::NoActivate
);
2534 nCurrPos
+= ( aWinRect
.X
- nCurrPos
) + aWinRect
.Width
;
2538 if ( aWinRect
.Y
< nCurrPos
)
2539 aWinRect
.Y
= nCurrPos
;
2540 pWindow
->SetPosSizePixel( ::Point( nOffset
, aWinRect
.Y
), ::Size( rRowColumnWindowData
.nStaticSize
, aWinRect
.Height
));
2541 pWindow
->Show( true, ShowFlags::NoFocusChange
| ShowFlags::NoActivate
);
2542 nCurrPos
+= ( aWinRect
.Y
- nCurrPos
) + aWinRect
.Height
;
2547 void ToolbarLayoutManager::implts_setLayoutDirty()
2550 m_bLayoutDirty
= true;
2553 void ToolbarLayoutManager::implts_setLayoutInProgress( bool bInProgress
)
2556 m_bLayoutInProgress
= bInProgress
;
2559 ::tools::Rectangle
ToolbarLayoutManager::implts_calcHotZoneRect( const ::tools::Rectangle
& rRect
, sal_Int32 nHotZoneOffset
)
2561 ::tools::Rectangle
aRect( rRect
);
2563 aRect
.AdjustLeft( -nHotZoneOffset
);
2564 aRect
.AdjustTop( -nHotZoneOffset
);
2565 aRect
.AdjustRight(nHotZoneOffset
);
2566 aRect
.AdjustBottom(nHotZoneOffset
);
2571 void ToolbarLayoutManager::implts_calcDockingPosSize(
2572 UIElement
& rUIElement
,
2573 DockingOperation
& rDockingOperation
,
2574 ::tools::Rectangle
& rTrackingRect
,
2575 const Point
& rMousePos
)
2577 SolarMutexResettableGuard aReadLock
;
2578 uno::Reference
< awt::XWindow2
> xContainerWindow( m_xContainerWindow
);
2579 ::Size aContainerWinSize
;
2580 vcl::Window
* pContainerWindow( nullptr );
2581 ::tools::Rectangle
aDockingAreaOffsets( m_aDockingAreaOffsets
);
2584 if ( !rUIElement
.m_xUIElement
.is() )
2586 rTrackingRect
= ::tools::Rectangle();
2591 // Retrieve output size from container Window
2592 SolarMutexGuard aGuard
;
2593 pContainerWindow
= VCLUnoHelper::GetWindow( xContainerWindow
);
2594 aContainerWinSize
= pContainerWindow
->GetOutputSizePixel();
2597 vcl::Window
* pDockingAreaWindow( nullptr );
2598 uno::Reference
< awt::XWindow
> xWindow( rUIElement
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
2599 uno::Reference
< awt::XWindow
> xDockingAreaWindow
;
2600 ::tools::Rectangle
aTrackingRect( rTrackingRect
);
2601 ui::DockingArea
eDockedArea( rUIElement
.m_aDockedData
.m_nDockedArea
);
2602 sal_Int32
nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() );
2603 sal_Int32
nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() );
2604 bool bHorizontalDockArea(( eDockedArea
== ui::DockingArea_DOCKINGAREA_TOP
) ||
2605 ( eDockedArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
));
2606 sal_Int32 nMaxLeftRightDockAreaSize
= aContainerWinSize
.Height() -
2607 nTopDockingAreaSize
-
2608 nBottomDockingAreaSize
-
2609 aDockingAreaOffsets
.Top() -
2610 aDockingAreaOffsets
.Bottom();
2611 ::tools::Rectangle aDockingAreaRect
;
2614 xDockingAreaWindow
= m_xDockAreaWindows
[static_cast<int>(eDockedArea
)];
2618 SolarMutexGuard aGuard
;
2619 pDockingAreaWindow
= VCLUnoHelper::GetWindow( xDockingAreaWindow
);
2620 VclPtr
<vcl::Window
> pDockWindow
= VCLUnoHelper::GetWindow( xWindow
);
2621 ToolBox
* pToolBox( nullptr );
2622 if ( pDockWindow
&& pDockWindow
->GetType() == WindowType::TOOLBOX
)
2623 pToolBox
= static_cast<ToolBox
*>(pDockWindow
.get());
2625 aDockingAreaRect
= ::tools::Rectangle( pDockingAreaWindow
->GetPosPixel(), pDockingAreaWindow
->GetSizePixel() );
2628 // docked toolbars always have one line
2629 ::Size aSize
= pToolBox
->CalcWindowSizePixel( 1, ImplConvertAlignment( eDockedArea
) );
2630 aTrackingRect
.SetSize( ::Size( aSize
.Width(), aSize
.Height() ));
2634 // default docking operation, dock on the given row/column
2635 bool bOpOutsideOfDockingArea( !aDockingAreaRect
.Contains( rMousePos
));
2637 std::vector
< SingleRowColumnWindowData
> aRowColumnsWindowData
;
2639 rDockingOperation
= DOCKOP_ON_COLROW
;
2640 implts_getDockingAreaElementInfos( eDockedArea
, aRowColumnsWindowData
);
2642 // determine current first row/column and last row/column
2643 sal_Int32
nMaxRowCol( -1 );
2644 sal_Int32
nMinRowCol( SAL_MAX_INT32
);
2645 const sal_uInt32 nCount
= aRowColumnsWindowData
.size();
2646 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
2648 if ( aRowColumnsWindowData
[i
].nRowColumn
> nMaxRowCol
)
2649 nMaxRowCol
= aRowColumnsWindowData
[i
].nRowColumn
;
2650 if ( aRowColumnsWindowData
[i
].nRowColumn
< nMinRowCol
)
2651 nMinRowCol
= aRowColumnsWindowData
[i
].nRowColumn
;
2654 if ( !bOpOutsideOfDockingArea
)
2656 // docking inside our docking area
2657 sal_Int32
nIndex( -1 );
2658 sal_Int32
nRowCol( -1 );
2659 ::tools::Rectangle aWindowRect
;
2660 ::tools::Rectangle aRowColumnRect
;
2662 const sal_uInt32 nWindowDataCount
= aRowColumnsWindowData
.size();
2663 for ( sal_uInt32 i
= 0; i
< nWindowDataCount
; i
++ )
2665 ::tools::Rectangle
aRect( aRowColumnsWindowData
[i
].aRowColumnRect
.X
,
2666 aRowColumnsWindowData
[i
].aRowColumnRect
.Y
,
2667 aRowColumnsWindowData
[i
].aRowColumnRect
.X
+ aRowColumnsWindowData
[i
].aRowColumnRect
.Width
,
2668 aRowColumnsWindowData
[i
].aRowColumnRect
.Y
+ aRowColumnsWindowData
[i
].aRowColumnRect
.Height
);
2671 // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect
2672 SolarMutexGuard aGuard
;
2673 aRect
.SetPos( pContainerWindow
->ScreenToOutputPixel( pDockingAreaWindow
->OutputToScreenPixel( aRect
.TopLeft() )));
2676 bool bIsInsideRowCol( aRect
.Contains( rMousePos
) );
2677 if ( bIsInsideRowCol
)
2680 nRowCol
= aRowColumnsWindowData
[i
].nRowColumn
;
2681 rDockingOperation
= implts_determineDockingOperation( eDockedArea
, aRect
, rMousePos
);
2682 aWindowRect
= implts_getWindowRectFromRowColumn( eDockedArea
, aRowColumnsWindowData
[i
], rMousePos
, rUIElement
.m_aName
);
2683 aRowColumnRect
= aRect
;
2688 OSL_ENSURE( ( nIndex
>= 0 ) && ( nRowCol
>= 0 ), "Impossible case - no row/column found but mouse pointer is inside our docking area" );
2689 if (( nIndex
>= 0 ) && ( nRowCol
>= 0 ))
2691 if ( rDockingOperation
== DOCKOP_ON_COLROW
)
2693 if ( !aWindowRect
.IsEmpty())
2695 // Tracking rect is on a row/column and mouse is over a docked toolbar.
2696 // Determine if the tracking rect must be located before/after the docked toolbar.
2698 ::tools::Rectangle
aUIElementRect( aWindowRect
);
2699 sal_Int32
nMiddle( bHorizontalDockArea
? ( aWindowRect
.Left() + aWindowRect
.getOpenWidth() / 2 ) :
2700 ( aWindowRect
.Top() + aWindowRect
.getOpenHeight() / 2 ));
2701 bool bInsertBefore( bHorizontalDockArea
? ( rMousePos
.X() < nMiddle
) : ( rMousePos
.Y() < nMiddle
));
2702 if ( bInsertBefore
)
2704 if ( bHorizontalDockArea
)
2706 sal_Int32 nSize
= std::clamp( sal_Int32(aContainerWinSize
.Width() - aWindowRect
.Left()),
2707 sal_Int32(0), sal_Int32(aTrackingRect
.getOpenWidth()) );
2709 nSize
= aWindowRect
.getOpenWidth();
2711 aUIElementRect
.SetSize( ::Size( nSize
, aWindowRect
.getOpenHeight() ));
2712 aWindowRect
= implts_determineFrontDockingRect( eDockedArea
, nRowCol
, aWindowRect
,rUIElement
.m_aName
, aUIElementRect
);
2714 // Set virtual position
2715 rUIElement
.m_aDockedData
.m_aPos
.X
= aWindowRect
.Left();
2716 rUIElement
.m_aDockedData
.m_aPos
.Y
= nRowCol
;
2720 sal_Int32 nSize
= std::clamp( sal_Int32(nTopDockingAreaSize
+ nMaxLeftRightDockAreaSize
- aWindowRect
.Top()),
2721 sal_Int32(0), sal_Int32(aTrackingRect
.getOpenHeight()) );
2723 nSize
= aWindowRect
.getOpenHeight();
2725 aUIElementRect
.SetSize( ::Size( aWindowRect
.getOpenWidth(), nSize
));
2726 aWindowRect
= implts_determineFrontDockingRect( eDockedArea
, nRowCol
, aWindowRect
, rUIElement
.m_aName
, aUIElementRect
);
2728 // Set virtual position
2729 sal_Int32 nPosY
= pDockingAreaWindow
->ScreenToOutputPixel(
2730 pContainerWindow
->OutputToScreenPixel( aWindowRect
.TopLeft() )).Y();
2731 rUIElement
.m_aDockedData
.m_aPos
.X
= nRowCol
;
2732 rUIElement
.m_aDockedData
.m_aPos
.Y
= nPosY
;
2735 rTrackingRect
= aWindowRect
;
2740 if ( bHorizontalDockArea
)
2742 sal_Int32 nSize
= ::std::clamp( sal_Int32(aContainerWinSize
.Width() - aWindowRect
.Right()),
2743 sal_Int32(0), sal_Int32(aTrackingRect
.getOpenWidth()) );
2746 aUIElementRect
.SetPos( ::Point( aContainerWinSize
.Width() - aTrackingRect
.getOpenWidth(), aWindowRect
.Top() ));
2747 aUIElementRect
.SetSize( ::Size( aTrackingRect
.getOpenWidth(), aWindowRect
.getOpenHeight() ));
2748 rUIElement
.m_aDockedData
.m_aPos
.X
= aUIElementRect
.Left();
2753 aUIElementRect
.SetPos( ::Point( aWindowRect
.Right(), aWindowRect
.Top() ));
2754 aUIElementRect
.SetSize( ::Size( nSize
, aWindowRect
.getOpenHeight() ));
2755 rUIElement
.m_aDockedData
.m_aPos
.X
= aWindowRect
.Right();
2758 // Set virtual position
2759 rUIElement
.m_aDockedData
.m_aPos
.Y
= nRowCol
;
2763 sal_Int32 nSize
= std::clamp( sal_Int32(nTopDockingAreaSize
+ nMaxLeftRightDockAreaSize
- aWindowRect
.Bottom()),
2764 sal_Int32(0), sal_Int32(aTrackingRect
.getOpenHeight()) );
2765 aUIElementRect
.SetPos( ::Point( aWindowRect
.Left(), aWindowRect
.Bottom() ));
2766 aUIElementRect
.SetSize( ::Size( aWindowRect
.getOpenWidth(), nSize
));
2768 // Set virtual position
2769 sal_Int32
nPosY( 0 );
2771 SolarMutexGuard aGuard
;
2772 nPosY
= pDockingAreaWindow
->ScreenToOutputPixel(
2773 pContainerWindow
->OutputToScreenPixel( aWindowRect
.BottomRight() )).Y();
2775 rUIElement
.m_aDockedData
.m_aPos
.X
= nRowCol
;
2776 rUIElement
.m_aDockedData
.m_aPos
.Y
= nPosY
;
2779 rTrackingRect
= aUIElementRect
;
2785 implts_setTrackingRect( eDockedArea
, rMousePos
, aTrackingRect
);
2786 rTrackingRect
= implts_calcTrackingAndElementRect(
2787 eDockedArea
, nRowCol
, rUIElement
,
2788 aTrackingRect
, aRowColumnRect
, aContainerWinSize
);
2794 if ((( nRowCol
== nMinRowCol
) && ( rDockingOperation
== DOCKOP_BEFORE_COLROW
)) ||
2795 (( nRowCol
== nMaxRowCol
) && ( rDockingOperation
== DOCKOP_AFTER_COLROW
)))
2796 bOpOutsideOfDockingArea
= true;
2799 // handle docking before/after a row
2800 implts_setTrackingRect( eDockedArea
, rMousePos
, aTrackingRect
);
2801 rTrackingRect
= implts_calcTrackingAndElementRect(
2802 eDockedArea
, nRowCol
, rUIElement
,
2803 aTrackingRect
, aRowColumnRect
, aContainerWinSize
);
2805 sal_Int32
nOffsetX( 0 );
2806 sal_Int32
nOffsetY( 0 );
2807 if ( bHorizontalDockArea
)
2808 nOffsetY
= sal_Int32( floor( aRowColumnRect
.getOpenHeight() / 2.0 + 0.5 ));
2810 nOffsetX
= sal_Int32( floor( aRowColumnRect
.getOpenWidth() / 2.0 + 0.5 ));
2812 if ( rDockingOperation
== DOCKOP_BEFORE_COLROW
)
2814 if (( eDockedArea
== ui::DockingArea_DOCKINGAREA_TOP
) || ( eDockedArea
== ui::DockingArea_DOCKINGAREA_LEFT
))
2816 // Docking before/after means move track rectangle half column/row.
2817 // As left and top are ordered 0...n instead of right and bottom
2818 // which uses n...0, we have to use negative values for top/left.
2825 if (( eDockedArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
) || ( eDockedArea
== ui::DockingArea_DOCKINGAREA_RIGHT
))
2827 // Docking before/after means move track rectangle half column/row.
2828 // As left and top are ordered 0...n instead of right and bottom
2829 // which uses n...0, we have to use negative values for top/left.
2836 if ( bHorizontalDockArea
)
2837 rUIElement
.m_aDockedData
.m_aPos
.Y
= nRowCol
;
2839 rUIElement
.m_aDockedData
.m_aPos
.X
= nRowCol
;
2841 rTrackingRect
.Move( nOffsetX
, nOffsetY
);
2842 rTrackingRect
.SetSize( aTrackingRect
.GetSize() );
2848 // Docking outside of our docking window area =>
2849 // Users want to dock before/after first/last docked element or to an empty docking area
2850 if ( !bOpOutsideOfDockingArea
)
2853 // set correct size for docking
2854 implts_setTrackingRect( eDockedArea
, rMousePos
, aTrackingRect
);
2855 rTrackingRect
= aTrackingRect
;
2857 if ( bHorizontalDockArea
)
2859 sal_Int32
nPosX( std::max( sal_Int32( rTrackingRect
.Left()), sal_Int32( 0 )));
2860 if (( nPosX
+ rTrackingRect
.getOpenWidth()) > aContainerWinSize
.Width() )
2861 nPosX
= std::min( nPosX
,
2862 std::max( sal_Int32( aContainerWinSize
.Width() - rTrackingRect
.getOpenWidth() ),
2865 sal_Int32 nSize
= std::min( aContainerWinSize
.Width(), rTrackingRect
.getOpenWidth() );
2866 sal_Int32 nDockHeight
= std::max( static_cast<sal_Int32
>(aDockingAreaRect
.getOpenHeight()), sal_Int32( 0 ));
2867 if ( nDockHeight
== 0 )
2869 sal_Int32
nPosY( std::max( aDockingAreaRect
.Top(), aDockingAreaRect
.Bottom() ));
2870 if ( eDockedArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
)
2871 nPosY
-= rTrackingRect
.getOpenHeight();
2872 rTrackingRect
.SetPos( Point( nPosX
, nPosY
));
2873 rUIElement
.m_aDockedData
.m_aPos
.Y
= 0;
2875 else if ( rMousePos
.Y() < ( aDockingAreaRect
.Top() + ( nDockHeight
/ 2 )))
2877 rTrackingRect
.SetPos( Point( nPosX
, aDockingAreaRect
.Top() - rTrackingRect
.getOpenHeight() ));
2878 if ( eDockedArea
== ui::DockingArea_DOCKINGAREA_TOP
)
2879 rUIElement
.m_aDockedData
.m_aPos
.Y
= 0;
2881 rUIElement
.m_aDockedData
.m_aPos
.Y
= ( nMaxRowCol
>= 0 ) ? nMaxRowCol
+1 : 0;
2882 rDockingOperation
= DOCKOP_BEFORE_COLROW
;
2886 rTrackingRect
.SetPos( Point( nPosX
, aDockingAreaRect
.Bottom() ));
2887 if ( eDockedArea
== ui::DockingArea_DOCKINGAREA_TOP
)
2888 rUIElement
.m_aDockedData
.m_aPos
.Y
= ( nMaxRowCol
>= 0 ) ? nMaxRowCol
+1 : 0;
2890 rUIElement
.m_aDockedData
.m_aPos
.Y
= 0;
2891 rDockingOperation
= DOCKOP_AFTER_COLROW
;
2893 rTrackingRect
.setWidth( nSize
);
2896 SolarMutexGuard aGuard
;
2897 nPosX
= pDockingAreaWindow
->ScreenToOutputPixel(
2898 pContainerWindow
->OutputToScreenPixel( rTrackingRect
.TopLeft() )).X();
2900 rUIElement
.m_aDockedData
.m_aPos
.X
= nPosX
;
2904 sal_Int32 nMaxDockingAreaHeight
= std::max
<sal_Int32
>( 0, nMaxLeftRightDockAreaSize
);
2905 sal_Int32
nPosY( std::max
<sal_Int32
>( aTrackingRect
.Top(), nTopDockingAreaSize
));
2906 if (( nPosY
+ aTrackingRect
.getOpenHeight()) > ( nTopDockingAreaSize
+ nMaxDockingAreaHeight
))
2907 nPosY
= std::min( nPosY
,
2908 std::max
<sal_Int32
>( nTopDockingAreaSize
+ ( nMaxDockingAreaHeight
- aTrackingRect
.getOpenHeight() ),
2909 nTopDockingAreaSize
));
2911 sal_Int32 nSize
= std::min( nMaxDockingAreaHeight
, static_cast<sal_Int32
>(aTrackingRect
.getOpenHeight()) );
2912 sal_Int32 nDockWidth
= std::max( static_cast<sal_Int32
>(aDockingAreaRect
.getOpenWidth()), sal_Int32( 0 ));
2913 if ( nDockWidth
== 0 )
2915 sal_Int32
nPosX( std::max( aDockingAreaRect
.Left(), aDockingAreaRect
.Right() ));
2916 if ( eDockedArea
== ui::DockingArea_DOCKINGAREA_RIGHT
)
2917 nPosX
-= rTrackingRect
.getOpenWidth();
2918 rTrackingRect
.SetPos( Point( nPosX
, nPosY
));
2919 rUIElement
.m_aDockedData
.m_aPos
.X
= 0;
2921 else if ( rMousePos
.X() < ( aDockingAreaRect
.Left() + ( nDockWidth
/ 2 )))
2923 rTrackingRect
.SetPos( Point( aDockingAreaRect
.Left() - rTrackingRect
.getOpenWidth(), nPosY
));
2924 if ( eDockedArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
2925 rUIElement
.m_aDockedData
.m_aPos
.X
= 0;
2927 rUIElement
.m_aDockedData
.m_aPos
.X
= ( nMaxRowCol
>= 0 ) ? nMaxRowCol
+1 : 0;
2928 rDockingOperation
= DOCKOP_BEFORE_COLROW
;
2932 rTrackingRect
.SetPos( Point( aDockingAreaRect
.Right(), nPosY
));
2933 if ( eDockedArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
2934 rUIElement
.m_aDockedData
.m_aPos
.X
= ( nMaxRowCol
>= 0 ) ? nMaxRowCol
+1 : 0;
2936 rUIElement
.m_aDockedData
.m_aPos
.X
= 0;
2937 rDockingOperation
= DOCKOP_AFTER_COLROW
;
2939 rTrackingRect
.setHeight( nSize
);
2942 SolarMutexGuard aGuard
;
2943 nPosY
= pDockingAreaWindow
->ScreenToOutputPixel(
2944 pContainerWindow
->OutputToScreenPixel( rTrackingRect
.TopLeft() )).Y();
2946 rUIElement
.m_aDockedData
.m_aPos
.Y
= nPosY
;
2950 framework::ToolbarLayoutManager::DockingOperation
ToolbarLayoutManager::implts_determineDockingOperation(
2951 ui::DockingArea DockingArea
,
2952 const ::tools::Rectangle
& rRowColRect
,
2953 const Point
& rMousePos
)
2955 constexpr sal_Int32 nHorzVerticalRegionSize
= 6;
2956 constexpr sal_Int32 nHorzVerticalMoveRegion
= 4;
2958 if ( rRowColRect
.Contains( rMousePos
))
2960 if ( isHorizontalDockingArea( DockingArea
))
2962 sal_Int32 nRegion
= rRowColRect
.getOpenHeight() / nHorzVerticalRegionSize
;
2963 sal_Int32 nPosY
= rRowColRect
.Top() + nRegion
;
2965 if ( rMousePos
.Y() < nPosY
)
2966 return ( DockingArea
== ui::DockingArea_DOCKINGAREA_TOP
) ? DOCKOP_BEFORE_COLROW
: DOCKOP_AFTER_COLROW
;
2967 else if ( rMousePos
.Y() < ( nPosY
+ nRegion
*nHorzVerticalMoveRegion
))
2968 return DOCKOP_ON_COLROW
;
2970 return ( DockingArea
== ui::DockingArea_DOCKINGAREA_TOP
) ? DOCKOP_AFTER_COLROW
: DOCKOP_BEFORE_COLROW
;
2974 sal_Int32 nRegion
= rRowColRect
.getOpenWidth() / nHorzVerticalRegionSize
;
2975 sal_Int32 nPosX
= rRowColRect
.Left() + nRegion
;
2977 if ( rMousePos
.X() < nPosX
)
2978 return ( DockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
) ? DOCKOP_BEFORE_COLROW
: DOCKOP_AFTER_COLROW
;
2979 else if ( rMousePos
.X() < ( nPosX
+ nRegion
*nHorzVerticalMoveRegion
))
2980 return DOCKOP_ON_COLROW
;
2982 return ( DockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
) ? DOCKOP_AFTER_COLROW
: DOCKOP_BEFORE_COLROW
;
2986 return DOCKOP_ON_COLROW
;
2989 ::tools::Rectangle
ToolbarLayoutManager::implts_calcTrackingAndElementRect(
2990 ui::DockingArea eDockingArea
,
2992 UIElement
& rUIElement
,
2993 const ::tools::Rectangle
& rTrackingRect
,
2994 const ::tools::Rectangle
& rRowColumnRect
,
2995 const ::Size
& rContainerWinSize
)
2997 SolarMutexResettableGuard aReadGuard
;
2998 ::tools::Rectangle
aDockingAreaOffsets( m_aDockingAreaOffsets
);
3001 bool bHorizontalDockArea( isHorizontalDockingArea( eDockingArea
));
3003 sal_Int32
nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() );
3004 sal_Int32
nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() );
3006 sal_Int32 nMaxLeftRightDockAreaSize
= rContainerWinSize
.Height() -
3007 nTopDockingAreaSize
-
3008 nBottomDockingAreaSize
-
3009 aDockingAreaOffsets
.Top() -
3010 aDockingAreaOffsets
.Bottom();
3012 ::tools::Rectangle
aTrackingRect( rTrackingRect
);
3013 if ( bHorizontalDockArea
)
3015 sal_Int32
nPosX( std::max( sal_Int32( rTrackingRect
.Left()), sal_Int32( 0 )));
3016 if (( nPosX
+ rTrackingRect
.getOpenWidth()) > rContainerWinSize
.Width() )
3017 nPosX
= std::min( nPosX
,
3018 std::max( sal_Int32( rContainerWinSize
.Width() - rTrackingRect
.getOpenWidth() ),
3021 sal_Int32 nSize
= std::min( rContainerWinSize
.Width(), rTrackingRect
.getOpenWidth() );
3023 aTrackingRect
.SetPos( ::Point( nPosX
, rRowColumnRect
.Top() ));
3024 aTrackingRect
.setWidth( nSize
);
3025 aTrackingRect
.setHeight( rRowColumnRect
.getOpenHeight() );
3027 // Set virtual position
3028 rUIElement
.m_aDockedData
.m_aPos
.X
= nPosX
;
3029 rUIElement
.m_aDockedData
.m_aPos
.Y
= nRowCol
;
3033 sal_Int32 nMaxDockingAreaHeight
= std::max
<sal_Int32
>( 0, nMaxLeftRightDockAreaSize
);
3035 sal_Int32
nPosY( std::max
<sal_Int32
>( aTrackingRect
.Top(), nTopDockingAreaSize
));
3036 if (( nPosY
+ aTrackingRect
.getOpenHeight()) > ( nTopDockingAreaSize
+ nMaxDockingAreaHeight
))
3037 nPosY
= std::min( nPosY
,
3038 std::max
<sal_Int32
>( nTopDockingAreaSize
+ ( nMaxDockingAreaHeight
- aTrackingRect
.getOpenHeight() ),
3039 nTopDockingAreaSize
));
3041 sal_Int32 nSize
= std::min( nMaxDockingAreaHeight
, static_cast<sal_Int32
>(aTrackingRect
.getOpenHeight()) );
3043 aTrackingRect
.SetPos( ::Point( rRowColumnRect
.Left(), nPosY
));
3044 aTrackingRect
.setWidth( rRowColumnRect
.getOpenWidth() );
3045 aTrackingRect
.setHeight( nSize
);
3048 uno::Reference
< awt::XWindow
> xDockingAreaWindow( m_xDockAreaWindows
[static_cast<int>(eDockingArea
)] );
3049 uno::Reference
< awt::XWindow2
> xContainerWindow( m_xContainerWindow
);
3052 sal_Int32
nDockPosY( 0 );
3054 SolarMutexGuard aGuard
;
3055 vcl::Window
* pDockingAreaWindow
= VCLUnoHelper::GetWindow( xDockingAreaWindow
);
3056 VclPtr
<vcl::Window
> pContainerWindow
= VCLUnoHelper::GetWindow( xContainerWindow
);
3057 nDockPosY
= pDockingAreaWindow
->ScreenToOutputPixel( pContainerWindow
->OutputToScreenPixel( ::Point( 0, nPosY
))).Y();
3060 // Set virtual position
3061 rUIElement
.m_aDockedData
.m_aPos
.X
= nRowCol
;
3062 rUIElement
.m_aDockedData
.m_aPos
.Y
= nDockPosY
;
3065 return aTrackingRect
;
3068 void ToolbarLayoutManager::implts_setTrackingRect( ui::DockingArea eDockingArea
, const ::Point
& rMousePos
, ::tools::Rectangle
& rTrackingRect
)
3070 ::Point
aPoint( rTrackingRect
.TopLeft());
3071 if ( isHorizontalDockingArea( eDockingArea
))
3072 aPoint
.setX( rMousePos
.X() );
3074 aPoint
.setY( rMousePos
.Y() );
3075 rTrackingRect
.SetPos( aPoint
);
3078 void ToolbarLayoutManager::implts_renumberRowColumnData(
3079 ui::DockingArea eDockingArea
,
3080 const UIElement
& rUIElement
)
3082 SolarMutexClearableGuard aReadLock
;
3083 uno::Reference
< container::XNameAccess
> xPersistentWindowState( m_xPersistentWindowState
);
3086 bool bHorzDockingArea( isHorizontalDockingArea( eDockingArea
));
3087 sal_Int32
nRowCol( bHorzDockingArea
? rUIElement
.m_aDockedData
.m_aPos
.Y
: rUIElement
.m_aDockedData
.m_aPos
.X
);
3089 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3091 SolarMutexGuard aWriteLock
;
3092 for (auto& elem
: m_aUIElements
)
3094 if ((elem
.m_aDockedData
.m_nDockedArea
== eDockingArea
)
3095 && (elem
.m_aName
!= rUIElement
.m_aName
))
3097 // Don't change toolbars without a valid docking position!
3098 if (isDefaultPos(elem
.m_aDockedData
.m_aPos
))
3101 sal_Int32 nWindowRowCol
3102 = bHorzDockingArea
? elem
.m_aDockedData
.m_aPos
.Y
: elem
.m_aDockedData
.m_aPos
.X
;
3103 if (nWindowRowCol
>= nRowCol
)
3105 if (bHorzDockingArea
)
3106 elem
.m_aDockedData
.m_aPos
.Y
+= 1;
3108 elem
.m_aDockedData
.m_aPos
.X
+= 1;
3113 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3115 // We have to change the persistent window state part
3116 if ( !xPersistentWindowState
.is() )
3121 const uno::Sequence
< OUString
> aWindowElements
= xPersistentWindowState
->getElementNames();
3122 for ( OUString
const & rWindowElementName
: aWindowElements
)
3124 if ( rUIElement
.m_aName
!= rWindowElementName
)
3128 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
;
3129 awt::Point aDockedPos
;
3130 ui::DockingArea
nDockedArea( ui::DockingArea_DOCKINGAREA_DEFAULT
);
3132 xPersistentWindowState
->getByName( rWindowElementName
) >>= aPropValueSeq
;
3133 for ( beans::PropertyValue
const & rProp
: std::as_const(aPropValueSeq
) )
3135 if ( rProp
.Name
== WINDOWSTATE_PROPERTY_DOCKINGAREA
)
3136 rProp
.Value
>>= nDockedArea
;
3137 else if ( rProp
.Name
== WINDOWSTATE_PROPERTY_DOCKPOS
)
3138 rProp
.Value
>>= aDockedPos
;
3141 // Don't change toolbars without a valid docking position!
3142 if ( isDefaultPos( aDockedPos
))
3145 sal_Int32 nWindowRowCol
= bHorzDockingArea
? aDockedPos
.Y
: aDockedPos
.X
;
3146 if (( nDockedArea
== eDockingArea
) && ( nWindowRowCol
>= nRowCol
))
3148 if ( bHorzDockingArea
)
3153 uno::Reference
< container::XNameReplace
> xReplace( xPersistentWindowState
, uno::UNO_QUERY
);
3154 xReplace
->replaceByName( rWindowElementName
, css::uno::Any( aPropValueSeq
));
3157 catch (const uno::Exception
&)
3163 catch (const uno::Exception
&)
3170 void SAL_CALL
ToolbarLayoutManager::windowResized( const awt::WindowEvent
& aEvent
)
3172 SolarMutexClearableGuard aWriteLock
;
3173 bool bLocked( m_bDockingInProgress
);
3174 bool bLayoutInProgress( m_bLayoutInProgress
);
3177 // Do not do anything if we are in the middle of a docking process. This would interfere all other
3178 // operations. We will store the new position and size in the docking handlers.
3179 // Do not do anything if we are in the middle of our layouting process. We will adapt the position
3180 // and size of the user interface elements.
3181 if ( bLocked
|| bLayoutInProgress
)
3184 bool bNotify( false );
3185 uno::Reference
< awt::XWindow
> xWindow( aEvent
.Source
, uno::UNO_QUERY
);
3187 UIElement aUIElement
= implts_findToolbar( aEvent
.Source
);
3188 if ( aUIElement
.m_xUIElement
.is() )
3190 if ( aUIElement
.m_bFloating
)
3192 uno::Reference
< awt::XWindow2
> xWindow2( xWindow
, uno::UNO_QUERY
);
3196 awt::Rectangle aPos
= xWindow2
->getPosSize();
3197 awt::Size aSize
= xWindow2
->getOutputSize(); // always use output size for consistency
3198 bool bVisible
= xWindow2
->isVisible();
3200 // update element data
3201 aUIElement
.m_aFloatingData
.m_aPos
= awt::Point(aPos
.X
, aPos
.Y
);
3202 aUIElement
.m_aFloatingData
.m_aSize
= aSize
;
3203 aUIElement
.m_bVisible
= bVisible
;
3206 implts_writeWindowStateData( aUIElement
);
3210 implts_setLayoutDirty();
3216 m_pParentLayouter
->requestLayout();
3219 void SAL_CALL
ToolbarLayoutManager::windowMoved( const awt::WindowEvent
& /*aEvent*/ )
3223 void SAL_CALL
ToolbarLayoutManager::windowShown( const lang::EventObject
& /*aEvent*/ )
3227 void SAL_CALL
ToolbarLayoutManager::windowHidden( const lang::EventObject
& /*aEvent*/ )
3231 // XDockableWindowListener
3233 void SAL_CALL
ToolbarLayoutManager::startDocking( const awt::DockingEvent
& e
)
3235 bool bWinFound( false );
3237 SolarMutexClearableGuard aReadGuard
;
3238 uno::Reference
< awt::XWindow2
> xWindow( e
.Source
, uno::UNO_QUERY
);
3241 UIElement aUIElement
= implts_findToolbar( e
.Source
);
3243 if ( aUIElement
.m_xUIElement
.is() && xWindow
.is() )
3246 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
3247 if ( xDockWindow
->isFloating() )
3249 awt::Rectangle aPos
= xWindow
->getPosSize();
3250 awt::Size aSize
= xWindow
->getOutputSize();
3252 aUIElement
.m_aFloatingData
.m_aPos
= awt::Point(aPos
.X
, aPos
.Y
);
3253 aUIElement
.m_aFloatingData
.m_aSize
= aSize
;
3255 SolarMutexGuard aGuard
;
3257 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( xWindow
);
3258 if ( pWindow
&& pWindow
->GetType() == WindowType::TOOLBOX
)
3260 ToolBox
* pToolBox
= static_cast<ToolBox
*>(pWindow
.get());
3261 aUIElement
.m_aFloatingData
.m_nLines
= pToolBox
->GetFloatingLines();
3262 aUIElement
.m_aFloatingData
.m_bIsHorizontal
= isToolboxHorizontalAligned( pToolBox
);
3268 m_bDockingInProgress
= bWinFound
;
3269 m_aDockUIElement
= aUIElement
;
3270 m_aDockUIElement
.m_bUserActive
= true;
3273 awt::DockingData SAL_CALL
ToolbarLayoutManager::docking( const awt::DockingEvent
& e
)
3275 constexpr sal_Int32 MAGNETIC_DISTANCE_UNDOCK
= 25;
3276 constexpr sal_Int32 MAGNETIC_DISTANCE_DOCK
= 20;
3278 SolarMutexClearableGuard aReadLock
;
3279 awt::DockingData aDockingData
;
3280 uno::Reference
< awt::XDockableWindow
> xDockWindow( e
.Source
, uno::UNO_QUERY
);
3281 uno::Reference
< awt::XWindow
> xWindow( e
.Source
, uno::UNO_QUERY
);
3282 uno::Reference
< awt::XWindow
> xTopDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_TOP
)] );
3283 uno::Reference
< awt::XWindow
> xLeftDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_LEFT
)] );
3284 uno::Reference
< awt::XWindow
> xRightDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_RIGHT
)] );
3285 uno::Reference
< awt::XWindow
> xBottomDockingWindow( m_xDockAreaWindows
[int(ui::DockingArea_DOCKINGAREA_BOTTOM
)] );
3286 uno::Reference
< awt::XWindow2
> xContainerWindow( m_xContainerWindow
);
3287 UIElement
aUIDockingElement( m_aDockUIElement
);
3289 bool bDockingInProgress( m_bDockingInProgress
);
3292 if ( bDockingInProgress
)
3293 aDockingData
.TrackingRectangle
= e
.TrackingRectangle
;
3295 if ( bDockingInProgress
&& xDockWindow
.is() && xWindow
.is() )
3299 SolarMutexGuard aGuard
;
3301 DockingOperation
eDockingOperation( DOCKOP_ON_COLROW
);
3302 ui::DockingArea
eDockingArea( ui::DockingArea(-1) ); // none
3303 sal_Int32
nMagneticZone( aUIDockingElement
.m_bFloating
? MAGNETIC_DISTANCE_DOCK
: MAGNETIC_DISTANCE_UNDOCK
);
3304 ::tools::Rectangle
aTrackingRect( e
.TrackingRectangle
.X
, e
.TrackingRectangle
.Y
,
3305 ( e
.TrackingRectangle
.X
+ e
.TrackingRectangle
.Width
),
3306 ( e
.TrackingRectangle
.Y
+ e
.TrackingRectangle
.Height
));
3308 awt::Rectangle aTmpRect
= xTopDockingWindow
->getPosSize();
3309 ::tools::Rectangle
aTopDockRect( aTmpRect
.X
, aTmpRect
.Y
, aTmpRect
.Width
, aTmpRect
.Height
);
3310 ::tools::Rectangle
aHotZoneTopDockRect( implts_calcHotZoneRect( aTopDockRect
, nMagneticZone
));
3312 aTmpRect
= xBottomDockingWindow
->getPosSize();
3313 ::tools::Rectangle
aBottomDockRect( aTmpRect
.X
, aTmpRect
.Y
, ( aTmpRect
.X
+ aTmpRect
.Width
), ( aTmpRect
.Y
+ aTmpRect
.Height
));
3314 ::tools::Rectangle
aHotZoneBottomDockRect( implts_calcHotZoneRect( aBottomDockRect
, nMagneticZone
));
3316 aTmpRect
= xLeftDockingWindow
->getPosSize();
3317 ::tools::Rectangle
aLeftDockRect( aTmpRect
.X
, aTmpRect
.Y
, ( aTmpRect
.X
+ aTmpRect
.Width
), ( aTmpRect
.Y
+ aTmpRect
.Height
));
3318 ::tools::Rectangle
aHotZoneLeftDockRect( implts_calcHotZoneRect( aLeftDockRect
, nMagneticZone
));
3320 aTmpRect
= xRightDockingWindow
->getPosSize();
3321 ::tools::Rectangle
aRightDockRect( aTmpRect
.X
, aTmpRect
.Y
, ( aTmpRect
.X
+ aTmpRect
.Width
), ( aTmpRect
.Y
+ aTmpRect
.Height
));
3322 ::tools::Rectangle
aHotZoneRightDockRect( implts_calcHotZoneRect( aRightDockRect
, nMagneticZone
));
3324 VclPtr
<vcl::Window
> pContainerWindow( VCLUnoHelper::GetWindow( xContainerWindow
) );
3325 ::Point
aMousePos( pContainerWindow
->ScreenToOutputPixel( ::Point( e
.MousePos
.X
, e
.MousePos
.Y
)));
3327 if ( aHotZoneTopDockRect
.Contains( aMousePos
))
3328 eDockingArea
= ui::DockingArea_DOCKINGAREA_TOP
;
3329 else if ( aHotZoneBottomDockRect
.Contains( aMousePos
))
3330 eDockingArea
= ui::DockingArea_DOCKINGAREA_BOTTOM
;
3331 else if ( aHotZoneLeftDockRect
.Contains( aMousePos
))
3332 eDockingArea
= ui::DockingArea_DOCKINGAREA_LEFT
;
3333 else if ( aHotZoneRightDockRect
.Contains( aMousePos
))
3334 eDockingArea
= ui::DockingArea_DOCKINGAREA_RIGHT
;
3336 // Higher priority for movements inside the real docking area
3337 if ( aTopDockRect
.Contains( aMousePos
))
3338 eDockingArea
= ui::DockingArea_DOCKINGAREA_TOP
;
3339 else if ( aBottomDockRect
.Contains( aMousePos
))
3340 eDockingArea
= ui::DockingArea_DOCKINGAREA_BOTTOM
;
3341 else if ( aLeftDockRect
.Contains( aMousePos
))
3342 eDockingArea
= ui::DockingArea_DOCKINGAREA_LEFT
;
3343 else if ( aRightDockRect
.Contains( aMousePos
))
3344 eDockingArea
= ui::DockingArea_DOCKINGAREA_RIGHT
;
3346 // Determine if we have a toolbar and set alignment according to the docking area!
3347 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( xWindow
);
3348 ToolBox
* pToolBox
= nullptr;
3349 if ( pWindow
&& pWindow
->GetType() == WindowType::TOOLBOX
)
3350 pToolBox
= static_cast<ToolBox
*>(pWindow
.get());
3352 if ( eDockingArea
!= ui::DockingArea(-1) )
3354 if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
3356 aUIDockingElement
.m_aDockedData
.m_nDockedArea
= ui::DockingArea_DOCKINGAREA_TOP
;
3357 aUIDockingElement
.m_bFloating
= false;
3359 else if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
)
3361 aUIDockingElement
.m_aDockedData
.m_nDockedArea
= ui::DockingArea_DOCKINGAREA_BOTTOM
;
3362 aUIDockingElement
.m_bFloating
= false;
3364 else if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
3366 aUIDockingElement
.m_aDockedData
.m_nDockedArea
= ui::DockingArea_DOCKINGAREA_LEFT
;
3367 aUIDockingElement
.m_bFloating
= false;
3369 else if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_RIGHT
)
3371 aUIDockingElement
.m_aDockedData
.m_nDockedArea
= ui::DockingArea_DOCKINGAREA_RIGHT
;
3372 aUIDockingElement
.m_bFloating
= false;
3375 ::Point aOutputPos
= pContainerWindow
->ScreenToOutputPixel( aTrackingRect
.TopLeft() );
3376 aTrackingRect
.SetPos( aOutputPos
);
3378 ::tools::Rectangle
aNewDockingRect( aTrackingRect
);
3380 implts_calcDockingPosSize( aUIDockingElement
, eDockingOperation
, aNewDockingRect
, aMousePos
);
3382 ::Point aScreenPos
= pContainerWindow
->OutputToScreenPixel( aNewDockingRect
.TopLeft() );
3383 aDockingData
.TrackingRectangle
= awt::Rectangle( aScreenPos
.X(), aScreenPos
.Y(),
3384 aNewDockingRect
.getOpenWidth(), aNewDockingRect
.getOpenHeight() );
3388 bool bIsHorizontal
= isToolboxHorizontalAligned( pToolBox
);
3389 awt::Size aFloatSize
= aUIDockingElement
.m_aFloatingData
.m_aSize
;
3390 if ( aFloatSize
.Width
> 0 && aFloatSize
.Height
> 0 )
3392 aUIDockingElement
.m_aFloatingData
.m_aPos
= AWTPoint(pContainerWindow
->ScreenToOutputPixel(VCLPoint(e
.MousePos
)));
3393 aDockingData
.TrackingRectangle
.Height
= aFloatSize
.Height
;
3394 aDockingData
.TrackingRectangle
.Width
= aFloatSize
.Width
;
3398 aFloatSize
= AWTSize(pToolBox
->CalcWindowSizePixel());
3399 if ( !bIsHorizontal
)
3401 // Floating toolbars are always horizontal aligned! We have to swap
3402 // width/height if we have a vertical aligned toolbar.
3403 sal_Int32 nTemp
= aFloatSize
.Height
;
3404 aFloatSize
.Height
= aFloatSize
.Width
;
3405 aFloatSize
.Width
= nTemp
;
3408 aDockingData
.TrackingRectangle
.Height
= aFloatSize
.Height
;
3409 aDockingData
.TrackingRectangle
.Width
= aFloatSize
.Width
;
3411 // For the first time we don't have any data about the floating size of a toolbar.
3412 // We calculate it and store it for later use.
3413 aUIDockingElement
.m_aFloatingData
.m_aPos
= AWTPoint(pContainerWindow
->ScreenToOutputPixel(VCLPoint(e
.MousePos
)));
3414 aUIDockingElement
.m_aFloatingData
.m_aSize
= aFloatSize
;
3415 aUIDockingElement
.m_aFloatingData
.m_nLines
= pToolBox
->GetFloatingLines();
3416 aUIDockingElement
.m_aFloatingData
.m_bIsHorizontal
= isToolboxHorizontalAligned( pToolBox
);
3418 aDockingData
.TrackingRectangle
.X
= e
.MousePos
.X
;
3419 aDockingData
.TrackingRectangle
.Y
= e
.MousePos
.Y
;
3422 aDockingData
.bFloating
= ( eDockingArea
== ui::DockingArea(-1) );
3424 // Write current data to the member docking progress data
3426 m_aDockUIElement
.m_bFloating
= aDockingData
.bFloating
;
3427 if ( !aDockingData
.bFloating
)
3429 m_aDockUIElement
.m_aDockedData
= aUIDockingElement
.m_aDockedData
;
3431 m_eDockOperation
= eDockingOperation
;
3434 m_aDockUIElement
.m_aFloatingData
= aUIDockingElement
.m_aFloatingData
;
3436 catch (const uno::Exception
&)
3441 return aDockingData
;
3444 void SAL_CALL
ToolbarLayoutManager::endDocking( const awt::EndDockingEvent
& e
)
3449 bool bDockingInProgress( false );
3450 bool bStartDockFloated( false );
3451 bool bFloating( false );
3452 UIElement aUIDockingElement
;
3454 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3455 SolarMutexResettableGuard aWriteLock
;
3456 bDockingInProgress
= m_bDockingInProgress
;
3457 aUIDockingElement
= m_aDockUIElement
;
3458 bFloating
= aUIDockingElement
.m_bFloating
;
3460 UIElement
& rUIElement
= impl_findToolbar( aUIDockingElement
.m_aName
);
3461 if ( rUIElement
.m_aName
== aUIDockingElement
.m_aName
)
3463 if ( aUIDockingElement
.m_bFloating
)
3465 // Write last position into position data
3466 uno::Reference
< awt::XWindow
> xWindow( aUIDockingElement
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
3467 rUIElement
.m_aFloatingData
= aUIDockingElement
.m_aFloatingData
;
3468 awt::Rectangle aTmpRect
= xWindow
->getPosSize();
3469 rUIElement
.m_aFloatingData
.m_aPos
= awt::Point(aTmpRect
.X
, aTmpRect
.Y
);
3470 // make changes also for our local data as we use it to make data persistent
3471 aUIDockingElement
.m_aFloatingData
= rUIElement
.m_aFloatingData
;
3475 rUIElement
.m_aDockedData
= aUIDockingElement
.m_aDockedData
;
3476 rUIElement
.m_aFloatingData
.m_aSize
= aUIDockingElement
.m_aFloatingData
.m_aSize
;
3478 if ( m_eDockOperation
!= DOCKOP_ON_COLROW
)
3480 // we have to renumber our row/column data to insert a new row/column
3481 implts_renumberRowColumnData(aUIDockingElement
.m_aDockedData
.m_nDockedArea
, aUIDockingElement
);
3485 bStartDockFloated
= rUIElement
.m_bFloating
;
3486 rUIElement
.m_bFloating
= m_aDockUIElement
.m_bFloating
;
3487 rUIElement
.m_bUserActive
= true;
3490 // reset member for next docking operation
3491 m_aDockUIElement
.m_xUIElement
.clear();
3492 m_eDockOperation
= DOCKOP_ON_COLROW
;
3494 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3496 implts_writeWindowStateData( aUIDockingElement
);
3498 if ( bDockingInProgress
)
3500 SolarMutexGuard aGuard
;
3501 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( uno::Reference
< awt::XWindow
>( e
.Source
, uno::UNO_QUERY
));
3502 ToolBox
* pToolBox
= nullptr;
3503 if ( pWindow
&& pWindow
->GetType() == WindowType::TOOLBOX
)
3504 pToolBox
= static_cast<ToolBox
*>(pWindow
.get());
3510 if ( aUIDockingElement
.m_aFloatingData
.m_bIsHorizontal
)
3511 pToolBox
->SetAlign();
3513 pToolBox
->SetAlign( WindowAlign::Left
);
3519 pToolBox
->SetAlign( ImplConvertAlignment( aUIDockingElement
.m_aDockedData
.m_nDockedArea
) );
3521 // Docked toolbars have always one line
3522 aSize
= pToolBox
->CalcWindowSizePixel( 1 );
3524 // Lock layouting updates as our listener would be called due to SetSizePixel
3525 pToolBox
->SetOutputSizePixel( aSize
);
3530 implts_sortUIElements();
3533 m_bDockingInProgress
= false;
3534 m_bLayoutDirty
= !bStartDockFloated
|| !bFloating
;
3535 bool bNotify
= m_bLayoutDirty
;
3539 m_pParentLayouter
->requestLayout();
3542 sal_Bool SAL_CALL
ToolbarLayoutManager::prepareToggleFloatingMode( const lang::EventObject
& e
)
3544 SolarMutexClearableGuard aReadLock
;
3545 bool bDockingInProgress
= m_bDockingInProgress
;
3548 UIElement aUIDockingElement
= implts_findToolbar( e
.Source
);
3549 bool bWinFound( !aUIDockingElement
.m_aName
.isEmpty() );
3550 uno::Reference
< awt::XWindow
> xWindow( e
.Source
, uno::UNO_QUERY
);
3552 if ( !bWinFound
|| !xWindow
.is() )
3555 if ( bDockingInProgress
)
3558 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
3559 if ( !xDockWindow
->isFloating() )
3563 SolarMutexGuard aGuard
;
3564 VclPtr
<vcl::Window
> pWindow
= VCLUnoHelper::GetWindow( xWindow
);
3565 if ( pWindow
&& pWindow
->GetType() == WindowType::TOOLBOX
)
3567 ToolBox
* pToolBox
= static_cast< ToolBox
*>( pWindow
.get() );
3568 aUIDockingElement
.m_aFloatingData
.m_aPos
= AWTPoint(pToolBox
->GetPosPixel());
3569 aUIDockingElement
.m_aFloatingData
.m_aSize
= AWTSize(pToolBox
->GetOutputSizePixel());
3570 aUIDockingElement
.m_aFloatingData
.m_nLines
= pToolBox
->GetFloatingLines();
3571 aUIDockingElement
.m_aFloatingData
.m_bIsHorizontal
= isToolboxHorizontalAligned( pToolBox
);
3575 UIElement aUIElement
= implts_findToolbar( aUIDockingElement
.m_aName
);
3576 if ( aUIElement
.m_aName
== aUIDockingElement
.m_aName
)
3577 implts_setToolbar( aUIDockingElement
);
3582 void SAL_CALL
ToolbarLayoutManager::toggleFloatingMode( const lang::EventObject
& e
)
3584 UIElement aUIDockingElement
;
3586 SolarMutexResettableGuard aReadLock
;
3587 bool bDockingInProgress( m_bDockingInProgress
);
3588 if ( bDockingInProgress
)
3589 aUIDockingElement
= m_aDockUIElement
;
3592 vcl::Window
* pWindow( nullptr );
3593 ToolBox
* pToolBox( nullptr );
3594 uno::Reference
< awt::XWindow2
> xWindow
;
3597 SolarMutexGuard aGuard
;
3598 xWindow
.set( e
.Source
, uno::UNO_QUERY
);
3599 pWindow
= VCLUnoHelper::GetWindow( xWindow
);
3601 if ( pWindow
&& pWindow
->GetType() == WindowType::TOOLBOX
)
3602 pToolBox
= static_cast<ToolBox
*>(pWindow
);
3605 if ( !bDockingInProgress
)
3607 aUIDockingElement
= implts_findToolbar( e
.Source
);
3608 bool bWinFound
= !aUIDockingElement
.m_aName
.isEmpty();
3610 if ( bWinFound
&& xWindow
.is() )
3612 aUIDockingElement
.m_bFloating
= !aUIDockingElement
.m_bFloating
;
3613 aUIDockingElement
.m_bUserActive
= true;
3615 implts_setLayoutInProgress();
3616 if ( aUIDockingElement
.m_bFloating
)
3618 SolarMutexGuard aGuard
;
3621 pToolBox
->SetLineCount( aUIDockingElement
.m_aFloatingData
.m_nLines
);
3622 if ( aUIDockingElement
.m_aFloatingData
.m_bIsHorizontal
)
3623 pToolBox
->SetAlign();
3625 pToolBox
->SetAlign( WindowAlign::Left
);
3628 bool bUndefPos
= hasDefaultPosValue( aUIDockingElement
.m_aFloatingData
.m_aPos
);
3629 bool bSetSize
= !hasEmptySize( aUIDockingElement
.m_aFloatingData
.m_aSize
);
3632 aUIDockingElement
.m_aFloatingData
.m_aPos
= implts_findNextCascadeFloatingPos();
3637 aUIDockingElement
.m_aFloatingData
.m_aSize
= AWTSize(pToolBox
->CalcFloatingWindowSizePixel());
3639 aUIDockingElement
.m_aFloatingData
.m_aSize
= AWTSize(pWindow
->GetOutputSizePixel());
3642 xWindow
->setPosSize( aUIDockingElement
.m_aFloatingData
.m_aPos
.X
,
3643 aUIDockingElement
.m_aFloatingData
.m_aPos
.Y
,
3644 0, 0, awt::PosSize::POS
);
3645 xWindow
->setOutputSize(aUIDockingElement
.m_aFloatingData
.m_aSize
);
3649 if ( isDefaultPos( aUIDockingElement
.m_aDockedData
.m_aPos
))
3651 // Docking on its default position without a preset position -
3652 // we have to find a good place for it.
3654 awt::Point aDockPos
;
3658 SolarMutexGuard aGuard
;
3660 aSize
= pToolBox
->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIDockingElement
.m_aDockedData
.m_nDockedArea
) );
3662 aSize
= pWindow
->GetSizePixel();
3665 implts_findNextDockingPos(aUIDockingElement
.m_aDockedData
.m_nDockedArea
, aSize
, aDockPos
, aPixelPos
);
3666 aUIDockingElement
.m_aDockedData
.m_aPos
= aDockPos
;
3669 SolarMutexGuard aGuard
;
3672 pToolBox
->SetAlign( ImplConvertAlignment( aUIDockingElement
.m_aDockedData
.m_nDockedArea
) );
3673 ::Size aSize
= pToolBox
->CalcWindowSizePixel( 1 );
3674 awt::Rectangle aRect
= xWindow
->getPosSize();
3675 xWindow
->setPosSize( aRect
.X
, aRect
.Y
, 0, 0, awt::PosSize::POS
);
3676 xWindow
->setOutputSize( AWTSize( aSize
) );
3680 implts_setLayoutInProgress( false );
3681 implts_setToolbar( aUIDockingElement
);
3682 implts_writeWindowStateData( aUIDockingElement
);
3683 implts_sortUIElements();
3684 implts_setLayoutDirty();
3687 LayoutManager
* pParentLayouter( m_pParentLayouter
);
3690 if ( pParentLayouter
)
3691 pParentLayouter
->requestLayout();
3696 SolarMutexGuard aGuard
;
3699 if ( aUIDockingElement
.m_bFloating
)
3701 if ( aUIDockingElement
.m_aFloatingData
.m_bIsHorizontal
)
3702 pToolBox
->SetAlign();
3704 pToolBox
->SetAlign( WindowAlign::Left
);
3707 pToolBox
->SetAlign( ImplConvertAlignment( aUIDockingElement
.m_aDockedData
.m_nDockedArea
) );
3712 void SAL_CALL
ToolbarLayoutManager::closed( const lang::EventObject
& e
)
3715 UIElement aUIElement
;
3718 SolarMutexGuard aWriteLock
;
3719 for (auto& elem
: m_aUIElements
)
3721 uno::Reference
<ui::XUIElement
> xUIElement(elem
.m_xUIElement
);
3722 if (xUIElement
.is())
3724 uno::Reference
<uno::XInterface
> xIfac(xUIElement
->getRealInterface(),
3726 if (xIfac
== e
.Source
)
3728 aName
= elem
.m_aName
;
3730 // user closes a toolbar =>
3731 // context sensitive toolbar: only destroy toolbar and store state.
3732 // non context sensitive toolbar: make it invisible, store state and destroy it.
3733 if (!elem
.m_bContextSensitive
)
3734 elem
.m_bVisible
= false;
3744 if ( aName
.isEmpty() )
3747 implts_writeWindowStateData( aUIElement
);
3748 destroyToolbar( aName
);
3750 SolarMutexClearableGuard aReadLock
;
3751 bool bLayoutDirty
= m_bLayoutDirty
;
3752 LayoutManager
* pParentLayouter( m_pParentLayouter
);
3755 if ( bLayoutDirty
&& pParentLayouter
)
3756 pParentLayouter
->requestLayout();
3759 void SAL_CALL
ToolbarLayoutManager::endPopupMode( const awt::EndPopupModeEvent
& /*e*/ )
3763 // XUIConfigurationListener
3765 void SAL_CALL
ToolbarLayoutManager::elementInserted( const ui::ConfigurationEvent
& rEvent
)
3767 UIElement aUIElement
= implts_findToolbar( rEvent
.ResourceURL
);
3769 uno::Reference
< ui::XUIElementSettings
> xElementSettings( aUIElement
.m_xUIElement
, uno::UNO_QUERY
);
3770 if ( xElementSettings
.is() )
3772 uno::Reference
< beans::XPropertySet
> xPropSet( xElementSettings
, uno::UNO_QUERY
);
3773 if ( xPropSet
.is() )
3775 if ( rEvent
.Source
== uno::Reference
< uno::XInterface
>( m_xDocCfgMgr
, uno::UNO_QUERY
))
3776 xPropSet
->setPropertyValue( "ConfigurationSource", css::uno::Any( m_xDocCfgMgr
));
3778 xElementSettings
->updateSettings();
3782 OUString aElementType
;
3783 OUString aElementName
;
3784 parseResourceURL( rEvent
.ResourceURL
, aElementType
, aElementName
);
3785 if ( aElementName
.indexOf( "custom_" ) != -1 )
3787 // custom toolbar must be directly created, shown and layouted!
3788 createToolbar( rEvent
.ResourceURL
);
3789 uno::Reference
< ui::XUIElement
> xUIElement
= getToolbar( rEvent
.ResourceURL
);
3790 if ( xUIElement
.is() )
3793 uno::Reference
< ui::XUIConfigurationManager
> xCfgMgr
;
3794 uno::Reference
< beans::XPropertySet
> xPropSet
;
3798 xCfgMgr
.set( rEvent
.Source
, uno::UNO_QUERY
);
3799 xPropSet
.set( xCfgMgr
->getSettings( rEvent
.ResourceURL
, false ), uno::UNO_QUERY
);
3801 if ( xPropSet
.is() )
3802 xPropSet
->getPropertyValue("UIName") >>= aUIName
;
3804 catch (const container::NoSuchElementException
&)
3807 catch (const beans::UnknownPropertyException
&)
3810 catch (const lang::WrappedTargetException
&)
3815 SolarMutexGuard aGuard
;
3816 vcl::Window
* pWindow
= getWindowFromXUIElement( xUIElement
);
3818 pWindow
->SetText( aUIName
);
3821 showToolbar( rEvent
.ResourceURL
);
3827 void SAL_CALL
ToolbarLayoutManager::elementRemoved( const ui::ConfigurationEvent
& rEvent
)
3829 SolarMutexClearableGuard aReadLock
;
3830 uno::Reference
< awt::XWindow
> xContainerWindow
= m_xContainerWindow
;
3831 uno::Reference
< ui::XUIConfigurationManager
> xModuleCfgMgr( m_xModuleCfgMgr
);
3832 uno::Reference
< ui::XUIConfigurationManager
> xDocCfgMgr( m_xDocCfgMgr
);
3835 UIElement aUIElement
= implts_findToolbar( rEvent
.ResourceURL
);
3836 uno::Reference
< ui::XUIElementSettings
> xElementSettings( aUIElement
.m_xUIElement
, uno::UNO_QUERY
);
3837 if ( !xElementSettings
.is() )
3840 bool bNoSettings( false );
3841 OUString
aConfigSourcePropName( "ConfigurationSource" );
3842 uno::Reference
< uno::XInterface
> xElementCfgMgr
;
3843 uno::Reference
< beans::XPropertySet
> xPropSet( xElementSettings
, uno::UNO_QUERY
);
3845 if ( xPropSet
.is() )
3846 xPropSet
->getPropertyValue( aConfigSourcePropName
) >>= xElementCfgMgr
;
3848 if ( !xElementCfgMgr
.is() )
3851 // Check if the same UI configuration manager has changed => check further
3852 if ( rEvent
.Source
== xElementCfgMgr
)
3854 // Same UI configuration manager where our element has its settings
3855 if ( rEvent
.Source
== uno::Reference
< uno::XInterface
>( xDocCfgMgr
, uno::UNO_QUERY
))
3857 // document settings removed
3858 if ( xModuleCfgMgr
->hasSettings( rEvent
.ResourceURL
))
3860 xPropSet
->setPropertyValue( aConfigSourcePropName
, css::uno::Any( xModuleCfgMgr
));
3861 xElementSettings
->updateSettings();
3869 // No settings anymore, element must be destroyed
3870 if ( xContainerWindow
.is() && bNoSettings
)
3871 destroyToolbar( rEvent
.ResourceURL
);
3874 void SAL_CALL
ToolbarLayoutManager::elementReplaced( const ui::ConfigurationEvent
& rEvent
)
3876 UIElement aUIElement
= implts_findToolbar( rEvent
.ResourceURL
);
3878 uno::Reference
< ui::XUIElementSettings
> xElementSettings( aUIElement
.m_xUIElement
, uno::UNO_QUERY
);
3879 if ( !xElementSettings
.is() )
3882 uno::Reference
< uno::XInterface
> xElementCfgMgr
;
3883 uno::Reference
< beans::XPropertySet
> xPropSet( xElementSettings
, uno::UNO_QUERY
);
3885 if ( xPropSet
.is() )
3886 xPropSet
->getPropertyValue( "ConfigurationSource" ) >>= xElementCfgMgr
;
3888 if ( !xElementCfgMgr
.is() )
3891 // Check if the same UI configuration manager has changed => update settings
3892 if ( rEvent
.Source
!= xElementCfgMgr
)
3895 xElementSettings
->updateSettings();
3897 SolarMutexClearableGuard aWriteLock
;
3898 bool bNotify
= !aUIElement
.m_bFloating
;
3899 m_bLayoutDirty
= bNotify
;
3900 LayoutManager
* pParentLayouter( m_pParentLayouter
);
3903 if ( bNotify
&& pParentLayouter
)
3904 pParentLayouter
->requestLayout();
3907 void ToolbarLayoutManager::updateToolbarsTips()
3911 for (auto& elem
: m_aUIElements
)
3913 uno::Reference
< ui::XUIElementSettings
> xElementSettings(elem
.m_xUIElement
, uno::UNO_QUERY
);
3914 if (!xElementSettings
.is())
3916 xElementSettings
->updateSettings();
3921 uno::Reference
< ui::XUIElement
> ToolbarLayoutManager::getToolbar( std::u16string_view aName
)
3923 return implts_findToolbar( aName
).m_xUIElement
;
3926 uno::Sequence
< uno::Reference
< ui::XUIElement
> > ToolbarLayoutManager::getToolbars()
3928 uno::Sequence
< uno::Reference
< ui::XUIElement
> > aSeq
;
3931 if ( !m_aUIElements
.empty() )
3933 sal_uInt32
nCount(0);
3934 for (auto const& elem
: m_aUIElements
)
3936 if ( elem
.m_xUIElement
.is() )
3939 aSeq
.realloc( nCount
);
3940 aSeq
.getArray()[nCount
-1] = elem
.m_xUIElement
;
3948 bool ToolbarLayoutManager::floatToolbar( std::u16string_view rResourceURL
)
3950 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
3951 if ( !aUIElement
.m_xUIElement
.is() )
3956 uno::Reference
< awt::XDockableWindow
> xDockWindow( aUIElement
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
3957 if ( xDockWindow
.is() && !xDockWindow
->isFloating() )
3959 aUIElement
.m_bFloating
= true;
3960 implts_writeWindowStateData( aUIElement
);
3961 xDockWindow
->setFloatingMode( true );
3963 implts_setLayoutDirty();
3964 implts_setToolbar( aUIElement
);
3968 catch (const lang::DisposedException
&)
3975 bool ToolbarLayoutManager::lockToolbar( std::u16string_view rResourceURL
)
3977 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
3978 if ( !aUIElement
.m_xUIElement
.is() )
3983 uno::Reference
< awt::XDockableWindow
> xDockWindow( aUIElement
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
3984 if ( xDockWindow
.is() && !xDockWindow
->isFloating() && !xDockWindow
->isLocked() )
3986 aUIElement
.m_aDockedData
.m_bLocked
= true;
3987 implts_writeWindowStateData( aUIElement
);
3988 xDockWindow
->lock();
3990 implts_setLayoutDirty();
3991 implts_setToolbar( aUIElement
);
3995 catch (const lang::DisposedException
&)
4002 bool ToolbarLayoutManager::unlockToolbar( std::u16string_view rResourceURL
)
4004 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
4005 if ( !aUIElement
.m_xUIElement
.is() )
4010 uno::Reference
< awt::XDockableWindow
> xDockWindow( aUIElement
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
4011 if ( xDockWindow
.is() && !xDockWindow
->isFloating() && xDockWindow
->isLocked() )
4013 aUIElement
.m_aDockedData
.m_bLocked
= false;
4014 implts_writeWindowStateData( aUIElement
);
4015 xDockWindow
->unlock();
4017 implts_setLayoutDirty();
4018 implts_setToolbar( aUIElement
);
4022 catch (const lang::DisposedException
&)
4029 bool ToolbarLayoutManager::isToolbarVisible( std::u16string_view rResourceURL
)
4031 uno::Reference
< awt::XWindow2
> xWindow2( implts_getXWindow( rResourceURL
), uno::UNO_QUERY
);
4032 return ( xWindow2
.is() && xWindow2
->isVisible() );
4035 bool ToolbarLayoutManager::isToolbarFloating( std::u16string_view rResourceURL
)
4037 uno::Reference
< awt::XDockableWindow
> xDockWindow( implts_getXWindow( rResourceURL
), uno::UNO_QUERY
);
4038 return ( xDockWindow
.is() && xDockWindow
->isFloating() );
4041 bool ToolbarLayoutManager::isToolbarDocked( std::u16string_view rResourceURL
)
4043 return !isToolbarFloating( rResourceURL
);
4046 bool ToolbarLayoutManager::isToolbarLocked( std::u16string_view rResourceURL
)
4048 uno::Reference
< awt::XDockableWindow
> xDockWindow( implts_getXWindow( rResourceURL
), uno::UNO_QUERY
);
4049 return ( xDockWindow
.is() && xDockWindow
->isLocked() );
4052 awt::Size
ToolbarLayoutManager::getToolbarSize( std::u16string_view rResourceURL
)
4054 vcl::Window
* pWindow
= implts_getWindow( rResourceURL
);
4056 SolarMutexGuard aGuard
;
4059 ::Size aSize
= pWindow
->GetSizePixel();
4061 aWinSize
.Width
= aSize
.Width();
4062 aWinSize
.Height
= aSize
.Height();
4069 awt::Point
ToolbarLayoutManager::getToolbarPos( std::u16string_view rResourceURL
)
4072 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
4074 uno::Reference
< awt::XWindow
> xWindow( implts_getXWindow( rResourceURL
));
4077 if ( aUIElement
.m_bFloating
)
4079 awt::Rectangle aRect
= xWindow
->getPosSize();
4084 aPos
= aUIElement
.m_aDockedData
.m_aPos
;
4090 void ToolbarLayoutManager::setToolbarSize( std::u16string_view rResourceURL
, const awt::Size
& aSize
)
4092 uno::Reference
< awt::XWindow2
> xWindow( implts_getXWindow( rResourceURL
), uno::UNO_QUERY
);
4093 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
4094 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
4096 if ( xWindow
.is() && xDockWindow
.is() && xDockWindow
->isFloating() )
4098 xWindow
->setOutputSize( aSize
);
4099 aUIElement
.m_aFloatingData
.m_aSize
= aSize
;
4100 implts_setToolbar( aUIElement
);
4101 implts_writeWindowStateData( aUIElement
);
4102 implts_sortUIElements();
4106 void ToolbarLayoutManager::setToolbarPos( std::u16string_view rResourceURL
, const awt::Point
& aPos
)
4108 uno::Reference
< awt::XWindow
> xWindow( implts_getXWindow( rResourceURL
));
4109 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
4110 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
4112 if ( xWindow
.is() && xDockWindow
.is() && xDockWindow
->isFloating() )
4114 xWindow
->setPosSize( aPos
.X
, aPos
.Y
, 0, 0, awt::PosSize::POS
);
4115 aUIElement
.m_aFloatingData
.m_aPos
= aPos
;
4116 implts_setToolbar( aUIElement
);
4117 implts_writeWindowStateData( aUIElement
);
4118 implts_sortUIElements();
4122 void ToolbarLayoutManager::setToolbarPosSize( std::u16string_view rResourceURL
, const awt::Point
& aPos
, const awt::Size
& aSize
)
4124 setToolbarPos( rResourceURL
, aPos
);
4125 setToolbarSize( rResourceURL
, aSize
);
4128 } // namespace framework
4130 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */