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"
25 #include <services/layoutmanager.hxx>
26 #include <classes/resource.hrc>
27 #include <classes/fwkresid.hxx>
29 #include <com/sun/star/awt/PosSize.hpp>
30 #include <com/sun/star/awt/Toolkit.hpp>
31 #include <com/sun/star/beans/XPropertySet.hpp>
32 #include <com/sun/star/ui/UIElementType.hpp>
33 #include <com/sun/star/container/XNameReplace.hpp>
34 #include <com/sun/star/container/XNameContainer.hpp>
35 #include <com/sun/star/ui/XUIElementSettings.hpp>
36 #include <com/sun/star/ui/XUIFunctionListener.hpp>
38 #include <unotools/cmdoptions.hxx>
39 #include <toolkit/helper/vclunohelper.hxx>
40 #include <toolkit/helper/convert.hxx>
41 #include <toolkit/awt/vclxwindow.hxx>
42 #include <vcl/i18nhelp.hxx>
43 #include <vcl/dockingarea.hxx>
44 #include <vcl/settings.hxx>
46 #include <boost/bind.hpp>
48 using namespace ::com::sun::star
;
53 ToolbarLayoutManager::ToolbarLayoutManager(
54 const uno::Reference
< uno::XComponentContext
>& rxContext
,
55 const uno::Reference
< ui::XUIElementFactory
>& xUIElementFactory
,
56 ILayoutNotifications
* pParentLayouter
):
57 m_xContext( rxContext
),
58 m_xUIElementFactoryManager( xUIElementFactory
),
59 m_pParentLayouter( pParentLayouter
),
60 m_eDockOperation( DOCKOP_ON_COLROW
),
61 m_ePreviewDetection( PREVIEWFRAME_UNKNOWN
),
63 m_pGlobalSettings( 0 ),
64 m_bComponentAttached( false ),
65 m_bLayoutDirty( false ),
66 m_bStoreWindowState( false ),
67 m_bGlobalSettings( false ),
68 m_bDockingInProgress( false ),
70 m_bLayoutInProgress( false ),
71 m_bToolbarCreation( false )
73 // initialize rectangles to zero values
74 setZeroRectangle( m_aDockingAreaOffsets
);
75 setZeroRectangle( m_aDockingArea
);
78 ToolbarLayoutManager::~ToolbarLayoutManager()
80 delete m_pGlobalSettings
;
81 delete m_pAddonOptions
;
86 void SAL_CALL
ToolbarLayoutManager::acquire() throw()
88 OWeakObject::acquire();
91 void SAL_CALL
ToolbarLayoutManager::release() throw()
93 OWeakObject::release();
96 uno::Any SAL_CALL
ToolbarLayoutManager::queryInterface( const uno::Type
& rType
) throw( uno::RuntimeException
, std::exception
)
98 uno::Any a
= ::cppu::queryInterface( rType
,
99 (static_cast< awt::XDockableWindowListener
* >(this)),
100 (static_cast< ui::XUIConfigurationListener
* >(this)),
101 (static_cast< awt::XWindowListener
* >(this)));
106 return OWeakObject::queryInterface( rType
);
109 void SAL_CALL
ToolbarLayoutManager::disposing( const lang::EventObject
& aEvent
) throw( uno::RuntimeException
, std::exception
)
111 if ( aEvent
.Source
== m_xFrame
)
113 // Reset all internal references
115 implts_destroyDockingAreaWindows();
119 awt::Rectangle
ToolbarLayoutManager::getDockingArea()
121 SolarMutexResettableGuard aWriteLock
;
122 Rectangle
aNewDockingArea( m_aDockingArea
);
125 if ( isLayoutDirty() )
126 aNewDockingArea
= implts_calcDockingArea();
129 m_aDockingArea
= aNewDockingArea
;
132 return putRectangleValueToAWT(aNewDockingArea
);
135 void ToolbarLayoutManager::setDockingArea( const awt::Rectangle
& rDockingArea
)
138 m_aDockingArea
= putAWTToRectangle( rDockingArea
);
139 m_bLayoutDirty
= true;
142 void ToolbarLayoutManager::implts_setDockingAreaWindowSizes( const awt::Rectangle
& rBorderSpace
)
144 SolarMutexClearableGuard aReadLock
;
145 Rectangle aDockOffsets
= m_aDockingAreaOffsets
;
146 uno::Reference
< awt::XWindow2
> xContainerWindow( m_xContainerWindow
);
147 uno::Reference
< awt::XWindow
> xTopDockAreaWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_TOP
] );
148 uno::Reference
< awt::XWindow
> xBottomDockAreaWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_BOTTOM
] );
149 uno::Reference
< awt::XWindow
> xLeftDockAreaWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_LEFT
] );
150 uno::Reference
< awt::XWindow
> xRightDockAreaWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_RIGHT
] );
153 uno::Reference
< awt::XDevice
> xDevice( xContainerWindow
, uno::UNO_QUERY
);
155 // Convert relativ size to output size.
156 awt::Rectangle aRectangle
= xContainerWindow
->getPosSize();
157 awt::DeviceInfo aInfo
= xDevice
->getInfo();
158 awt::Size aContainerClientSize
= awt::Size( aRectangle
.Width
- aInfo
.LeftInset
- aInfo
.RightInset
,
159 aRectangle
.Height
- aInfo
.TopInset
- aInfo
.BottomInset
);
160 long aStatusBarHeight
= aDockOffsets
.GetHeight();
162 sal_Int32
nLeftRightDockingAreaHeight( aContainerClientSize
.Height
);
163 if ( rBorderSpace
.Y
>= 0 )
165 // Top docking area window
166 xTopDockAreaWindow
->setPosSize( 0, 0, aContainerClientSize
.Width
, rBorderSpace
.Y
, awt::PosSize::POSSIZE
);
167 xTopDockAreaWindow
->setVisible( sal_True
);
168 nLeftRightDockingAreaHeight
-= rBorderSpace
.Y
;
171 if ( rBorderSpace
.Height
>= 0 )
173 // Bottom docking area window
174 sal_Int32 nBottomPos
= std::max( sal_Int32( aContainerClientSize
.Height
- rBorderSpace
.Height
- aStatusBarHeight
+ 1 ), sal_Int32( 0 ));
175 sal_Int32 nHeight
= ( nBottomPos
== 0 ) ? 0 : rBorderSpace
.Height
;
177 xBottomDockAreaWindow
->setPosSize( 0, nBottomPos
, aContainerClientSize
.Width
, nHeight
, awt::PosSize::POSSIZE
);
178 xBottomDockAreaWindow
->setVisible( sal_True
);
179 nLeftRightDockingAreaHeight
-= nHeight
- 1;
182 nLeftRightDockingAreaHeight
-= aStatusBarHeight
;
183 if ( rBorderSpace
.X
>= 0 || nLeftRightDockingAreaHeight
> 0 )
185 // Left docking area window
186 // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority!
187 sal_Int32 nHeight
= std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight
));
189 xLeftDockAreaWindow
->setPosSize( 0, rBorderSpace
.Y
, rBorderSpace
.X
, nHeight
, awt::PosSize::POSSIZE
);
190 xLeftDockAreaWindow
->setVisible( sal_True
);
192 if ( rBorderSpace
.Width
>= 0 || nLeftRightDockingAreaHeight
> 0 )
194 // Right docking area window
195 // We also have to change our right docking area window if the top or bottom area has changed. They have a higher priority!
196 sal_Int32 nLeftPos
= std::max( sal_Int32( 0 ), sal_Int32( aContainerClientSize
.Width
- rBorderSpace
.Width
));
197 sal_Int32 nHeight
= std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight
));
198 sal_Int32 nWidth
= ( nLeftPos
== 0 ) ? 0 : rBorderSpace
.Width
;
200 xRightDockAreaWindow
->setPosSize( nLeftPos
, rBorderSpace
.Y
, nWidth
, nHeight
, awt::PosSize::POSSIZE
);
201 xRightDockAreaWindow
->setVisible( sal_True
);
206 void ToolbarLayoutManager::doLayout(const ::Size
& aContainerSize
)
208 SolarMutexResettableGuard aWriteLock
;
209 bool bLayoutInProgress( m_bLayoutInProgress
);
210 m_bLayoutInProgress
= true;
211 awt::Rectangle aDockingArea
= putRectangleValueToAWT( m_aDockingArea
);
214 if ( bLayoutInProgress
)
217 // Retrieve row/column dependent data from all docked user-interface elements
218 for ( sal_Int32 i
= 0; i
< DOCKINGAREAS_COUNT
; i
++ )
220 bool bReverse( isReverseOrderDockingArea( i
));
221 std::vector
< SingleRowColumnWindowData
> aRowColumnsWindowData
;
223 implts_getDockingAreaElementInfos( (ui::DockingArea
)i
, aRowColumnsWindowData
);
225 sal_Int32
nOffset( 0 );
226 const sal_uInt32 nCount
= aRowColumnsWindowData
.size();
227 for ( sal_uInt32 j
= 0; j
< nCount
; ++j
)
229 sal_uInt32 nIndex
= bReverse
? nCount
-j
-1 : j
;
230 implts_calcWindowPosSizeOnSingleRowColumn( i
, nOffset
, aRowColumnsWindowData
[nIndex
], aContainerSize
);
231 nOffset
+= aRowColumnsWindowData
[j
].nStaticSize
;
235 implts_setDockingAreaWindowSizes( aDockingArea
);
238 m_bLayoutDirty
= false;
239 m_bLayoutInProgress
= false;
243 bool ToolbarLayoutManager::implts_isParentWindowVisible() const
246 bool bVisible( false );
247 if ( m_xContainerWindow
.is() )
248 bVisible
= m_xContainerWindow
->isVisible();
253 Rectangle
ToolbarLayoutManager::implts_calcDockingArea()
255 SolarMutexClearableGuard aReadLock
;
256 UIElementVector
aWindowVector( m_aUIElements
);
259 Rectangle aBorderSpace
;
260 sal_Int32
nCurrRowColumn( 0 );
261 sal_Int32
nCurrPos( 0 );
262 sal_Int32
nCurrDockingArea( ui::DockingArea_DOCKINGAREA_TOP
);
263 std::vector
< sal_Int32
> aRowColumnSizes
[DOCKINGAREAS_COUNT
];
264 UIElementVector::const_iterator pConstIter
;
266 // initialize rectangle with zero values!
267 aBorderSpace
.setWidth(0);
268 aBorderSpace
.setHeight(0);
270 aRowColumnSizes
[nCurrDockingArea
].clear();
271 aRowColumnSizes
[nCurrDockingArea
].push_back( 0 );
273 for ( pConstIter
= aWindowVector
.begin(); pConstIter
!= aWindowVector
.end(); ++pConstIter
)
275 uno::Reference
< ui::XUIElement
> xUIElement( pConstIter
->m_xUIElement
, uno::UNO_QUERY
);
276 if ( xUIElement
.is() )
278 uno::Reference
< awt::XWindow
> xWindow( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
279 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
280 if ( xWindow
.is() && xDockWindow
.is() )
282 SolarMutexGuard aGuard
;
284 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
285 if ( pWindow
&& !xDockWindow
->isFloating() && pConstIter
->m_bVisible
&& !pConstIter
->m_bMasterHide
)
287 awt::Rectangle aPosSize
= xWindow
->getPosSize();
288 if ( pConstIter
->m_aDockedData
.m_nDockedArea
!= nCurrDockingArea
)
290 nCurrDockingArea
= pConstIter
->m_aDockedData
.m_nDockedArea
;
293 aRowColumnSizes
[nCurrDockingArea
].clear();
294 aRowColumnSizes
[nCurrDockingArea
].push_back( 0 );
297 if ( pConstIter
->m_aDockedData
.m_nDockedArea
== nCurrDockingArea
)
299 if ( isHorizontalDockingArea( pConstIter
->m_aDockedData
.m_nDockedArea
))
301 if ( pConstIter
->m_aDockedData
.m_aPos
.Y
> nCurrPos
)
304 nCurrPos
= pConstIter
->m_aDockedData
.m_aPos
.Y
;
305 aRowColumnSizes
[nCurrDockingArea
].push_back( 0 );
308 if ( aPosSize
.Height
> aRowColumnSizes
[nCurrDockingArea
][nCurrRowColumn
] )
309 aRowColumnSizes
[nCurrDockingArea
][nCurrRowColumn
] = aPosSize
.Height
;
313 if ( pConstIter
->m_aDockedData
.m_aPos
.X
> nCurrPos
)
316 nCurrPos
= pConstIter
->m_aDockedData
.m_aPos
.X
;
317 aRowColumnSizes
[nCurrDockingArea
].push_back( 0 );
320 if ( aPosSize
.Width
> aRowColumnSizes
[nCurrDockingArea
][nCurrRowColumn
] )
321 aRowColumnSizes
[nCurrDockingArea
][nCurrRowColumn
] = aPosSize
.Width
;
329 // Sum up max heights from every row/column
330 if ( !aWindowVector
.empty() )
332 for ( sal_Int32 i
= 0; i
<= ui::DockingArea_DOCKINGAREA_RIGHT
; i
++ )
334 sal_Int32
nSize( 0 );
335 const sal_uInt32 nCount
= aRowColumnSizes
[i
].size();
336 for ( sal_uInt32 j
= 0; j
< nCount
; j
++ )
337 nSize
+= aRowColumnSizes
[i
][j
];
339 if ( i
== ui::DockingArea_DOCKINGAREA_TOP
)
340 aBorderSpace
.Top() = nSize
;
341 else if ( i
== ui::DockingArea_DOCKINGAREA_BOTTOM
)
342 aBorderSpace
.Bottom() = nSize
;
343 else if ( i
== ui::DockingArea_DOCKINGAREA_LEFT
)
344 aBorderSpace
.Left() = nSize
;
346 aBorderSpace
.Right() = nSize
;
353 void ToolbarLayoutManager::reset()
355 SolarMutexClearableGuard aWriteLock
;
356 uno::Reference
< ui::XUIConfigurationManager
> xModuleCfgMgr( m_xModuleCfgMgr
);
357 uno::Reference
< ui::XUIConfigurationManager
> xDocCfgMgr( m_xDocCfgMgr
);
358 m_xModuleCfgMgr
.clear();
359 m_xDocCfgMgr
.clear();
360 m_ePreviewDetection
= PREVIEWFRAME_UNKNOWN
;
361 m_bComponentAttached
= false;
368 void ToolbarLayoutManager::attach(
369 const uno::Reference
< frame::XFrame
>& xFrame
,
370 const uno::Reference
< ui::XUIConfigurationManager
>& xModuleCfgMgr
,
371 const uno::Reference
< ui::XUIConfigurationManager
>& xDocCfgMgr
,
372 const uno::Reference
< container::XNameAccess
>& xPersistentWindowState
)
374 // reset toolbar manager if we lose our current frame
375 if ( m_xFrame
.is() && m_xFrame
!= xFrame
)
380 m_xModuleCfgMgr
= xModuleCfgMgr
;
381 m_xDocCfgMgr
= xDocCfgMgr
;
382 m_xPersistentWindowState
= xPersistentWindowState
;
383 m_bComponentAttached
= true;
386 bool ToolbarLayoutManager::isPreviewFrame()
389 if (m_ePreviewDetection
== PREVIEWFRAME_UNKNOWN
)
391 uno::Reference
< frame::XFrame
> xFrame( m_xFrame
);
393 uno::Reference
< frame::XModel
> xModel( impl_getModelFromFrame( xFrame
));
395 m_ePreviewDetection
= (implts_isPreviewModel( xModel
) ? PREVIEWFRAME_YES
: PREVIEWFRAME_NO
);
397 return m_ePreviewDetection
== PREVIEWFRAME_YES
;
400 void ToolbarLayoutManager::createStaticToolbars()
403 implts_createCustomToolBars();
404 implts_createAddonsToolBars();
405 implts_createNonContextSensitiveToolBars();
406 implts_sortUIElements();
409 bool ToolbarLayoutManager::requestToolbar( const OUString
& rResourceURL
)
411 if (isPreviewFrame())
412 return false; // no toolbars for preview frame!
414 bool bNotify( false );
415 bool bMustCallCreate( false );
416 uno::Reference
< ui::XUIElement
> xUIElement
;
418 UIElement aRequestedToolbar
= impl_findToolbar( rResourceURL
);
419 if ( aRequestedToolbar
.m_aName
!= rResourceURL
)
421 bMustCallCreate
= true;
422 aRequestedToolbar
.m_aName
= rResourceURL
;
423 aRequestedToolbar
.m_aType
= UIRESOURCETYPE_TOOLBAR
;
424 aRequestedToolbar
.m_xUIElement
= xUIElement
;
425 implts_readWindowStateData( rResourceURL
, aRequestedToolbar
);
428 xUIElement
= aRequestedToolbar
.m_xUIElement
;
429 if ( !xUIElement
.is() )
430 bMustCallCreate
= true;
432 bool bCreateOrShowToolbar( aRequestedToolbar
.m_bVisible
&& !aRequestedToolbar
.m_bMasterHide
);
434 uno::Reference
< awt::XWindow2
> xContainerWindow( m_xContainerWindow
, uno::UNO_QUERY
);
435 if ( xContainerWindow
.is() && aRequestedToolbar
.m_bFloating
)
436 bCreateOrShowToolbar
&= bool( xContainerWindow
->isActive());
438 if ( bCreateOrShowToolbar
)
439 bNotify
= ( bMustCallCreate
) ? createToolbar( rResourceURL
) : showToolbar( rResourceURL
);
444 bool ToolbarLayoutManager::createToolbar( const OUString
& rResourceURL
)
446 bool bNotify( false );
448 SolarMutexClearableGuard aReadLock
;
449 uno::Reference
< frame::XFrame
> xFrame( m_xFrame
);
450 uno::Reference
< awt::XWindow2
> xContainerWindow( m_xContainerWindow
);
455 if ( !xFrame
.is() || !xContainerWindow
.is() )
458 UIElement aToolbarElement
= implts_findToolbar( rResourceURL
);
459 if ( !aToolbarElement
.m_xUIElement
.is() )
461 uno::Reference
< ui::XUIElement
> xUIElement
;
463 uno::Sequence
< beans::PropertyValue
> aPropSeq( 2 );
464 aPropSeq
[0].Name
= "Frame";
465 aPropSeq
[0].Value
<<= m_xFrame
;
466 aPropSeq
[1].Name
= "Persistent";
467 aPropSeq
[1].Value
<<= true;
468 uno::Reference
< ui::XUIElementFactory
> xUIElementFactory( m_xUIElementFactoryManager
);
471 implts_setToolbarCreation( true );
474 if ( xUIElementFactory
.is() )
475 xUIElement
= xUIElementFactory
->createUIElement( rResourceURL
, aPropSeq
);
477 catch (const container::NoSuchElementException
&)
480 catch (const lang::IllegalArgumentException
&)
483 implts_setToolbarCreation( false );
485 if ( xUIElement
.is() )
487 uno::Reference
< awt::XWindow
> xWindow( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
488 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
489 if ( xDockWindow
.is() && xWindow
.is() )
493 xDockWindow
->addDockableWindowListener( uno::Reference
< awt::XDockableWindowListener
>(
494 static_cast< OWeakObject
* >( this ), uno::UNO_QUERY
));
495 xWindow
->addWindowListener( uno::Reference
< awt::XWindowListener
>(
496 static_cast< OWeakObject
* >( this ), uno::UNO_QUERY
));
497 xDockWindow
->enableDocking( sal_True
);
499 catch (const uno::Exception
&)
504 bool bVisible
= false;
505 bool bFloating
= false;
507 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
508 SolarMutexClearableGuard aWriteLock
;
510 UIElement
& rElement
= impl_findToolbar( rResourceURL
);
511 if ( !rElement
.m_aName
.isEmpty() )
513 // Reuse a local entry so we are able to use the latest
514 // UI changes for this document.
515 implts_setElementData( rElement
, xDockWindow
);
516 rElement
.m_xUIElement
= xUIElement
;
517 bVisible
= rElement
.m_bVisible
;
518 bFloating
= rElement
.m_bFloating
;
522 // Create new UI element and try to read its state data
523 UIElement
aNewToolbar( rResourceURL
, UIRESOURCETYPE_TOOLBAR
, xUIElement
);
524 implts_readWindowStateData( rResourceURL
, aNewToolbar
);
525 implts_setElementData( aNewToolbar
, xDockWindow
);
526 implts_insertToolbar( aNewToolbar
);
527 bVisible
= aNewToolbar
.m_bVisible
;
528 bFloating
= rElement
.m_bFloating
;
531 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
533 // set toolbar menu style according to customize command state
534 SvtCommandOptions aCmdOptions
;
536 SolarMutexGuard aGuard
;
537 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
538 if ( pWindow
&& pWindow
->GetType() == WINDOW_TOOLBOX
)
540 ToolBox
* pToolbar
= static_cast<ToolBox
*>(pWindow
);
541 sal_uInt16 nMenuType
= pToolbar
->GetMenuType();
542 if ( aCmdOptions
.Lookup( SvtCommandOptions::CMDOPTION_DISABLED
, "ConfigureDialog" ))
543 pToolbar
->SetMenuType( nMenuType
& ~TOOLBOX_MENUTYPE_CUSTOMIZE
);
545 pToolbar
->SetMenuType( nMenuType
| TOOLBOX_MENUTYPE_CUSTOMIZE
);
549 implts_sortUIElements();
551 if ( bVisible
&& !bFloating
)
552 implts_setLayoutDirty();
559 bool ToolbarLayoutManager::destroyToolbar( const OUString
& rResourceURL
)
561 UIElementVector::iterator pIter
;
562 uno::Reference
< lang::XComponent
> xComponent
;
564 bool bNotify( false );
565 bool bMustBeSorted( false );
566 bool bMustLayouted( false );
567 bool bMustBeDestroyed( !rResourceURL
.startsWith("private:resource/toolbar/addon_") );
569 SolarMutexClearableGuard aWriteLock
;
570 for ( pIter
= m_aUIElements
.begin(); pIter
!= m_aUIElements
.end(); ++pIter
)
572 if ( pIter
->m_aName
== rResourceURL
)
574 xComponent
.set( pIter
->m_xUIElement
, uno::UNO_QUERY
);
575 if ( bMustBeDestroyed
)
576 pIter
->m_xUIElement
.clear();
578 pIter
->m_bVisible
= false;
584 uno::Reference
< ui::XUIElement
> xUIElement( xComponent
, uno::UNO_QUERY
);
585 if ( xUIElement
.is() )
587 uno::Reference
< awt::XWindow
> xWindow( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
588 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
590 if ( bMustBeDestroyed
)
595 xWindow
->removeWindowListener( uno::Reference
< awt::XWindowListener
>(
596 static_cast< OWeakObject
* >( this ), uno::UNO_QUERY
));
598 catch (const uno::Exception
&)
604 if ( xDockWindow
.is() )
605 xDockWindow
->removeDockableWindowListener( uno::Reference
< awt::XDockableWindowListener
>(
606 static_cast< OWeakObject
* >( this ), uno::UNO_QUERY
));
608 catch (const uno::Exception
&)
615 xWindow
->setVisible( sal_False
);
619 if ( !xDockWindow
->isFloating() )
620 bMustLayouted
= true;
621 bMustBeSorted
= true;
624 if ( bMustBeDestroyed
)
626 if ( xComponent
.is() )
627 xComponent
->dispose();
632 implts_setLayoutDirty();
635 implts_sortUIElements();
640 void ToolbarLayoutManager::destroyToolbars()
642 UIElementVector aUIElementVector
;
643 implts_getUIElementVectorCopy( aUIElementVector
);
645 SolarMutexClearableGuard aWriteLock
;
646 m_aUIElements
.clear();
647 m_bLayoutDirty
= true;
650 UIElementVector::iterator pIter
;
651 for ( pIter
= aUIElementVector
.begin(); pIter
!= aUIElementVector
.end(); ++pIter
)
653 uno::Reference
< lang::XComponent
> xComponent( pIter
->m_xUIElement
, uno::UNO_QUERY
);
654 if ( xComponent
.is() )
655 xComponent
->dispose();
659 bool ToolbarLayoutManager::showToolbar( const OUString
& rResourceURL
)
661 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
663 SolarMutexGuard aGuard
;
664 vcl::Window
* pWindow
= getWindowFromXUIElement( aUIElement
.m_xUIElement
);
666 // Addons appear to need to be populated at start, but we don't
667 // want to populate them with (scaled) images until later.
668 AddonsToolBarWrapper
*pAddOns
;
669 pAddOns
= dynamic_cast<AddonsToolBarWrapper
*>( aUIElement
.m_xUIElement
.get());
671 pAddOns
->populateImages();
675 if ( !aUIElement
.m_bFloating
)
676 implts_setLayoutDirty();
678 pWindow
->Show( true, SHOW_NOFOCUSCHANGE
| SHOW_NOACTIVATE
);
680 aUIElement
.m_bVisible
= true;
681 implts_writeWindowStateData( aUIElement
);
682 implts_setToolbar( aUIElement
);
683 implts_sortUIElements();
690 bool ToolbarLayoutManager::hideToolbar( const OUString
& rResourceURL
)
692 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
694 SolarMutexGuard aGuard
;
695 vcl::Window
* pWindow
= getWindowFromXUIElement( aUIElement
.m_xUIElement
);
698 pWindow
->Show( false );
699 if ( !aUIElement
.m_bFloating
)
700 implts_setLayoutDirty();
702 aUIElement
.m_bVisible
= false;
703 implts_writeWindowStateData( aUIElement
);
704 implts_setToolbar( aUIElement
);
711 void ToolbarLayoutManager::refreshToolbarsVisibility( bool bAutomaticToolbars
)
713 UIElementVector aUIElementVector
;
715 SolarMutexClearableGuard aReadLock
;
716 bool bVisible( m_bVisible
);
719 if ( !bVisible
|| !bAutomaticToolbars
)
722 implts_getUIElementVectorCopy( aUIElementVector
);
724 UIElement aUIElement
;
725 SolarMutexGuard aGuard
;
726 UIElementVector::iterator pIter
;
727 for ( pIter
= aUIElementVector
.begin(); pIter
!= aUIElementVector
.end(); ++pIter
)
729 if ( implts_readWindowStateData( pIter
->m_aName
, aUIElement
) &&
730 ( pIter
->m_bVisible
!= aUIElement
.m_bVisible
) && !pIter
->m_bMasterHide
)
733 UIElement
& rUIElement
= impl_findToolbar( pIter
->m_aName
);
734 if ( rUIElement
.m_aName
== pIter
->m_aName
)
736 rUIElement
.m_bVisible
= aUIElement
.m_bVisible
;
737 implts_setLayoutDirty();
743 void ToolbarLayoutManager::setFloatingToolbarsVisibility( bool bVisible
)
745 UIElementVector aUIElementVector
;
746 implts_getUIElementVectorCopy( aUIElementVector
);
748 SolarMutexGuard aGuard
;
749 UIElementVector::iterator pIter
;
750 for ( pIter
= aUIElementVector
.begin(); pIter
!= aUIElementVector
.end(); ++pIter
)
752 vcl::Window
* pWindow
= getWindowFromXUIElement( pIter
->m_xUIElement
);
753 if ( pWindow
&& pIter
->m_bFloating
)
757 if ( pIter
->m_bVisible
&& !pIter
->m_bMasterHide
)
758 pWindow
->Show( true, SHOW_NOFOCUSCHANGE
| SHOW_NOACTIVATE
);
761 pWindow
->Show( false );
766 void ToolbarLayoutManager::setVisible( bool bVisible
)
768 UIElementVector aUIElementVector
;
769 implts_getUIElementVectorCopy( aUIElementVector
);
771 SolarMutexGuard aGuard
;
772 UIElementVector::iterator pIter
;
773 for ( pIter
= aUIElementVector
.begin(); pIter
!= aUIElementVector
.end(); ++pIter
)
775 if (!pIter
->m_bFloating
)
777 UIElement
aUIElement(*pIter
);
778 aUIElement
.m_bMasterHide
= !bVisible
;
779 implts_setToolbar(aUIElement
);
780 implts_setLayoutDirty();
783 vcl::Window
* pWindow
= getWindowFromXUIElement( pIter
->m_xUIElement
);
786 bool bSetVisible( pIter
->m_bVisible
&& bVisible
);
791 if ( pIter
->m_bFloating
)
792 pWindow
->Show(true, SHOW_NOFOCUSCHANGE
| SHOW_NOACTIVATE
);
801 bool ToolbarLayoutManager::dockToolbar( const OUString
& rResourceURL
, ui::DockingArea eDockingArea
, const awt::Point
& aPos
)
803 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
805 if ( aUIElement
.m_xUIElement
.is() )
809 uno::Reference
< awt::XWindow
> xWindow( aUIElement
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
810 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
811 if ( xDockWindow
.is() )
813 if ( eDockingArea
!= ui::DockingArea_DOCKINGAREA_DEFAULT
)
814 aUIElement
.m_aDockedData
.m_nDockedArea
= sal_Int16( eDockingArea
);
816 if ( !isDefaultPos( aPos
))
817 aUIElement
.m_aDockedData
.m_aPos
= aPos
;
819 if ( !xDockWindow
->isFloating() )
821 vcl::Window
* pWindow( 0 );
822 ToolBox
* pToolBox( 0 );
825 SolarMutexGuard aGuard
;
826 pWindow
= VCLUnoHelper::GetWindow( xWindow
);
827 if ( pWindow
&& pWindow
->GetType() == WINDOW_TOOLBOX
)
829 pToolBox
= static_cast<ToolBox
*>(pWindow
);
831 // We have to set the alignment of the toolbox. It's possible that the toolbox is moved from a
832 // horizontal to a vertical docking area!
833 pToolBox
->SetAlign( ImplConvertAlignment( aUIElement
.m_aDockedData
.m_nDockedArea
));
837 if ( hasDefaultPosValue( aUIElement
.m_aDockedData
.m_aPos
))
839 // Docking on its default position without a preset position -
840 // we have to find a good place for it.
843 SolarMutexGuard aGuard
;
846 aSize
= pToolBox
->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIElement
.m_aDockedData
.m_nDockedArea
) );
848 aSize
= pWindow
->GetSizePixel();
853 implts_findNextDockingPos((ui::DockingArea
)aUIElement
.m_aDockedData
.m_nDockedArea
, aSize
, aDockPos
, aPixelPos
);
854 aUIElement
.m_aDockedData
.m_aPos
= aDockPos
;
858 implts_setToolbar( aUIElement
);
860 if ( xDockWindow
->isFloating() )
862 // ATTENTION: This will call toggleFloatingMode() via notifications which
863 // sets the floating member of the UIElement correctly!
864 xDockWindow
->setFloatingMode( sal_False
);
868 implts_writeWindowStateData( aUIElement
);
869 implts_sortUIElements();
871 if ( aUIElement
.m_bVisible
)
872 implts_setLayoutDirty();
877 catch (const lang::DisposedException
&)
885 bool ToolbarLayoutManager::dockAllToolbars()
887 std::vector
< OUString
> aToolBarNameVector
;
889 SolarMutexClearableGuard aReadLock
;
890 UIElementVector::iterator pIter
;
891 for ( pIter
= m_aUIElements
.begin(); pIter
!= m_aUIElements
.end(); ++pIter
)
893 if ( pIter
->m_aType
== "toolbar" && pIter
->m_xUIElement
.is() && pIter
->m_bFloating
&& pIter
->m_bVisible
)
894 aToolBarNameVector
.push_back( pIter
->m_aName
);
899 const sal_uInt32 nCount
= aToolBarNameVector
.size();
900 for ( sal_uInt32 i
= 0; i
< nCount
; ++i
)
903 aPoint
.X
= aPoint
.Y
= SAL_MAX_INT32
;
904 bResult
&= dockToolbar( aToolBarNameVector
[i
], ui::DockingArea_DOCKINGAREA_DEFAULT
, aPoint
);
910 long ToolbarLayoutManager::childWindowEvent( VclSimpleEvent
* pEvent
)
912 // To enable toolbar controllers to change their image when a sub-toolbar function
913 // is activated, we need this mechanism. We have NO connection between these toolbars
915 if ( pEvent
&& pEvent
->ISA( VclWindowEvent
))
917 if ( pEvent
->GetId() == VCLEVENT_TOOLBOX_SELECT
)
919 OUString aToolbarName
;
921 ToolBox
* pToolBox
= getToolboxPtr( static_cast<VclWindowEvent
*>(pEvent
)->GetWindow() );
925 aToolbarName
= retrieveToolbarNameFromHelpURL( pToolBox
);
926 sal_uInt16 nId
= pToolBox
->GetCurItemId();
928 aCommand
= pToolBox
->GetItemCommand( nId
);
931 if ( !aToolbarName
.isEmpty() && !aCommand
.isEmpty() )
933 SolarMutexClearableGuard aReadLock
;
934 ::std::vector
< uno::Reference
< ui::XUIFunctionListener
> > aListenerArray
;
935 UIElementVector::iterator pIter
;
937 for ( pIter
= m_aUIElements
.begin(); pIter
!= m_aUIElements
.end(); ++pIter
)
939 if ( pIter
->m_xUIElement
.is() )
941 uno::Reference
< ui::XUIFunctionListener
> xListener( pIter
->m_xUIElement
, uno::UNO_QUERY
);
942 if ( xListener
.is() )
943 aListenerArray
.push_back( xListener
);
948 const sal_uInt32 nCount
= aListenerArray
.size();
949 for ( sal_uInt32 i
= 0; i
< nCount
; ++i
)
953 aListenerArray
[i
]->functionExecute( aToolbarName
, aCommand
);
955 catch (const uno::RuntimeException
&)
959 catch (const uno::Exception
&)
965 else if ( pEvent
->GetId() == VCLEVENT_TOOLBOX_FORMATCHANGED
)
967 if ( !implts_isToolbarCreationActive() )
969 ToolBox
* pToolBox
= getToolboxPtr( static_cast<VclWindowEvent
*>(pEvent
)->GetWindow() );
972 OUString aToolbarName
= retrieveToolbarNameFromHelpURL( pToolBox
);
973 if ( !aToolbarName
.isEmpty() )
975 OUStringBuffer
aBuf(100);
976 aBuf
.appendAscii( "private:resource/toolbar/" );
977 aBuf
.append( aToolbarName
);
979 UIElement aToolbar
= implts_findToolbar( aBuf
.makeStringAndClear() );
980 if ( aToolbar
.m_xUIElement
.is() && !aToolbar
.m_bFloating
)
982 implts_setLayoutDirty();
983 m_pParentLayouter
->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED
);
994 void ToolbarLayoutManager::resetDockingArea()
996 SolarMutexClearableGuard aReadLock
;
997 uno::Reference
< awt::XWindow
> xTopDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_TOP
] );
998 uno::Reference
< awt::XWindow
> xLeftDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_LEFT
] );
999 uno::Reference
< awt::XWindow
> xRightDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_RIGHT
] );
1000 uno::Reference
< awt::XWindow
> xBottomDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_BOTTOM
] );
1003 if ( xTopDockingWindow
.is() )
1004 xTopDockingWindow
->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE
);
1005 if ( xLeftDockingWindow
.is() )
1006 xLeftDockingWindow
->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE
);
1007 if ( xRightDockingWindow
.is() )
1008 xRightDockingWindow
->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE
);
1009 if ( xBottomDockingWindow
.is() )
1010 xBottomDockingWindow
->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE
);
1013 void ToolbarLayoutManager::setParentWindow(
1014 const uno::Reference
< awt::XWindowPeer
>& xParentWindow
)
1016 static const char DOCKINGAREASTRING
[] = "dockingarea";
1018 uno::Reference
< awt::XWindow
> xTopDockWindow
= uno::Reference
< awt::XWindow
>( createToolkitWindow( m_xContext
, xParentWindow
, DOCKINGAREASTRING
), uno::UNO_QUERY
);
1019 uno::Reference
< awt::XWindow
> xLeftDockWindow
= uno::Reference
< awt::XWindow
>( createToolkitWindow( m_xContext
, xParentWindow
, DOCKINGAREASTRING
), uno::UNO_QUERY
);
1020 uno::Reference
< awt::XWindow
> xRightDockWindow
= uno::Reference
< awt::XWindow
>( createToolkitWindow( m_xContext
, xParentWindow
, DOCKINGAREASTRING
), uno::UNO_QUERY
);
1021 uno::Reference
< awt::XWindow
> xBottomDockWindow
= uno::Reference
< awt::XWindow
>( createToolkitWindow( m_xContext
, xParentWindow
, DOCKINGAREASTRING
), uno::UNO_QUERY
);
1023 SolarMutexClearableGuard aWriteLock
;
1024 m_xContainerWindow
= uno::Reference
< awt::XWindow2
>( xParentWindow
, uno::UNO_QUERY
);
1025 m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_TOP
] = xTopDockWindow
;
1026 m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_LEFT
] = xLeftDockWindow
;
1027 m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_RIGHT
] = xRightDockWindow
;
1028 m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_BOTTOM
] = xBottomDockWindow
;
1031 if ( xParentWindow
.is() )
1033 SolarMutexGuard aGuard
;
1034 VclPtr
< ::DockingAreaWindow
> pWindow
= dynamic_cast< ::DockingAreaWindow
* >(VCLUnoHelper::GetWindow( xTopDockWindow
).get() );
1035 if( pWindow
) pWindow
->SetAlign( WINDOWALIGN_TOP
);
1036 pWindow
= dynamic_cast< ::DockingAreaWindow
* >(VCLUnoHelper::GetWindow( xBottomDockWindow
).get() );
1037 if( pWindow
) pWindow
->SetAlign( WINDOWALIGN_BOTTOM
);
1038 pWindow
= dynamic_cast< ::DockingAreaWindow
* >(VCLUnoHelper::GetWindow( xLeftDockWindow
).get() );
1039 if( pWindow
) pWindow
->SetAlign( WINDOWALIGN_LEFT
);
1040 pWindow
= dynamic_cast< ::DockingAreaWindow
* >(VCLUnoHelper::GetWindow( xRightDockWindow
).get() );
1041 if( pWindow
) pWindow
->SetAlign( WINDOWALIGN_RIGHT
);
1042 implts_reparentToolbars();
1051 void ToolbarLayoutManager::setDockingAreaOffsets( const ::Rectangle
& rOffsets
)
1054 m_aDockingAreaOffsets
= rOffsets
;
1055 m_bLayoutDirty
= true;
1058 OUString
ToolbarLayoutManager::implts_generateGenericAddonToolbarTitle( sal_Int32 nNumber
) const
1060 OUString
aAddonGenericTitle(FWK_RESSTR(STR_TOOLBAR_TITLE_ADDON
));
1061 const vcl::I18nHelper
& rI18nHelper
= Application::GetSettings().GetUILocaleI18nHelper();
1063 OUString aNumStr
= rI18nHelper
.GetNum( nNumber
, 0, false, false );
1064 aAddonGenericTitle
= aAddonGenericTitle
.replaceFirst( "%num%", aNumStr
);
1066 return OUString( aAddonGenericTitle
);
1069 void ToolbarLayoutManager::implts_createAddonsToolBars()
1071 SolarMutexClearableGuard aWriteLock
;
1072 if ( !m_pAddonOptions
)
1073 m_pAddonOptions
= new AddonsOptions
;
1075 uno::Reference
< ui::XUIElementFactory
> xUIElementFactory( m_xUIElementFactoryManager
);
1076 uno::Reference
< frame::XFrame
> xFrame( m_xFrame
);
1079 if (isPreviewFrame())
1080 return; // no addon toolbars for preview frame!
1082 uno::Sequence
< uno::Sequence
< beans::PropertyValue
> > aAddonToolBarData
;
1083 uno::Reference
< ui::XUIElement
> xUIElement
;
1085 sal_uInt32 nCount
= m_pAddonOptions
->GetAddonsToolBarCount();
1086 OUString
aElementType( "toolbar" );
1088 uno::Sequence
< beans::PropertyValue
> aPropSeq( 2 );
1089 aPropSeq
[0].Name
= "Frame";
1090 aPropSeq
[0].Value
<<= xFrame
;
1091 aPropSeq
[1].Name
= "ConfigurationData";
1092 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
1094 OUString
aAddonToolBarName( "private:resource/toolbar/addon_" +
1095 m_pAddonOptions
->GetAddonsToolbarResourceName(i
) );
1096 aAddonToolBarData
= m_pAddonOptions
->GetAddonsToolBarPart( i
);
1097 aPropSeq
[1].Value
<<= aAddonToolBarData
;
1099 UIElement aElement
= implts_findToolbar( aAddonToolBarName
);
1102 // It's now possible that we are called more than once. Be sure to not create
1103 // add-on toolbars more than once!
1104 if ( aElement
.m_xUIElement
.is() )
1109 xUIElement
= xUIElementFactory
->createUIElement( aAddonToolBarName
, aPropSeq
);
1110 if ( xUIElement
.is() )
1112 uno::Reference
< awt::XDockableWindow
> xDockWindow( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
1113 if ( xDockWindow
.is() )
1117 xDockWindow
->addDockableWindowListener( uno::Reference
< awt::XDockableWindowListener
>( static_cast< OWeakObject
* >( this ), uno::UNO_QUERY
));
1118 xDockWindow
->enableDocking( sal_True
);
1119 uno::Reference
< awt::XWindow
> xWindow( xDockWindow
, uno::UNO_QUERY
);
1121 xWindow
->addWindowListener( uno::Reference
< awt::XWindowListener
>( static_cast< OWeakObject
* >( this ), uno::UNO_QUERY
));
1123 catch (const uno::Exception
&)
1128 OUString aGenericAddonTitle
= implts_generateGenericAddonToolbarTitle( i
+1 );
1130 if ( !aElement
.m_aName
.isEmpty() )
1132 // Reuse a local entry so we are able to use the latest
1133 // UI changes for this document.
1134 implts_setElementData( aElement
, xDockWindow
);
1135 aElement
.m_xUIElement
= xUIElement
;
1136 if ( aElement
.m_aUIName
.isEmpty() )
1138 aElement
.m_aUIName
= aGenericAddonTitle
;
1139 implts_writeWindowStateData( aElement
);
1144 // Create new UI element and try to read its state data
1145 UIElement
aNewToolbar( aAddonToolBarName
, aElementType
, xUIElement
);
1146 aNewToolbar
.m_bFloating
= true;
1147 implts_readWindowStateData( aAddonToolBarName
, aNewToolbar
);
1148 implts_setElementData( aNewToolbar
, xDockWindow
);
1149 if ( aNewToolbar
.m_aUIName
.isEmpty() )
1151 aNewToolbar
.m_aUIName
= aGenericAddonTitle
;
1152 implts_writeWindowStateData( aNewToolbar
);
1154 implts_insertToolbar( aNewToolbar
);
1157 uno::Reference
< awt::XWindow
> xWindow( xDockWindow
, uno::UNO_QUERY
);
1160 // Set generic title for add-on toolbar
1161 SolarMutexGuard aGuard
;
1162 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
1163 if ( pWindow
->GetText().isEmpty() )
1164 pWindow
->SetText( aGenericAddonTitle
);
1165 if ( pWindow
->GetType() == WINDOW_TOOLBOX
)
1167 ToolBox
* pToolbar
= static_cast<ToolBox
*>(pWindow
);
1168 pToolbar
->SetMenuType();
1173 catch (const container::NoSuchElementException
&)
1176 catch (const lang::IllegalArgumentException
&)
1182 void ToolbarLayoutManager::implts_createCustomToolBars()
1184 SolarMutexClearableGuard aReadLock
;
1185 if ( !m_bComponentAttached
)
1188 uno::Reference
< ui::XUIElementFactory
> xUIElementFactory( m_xUIElementFactoryManager
);
1189 uno::Reference
< frame::XFrame
> xFrame( m_xFrame
);
1190 uno::Reference
< ui::XUIConfigurationManager
> xModuleCfgMgr( m_xModuleCfgMgr
, uno::UNO_QUERY
);
1191 uno::Reference
< ui::XUIConfigurationManager
> xDocCfgMgr( m_xDocCfgMgr
, uno::UNO_QUERY
);
1196 if (isPreviewFrame())
1197 return; // no custom toolbars for preview frame!
1199 uno::Sequence
< uno::Sequence
< beans::PropertyValue
> > aTbxSeq
;
1200 if ( xDocCfgMgr
.is() )
1202 aTbxSeq
= xDocCfgMgr
->getUIElementsInfo( ui::UIElementType::TOOLBAR
);
1203 implts_createCustomToolBars( aTbxSeq
); // first create all document based toolbars
1205 if ( xModuleCfgMgr
.is() )
1207 aTbxSeq
= xModuleCfgMgr
->getUIElementsInfo( ui::UIElementType::TOOLBAR
);
1208 implts_createCustomToolBars( aTbxSeq
); // second create module based toolbars
1213 void ToolbarLayoutManager::implts_createNonContextSensitiveToolBars()
1215 SolarMutexClearableGuard aReadLock
;
1217 if ( !m_xPersistentWindowState
.is() || !m_xFrame
.is() || !m_bComponentAttached
)
1220 uno::Reference
< ui::XUIElementFactory
> xUIElementFactory( m_xUIElementFactoryManager
);
1221 uno::Reference
< container::XNameAccess
> xPersistentWindowState( m_xPersistentWindowState
);
1224 if (isPreviewFrame())
1227 std::vector
< OUString
> aMakeVisibleToolbars
;
1231 uno::Sequence
< OUString
> aToolbarNames
= xPersistentWindowState
->getElementNames();
1233 if ( aToolbarNames
.getLength() > 0 )
1235 OUString aElementType
;
1236 OUString aElementName
;
1239 uno::Reference
< ui::XUIElement
> xUIElement
;
1240 aMakeVisibleToolbars
.reserve(aToolbarNames
.getLength());
1244 const OUString
* pTbNames
= aToolbarNames
.getConstArray();
1245 for ( sal_Int32 i
= 0; i
< aToolbarNames
.getLength(); i
++ )
1247 aName
= pTbNames
[i
];
1248 parseResourceURL( aName
, aElementType
, aElementName
);
1250 // Check that we only create:
1251 // - Toolbars (the statusbar is also member of the persistent window state)
1252 // - Not custom toolbars, there are created with their own method (implts_createCustomToolbars)
1253 if ( aElementType
.equalsIgnoreAsciiCase("toolbar") &&
1254 aElementName
.indexOf( "custom_" ) == -1 )
1256 UIElement aNewToolbar
= implts_findToolbar( aName
);
1257 bool bFound
= ( aNewToolbar
.m_aName
== aName
);
1259 implts_readWindowStateData( aName
, aNewToolbar
);
1261 if ( aNewToolbar
.m_bVisible
&& !aNewToolbar
.m_bContextSensitive
)
1264 implts_insertToolbar( aNewToolbar
);
1265 aMakeVisibleToolbars
.push_back( aName
);
1271 catch (const uno::RuntimeException
&)
1275 catch (const uno::Exception
&)
1279 if ( !aMakeVisibleToolbars
.empty() )
1280 ::std::for_each( aMakeVisibleToolbars
.begin(), aMakeVisibleToolbars
.end(),
1281 ::boost::bind( &ToolbarLayoutManager::requestToolbar
, this, _1
));
1284 void ToolbarLayoutManager::implts_createCustomToolBars( const uno::Sequence
< uno::Sequence
< beans::PropertyValue
> >& aTbxSeqSeq
)
1286 const uno::Sequence
< beans::PropertyValue
>* pTbxSeq
= aTbxSeqSeq
.getConstArray();
1287 for ( sal_Int32 i
= 0; i
< aTbxSeqSeq
.getLength(); i
++ )
1289 const uno::Sequence
< beans::PropertyValue
>& rTbxSeq
= pTbxSeq
[i
];
1290 OUString aTbxResName
;
1292 for ( sal_Int32 j
= 0; j
< rTbxSeq
.getLength(); j
++ )
1294 if ( rTbxSeq
[j
].Name
== "ResourceURL" )
1295 rTbxSeq
[j
].Value
>>= aTbxResName
;
1296 else if ( rTbxSeq
[j
].Name
== "UIName" )
1297 rTbxSeq
[j
].Value
>>= aTbxTitle
;
1300 // Only create custom toolbars. Their name have to start with "custom_"!
1301 if ( !aTbxResName
.isEmpty() && ( aTbxResName
.indexOf( "custom_" ) != -1 ) )
1302 implts_createCustomToolBar( aTbxResName
, aTbxTitle
);
1306 void ToolbarLayoutManager::implts_createCustomToolBar( const OUString
& aTbxResName
, const OUString
& aTitle
)
1308 if ( !aTbxResName
.isEmpty() )
1310 if ( !createToolbar( aTbxResName
) )
1311 SAL_WARN("fwk.uielement", "ToolbarLayoutManager cannot create custom toolbar");
1313 uno::Reference
< ui::XUIElement
> xUIElement
= getToolbar( aTbxResName
);
1315 if ( !aTitle
.isEmpty() && xUIElement
.is() )
1317 SolarMutexGuard aGuard
;
1319 vcl::Window
* pWindow
= getWindowFromXUIElement( xUIElement
);
1321 pWindow
->SetText( aTitle
);
1326 void ToolbarLayoutManager::implts_reparentToolbars()
1328 SolarMutexClearableGuard aWriteLock
;
1329 UIElementVector aUIElementVector
= m_aUIElements
;
1330 vcl::Window
* pContainerWindow
= VCLUnoHelper::GetWindow( m_xContainerWindow
);
1331 vcl::Window
* pTopDockWindow
= VCLUnoHelper::GetWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_TOP
] );
1332 vcl::Window
* pBottomDockWindow
= VCLUnoHelper::GetWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_BOTTOM
] );
1333 vcl::Window
* pLeftDockWindow
= VCLUnoHelper::GetWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_LEFT
] );
1334 vcl::Window
* pRightDockWindow
= VCLUnoHelper::GetWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_RIGHT
] );
1337 SolarMutexGuard aGuard
;
1338 if ( pContainerWindow
)
1340 UIElementVector::iterator pIter
;
1341 for ( pIter
= aUIElementVector
.begin(); pIter
!= aUIElementVector
.end(); ++pIter
)
1343 uno::Reference
< ui::XUIElement
> xUIElement( pIter
->m_xUIElement
);
1344 if ( xUIElement
.is() )
1346 uno::Reference
< awt::XWindow
> xWindow
;
1349 // We have to retrieve the window reference with try/catch as it is
1350 // possible that all elements have been disposed!
1351 xWindow
= uno::Reference
< awt::XWindow
>( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
1353 catch (const uno::RuntimeException
&)
1357 catch (const uno::Exception
&)
1361 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
1364 // Reparent our child windows according to their current state.
1365 if ( pIter
->m_bFloating
)
1366 pWindow
->SetParent( pContainerWindow
);
1369 if ( pIter
->m_aDockedData
.m_nDockedArea
== ui::DockingArea_DOCKINGAREA_TOP
)
1370 pWindow
->SetParent( pTopDockWindow
);
1371 else if ( pIter
->m_aDockedData
.m_nDockedArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
)
1372 pWindow
->SetParent( pBottomDockWindow
);
1373 else if ( pIter
->m_aDockedData
.m_nDockedArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
1374 pWindow
->SetParent( pLeftDockWindow
);
1376 pWindow
->SetParent( pRightDockWindow
);
1384 void ToolbarLayoutManager::implts_setToolbarCreation( bool bStart
)
1387 m_bToolbarCreation
= bStart
;
1390 bool ToolbarLayoutManager::implts_isToolbarCreationActive()
1393 return m_bToolbarCreation
;
1396 void ToolbarLayoutManager::implts_setElementData( UIElement
& rElement
, const uno::Reference
< awt::XDockableWindow
>& rDockWindow
)
1398 SolarMutexClearableGuard aReadLock
;
1399 bool bShowElement( rElement
.m_bVisible
&& !rElement
.m_bMasterHide
&& implts_isParentWindowVisible() );
1402 uno::Reference
< awt::XDockableWindow
> xDockWindow( rDockWindow
);
1403 uno::Reference
< awt::XWindow2
> xWindow( xDockWindow
, uno::UNO_QUERY
);
1405 vcl::Window
* pWindow( 0 );
1406 ToolBox
* pToolBox( 0 );
1408 if ( xDockWindow
.is() && xWindow
.is() )
1411 SolarMutexGuard aGuard
;
1412 pWindow
= VCLUnoHelper::GetWindow( xWindow
);
1415 OUString aText
= pWindow
->GetText();
1416 if ( aText
.isEmpty() )
1417 pWindow
->SetText( rElement
.m_aUIName
);
1418 if ( rElement
.m_bNoClose
)
1419 pWindow
->SetStyle( pWindow
->GetStyle() & ~WB_CLOSEABLE
);
1420 if ( pWindow
->GetType() == WINDOW_TOOLBOX
)
1421 pToolBox
= static_cast<ToolBox
*>(pWindow
);
1425 pToolBox
->SetButtonType( (ButtonType
)rElement
.m_nStyle
);
1426 if ( rElement
.m_bNoClose
)
1427 pToolBox
->SetFloatStyle( pToolBox
->GetFloatStyle() & ~WB_CLOSEABLE
);
1431 if ( rElement
.m_bFloating
)
1435 SolarMutexGuard aGuard
;
1436 OUString aText
= pWindow
->GetText();
1437 if ( aText
.isEmpty() )
1438 pWindow
->SetText( rElement
.m_aUIName
);
1441 awt::Point
aPos(rElement
.m_aFloatingData
.m_aPos
);
1442 bool bWriteData( false );
1443 bool bUndefPos
= hasDefaultPosValue( rElement
.m_aFloatingData
.m_aPos
);
1444 bool bSetSize
= ( rElement
.m_aFloatingData
.m_aSize
.Width
!= 0 &&
1445 rElement
.m_aFloatingData
.m_aSize
.Height
!= 0 );
1446 xDockWindow
->setFloatingMode( sal_True
);
1449 aPos
= implts_findNextCascadeFloatingPos();
1450 rElement
.m_aFloatingData
.m_aPos
= aPos
; // set new cascaded position
1455 xWindow
->setOutputSize(rElement
.m_aFloatingData
.m_aSize
);
1460 // set an optimal initial floating size
1461 SolarMutexGuard aGuard
;
1462 ::Size
aSize( pToolBox
->CalcFloatingWindowSizePixel() );
1463 pToolBox
->SetOutputSizePixel( aSize
);
1467 // #i60882# IMPORTANT: Set position after size as it is
1468 // possible that we position some part of the toolbar
1469 // outside of the desktop. A default constructed toolbar
1470 // always has one line. Now VCL automatically
1471 // position the toolbar back into the desktop. Therefore
1472 // we resize the toolbar with the new (wrong) position.
1473 // To fix this problem we have to set the size BEFORE the
1475 xWindow
->setPosSize( aPos
.X
, aPos
.Y
, 0, 0, awt::PosSize::POS
);
1478 implts_writeWindowStateData( rElement
);
1479 if ( bShowElement
&& pWindow
)
1481 SolarMutexGuard aGuard
;
1482 pWindow
->Show( true, SHOW_NOFOCUSCHANGE
| SHOW_NOACTIVATE
);
1487 bool bSetSize( false );
1488 awt::Point aDockPos
;
1494 SolarMutexGuard aGuard
;
1495 pToolBox
->SetAlign( ImplConvertAlignment(rElement
.m_aDockedData
.m_nDockedArea
) );
1496 pToolBox
->SetLineCount( 1 );
1497 xDockWindow
->setFloatingMode( sal_False
);
1498 if ( rElement
.m_aDockedData
.m_bLocked
)
1499 xDockWindow
->lock();
1500 aSize
= pToolBox
->CalcWindowSizePixel();
1503 if ( isDefaultPos( rElement
.m_aDockedData
.m_aPos
))
1505 implts_findNextDockingPos( (ui::DockingArea
)rElement
.m_aDockedData
.m_nDockedArea
, aSize
, aDockPos
, aPixelPos
);
1506 rElement
.m_aDockedData
.m_aPos
= aDockPos
;
1510 xWindow
->setPosSize( aPixelPos
.X(), aPixelPos
.Y(), 0, 0, awt::PosSize::POS
);
1512 xWindow
->setOutputSize( AWTSize( aSize
) );
1516 SolarMutexGuard aGuard
;
1517 if ( !bShowElement
)
1524 void ToolbarLayoutManager::implts_destroyDockingAreaWindows()
1526 SolarMutexClearableGuard aWriteLock
;
1527 uno::Reference
< awt::XWindow
> xTopDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_TOP
] );
1528 uno::Reference
< awt::XWindow
> xLeftDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_LEFT
] );
1529 uno::Reference
< awt::XWindow
> xRightDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_RIGHT
] );
1530 uno::Reference
< awt::XWindow
> xBottomDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_BOTTOM
] );
1531 m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_TOP
].clear();
1532 m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_LEFT
].clear();
1533 m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_RIGHT
].clear();
1534 m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_BOTTOM
].clear();
1538 xTopDockingWindow
->dispose();
1539 xLeftDockingWindow
->dispose();
1540 xRightDockingWindow
->dispose();
1541 xBottomDockingWindow
->dispose();
1544 // persistence methods
1546 bool ToolbarLayoutManager::implts_readWindowStateData( const OUString
& aName
, UIElement
& rElementData
)
1548 return LayoutManager::readWindowStateData( aName
, rElementData
, m_xPersistentWindowState
,
1549 m_pGlobalSettings
, m_bGlobalSettings
, m_xContext
);
1552 void ToolbarLayoutManager::implts_writeWindowStateData( const UIElement
& rElementData
)
1554 SolarMutexResettableGuard aWriteLock
;
1555 uno::Reference
< container::XNameAccess
> xPersistentWindowState( m_xPersistentWindowState
);
1556 m_bStoreWindowState
= true; // set flag to determine that we triggered the notification
1559 bool bPersistent( false );
1560 uno::Reference
< beans::XPropertySet
> xPropSet( rElementData
.m_xUIElement
, uno::UNO_QUERY
);
1561 if ( xPropSet
.is() )
1565 // Check persistent flag of the user interface element
1566 xPropSet
->getPropertyValue("Persistent") >>= bPersistent
;
1568 catch (const beans::UnknownPropertyException
&)
1570 bPersistent
= true; // Non-configurable elements should at least store their dimension/position
1572 catch (const lang::WrappedTargetException
&)
1577 if ( bPersistent
&& xPersistentWindowState
.is() )
1581 uno::Sequence
< beans::PropertyValue
> aWindowState( 9 );
1583 aWindowState
[0].Name
= WINDOWSTATE_PROPERTY_DOCKED
;
1584 aWindowState
[0].Value
= ::uno::makeAny( !rElementData
.m_bFloating
);
1585 aWindowState
[1].Name
= WINDOWSTATE_PROPERTY_VISIBLE
;
1586 aWindowState
[1].Value
= uno::makeAny( rElementData
.m_bVisible
);
1587 aWindowState
[2].Name
= WINDOWSTATE_PROPERTY_DOCKINGAREA
;
1588 aWindowState
[2].Value
= uno::makeAny( static_cast< ui::DockingArea
>( rElementData
.m_aDockedData
.m_nDockedArea
) );
1590 awt::Point aPos
= rElementData
.m_aDockedData
.m_aPos
;
1591 aWindowState
[3].Name
= WINDOWSTATE_PROPERTY_DOCKPOS
;
1592 aWindowState
[3].Value
<<= aPos
;
1594 aPos
= rElementData
.m_aFloatingData
.m_aPos
;
1595 aWindowState
[4].Name
= WINDOWSTATE_PROPERTY_POS
;
1596 aWindowState
[4].Value
<<= aPos
;
1598 aWindowState
[5].Name
= WINDOWSTATE_PROPERTY_SIZE
;
1599 aWindowState
[5].Value
<<= rElementData
.m_aFloatingData
.m_aSize
;
1600 aWindowState
[6].Name
= WINDOWSTATE_PROPERTY_UINAME
;
1601 aWindowState
[6].Value
= uno::makeAny( rElementData
.m_aUIName
);
1602 aWindowState
[7].Name
= WINDOWSTATE_PROPERTY_LOCKED
;
1603 aWindowState
[7].Value
= uno::makeAny( rElementData
.m_aDockedData
.m_bLocked
);
1604 aWindowState
[8].Name
= WINDOWSTATE_PROPERTY_STYLE
;
1605 aWindowState
[8].Value
= uno::makeAny( static_cast<sal_uInt16
>(rElementData
.m_nStyle
) );
1607 OUString aName
= rElementData
.m_aName
;
1608 if ( xPersistentWindowState
->hasByName( aName
))
1610 uno::Reference
< container::XNameReplace
> xReplace( xPersistentWindowState
, uno::UNO_QUERY
);
1611 xReplace
->replaceByName( aName
, uno::makeAny( aWindowState
));
1615 uno::Reference
< container::XNameContainer
> xInsert( xPersistentWindowState
, uno::UNO_QUERY
);
1616 xInsert
->insertByName( aName
, uno::makeAny( aWindowState
));
1619 catch (const uno::Exception
&)
1626 m_bStoreWindowState
= false;
1630 /******************************************************************************
1631 LOOKUP PART FOR TOOLBARS
1632 ******************************************************************************/
1634 UIElement
& ToolbarLayoutManager::impl_findToolbar( const OUString
& aName
)
1636 static UIElement aEmptyElement
;
1637 UIElementVector::iterator pIter
;
1640 for ( pIter
= m_aUIElements
.begin(); pIter
!= m_aUIElements
.end(); ++pIter
)
1642 if ( pIter
->m_aName
== aName
)
1646 return aEmptyElement
;
1649 UIElement
ToolbarLayoutManager::implts_findToolbar( const OUString
& aName
)
1652 return impl_findToolbar( aName
);
1655 UIElement
ToolbarLayoutManager::implts_findToolbar( const uno::Reference
< uno::XInterface
>& xToolbar
)
1658 UIElementVector::const_iterator pIter
;
1661 for ( pIter
= m_aUIElements
.begin(); pIter
!= m_aUIElements
.end(); ++pIter
)
1663 if ( pIter
->m_xUIElement
.is() )
1665 uno::Reference
< uno::XInterface
> xIfac( pIter
->m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
1666 if ( xIfac
== xToolbar
)
1677 uno::Reference
< awt::XWindow
> ToolbarLayoutManager::implts_getXWindow( const OUString
& aName
)
1679 UIElementVector::iterator pIter
;
1680 uno::Reference
< awt::XWindow
> xWindow
;
1683 for ( pIter
= m_aUIElements
.begin(); pIter
!= m_aUIElements
.end(); ++pIter
)
1685 if ( pIter
->m_aName
== aName
&& pIter
->m_xUIElement
.is() )
1687 xWindow
= uno::Reference
< awt::XWindow
>( pIter
->m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
1695 vcl::Window
* ToolbarLayoutManager::implts_getWindow( const OUString
& aName
)
1697 uno::Reference
< awt::XWindow
> xWindow
= implts_getXWindow( aName
);
1698 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
1703 bool ToolbarLayoutManager::implts_insertToolbar( const UIElement
& rUIElement
)
1705 UIElement aTempData
;
1706 bool bFound( false );
1707 bool bResult( false );
1709 aTempData
= implts_findToolbar( rUIElement
.m_aName
);
1710 if ( aTempData
.m_aName
== rUIElement
.m_aName
)
1716 m_aUIElements
.push_back( rUIElement
);
1723 void ToolbarLayoutManager::implts_setToolbar( const UIElement
& rUIElement
)
1726 UIElement
& rData
= impl_findToolbar( rUIElement
.m_aName
);
1727 if ( rData
.m_aName
== rUIElement
.m_aName
)
1730 m_aUIElements
.push_back( rUIElement
);
1733 /******************************************************************************
1734 LAYOUT CODE PART FOR TOOLBARS
1735 ******************************************************************************/
1737 awt::Point
ToolbarLayoutManager::implts_findNextCascadeFloatingPos()
1739 const sal_Int32 nHotZoneX
= 50;
1740 const sal_Int32 nHotZoneY
= 50;
1741 const sal_Int32 nCascadeIndentX
= 15;
1742 const sal_Int32 nCascadeIndentY
= 15;
1744 SolarMutexClearableGuard aReadLock
;
1745 uno::Reference
< awt::XWindow2
> xContainerWindow( m_xContainerWindow
);
1746 uno::Reference
< awt::XWindow
> xTopDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_TOP
] );
1747 uno::Reference
< awt::XWindow
> xLeftDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_LEFT
] );
1750 awt::Point
aStartPos( nCascadeIndentX
, nCascadeIndentY
);
1751 awt::Point
aCurrPos( aStartPos
);
1752 awt::Rectangle aRect
;
1754 if ( xContainerWindow
.is() )
1756 SolarMutexGuard aGuard
;
1757 vcl::Window
* pContainerWindow
= VCLUnoHelper::GetWindow( xContainerWindow
);
1758 if ( pContainerWindow
)
1759 aStartPos
= AWTPoint(pContainerWindow
->OutputToScreenPixel(VCLPoint(aStartPos
)));
1762 // Determine size of top and left docking area
1763 awt::Rectangle
aTopRect( xTopDockingWindow
->getPosSize() );
1764 awt::Rectangle
aLeftRect( xLeftDockingWindow
->getPosSize() );
1766 aStartPos
.X
+= aLeftRect
.Width
+ nCascadeIndentX
;
1767 aStartPos
.Y
+= aTopRect
.Height
+ nCascadeIndentY
;
1768 aCurrPos
= aStartPos
;
1770 // Try to find a cascaded position for the new floating window
1771 UIElementVector::const_iterator pIter
;
1772 for ( pIter
= m_aUIElements
.begin(); pIter
!= m_aUIElements
.end(); ++pIter
)
1774 if ( pIter
->m_xUIElement
.is() )
1776 uno::Reference
< awt::XDockableWindow
> xDockWindow( pIter
->m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
1777 uno::Reference
< awt::XWindow
> xWindow( xDockWindow
, uno::UNO_QUERY
);
1778 if ( xDockWindow
.is() && xDockWindow
->isFloating() )
1780 SolarMutexGuard aGuard
;
1781 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
1782 if ( pWindow
&& pWindow
->IsVisible() )
1784 awt::Rectangle aFloatRect
= xWindow
->getPosSize();
1785 if ((( aFloatRect
.X
- nHotZoneX
) <= aCurrPos
.X
) &&
1786 ( aFloatRect
.X
>= aCurrPos
.X
) &&
1787 (( aFloatRect
.Y
- nHotZoneY
) <= aCurrPos
.Y
) &&
1788 ( aFloatRect
.Y
>= aCurrPos
.Y
))
1790 aCurrPos
.X
= aFloatRect
.X
+ nCascadeIndentX
;
1791 aCurrPos
.Y
= aFloatRect
.Y
+ nCascadeIndentY
;
1801 void ToolbarLayoutManager::implts_sortUIElements()
1804 UIElementVector::iterator pIterStart
= m_aUIElements
.begin();
1805 UIElementVector::iterator pIterEnd
= m_aUIElements
.end();
1807 std::stable_sort( pIterStart
, pIterEnd
); // first created element should first
1809 // We have to reset our temporary flags.
1810 UIElementVector::iterator pIter
;
1811 for ( pIter
= m_aUIElements
.begin(); pIter
!= m_aUIElements
.end(); ++pIter
)
1812 pIter
->m_bUserActive
= false;
1815 void ToolbarLayoutManager::implts_getUIElementVectorCopy( UIElementVector
& rCopy
)
1818 rCopy
= m_aUIElements
;
1821 ::Size
ToolbarLayoutManager::implts_getTopBottomDockingAreaSizes()
1824 uno::Reference
< awt::XWindow
> xTopDockingAreaWindow
;
1825 uno::Reference
< awt::XWindow
> xBottomDockingAreaWindow
;
1827 SolarMutexClearableGuard aReadLock
;
1828 xTopDockingAreaWindow
= m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_TOP
];
1829 xBottomDockingAreaWindow
= m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_BOTTOM
];
1832 if ( xTopDockingAreaWindow
.is() )
1833 aSize
.Width() = xTopDockingAreaWindow
->getPosSize().Height
;
1834 if ( xBottomDockingAreaWindow
.is() )
1835 aSize
.Height() = xBottomDockingAreaWindow
->getPosSize().Height
;
1840 void ToolbarLayoutManager::implts_getDockingAreaElementInfos( ui::DockingArea eDockingArea
, std::vector
< SingleRowColumnWindowData
>& rRowColumnsWindowData
)
1842 std::vector
< UIElement
> aWindowVector
;
1844 if (( eDockingArea
< ui::DockingArea_DOCKINGAREA_TOP
) || ( eDockingArea
> ui::DockingArea_DOCKINGAREA_RIGHT
))
1845 eDockingArea
= ui::DockingArea_DOCKINGAREA_TOP
;
1847 uno::Reference
< awt::XWindow
> xDockAreaWindow
;
1849 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1850 SolarMutexClearableGuard aReadLock
;
1851 aWindowVector
.reserve(m_aUIElements
.size());
1852 xDockAreaWindow
= m_xDockAreaWindows
[eDockingArea
];
1853 UIElementVector::iterator pIter
;
1854 for ( pIter
= m_aUIElements
.begin(); pIter
!= m_aUIElements
.end(); ++pIter
)
1856 if ( pIter
->m_aDockedData
.m_nDockedArea
== eDockingArea
&& pIter
->m_bVisible
&& !pIter
->m_bFloating
)
1858 uno::Reference
< ui::XUIElement
> xUIElement( pIter
->m_xUIElement
);
1859 if ( xUIElement
.is() )
1861 uno::Reference
< awt::XWindow
> xWindow( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
1862 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
1863 if ( xDockWindow
.is() )
1866 aWindowVector
.push_back( *pIter
);
1872 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1874 rRowColumnsWindowData
.clear();
1876 // Collect data from windows that are on the same row/column
1878 sal_Int32
nIndex( 0 );
1879 sal_Int32
nLastPos( 0 );
1880 sal_Int32
nCurrPos( -1 );
1881 sal_Int32
nLastRowColPixelPos( 0 );
1882 awt::Rectangle aDockAreaRect
;
1884 if ( xDockAreaWindow
.is() )
1885 aDockAreaRect
= xDockAreaWindow
->getPosSize();
1887 if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
1888 nLastRowColPixelPos
= 0;
1889 else if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
)
1890 nLastRowColPixelPos
= aDockAreaRect
.Height
;
1891 else if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
1892 nLastRowColPixelPos
= 0;
1894 nLastRowColPixelPos
= aDockAreaRect
.Width
;
1896 const sal_uInt32 nCount
= aWindowVector
.size();
1897 for ( j
= 0; j
< sal_Int32( nCount
); j
++ )
1899 const UIElement
& rElement
= aWindowVector
[j
];
1900 uno::Reference
< awt::XWindow
> xWindow
;
1901 uno::Reference
< ui::XUIElement
> xUIElement( rElement
.m_xUIElement
);
1902 awt::Rectangle aPosSize
;
1904 if ( !lcl_checkUIElement(xUIElement
,aPosSize
,xWindow
) )
1906 if ( isHorizontalDockingArea( eDockingArea
))
1908 if ( nCurrPos
== -1 )
1910 nCurrPos
= rElement
.m_aDockedData
.m_aPos
.Y
;
1913 SingleRowColumnWindowData aRowColumnWindowData
;
1914 aRowColumnWindowData
.nRowColumn
= nCurrPos
;
1915 rRowColumnsWindowData
.push_back( aRowColumnWindowData
);
1918 sal_Int32
nSpace( 0 );
1919 if ( rElement
.m_aDockedData
.m_aPos
.Y
!= nCurrPos
)
1921 if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
1922 nLastRowColPixelPos
+= rRowColumnsWindowData
[nIndex
].nStaticSize
;
1924 nLastRowColPixelPos
-= rRowColumnsWindowData
[nIndex
].nStaticSize
;
1927 nCurrPos
= rElement
.m_aDockedData
.m_aPos
.Y
;
1928 SingleRowColumnWindowData aRowColumnWindowData
;
1929 aRowColumnWindowData
.nRowColumn
= nCurrPos
;
1930 rRowColumnsWindowData
.push_back( aRowColumnWindowData
);
1933 // Calc space before an element and store it
1934 nSpace
= ( rElement
.m_aDockedData
.m_aPos
.X
- nLastPos
);
1935 if ( rElement
.m_aDockedData
.m_aPos
.X
>= nLastPos
)
1937 rRowColumnsWindowData
[nIndex
].nSpace
+= nSpace
;
1938 nLastPos
= rElement
.m_aDockedData
.m_aPos
.X
+ aPosSize
.Width
;
1943 nLastPos
+= aPosSize
.Width
;
1945 rRowColumnsWindowData
[nIndex
].aRowColumnSpace
.push_back( nSpace
);
1947 rRowColumnsWindowData
[nIndex
].aRowColumnWindows
.push_back( xWindow
);
1948 rRowColumnsWindowData
[nIndex
].aUIElementNames
.push_back( rElement
.m_aName
);
1949 rRowColumnsWindowData
[nIndex
].aRowColumnWindowSizes
.push_back(
1950 awt::Rectangle( rElement
.m_aDockedData
.m_aPos
.X
,
1951 rElement
.m_aDockedData
.m_aPos
.Y
,
1954 if ( rRowColumnsWindowData
[nIndex
].nStaticSize
< aPosSize
.Height
)
1955 rRowColumnsWindowData
[nIndex
].nStaticSize
= aPosSize
.Height
;
1956 if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
1957 rRowColumnsWindowData
[nIndex
].aRowColumnRect
= awt::Rectangle( 0, nLastRowColPixelPos
,
1958 aDockAreaRect
.Width
, aPosSize
.Height
);
1960 rRowColumnsWindowData
[nIndex
].aRowColumnRect
= awt::Rectangle( 0, ( nLastRowColPixelPos
- aPosSize
.Height
),
1961 aDockAreaRect
.Width
, aPosSize
.Height
);
1962 rRowColumnsWindowData
[nIndex
].nVarSize
+= aPosSize
.Width
+ nSpace
;
1966 if ( nCurrPos
== -1 )
1968 nCurrPos
= rElement
.m_aDockedData
.m_aPos
.X
;
1971 SingleRowColumnWindowData aRowColumnWindowData
;
1972 aRowColumnWindowData
.nRowColumn
= nCurrPos
;
1973 rRowColumnsWindowData
.push_back( aRowColumnWindowData
);
1976 sal_Int32
nSpace( 0 );
1977 if ( rElement
.m_aDockedData
.m_aPos
.X
!= nCurrPos
)
1979 if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
1980 nLastRowColPixelPos
+= rRowColumnsWindowData
[nIndex
].nStaticSize
;
1982 nLastRowColPixelPos
-= rRowColumnsWindowData
[nIndex
].nStaticSize
;
1985 nCurrPos
= rElement
.m_aDockedData
.m_aPos
.X
;
1986 SingleRowColumnWindowData aRowColumnWindowData
;
1987 aRowColumnWindowData
.nRowColumn
= nCurrPos
;
1988 rRowColumnsWindowData
.push_back( aRowColumnWindowData
);
1991 // Calc space before an element and store it
1992 nSpace
= ( rElement
.m_aDockedData
.m_aPos
.Y
- nLastPos
);
1993 if ( rElement
.m_aDockedData
.m_aPos
.Y
> nLastPos
)
1995 rRowColumnsWindowData
[nIndex
].nSpace
+= nSpace
;
1996 nLastPos
= rElement
.m_aDockedData
.m_aPos
.Y
+ aPosSize
.Height
;
2001 nLastPos
+= aPosSize
.Height
;
2003 rRowColumnsWindowData
[nIndex
].aRowColumnSpace
.push_back( nSpace
);
2005 rRowColumnsWindowData
[nIndex
].aRowColumnWindows
.push_back( xWindow
);
2006 rRowColumnsWindowData
[nIndex
].aUIElementNames
.push_back( rElement
.m_aName
);
2007 rRowColumnsWindowData
[nIndex
].aRowColumnWindowSizes
.push_back(
2008 awt::Rectangle( rElement
.m_aDockedData
.m_aPos
.X
,
2009 rElement
.m_aDockedData
.m_aPos
.Y
,
2012 if ( rRowColumnsWindowData
[nIndex
].nStaticSize
< aPosSize
.Width
)
2013 rRowColumnsWindowData
[nIndex
].nStaticSize
= aPosSize
.Width
;
2014 if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
2015 rRowColumnsWindowData
[nIndex
].aRowColumnRect
= awt::Rectangle( nLastRowColPixelPos
, 0,
2016 aPosSize
.Width
, aDockAreaRect
.Height
);
2018 rRowColumnsWindowData
[nIndex
].aRowColumnRect
= awt::Rectangle( ( nLastRowColPixelPos
- aPosSize
.Width
), 0,
2019 aPosSize
.Width
, aDockAreaRect
.Height
);
2020 rRowColumnsWindowData
[nIndex
].nVarSize
+= aPosSize
.Height
+ nSpace
;
2025 void ToolbarLayoutManager::implts_getDockingAreaElementInfoOnSingleRowCol( ui::DockingArea eDockingArea
, sal_Int32 nRowCol
, SingleRowColumnWindowData
& rRowColumnWindowData
)
2027 std::vector
< UIElement
> aWindowVector
;
2029 if (( eDockingArea
< ui::DockingArea_DOCKINGAREA_TOP
) || ( eDockingArea
> ui::DockingArea_DOCKINGAREA_RIGHT
))
2030 eDockingArea
= ui::DockingArea_DOCKINGAREA_TOP
;
2032 bool bHorzDockArea
= isHorizontalDockingArea( eDockingArea
);
2034 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2035 SolarMutexClearableGuard aReadLock
;
2036 UIElementVector::iterator pIter
;
2037 UIElementVector::iterator pEnd
= m_aUIElements
.end();
2038 for ( pIter
= m_aUIElements
.begin(); pIter
!= pEnd
; ++pIter
)
2040 if ( pIter
->m_aDockedData
.m_nDockedArea
== eDockingArea
)
2042 bool bSameRowCol
= bHorzDockArea
? ( pIter
->m_aDockedData
.m_aPos
.Y
== nRowCol
) : ( pIter
->m_aDockedData
.m_aPos
.X
== nRowCol
);
2043 uno::Reference
< ui::XUIElement
> xUIElement( pIter
->m_xUIElement
);
2045 if ( bSameRowCol
&& xUIElement
.is() )
2047 uno::Reference
< awt::XWindow
> xWindow( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
2050 SolarMutexGuard aGuard
;
2051 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
2052 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
2053 if ( pWindow
&& pIter
->m_bVisible
&& xDockWindow
.is() && !pIter
->m_bFloating
)
2054 aWindowVector
.push_back( *pIter
); // docked windows
2060 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2062 // Initialize structure
2063 rRowColumnWindowData
.aUIElementNames
.clear();
2064 rRowColumnWindowData
.aRowColumnWindows
.clear();
2065 rRowColumnWindowData
.aRowColumnWindowSizes
.clear();
2066 rRowColumnWindowData
.aRowColumnSpace
.clear();
2067 rRowColumnWindowData
.nVarSize
= 0;
2068 rRowColumnWindowData
.nStaticSize
= 0;
2069 rRowColumnWindowData
.nSpace
= 0;
2070 rRowColumnWindowData
.nRowColumn
= nRowCol
;
2072 // Collect data from windows that are on the same row/column
2074 sal_Int32
nLastPos( 0 );
2076 const sal_uInt32 nCount
= aWindowVector
.size();
2077 for ( j
= 0; j
< sal_Int32( nCount
); j
++ )
2079 const UIElement
& rElement
= aWindowVector
[j
];
2080 uno::Reference
< awt::XWindow
> xWindow
;
2081 uno::Reference
< ui::XUIElement
> xUIElement( rElement
.m_xUIElement
);
2082 awt::Rectangle aPosSize
;
2083 if ( !lcl_checkUIElement(xUIElement
,aPosSize
,xWindow
) )
2087 if ( isHorizontalDockingArea( eDockingArea
))
2089 nSpace
= ( rElement
.m_aDockedData
.m_aPos
.X
- nLastPos
);
2091 // Calc space before an element and store it
2092 if ( rElement
.m_aDockedData
.m_aPos
.X
> nLastPos
)
2093 rRowColumnWindowData
.nSpace
+= nSpace
;
2097 nLastPos
= rElement
.m_aDockedData
.m_aPos
.X
+ aPosSize
.Width
;
2099 rRowColumnWindowData
.aRowColumnWindowSizes
.push_back(
2100 awt::Rectangle( rElement
.m_aDockedData
.m_aPos
.X
, rElement
.m_aDockedData
.m_aPos
.Y
,
2101 aPosSize
.Width
, aPosSize
.Height
));
2102 if ( rRowColumnWindowData
.nStaticSize
< aPosSize
.Height
)
2103 rRowColumnWindowData
.nStaticSize
= aPosSize
.Height
;
2104 rRowColumnWindowData
.nVarSize
+= aPosSize
.Width
;
2108 // Calc space before an element and store it
2109 nSpace
= ( rElement
.m_aDockedData
.m_aPos
.Y
- nLastPos
);
2110 if ( rElement
.m_aDockedData
.m_aPos
.Y
> nLastPos
)
2111 rRowColumnWindowData
.nSpace
+= nSpace
;
2115 nLastPos
= rElement
.m_aDockedData
.m_aPos
.Y
+ aPosSize
.Height
;
2117 rRowColumnWindowData
.aRowColumnWindowSizes
.push_back(
2118 awt::Rectangle( rElement
.m_aDockedData
.m_aPos
.X
, rElement
.m_aDockedData
.m_aPos
.Y
,
2119 aPosSize
.Width
, aPosSize
.Height
));
2120 if ( rRowColumnWindowData
.nStaticSize
< aPosSize
.Width
)
2121 rRowColumnWindowData
.nStaticSize
= aPosSize
.Width
;
2122 rRowColumnWindowData
.nVarSize
+= aPosSize
.Height
;
2125 rRowColumnWindowData
.aUIElementNames
.push_back( rElement
.m_aName
);
2126 rRowColumnWindowData
.aRowColumnWindows
.push_back( xWindow
);
2127 rRowColumnWindowData
.aRowColumnSpace
.push_back( nSpace
);
2128 rRowColumnWindowData
.nVarSize
+= nSpace
;
2132 ::Rectangle
ToolbarLayoutManager::implts_getWindowRectFromRowColumn(
2133 ui::DockingArea DockingArea
,
2134 const SingleRowColumnWindowData
& rRowColumnWindowData
,
2135 const ::Point
& rMousePos
,
2136 const OUString
& rExcludeElementName
)
2138 ::Rectangle aWinRect
;
2140 if (( DockingArea
< ui::DockingArea_DOCKINGAREA_TOP
) || ( DockingArea
> ui::DockingArea_DOCKINGAREA_RIGHT
))
2141 DockingArea
= ui::DockingArea_DOCKINGAREA_TOP
;
2143 if ( rRowColumnWindowData
.aRowColumnWindows
.empty() )
2147 SolarMutexClearableGuard aReadLock
;
2148 vcl::Window
* pContainerWindow( VCLUnoHelper::GetWindow( m_xContainerWindow
));
2149 vcl::Window
* pDockingAreaWindow( VCLUnoHelper::GetWindow( m_xDockAreaWindows
[DockingArea
] ));
2152 // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect
2153 SolarMutexGuard aGuard
;
2155 // Retrieve output size from container Window
2156 if ( pDockingAreaWindow
&& pContainerWindow
)
2158 const sal_uInt32 nCount
= rRowColumnWindowData
.aRowColumnWindows
.size();
2159 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
2161 awt::Rectangle aWindowRect
= rRowColumnWindowData
.aRowColumnWindows
[i
]->getPosSize();
2162 ::Rectangle
aRect( aWindowRect
.X
, aWindowRect
.Y
, aWindowRect
.X
+aWindowRect
.Width
, aWindowRect
.Y
+aWindowRect
.Height
);
2163 aRect
.SetPos( pContainerWindow
->ScreenToOutputPixel( pDockingAreaWindow
->OutputToScreenPixel( aRect
.TopLeft() )));
2164 if ( aRect
.IsInside( rMousePos
))
2166 // Check if we have found the excluded element. If yes, we have to provide an empty rectangle.
2167 // We prevent that a toolbar cannot be moved when the mouse pointer is inside its own rectangle!
2168 if ( rExcludeElementName
!= rRowColumnWindowData
.aUIElementNames
[i
] )
2180 ::Rectangle
ToolbarLayoutManager::implts_determineFrontDockingRect(
2181 ui::DockingArea eDockingArea
,
2183 const ::Rectangle
& rDockedElementRect
,
2184 const OUString
& rMovedElementName
,
2185 const ::Rectangle
& rMovedElementRect
)
2187 SingleRowColumnWindowData aRowColumnWindowData
;
2189 bool bHorzDockArea( isHorizontalDockingArea( eDockingArea
));
2190 implts_getDockingAreaElementInfoOnSingleRowCol( eDockingArea
, nRowCol
, aRowColumnWindowData
);
2191 if ( aRowColumnWindowData
.aRowColumnWindows
.empty() )
2192 return rMovedElementRect
;
2195 sal_Int32
nSpace( 0 );
2196 ::Rectangle
aFrontDockingRect( rMovedElementRect
);
2197 const sal_uInt32 nCount
= aRowColumnWindowData
.aRowColumnWindows
.size();
2198 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
2200 if ( bHorzDockArea
)
2202 if ( aRowColumnWindowData
.aRowColumnWindowSizes
[i
].X
>= rDockedElementRect
.Left() )
2204 nSpace
+= aRowColumnWindowData
.aRowColumnSpace
[i
];
2207 else if ( aRowColumnWindowData
.aUIElementNames
[i
] == rMovedElementName
)
2208 nSpace
+= aRowColumnWindowData
.aRowColumnWindowSizes
[i
].Width
+
2209 aRowColumnWindowData
.aRowColumnSpace
[i
];
2215 if ( aRowColumnWindowData
.aRowColumnWindowSizes
[i
].Y
>= rDockedElementRect
.Top() )
2217 nSpace
+= aRowColumnWindowData
.aRowColumnSpace
[i
];
2220 else if ( aRowColumnWindowData
.aUIElementNames
[i
] == rMovedElementName
)
2221 nSpace
+= aRowColumnWindowData
.aRowColumnWindowSizes
[i
].Height
+
2222 aRowColumnWindowData
.aRowColumnSpace
[i
];
2230 sal_Int32 nMove
= std::min( nSpace
, static_cast<sal_Int32
>(aFrontDockingRect
.getWidth()) );
2231 if ( bHorzDockArea
)
2232 aFrontDockingRect
.Move( -nMove
, 0 );
2234 aFrontDockingRect
.Move( 0, -nMove
);
2237 return aFrontDockingRect
;
2241 void ToolbarLayoutManager::implts_findNextDockingPos( ui::DockingArea DockingArea
, const ::Size
& aUIElementSize
, awt::Point
& rVirtualPos
, ::Point
& rPixelPos
)
2243 SolarMutexClearableGuard aReadLock
;
2244 if (( DockingArea
< ui::DockingArea_DOCKINGAREA_TOP
) || ( DockingArea
> ui::DockingArea_DOCKINGAREA_RIGHT
))
2245 DockingArea
= ui::DockingArea_DOCKINGAREA_TOP
;
2246 uno::Reference
< awt::XWindow
> xDockingWindow( m_xDockAreaWindows
[DockingArea
] );
2247 ::Size aDockingWinSize
;
2248 vcl::Window
* pDockingWindow( 0 );
2252 // Retrieve output size from container Window
2253 SolarMutexGuard aGuard
;
2254 pDockingWindow
= VCLUnoHelper::GetWindow( xDockingWindow
);
2255 if ( pDockingWindow
)
2256 aDockingWinSize
= pDockingWindow
->GetOutputSizePixel();
2259 sal_Int32
nFreeRowColPixelPos( 0 );
2260 sal_Int32
nMaxSpace( 0 );
2261 sal_Int32
nNeededSpace( 0 );
2262 sal_Int32
nTopDockingAreaSize( 0 );
2264 if ( isHorizontalDockingArea( DockingArea
))
2266 nMaxSpace
= aDockingWinSize
.Width();
2267 nNeededSpace
= aUIElementSize
.Width();
2271 nMaxSpace
= aDockingWinSize
.Height();
2272 nNeededSpace
= aUIElementSize
.Height();
2273 nTopDockingAreaSize
= implts_getTopBottomDockingAreaSizes().Width();
2276 std::vector
< SingleRowColumnWindowData
> aRowColumnsWindowData
;
2278 implts_getDockingAreaElementInfos( DockingArea
, aRowColumnsWindowData
);
2279 sal_Int32
nPixelPos( 0 );
2280 const sal_uInt32 nCount
= aRowColumnsWindowData
.size();
2281 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
2283 SingleRowColumnWindowData
& rRowColumnWindowData
= aRowColumnsWindowData
[i
];
2285 if (( DockingArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
) ||
2286 ( DockingArea
== ui::DockingArea_DOCKINGAREA_RIGHT
))
2287 nPixelPos
+= rRowColumnWindowData
.nStaticSize
;
2289 if ((( nMaxSpace
- rRowColumnWindowData
.nVarSize
) >= nNeededSpace
) ||
2290 ( rRowColumnWindowData
.nSpace
>= nNeededSpace
))
2292 // Check current row where we can find the needed space
2293 sal_Int32
nCurrPos( 0 );
2294 const sal_uInt32 nWindowSizesCount
= rRowColumnWindowData
.aRowColumnWindowSizes
.size();
2295 for ( sal_uInt32 j
= 0; j
< nWindowSizesCount
; j
++ )
2297 awt::Rectangle rRect
= rRowColumnWindowData
.aRowColumnWindowSizes
[j
];
2298 sal_Int32
& rSpace
= rRowColumnWindowData
.aRowColumnSpace
[j
];
2299 if ( isHorizontalDockingArea( DockingArea
))
2301 if ( rSpace
>= nNeededSpace
)
2303 rVirtualPos
= awt::Point( nCurrPos
, rRowColumnWindowData
.nRowColumn
);
2304 if ( DockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
2305 rPixelPos
= ::Point( nCurrPos
, nPixelPos
);
2307 rPixelPos
= ::Point( nCurrPos
, aDockingWinSize
.Height() - nPixelPos
);
2310 nCurrPos
= rRect
.X
+ rRect
.Width
;
2314 if ( rSpace
>= nNeededSpace
)
2316 rVirtualPos
= awt::Point( rRowColumnWindowData
.nRowColumn
, nCurrPos
);
2317 if ( DockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
2318 rPixelPos
= ::Point( nPixelPos
, nTopDockingAreaSize
+ nCurrPos
);
2320 rPixelPos
= ::Point( aDockingWinSize
.Width() - nPixelPos
, nTopDockingAreaSize
+ nCurrPos
);
2323 nCurrPos
= rRect
.Y
+ rRect
.Height
;
2327 if (( nCurrPos
+ nNeededSpace
) <= nMaxSpace
)
2329 if ( isHorizontalDockingArea( DockingArea
))
2331 rVirtualPos
= awt::Point( nCurrPos
, rRowColumnWindowData
.nRowColumn
);
2332 if ( DockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
2333 rPixelPos
= ::Point( nCurrPos
, nPixelPos
);
2335 rPixelPos
= ::Point( nCurrPos
, aDockingWinSize
.Height() - nPixelPos
);
2340 rVirtualPos
= awt::Point( rRowColumnWindowData
.nRowColumn
, nCurrPos
);
2341 if ( DockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
2342 rPixelPos
= ::Point( nPixelPos
, nTopDockingAreaSize
+ nCurrPos
);
2344 rPixelPos
= ::Point( aDockingWinSize
.Width() - nPixelPos
, nTopDockingAreaSize
+ nCurrPos
);
2350 if (( DockingArea
== ui::DockingArea_DOCKINGAREA_TOP
) || ( DockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
))
2351 nPixelPos
+= rRowColumnWindowData
.nStaticSize
;
2354 sal_Int32
nNextFreeRowCol( 0 );
2355 sal_Int32 nRowColumnsCount
= aRowColumnsWindowData
.size();
2356 if ( nRowColumnsCount
> 0 )
2357 nNextFreeRowCol
= aRowColumnsWindowData
[nRowColumnsCount
-1].nRowColumn
+1;
2359 nNextFreeRowCol
= 0;
2361 if ( nNextFreeRowCol
== 0 )
2363 if ( DockingArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
)
2364 nFreeRowColPixelPos
= aDockingWinSize
.Height() - aUIElementSize
.Height();
2365 else if ( DockingArea
== ui::DockingArea_DOCKINGAREA_RIGHT
)
2366 nFreeRowColPixelPos
= aDockingWinSize
.Width() - aUIElementSize
.Width();
2369 if ( isHorizontalDockingArea( DockingArea
))
2371 rVirtualPos
= awt::Point( 0, nNextFreeRowCol
);
2372 if ( DockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
2373 rPixelPos
= ::Point( 0, nFreeRowColPixelPos
);
2375 rPixelPos
= ::Point( 0, aDockingWinSize
.Height() - nFreeRowColPixelPos
);
2379 rVirtualPos
= awt::Point( nNextFreeRowCol
, 0 );
2380 rPixelPos
= ::Point( aDockingWinSize
.Width() - nFreeRowColPixelPos
, 0 );
2384 void ToolbarLayoutManager::implts_calcWindowPosSizeOnSingleRowColumn(
2385 sal_Int32 nDockingArea
,
2387 SingleRowColumnWindowData
& rRowColumnWindowData
,
2388 const ::Size
& rContainerSize
)
2391 sal_Int32
nRCSpace( rRowColumnWindowData
.nSpace
);
2392 sal_Int32
nTopDockingAreaSize(0);
2393 sal_Int32
nBottomDockingAreaSize(0);
2394 sal_Int32
nContainerClientSize(0);
2396 if ( rRowColumnWindowData
.aRowColumnWindows
.empty() )
2399 if ( isHorizontalDockingArea( nDockingArea
))
2401 nContainerClientSize
= rContainerSize
.Width();
2402 nDiff
= nContainerClientSize
- rRowColumnWindowData
.nVarSize
;
2406 nTopDockingAreaSize
= implts_getTopBottomDockingAreaSizes().Width();
2407 nBottomDockingAreaSize
= implts_getTopBottomDockingAreaSizes().Height();
2408 nContainerClientSize
= ( rContainerSize
.Height() - nTopDockingAreaSize
- nBottomDockingAreaSize
);
2409 nDiff
= nContainerClientSize
- rRowColumnWindowData
.nVarSize
;
2412 const sal_uInt32 nCount
= rRowColumnWindowData
.aRowColumnWindowSizes
.size();
2413 if (( nDiff
< 0 ) && ( nRCSpace
> 0 ))
2415 // First we try to reduce the size of blank space before/behind docked windows
2416 sal_Int32 i
= nCount
- 1;
2419 sal_Int32 nSpace
= rRowColumnWindowData
.aRowColumnSpace
[i
];
2420 if ( nSpace
>= -nDiff
)
2422 if ( isHorizontalDockingArea( nDockingArea
))
2424 // Try to move this and all user elements behind with the calculated difference
2425 for ( sal_uInt32 j
= i
; j
< nCount
; j
++ )
2426 rRowColumnWindowData
.aRowColumnWindowSizes
[j
].X
+= nDiff
;
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
].Y
+= nDiff
;
2438 else if ( nSpace
> 0 )
2440 if ( isHorizontalDockingArea( nDockingArea
))
2442 // Try to move this and all user elements behind with the calculated difference
2443 for ( sal_uInt32 j
= i
; j
< nCount
; j
++ )
2444 rRowColumnWindowData
.aRowColumnWindowSizes
[j
].X
-= nSpace
;
2448 // Try to move this and all user elements behind with the calculated difference
2449 for ( sal_uInt32 j
= i
; j
< nCount
; j
++ )
2450 rRowColumnWindowData
.aRowColumnWindowSizes
[j
].Y
-= nSpace
;
2458 // Check if we have to reduce further
2461 // Now we have to reduce the size of certain docked windows
2462 sal_Int32 i
= sal_Int32( nCount
- 1 );
2465 awt::Rectangle
& rWinRect
= rRowColumnWindowData
.aRowColumnWindowSizes
[i
];
2468 SolarMutexGuard aGuard
;
2470 uno::Reference
< awt::XWindow
> xWindow
= rRowColumnWindowData
.aRowColumnWindows
[i
];
2471 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
2472 if ( pWindow
&& pWindow
->GetType() == WINDOW_TOOLBOX
)
2473 aMinSize
= static_cast<ToolBox
*>(pWindow
)->CalcMinimumWindowSizePixel();
2476 if (( aMinSize
.Width() > 0 ) && ( aMinSize
.Height() > 0 ))
2478 if ( isHorizontalDockingArea( nDockingArea
))
2480 sal_Int32 nMaxReducation
= ( rWinRect
.Width
- aMinSize
.Width() );
2481 if ( nMaxReducation
>= -nDiff
)
2483 rWinRect
.Width
= rWinRect
.Width
+ nDiff
;
2488 rWinRect
.Width
= aMinSize
.Width();
2489 nDiff
+= nMaxReducation
;
2492 // Try to move this and all user elements behind with the calculated difference
2493 for ( sal_uInt32 j
= i
; j
< nCount
; j
++ )
2494 rRowColumnWindowData
.aRowColumnWindowSizes
[j
].X
+= nDiff
;
2498 sal_Int32 nMaxReducation
= ( rWinRect
.Height
- aMinSize
.Height() );
2499 if ( nMaxReducation
>= -nDiff
)
2501 rWinRect
.Height
= rWinRect
.Height
+ nDiff
;
2506 rWinRect
.Height
= aMinSize
.Height();
2507 nDiff
+= nMaxReducation
;
2510 // Try to move this and all user elements behind with the calculated difference
2511 for ( sal_uInt32 j
= i
; j
< nCount
; j
++ )
2512 rRowColumnWindowData
.aRowColumnWindowSizes
[j
].Y
+= nDiff
;
2523 SolarMutexClearableGuard aReadLock
;
2524 vcl::Window
* pDockAreaWindow
= VCLUnoHelper::GetWindow( m_xDockAreaWindows
[nDockingArea
] );
2527 sal_Int32
nCurrPos( 0 );
2529 SolarMutexGuard aGuard
;
2530 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
2532 uno::Reference
< awt::XWindow
> xWindow
= rRowColumnWindowData
.aRowColumnWindows
[i
];
2533 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
2534 vcl::Window
* pOldParentWindow
= pWindow
->GetParent();
2536 if ( pDockAreaWindow
!= pOldParentWindow
)
2537 pWindow
->SetParent( pDockAreaWindow
);
2539 awt::Rectangle aWinRect
= rRowColumnWindowData
.aRowColumnWindowSizes
[i
];
2540 if ( isHorizontalDockingArea( nDockingArea
))
2542 if ( aWinRect
.X
< nCurrPos
)
2543 aWinRect
.X
= nCurrPos
;
2544 pWindow
->SetPosSizePixel( ::Point( aWinRect
.X
, nOffset
), ::Size( aWinRect
.Width
, rRowColumnWindowData
.nStaticSize
));
2545 pWindow
->Show( true, SHOW_NOFOCUSCHANGE
| SHOW_NOACTIVATE
);
2546 nCurrPos
+= ( aWinRect
.X
- nCurrPos
) + aWinRect
.Width
;
2550 if ( aWinRect
.Y
< nCurrPos
)
2551 aWinRect
.Y
= nCurrPos
;
2552 pWindow
->SetPosSizePixel( ::Point( nOffset
, aWinRect
.Y
), ::Size( rRowColumnWindowData
.nStaticSize
, aWinRect
.Height
));
2553 pWindow
->Show( true, SHOW_NOFOCUSCHANGE
| SHOW_NOACTIVATE
);
2554 nCurrPos
+= ( aWinRect
.Y
- nCurrPos
) + aWinRect
.Height
;
2559 void ToolbarLayoutManager::implts_setLayoutDirty()
2562 m_bLayoutDirty
= true;
2565 void ToolbarLayoutManager::implts_setLayoutInProgress( bool bInProgress
)
2568 m_bLayoutInProgress
= bInProgress
;
2571 ::Rectangle
ToolbarLayoutManager::implts_calcHotZoneRect( const ::Rectangle
& rRect
, sal_Int32 nHotZoneOffset
)
2573 ::Rectangle
aRect( rRect
);
2575 aRect
.Left() -= nHotZoneOffset
;
2576 aRect
.Top() -= nHotZoneOffset
;
2577 aRect
.Right() += nHotZoneOffset
;
2578 aRect
.Bottom() += nHotZoneOffset
;
2583 void ToolbarLayoutManager::implts_calcDockingPosSize(
2584 UIElement
& rUIElement
,
2585 DockingOperation
& rDockingOperation
,
2586 ::Rectangle
& rTrackingRect
,
2587 const Point
& rMousePos
)
2589 SolarMutexResettableGuard aReadLock
;
2590 uno::Reference
< awt::XWindow2
> xContainerWindow( m_xContainerWindow
);
2591 ::Size aContainerWinSize
;
2592 vcl::Window
* pContainerWindow( 0 );
2593 ::Rectangle
aDockingAreaOffsets( m_aDockingAreaOffsets
);
2596 if ( !rUIElement
.m_xUIElement
.is() )
2598 rTrackingRect
= ::Rectangle();
2603 // Retrieve output size from container Window
2604 SolarMutexGuard aGuard
;
2605 pContainerWindow
= VCLUnoHelper::GetWindow( xContainerWindow
);
2606 aContainerWinSize
= pContainerWindow
->GetOutputSizePixel();
2609 vcl::Window
* pDockingAreaWindow( 0 );
2610 ToolBox
* pToolBox( 0 );
2611 uno::Reference
< awt::XWindow
> xWindow( rUIElement
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
2612 uno::Reference
< awt::XWindow
> xDockingAreaWindow
;
2613 ::Rectangle
aTrackingRect( rTrackingRect
);
2614 ui::DockingArea
eDockedArea( (ui::DockingArea
)rUIElement
.m_aDockedData
.m_nDockedArea
);
2615 sal_Int32
nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() );
2616 sal_Int32
nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() );
2617 bool bHorizontalDockArea(( eDockedArea
== ui::DockingArea_DOCKINGAREA_TOP
) ||
2618 ( eDockedArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
));
2619 sal_Int32 nMaxLeftRightDockAreaSize
= aContainerWinSize
.Height() -
2620 nTopDockingAreaSize
-
2621 nBottomDockingAreaSize
-
2622 aDockingAreaOffsets
.Top() -
2623 aDockingAreaOffsets
.Bottom();
2624 ::Rectangle aDockingAreaRect
;
2627 xDockingAreaWindow
= m_xDockAreaWindows
[eDockedArea
];
2631 SolarMutexGuard aGuard
;
2632 pDockingAreaWindow
= VCLUnoHelper::GetWindow( xDockingAreaWindow
);
2633 vcl::Window
* pDockWindow
= VCLUnoHelper::GetWindow( xWindow
);
2634 if ( pDockWindow
&& pDockWindow
->GetType() == WINDOW_TOOLBOX
)
2635 pToolBox
= static_cast<ToolBox
*>(pDockWindow
);
2637 aDockingAreaRect
= ::Rectangle( pDockingAreaWindow
->GetPosPixel(), pDockingAreaWindow
->GetSizePixel() );
2640 // docked toolbars always have one line
2641 ::Size aSize
= pToolBox
->CalcWindowSizePixel( 1, ImplConvertAlignment( sal_Int16( eDockedArea
)) );
2642 aTrackingRect
.SetSize( ::Size( aSize
.Width(), aSize
.Height() ));
2646 // default docking operation, dock on the given row/column
2647 bool bOpOutsideOfDockingArea( !aDockingAreaRect
.IsInside( rMousePos
));
2649 std::vector
< SingleRowColumnWindowData
> aRowColumnsWindowData
;
2651 rDockingOperation
= DOCKOP_ON_COLROW
;
2652 implts_getDockingAreaElementInfos( eDockedArea
, aRowColumnsWindowData
);
2654 // determine current first row/column and last row/column
2655 sal_Int32
nMaxRowCol( -1 );
2656 sal_Int32
nMinRowCol( SAL_MAX_INT32
);
2657 const sal_uInt32 nCount
= aRowColumnsWindowData
.size();
2658 for ( sal_uInt32 i
= 0; i
< nCount
; i
++ )
2660 if ( aRowColumnsWindowData
[i
].nRowColumn
> nMaxRowCol
)
2661 nMaxRowCol
= aRowColumnsWindowData
[i
].nRowColumn
;
2662 if ( aRowColumnsWindowData
[i
].nRowColumn
< nMinRowCol
)
2663 nMinRowCol
= aRowColumnsWindowData
[i
].nRowColumn
;
2666 if ( !bOpOutsideOfDockingArea
)
2668 // docking inside our docking area
2669 sal_Int32
nIndex( -1 );
2670 sal_Int32
nRowCol( -1 );
2671 ::Rectangle aWindowRect
;
2672 ::Rectangle aRowColumnRect
;
2674 const sal_uInt32 nWindowDataCount
= aRowColumnsWindowData
.size();
2675 for ( sal_uInt32 i
= 0; i
< nWindowDataCount
; i
++ )
2677 ::Rectangle
aRect( aRowColumnsWindowData
[i
].aRowColumnRect
.X
,
2678 aRowColumnsWindowData
[i
].aRowColumnRect
.Y
,
2679 aRowColumnsWindowData
[i
].aRowColumnRect
.X
+ aRowColumnsWindowData
[i
].aRowColumnRect
.Width
,
2680 aRowColumnsWindowData
[i
].aRowColumnRect
.Y
+ aRowColumnsWindowData
[i
].aRowColumnRect
.Height
);
2683 // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect
2684 SolarMutexGuard aGuard
;
2685 aRect
.SetPos( pContainerWindow
->ScreenToOutputPixel( pDockingAreaWindow
->OutputToScreenPixel( aRect
.TopLeft() )));
2688 bool bIsInsideRowCol( aRect
.IsInside( rMousePos
) );
2689 if ( bIsInsideRowCol
)
2692 nRowCol
= aRowColumnsWindowData
[i
].nRowColumn
;
2693 rDockingOperation
= implts_determineDockingOperation( eDockedArea
, aRect
, rMousePos
);
2694 aWindowRect
= implts_getWindowRectFromRowColumn( eDockedArea
, aRowColumnsWindowData
[i
], rMousePos
, rUIElement
.m_aName
);
2695 aRowColumnRect
= aRect
;
2700 OSL_ENSURE( ( nIndex
>= 0 ) && ( nRowCol
>= 0 ), "Impossible case - no row/column found but mouse pointer is inside our docking area" );
2701 if (( nIndex
>= 0 ) && ( nRowCol
>= 0 ))
2703 if ( rDockingOperation
== DOCKOP_ON_COLROW
)
2705 if ( !aWindowRect
.IsEmpty())
2707 // Tracking rect is on a row/column and mouse is over a docked toolbar.
2708 // Determine if the tracking rect must be located before/after the docked toolbar.
2710 ::Rectangle
aUIElementRect( aWindowRect
);
2711 sal_Int32
nMiddle( bHorizontalDockArea
? ( aWindowRect
.Left() + aWindowRect
.getWidth() / 2 ) :
2712 ( aWindowRect
.Top() + aWindowRect
.getHeight() / 2 ));
2713 bool bInsertBefore( bHorizontalDockArea
? ( rMousePos
.X() < nMiddle
) : ( rMousePos
.Y() < nMiddle
));
2714 if ( bInsertBefore
)
2716 if ( bHorizontalDockArea
)
2718 sal_Int32 nSize
= ::std::max( sal_Int32( 0 ), std::min( sal_Int32( aContainerWinSize
.Width() - aWindowRect
.Left() ),
2719 sal_Int32( aTrackingRect
.getWidth() )));
2721 nSize
= aWindowRect
.getWidth();
2723 aUIElementRect
.SetSize( ::Size( nSize
, aWindowRect
.getHeight() ));
2724 aWindowRect
= implts_determineFrontDockingRect( eDockedArea
, nRowCol
, aWindowRect
,rUIElement
.m_aName
, aUIElementRect
);
2726 // Set virtual position
2727 rUIElement
.m_aDockedData
.m_aPos
.X
= aWindowRect
.Left();
2728 rUIElement
.m_aDockedData
.m_aPos
.Y
= nRowCol
;
2732 sal_Int32 nSize
= ::std::max( sal_Int32( 0 ), std::min( sal_Int32(
2733 nTopDockingAreaSize
+ nMaxLeftRightDockAreaSize
- aWindowRect
.Top() ),
2734 sal_Int32( aTrackingRect
.getHeight() )));
2736 nSize
= aWindowRect
.getHeight();
2738 aUIElementRect
.SetSize( ::Size( aWindowRect
.getWidth(), nSize
));
2739 aWindowRect
= implts_determineFrontDockingRect( eDockedArea
, nRowCol
, aWindowRect
, rUIElement
.m_aName
, aUIElementRect
);
2741 // Set virtual position
2742 sal_Int32 nPosY
= pDockingAreaWindow
->ScreenToOutputPixel(
2743 pContainerWindow
->OutputToScreenPixel( aWindowRect
.TopLeft() )).Y();
2744 rUIElement
.m_aDockedData
.m_aPos
.X
= nRowCol
;
2745 rUIElement
.m_aDockedData
.m_aPos
.Y
= nPosY
;
2748 rTrackingRect
= aWindowRect
;
2753 if ( bHorizontalDockArea
)
2755 sal_Int32 nSize
= ::std::max( sal_Int32( 0 ), std::min( sal_Int32(( aContainerWinSize
.Width() ) - aWindowRect
.Right() ),
2756 sal_Int32( aTrackingRect
.getWidth() )));
2759 aUIElementRect
.SetPos( ::Point( aContainerWinSize
.Width() - aTrackingRect
.getWidth(), aWindowRect
.Top() ));
2760 aUIElementRect
.SetSize( ::Size( aTrackingRect
.getWidth(), aWindowRect
.getHeight() ));
2761 rUIElement
.m_aDockedData
.m_aPos
.X
= aUIElementRect
.Left();
2766 aUIElementRect
.SetPos( ::Point( aWindowRect
.Right(), aWindowRect
.Top() ));
2767 aUIElementRect
.SetSize( ::Size( nSize
, aWindowRect
.getHeight() ));
2768 rUIElement
.m_aDockedData
.m_aPos
.X
= aWindowRect
.Right();
2771 // Set virtual position
2772 rUIElement
.m_aDockedData
.m_aPos
.Y
= nRowCol
;
2776 sal_Int32 nSize
= ::std::max( sal_Int32( 0 ), std::min( sal_Int32( nTopDockingAreaSize
+ nMaxLeftRightDockAreaSize
- aWindowRect
.Bottom() ),
2777 sal_Int32( aTrackingRect
.getHeight() )));
2778 aUIElementRect
.SetPos( ::Point( aWindowRect
.Left(), aWindowRect
.Bottom() ));
2779 aUIElementRect
.SetSize( ::Size( aWindowRect
.getWidth(), nSize
));
2781 // Set virtual position
2782 sal_Int32
nPosY( 0 );
2784 SolarMutexGuard aGuard
;
2785 nPosY
= pDockingAreaWindow
->ScreenToOutputPixel(
2786 pContainerWindow
->OutputToScreenPixel( aWindowRect
.BottomRight() )).Y();
2788 rUIElement
.m_aDockedData
.m_aPos
.X
= nRowCol
;
2789 rUIElement
.m_aDockedData
.m_aPos
.Y
= nPosY
;
2792 rTrackingRect
= aUIElementRect
;
2798 implts_setTrackingRect( eDockedArea
, rMousePos
, aTrackingRect
);
2799 rTrackingRect
= implts_calcTrackingAndElementRect(
2800 eDockedArea
, nRowCol
, rUIElement
,
2801 aTrackingRect
, aRowColumnRect
, aContainerWinSize
);
2807 if ((( nRowCol
== nMinRowCol
) && ( rDockingOperation
== DOCKOP_BEFORE_COLROW
)) ||
2808 (( nRowCol
== nMaxRowCol
) && ( rDockingOperation
== DOCKOP_AFTER_COLROW
)))
2809 bOpOutsideOfDockingArea
= true;
2812 // handle docking before/after a row
2813 implts_setTrackingRect( eDockedArea
, rMousePos
, aTrackingRect
);
2814 rTrackingRect
= implts_calcTrackingAndElementRect(
2815 eDockedArea
, nRowCol
, rUIElement
,
2816 aTrackingRect
, aRowColumnRect
, aContainerWinSize
);
2818 sal_Int32
nOffsetX( 0 );
2819 sal_Int32
nOffsetY( 0 );
2820 if ( bHorizontalDockArea
)
2821 nOffsetY
= sal_Int32( floor( aRowColumnRect
.getHeight() / 2.0 + 0.5 ));
2823 nOffsetX
= sal_Int32( floor( aRowColumnRect
.getWidth() / 2.0 + 0.5 ));
2825 if ( rDockingOperation
== DOCKOP_BEFORE_COLROW
)
2827 if (( eDockedArea
== ui::DockingArea_DOCKINGAREA_TOP
) || ( eDockedArea
== ui::DockingArea_DOCKINGAREA_LEFT
))
2829 // Docking before/after means move track rectangle half column/row.
2830 // As left and top are ordered 0...n instead of right and bottom
2831 // which uses n...0, we have to use negative values for top/left.
2838 if (( eDockedArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
) || ( eDockedArea
== ui::DockingArea_DOCKINGAREA_RIGHT
))
2840 // Docking before/after means move track rectangle half column/row.
2841 // As left and top are ordered 0...n instead of right and bottom
2842 // which uses n...0, we have to use negative values for top/left.
2849 if ( bHorizontalDockArea
)
2850 rUIElement
.m_aDockedData
.m_aPos
.Y
= nRowCol
;
2852 rUIElement
.m_aDockedData
.m_aPos
.X
= nRowCol
;
2854 rTrackingRect
.Move( nOffsetX
, nOffsetY
);
2855 rTrackingRect
.SetSize( aTrackingRect
.GetSize() );
2861 // Docking outside of our docking window area =>
2862 // Users want to dock before/after first/last docked element or to an empty docking area
2863 if ( bOpOutsideOfDockingArea
)
2865 // set correct size for docking
2866 implts_setTrackingRect( eDockedArea
, rMousePos
, aTrackingRect
);
2867 rTrackingRect
= aTrackingRect
;
2869 if ( bHorizontalDockArea
)
2871 sal_Int32
nPosX( std::max( sal_Int32( rTrackingRect
.Left()), sal_Int32( 0 )));
2872 if (( nPosX
+ rTrackingRect
.getWidth()) > aContainerWinSize
.Width() )
2873 nPosX
= std::min( nPosX
,
2874 std::max( sal_Int32( aContainerWinSize
.Width() - rTrackingRect
.getWidth() ),
2877 sal_Int32 nSize
= std::min( aContainerWinSize
.Width(), rTrackingRect
.getWidth() );
2878 sal_Int32 nDockHeight
= std::max( static_cast<sal_Int32
>(aDockingAreaRect
.getHeight()), sal_Int32( 0 ));
2879 if ( nDockHeight
== 0 )
2881 sal_Int32
nPosY( std::max( aDockingAreaRect
.Top(), aDockingAreaRect
.Bottom() ));
2882 if ( eDockedArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
)
2883 nPosY
-= rTrackingRect
.getHeight();
2884 rTrackingRect
.SetPos( Point( nPosX
, nPosY
));
2885 rUIElement
.m_aDockedData
.m_aPos
.Y
= 0;
2887 else if ( rMousePos
.Y() < ( aDockingAreaRect
.Top() + ( nDockHeight
/ 2 )))
2889 rTrackingRect
.SetPos( Point( nPosX
, aDockingAreaRect
.Top() - rTrackingRect
.getHeight() ));
2890 if ( eDockedArea
== ui::DockingArea_DOCKINGAREA_TOP
)
2891 rUIElement
.m_aDockedData
.m_aPos
.Y
= 0;
2893 rUIElement
.m_aDockedData
.m_aPos
.Y
= ( nMaxRowCol
>= 0 ) ? nMaxRowCol
+1 : 0;
2894 rDockingOperation
= DOCKOP_BEFORE_COLROW
;
2898 rTrackingRect
.SetPos( Point( nPosX
, aDockingAreaRect
.Bottom() ));
2899 if ( eDockedArea
== ui::DockingArea_DOCKINGAREA_TOP
)
2900 rUIElement
.m_aDockedData
.m_aPos
.Y
= ( nMaxRowCol
>= 0 ) ? nMaxRowCol
+1 : 0;
2902 rUIElement
.m_aDockedData
.m_aPos
.Y
= 0;
2903 rDockingOperation
= DOCKOP_AFTER_COLROW
;
2905 rTrackingRect
.setWidth( nSize
);
2908 SolarMutexGuard aGuard
;
2909 nPosX
= pDockingAreaWindow
->ScreenToOutputPixel(
2910 pContainerWindow
->OutputToScreenPixel( rTrackingRect
.TopLeft() )).X();
2912 rUIElement
.m_aDockedData
.m_aPos
.X
= nPosX
;
2916 sal_Int32 nMaxDockingAreaHeight
= std::max( sal_Int32( 0 ), sal_Int32( nMaxLeftRightDockAreaSize
));
2917 sal_Int32
nPosY( std::max( sal_Int32( aTrackingRect
.Top()), sal_Int32( nTopDockingAreaSize
)));
2918 if (( nPosY
+ aTrackingRect
.getHeight()) > ( nTopDockingAreaSize
+ nMaxDockingAreaHeight
))
2919 nPosY
= std::min( nPosY
,
2920 std::max( sal_Int32( nTopDockingAreaSize
+ ( nMaxDockingAreaHeight
- aTrackingRect
.getHeight() )),
2921 sal_Int32( nTopDockingAreaSize
)));
2923 sal_Int32 nSize
= std::min( nMaxDockingAreaHeight
, static_cast<sal_Int32
>(aTrackingRect
.getHeight()) );
2924 sal_Int32 nDockWidth
= std::max( static_cast<sal_Int32
>(aDockingAreaRect
.getWidth()), sal_Int32( 0 ));
2925 if ( nDockWidth
== 0 )
2927 sal_Int32
nPosX( std::max( aDockingAreaRect
.Left(), aDockingAreaRect
.Right() ));
2928 if ( eDockedArea
== ui::DockingArea_DOCKINGAREA_RIGHT
)
2929 nPosX
-= rTrackingRect
.getWidth();
2930 rTrackingRect
.SetPos( Point( nPosX
, nPosY
));
2931 rUIElement
.m_aDockedData
.m_aPos
.X
= 0;
2933 else if ( rMousePos
.X() < ( aDockingAreaRect
.Left() + ( nDockWidth
/ 2 )))
2935 rTrackingRect
.SetPos( Point( aDockingAreaRect
.Left() - rTrackingRect
.getWidth(), nPosY
));
2936 if ( eDockedArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
2937 rUIElement
.m_aDockedData
.m_aPos
.X
= 0;
2939 rUIElement
.m_aDockedData
.m_aPos
.X
= ( nMaxRowCol
>= 0 ) ? nMaxRowCol
+1 : 0;
2940 rDockingOperation
= DOCKOP_BEFORE_COLROW
;
2944 rTrackingRect
.SetPos( Point( aDockingAreaRect
.Right(), nPosY
));
2945 if ( eDockedArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
2946 rUIElement
.m_aDockedData
.m_aPos
.X
= ( nMaxRowCol
>= 0 ) ? nMaxRowCol
+1 : 0;
2948 rUIElement
.m_aDockedData
.m_aPos
.X
= 0;
2949 rDockingOperation
= DOCKOP_AFTER_COLROW
;
2951 rTrackingRect
.setHeight( nSize
);
2954 SolarMutexGuard aGuard
;
2955 nPosY
= pDockingAreaWindow
->ScreenToOutputPixel(
2956 pContainerWindow
->OutputToScreenPixel( rTrackingRect
.TopLeft() )).Y();
2958 rUIElement
.m_aDockedData
.m_aPos
.Y
= nPosY
;
2963 framework::ToolbarLayoutManager::DockingOperation
ToolbarLayoutManager::implts_determineDockingOperation(
2964 ui::DockingArea DockingArea
,
2965 const ::Rectangle
& rRowColRect
,
2966 const Point
& rMousePos
)
2968 const sal_Int32 nHorzVerticalRegionSize
= 6;
2969 const sal_Int32 nHorzVerticalMoveRegion
= 4;
2971 if ( rRowColRect
.IsInside( rMousePos
))
2973 if ( isHorizontalDockingArea( DockingArea
))
2975 sal_Int32 nRegion
= rRowColRect
.getHeight() / nHorzVerticalRegionSize
;
2976 sal_Int32 nPosY
= rRowColRect
.Top() + nRegion
;
2978 if ( rMousePos
.Y() < nPosY
)
2979 return ( DockingArea
== ui::DockingArea_DOCKINGAREA_TOP
) ? DOCKOP_BEFORE_COLROW
: DOCKOP_AFTER_COLROW
;
2980 else if ( rMousePos
.Y() < ( nPosY
+ nRegion
*nHorzVerticalMoveRegion
))
2981 return DOCKOP_ON_COLROW
;
2983 return ( DockingArea
== ui::DockingArea_DOCKINGAREA_TOP
) ? DOCKOP_AFTER_COLROW
: DOCKOP_BEFORE_COLROW
;
2987 sal_Int32 nRegion
= rRowColRect
.getWidth() / nHorzVerticalRegionSize
;
2988 sal_Int32 nPosX
= rRowColRect
.Left() + nRegion
;
2990 if ( rMousePos
.X() < nPosX
)
2991 return ( DockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
) ? DOCKOP_BEFORE_COLROW
: DOCKOP_AFTER_COLROW
;
2992 else if ( rMousePos
.X() < ( nPosX
+ nRegion
*nHorzVerticalMoveRegion
))
2993 return DOCKOP_ON_COLROW
;
2995 return ( DockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
) ? DOCKOP_AFTER_COLROW
: DOCKOP_BEFORE_COLROW
;
2999 return DOCKOP_ON_COLROW
;
3002 ::Rectangle
ToolbarLayoutManager::implts_calcTrackingAndElementRect(
3003 ui::DockingArea eDockingArea
,
3005 UIElement
& rUIElement
,
3006 const ::Rectangle
& rTrackingRect
,
3007 const ::Rectangle
& rRowColumnRect
,
3008 const ::Size
& rContainerWinSize
)
3010 SolarMutexResettableGuard aReadGuard
;
3011 ::Rectangle
aDockingAreaOffsets( m_aDockingAreaOffsets
);
3014 bool bHorizontalDockArea( isHorizontalDockingArea( eDockingArea
));
3016 sal_Int32
nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() );
3017 sal_Int32
nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() );
3019 sal_Int32 nMaxLeftRightDockAreaSize
= rContainerWinSize
.Height() -
3020 nTopDockingAreaSize
-
3021 nBottomDockingAreaSize
-
3022 aDockingAreaOffsets
.Top() -
3023 aDockingAreaOffsets
.Bottom();
3025 ::Rectangle
aTrackingRect( rTrackingRect
);
3026 if ( bHorizontalDockArea
)
3028 sal_Int32
nPosX( std::max( sal_Int32( rTrackingRect
.Left()), sal_Int32( 0 )));
3029 if (( nPosX
+ rTrackingRect
.getWidth()) > rContainerWinSize
.Width() )
3030 nPosX
= std::min( nPosX
,
3031 std::max( sal_Int32( rContainerWinSize
.Width() - rTrackingRect
.getWidth() ),
3034 sal_Int32 nSize
= std::min( rContainerWinSize
.Width(), rTrackingRect
.getWidth() );
3036 aTrackingRect
.SetPos( ::Point( nPosX
, rRowColumnRect
.Top() ));
3037 aTrackingRect
.setWidth( nSize
);
3038 aTrackingRect
.setHeight( rRowColumnRect
.getHeight() );
3040 // Set virtual position
3041 rUIElement
.m_aDockedData
.m_aPos
.X
= nPosX
;
3042 rUIElement
.m_aDockedData
.m_aPos
.Y
= nRowCol
;
3046 sal_Int32 nMaxDockingAreaHeight
= std::max( sal_Int32( 0 ),
3047 sal_Int32( nMaxLeftRightDockAreaSize
));
3049 sal_Int32
nPosY( std::max( sal_Int32( aTrackingRect
.Top()), sal_Int32( nTopDockingAreaSize
)));
3050 if (( nPosY
+ aTrackingRect
.getHeight()) > ( nTopDockingAreaSize
+ nMaxDockingAreaHeight
))
3051 nPosY
= std::min( nPosY
,
3052 std::max( sal_Int32( nTopDockingAreaSize
+ ( nMaxDockingAreaHeight
- aTrackingRect
.getHeight() )),
3053 sal_Int32( nTopDockingAreaSize
)));
3055 sal_Int32 nSize
= std::min( nMaxDockingAreaHeight
, static_cast<sal_Int32
>(aTrackingRect
.getHeight()) );
3057 aTrackingRect
.SetPos( ::Point( rRowColumnRect
.Left(), nPosY
));
3058 aTrackingRect
.setWidth( rRowColumnRect
.getWidth() );
3059 aTrackingRect
.setHeight( nSize
);
3062 uno::Reference
< awt::XWindow
> xDockingAreaWindow( m_xDockAreaWindows
[eDockingArea
] );
3063 uno::Reference
< awt::XWindow2
> xContainerWindow( m_xContainerWindow
);
3066 sal_Int32
nDockPosY( 0 );
3067 vcl::Window
* pDockingAreaWindow( 0 );
3069 SolarMutexGuard aGuard
;
3070 pDockingAreaWindow
= VCLUnoHelper::GetWindow( xDockingAreaWindow
);
3071 vcl::Window
* pContainerWindow
= VCLUnoHelper::GetWindow( xContainerWindow
);
3072 nDockPosY
= pDockingAreaWindow
->ScreenToOutputPixel( pContainerWindow
->OutputToScreenPixel( ::Point( 0, nPosY
))).Y();
3075 // Set virtual position
3076 rUIElement
.m_aDockedData
.m_aPos
.X
= nRowCol
;
3077 rUIElement
.m_aDockedData
.m_aPos
.Y
= nDockPosY
;
3080 return aTrackingRect
;
3083 void ToolbarLayoutManager::implts_setTrackingRect( ui::DockingArea eDockingArea
, const ::Point
& rMousePos
, ::Rectangle
& rTrackingRect
)
3085 ::Point
aPoint( rTrackingRect
.TopLeft());
3086 if ( isHorizontalDockingArea( eDockingArea
))
3087 aPoint
.X() = rMousePos
.X();
3089 aPoint
.Y() = rMousePos
.Y();
3090 rTrackingRect
.SetPos( aPoint
);
3093 void ToolbarLayoutManager::implts_renumberRowColumnData(
3094 ui::DockingArea eDockingArea
,
3095 DockingOperation
/*eDockingOperation*/,
3096 const UIElement
& rUIElement
)
3098 SolarMutexClearableGuard aReadLock
;
3099 uno::Reference
< container::XNameAccess
> xPersistentWindowState( m_xPersistentWindowState
);
3102 bool bHorzDockingArea( isHorizontalDockingArea( eDockingArea
));
3103 sal_Int32
nRowCol( bHorzDockingArea
? rUIElement
.m_aDockedData
.m_aPos
.Y
: rUIElement
.m_aDockedData
.m_aPos
.X
);
3105 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3106 SolarMutexClearableGuard aWriteLock
;
3107 UIElementVector::iterator pIter
;
3108 for ( pIter
= m_aUIElements
.begin(); pIter
!= m_aUIElements
.end(); ++pIter
)
3110 if (( pIter
->m_aDockedData
.m_nDockedArea
== sal_Int16( eDockingArea
)) && ( pIter
->m_aName
!= rUIElement
.m_aName
))
3112 // Don't change toolbars without a valid docking position!
3113 if ( isDefaultPos( pIter
->m_aDockedData
.m_aPos
))
3116 sal_Int32 nWindowRowCol
= ( bHorzDockingArea
) ? pIter
->m_aDockedData
.m_aPos
.Y
: pIter
->m_aDockedData
.m_aPos
.X
;
3117 if ( nWindowRowCol
>= nRowCol
)
3119 if ( bHorzDockingArea
)
3120 pIter
->m_aDockedData
.m_aPos
.Y
+= 1;
3122 pIter
->m_aDockedData
.m_aPos
.X
+= 1;
3127 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3129 // We have to change the persistent window state part
3130 if ( xPersistentWindowState
.is() )
3134 uno::Sequence
< OUString
> aWindowElements
= xPersistentWindowState
->getElementNames();
3135 for ( sal_Int32 i
= 0; i
< aWindowElements
.getLength(); i
++ )
3137 if ( rUIElement
.m_aName
!= aWindowElements
[i
] )
3141 uno::Sequence
< beans::PropertyValue
> aPropValueSeq
;
3142 awt::Point aDockedPos
;
3143 ui::DockingArea
nDockedArea( ui::DockingArea_DOCKINGAREA_DEFAULT
);
3145 xPersistentWindowState
->getByName( aWindowElements
[i
] ) >>= aPropValueSeq
;
3146 for ( sal_Int32 j
= 0; j
< aPropValueSeq
.getLength(); j
++ )
3148 if ( aPropValueSeq
[j
].Name
== WINDOWSTATE_PROPERTY_DOCKINGAREA
)
3149 aPropValueSeq
[j
].Value
>>= nDockedArea
;
3150 else if ( aPropValueSeq
[j
].Name
== WINDOWSTATE_PROPERTY_DOCKPOS
)
3151 aPropValueSeq
[j
].Value
>>= aDockedPos
;
3154 // Don't change toolbars without a valid docking position!
3155 if ( isDefaultPos( aDockedPos
))
3158 sal_Int32 nWindowRowCol
= ( bHorzDockingArea
) ? aDockedPos
.Y
: aDockedPos
.X
;
3159 if (( nDockedArea
== eDockingArea
) && ( nWindowRowCol
>= nRowCol
))
3161 if ( bHorzDockingArea
)
3166 uno::Reference
< container::XNameReplace
> xReplace( xPersistentWindowState
, uno::UNO_QUERY
);
3167 xReplace
->replaceByName( aWindowElements
[i
], makeAny( aPropValueSeq
));
3170 catch (const uno::Exception
&)
3176 catch (const uno::Exception
&)
3184 void SAL_CALL
ToolbarLayoutManager::windowResized( const awt::WindowEvent
& aEvent
)
3185 throw( uno::RuntimeException
, std::exception
)
3187 SolarMutexClearableGuard aWriteLock
;
3188 bool bLocked( m_bDockingInProgress
);
3189 bool bLayoutInProgress( m_bLayoutInProgress
);
3192 // Do not do anything if we are in the middle of a docking process. This would interfere all other
3193 // operations. We will store the new position and size in the docking handlers.
3194 // Do not do anything if we are in the middle of our layouting process. We will adapt the position
3195 // and size of the user interface elements.
3196 if ( !bLocked
&& !bLayoutInProgress
)
3198 bool bNotify( false );
3199 uno::Reference
< awt::XWindow
> xWindow( aEvent
.Source
, uno::UNO_QUERY
);
3201 UIElement aUIElement
= implts_findToolbar( aEvent
.Source
);
3202 if ( aUIElement
.m_xUIElement
.is() )
3204 if ( aUIElement
.m_bFloating
)
3206 uno::Reference
< awt::XWindow2
> xWindow2( xWindow
, uno::UNO_QUERY
);
3210 awt::Rectangle aPos
= xWindow2
->getPosSize();
3211 awt::Size aSize
= xWindow2
->getOutputSize(); // always use output size for consistency
3212 bool bVisible
= xWindow2
->isVisible();
3214 // update element data
3215 aUIElement
.m_aFloatingData
.m_aPos
= awt::Point(aPos
.X
, aPos
.Y
);
3216 aUIElement
.m_aFloatingData
.m_aSize
= aSize
;
3217 aUIElement
.m_bVisible
= bVisible
;
3220 implts_writeWindowStateData( aUIElement
);
3224 implts_setLayoutDirty();
3230 m_pParentLayouter
->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED
);
3234 void SAL_CALL
ToolbarLayoutManager::windowMoved( const awt::WindowEvent
& /*aEvent*/ )
3235 throw( uno::RuntimeException
, std::exception
)
3239 void SAL_CALL
ToolbarLayoutManager::windowShown( const lang::EventObject
& /*aEvent*/ )
3240 throw( uno::RuntimeException
, std::exception
)
3244 void SAL_CALL
ToolbarLayoutManager::windowHidden( const lang::EventObject
& /*aEvent*/ )
3245 throw( uno::RuntimeException
, std::exception
)
3249 // XDockableWindowListener
3251 void SAL_CALL
ToolbarLayoutManager::startDocking( const awt::DockingEvent
& e
)
3252 throw (uno::RuntimeException
, std::exception
)
3254 bool bWinFound( false );
3256 SolarMutexClearableGuard aReadGuard
;
3257 uno::Reference
< awt::XWindow2
> xContainerWindow( m_xContainerWindow
);
3258 uno::Reference
< awt::XWindow2
> xWindow( e
.Source
, uno::UNO_QUERY
);
3261 vcl::Window
* pContainerWindow( 0 );
3264 SolarMutexGuard aGuard
;
3265 pContainerWindow
= VCLUnoHelper::GetWindow( xContainerWindow
);
3266 aMousePos
= pContainerWindow
->ScreenToOutputPixel( ::Point( e
.MousePos
.X
, e
.MousePos
.Y
));
3269 UIElement aUIElement
= implts_findToolbar( e
.Source
);
3271 if ( aUIElement
.m_xUIElement
.is() && xWindow
.is() )
3273 awt::Rectangle aRect
;
3276 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
3277 if ( xDockWindow
->isFloating() )
3279 awt::Rectangle aPos
= xWindow
->getPosSize();
3280 awt::Size aSize
= xWindow
->getOutputSize();
3282 aUIElement
.m_aFloatingData
.m_aPos
= awt::Point(aPos
.X
, aPos
.Y
);
3283 aUIElement
.m_aFloatingData
.m_aSize
= aSize
;
3285 SolarMutexGuard aGuard
;
3287 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
3288 if ( pWindow
&& pWindow
->GetType() == WINDOW_TOOLBOX
)
3290 ToolBox
* pToolBox
= static_cast<ToolBox
*>(pWindow
);
3291 aUIElement
.m_aFloatingData
.m_nLines
= pToolBox
->GetFloatingLines();
3292 aUIElement
.m_aFloatingData
.m_bIsHorizontal
= isToolboxHorizontalAligned( pToolBox
);
3298 m_bDockingInProgress
= bWinFound
;
3299 m_aDockUIElement
= aUIElement
;
3300 m_aDockUIElement
.m_bUserActive
= true;
3301 m_aStartDockMousePos
= aMousePos
;
3304 awt::DockingData SAL_CALL
ToolbarLayoutManager::docking( const awt::DockingEvent
& e
)
3305 throw (uno::RuntimeException
, std::exception
)
3307 const sal_Int32 MAGNETIC_DISTANCE_UNDOCK
= 25;
3308 const sal_Int32 MAGNETIC_DISTANCE_DOCK
= 20;
3310 SolarMutexClearableGuard aReadLock
;
3311 awt::DockingData aDockingData
;
3312 uno::Reference
< awt::XDockableWindow
> xDockWindow( e
.Source
, uno::UNO_QUERY
);
3313 uno::Reference
< awt::XWindow
> xWindow( e
.Source
, uno::UNO_QUERY
);
3314 uno::Reference
< awt::XWindow
> xTopDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_TOP
] );
3315 uno::Reference
< awt::XWindow
> xLeftDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_LEFT
] );
3316 uno::Reference
< awt::XWindow
> xRightDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_RIGHT
] );
3317 uno::Reference
< awt::XWindow
> xBottomDockingWindow( m_xDockAreaWindows
[ui::DockingArea_DOCKINGAREA_BOTTOM
] );
3318 uno::Reference
< awt::XWindow2
> xContainerWindow( m_xContainerWindow
);
3319 UIElement
aUIDockingElement( m_aDockUIElement
);
3321 DockingOperation
eDockingOperation( DOCKOP_ON_COLROW
);
3322 bool bDockingInProgress( m_bDockingInProgress
);
3325 if ( bDockingInProgress
)
3326 aDockingData
.TrackingRectangle
= e
.TrackingRectangle
;
3328 if ( bDockingInProgress
&& xDockWindow
.is() && xWindow
.is() )
3332 SolarMutexGuard aGuard
;
3334 sal_Int16
eDockingArea( -1 ); // none
3335 sal_Int32
nMagneticZone( aUIDockingElement
.m_bFloating
? MAGNETIC_DISTANCE_DOCK
: MAGNETIC_DISTANCE_UNDOCK
);
3336 awt::Rectangle aNewTrackingRect
;
3337 ::Rectangle
aTrackingRect( e
.TrackingRectangle
.X
, e
.TrackingRectangle
.Y
,
3338 ( e
.TrackingRectangle
.X
+ e
.TrackingRectangle
.Width
),
3339 ( e
.TrackingRectangle
.Y
+ e
.TrackingRectangle
.Height
));
3341 awt::Rectangle aTmpRect
= xTopDockingWindow
->getPosSize();
3342 ::Rectangle
aTopDockRect( aTmpRect
.X
, aTmpRect
.Y
, aTmpRect
.Width
, aTmpRect
.Height
);
3343 ::Rectangle
aHotZoneTopDockRect( implts_calcHotZoneRect( aTopDockRect
, nMagneticZone
));
3345 aTmpRect
= xBottomDockingWindow
->getPosSize();
3346 ::Rectangle
aBottomDockRect( aTmpRect
.X
, aTmpRect
.Y
, ( aTmpRect
.X
+ aTmpRect
.Width
), ( aTmpRect
.Y
+ aTmpRect
.Height
));
3347 ::Rectangle
aHotZoneBottomDockRect( implts_calcHotZoneRect( aBottomDockRect
, nMagneticZone
));
3349 aTmpRect
= xLeftDockingWindow
->getPosSize();
3350 ::Rectangle
aLeftDockRect( aTmpRect
.X
, aTmpRect
.Y
, ( aTmpRect
.X
+ aTmpRect
.Width
), ( aTmpRect
.Y
+ aTmpRect
.Height
));
3351 ::Rectangle
aHotZoneLeftDockRect( implts_calcHotZoneRect( aLeftDockRect
, nMagneticZone
));
3353 aTmpRect
= xRightDockingWindow
->getPosSize();
3354 ::Rectangle
aRightDockRect( aTmpRect
.X
, aTmpRect
.Y
, ( aTmpRect
.X
+ aTmpRect
.Width
), ( aTmpRect
.Y
+ aTmpRect
.Height
));
3355 ::Rectangle
aHotZoneRightDockRect( implts_calcHotZoneRect( aRightDockRect
, nMagneticZone
));
3357 vcl::Window
* pContainerWindow( VCLUnoHelper::GetWindow( xContainerWindow
) );
3358 ::Point
aMousePos( pContainerWindow
->ScreenToOutputPixel( ::Point( e
.MousePos
.X
, e
.MousePos
.Y
)));
3360 if ( aHotZoneTopDockRect
.IsInside( aMousePos
))
3361 eDockingArea
= ui::DockingArea_DOCKINGAREA_TOP
;
3362 else if ( aHotZoneBottomDockRect
.IsInside( aMousePos
))
3363 eDockingArea
= ui::DockingArea_DOCKINGAREA_BOTTOM
;
3364 else if ( aHotZoneLeftDockRect
.IsInside( aMousePos
))
3365 eDockingArea
= ui::DockingArea_DOCKINGAREA_LEFT
;
3366 else if ( aHotZoneRightDockRect
.IsInside( aMousePos
))
3367 eDockingArea
= ui::DockingArea_DOCKINGAREA_RIGHT
;
3369 // Higher priority for movements inside the real docking area
3370 if ( aTopDockRect
.IsInside( aMousePos
))
3371 eDockingArea
= ui::DockingArea_DOCKINGAREA_TOP
;
3372 else if ( aBottomDockRect
.IsInside( aMousePos
))
3373 eDockingArea
= ui::DockingArea_DOCKINGAREA_BOTTOM
;
3374 else if ( aLeftDockRect
.IsInside( aMousePos
))
3375 eDockingArea
= ui::DockingArea_DOCKINGAREA_LEFT
;
3376 else if ( aRightDockRect
.IsInside( aMousePos
))
3377 eDockingArea
= ui::DockingArea_DOCKINGAREA_RIGHT
;
3379 // Determine if we have a toolbar and set alignment according to the docking area!
3380 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
3381 ToolBox
* pToolBox
= 0;
3382 if ( pWindow
&& pWindow
->GetType() == WINDOW_TOOLBOX
)
3383 pToolBox
= static_cast<ToolBox
*>(pWindow
);
3385 if ( eDockingArea
!= -1 )
3387 if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_TOP
)
3389 aUIDockingElement
.m_aDockedData
.m_nDockedArea
= ui::DockingArea_DOCKINGAREA_TOP
;
3390 aUIDockingElement
.m_bFloating
= false;
3392 else if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_BOTTOM
)
3394 aUIDockingElement
.m_aDockedData
.m_nDockedArea
= ui::DockingArea_DOCKINGAREA_BOTTOM
;
3395 aUIDockingElement
.m_bFloating
= false;
3397 else if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_LEFT
)
3399 aUIDockingElement
.m_aDockedData
.m_nDockedArea
= ui::DockingArea_DOCKINGAREA_LEFT
;
3400 aUIDockingElement
.m_bFloating
= false;
3402 else if ( eDockingArea
== ui::DockingArea_DOCKINGAREA_RIGHT
)
3404 aUIDockingElement
.m_aDockedData
.m_nDockedArea
= ui::DockingArea_DOCKINGAREA_RIGHT
;
3405 aUIDockingElement
.m_bFloating
= false;
3408 ::Point aOutputPos
= pContainerWindow
->ScreenToOutputPixel( aTrackingRect
.TopLeft() );
3409 aTrackingRect
.SetPos( aOutputPos
);
3411 ::Rectangle
aNewDockingRect( aTrackingRect
);
3413 implts_calcDockingPosSize( aUIDockingElement
, eDockingOperation
, aNewDockingRect
, aMousePos
);
3415 ::Point aScreenPos
= pContainerWindow
->OutputToScreenPixel( aNewDockingRect
.TopLeft() );
3416 aNewTrackingRect
= awt::Rectangle( aScreenPos
.X(), aScreenPos
.Y(),
3417 aNewDockingRect
.getWidth(), aNewDockingRect
.getHeight() );
3418 aDockingData
.TrackingRectangle
= aNewTrackingRect
;
3420 else if ( pToolBox
&& bDockingInProgress
)
3422 bool bIsHorizontal
= isToolboxHorizontalAligned( pToolBox
);
3423 awt::Size aFloatSize
= aUIDockingElement
.m_aFloatingData
.m_aSize
;
3424 if ( aFloatSize
.Width
> 0 && aFloatSize
.Height
> 0 )
3426 aUIDockingElement
.m_aFloatingData
.m_aPos
= AWTPoint(pContainerWindow
->ScreenToOutputPixel(VCLPoint(e
.MousePos
)));
3427 aDockingData
.TrackingRectangle
.Height
= aFloatSize
.Height
;
3428 aDockingData
.TrackingRectangle
.Width
= aFloatSize
.Width
;
3432 aFloatSize
= AWTSize(pToolBox
->CalcWindowSizePixel());
3433 if ( !bIsHorizontal
)
3435 // Floating toolbars are always horizontal aligned! We have to swap
3436 // width/height if we have a vertical aligned toolbar.
3437 sal_Int32 nTemp
= aFloatSize
.Height
;
3438 aFloatSize
.Height
= aFloatSize
.Width
;
3439 aFloatSize
.Width
= nTemp
;
3442 aDockingData
.TrackingRectangle
.Height
= aFloatSize
.Height
;
3443 aDockingData
.TrackingRectangle
.Width
= aFloatSize
.Width
;
3445 // For the first time we don't have any data about the floating size of a toolbar.
3446 // We calculate it and store it for later use.
3447 aUIDockingElement
.m_aFloatingData
.m_aPos
= AWTPoint(pContainerWindow
->ScreenToOutputPixel(VCLPoint(e
.MousePos
)));
3448 aUIDockingElement
.m_aFloatingData
.m_aSize
= aFloatSize
;
3449 aUIDockingElement
.m_aFloatingData
.m_nLines
= pToolBox
->GetFloatingLines();
3450 aUIDockingElement
.m_aFloatingData
.m_bIsHorizontal
= isToolboxHorizontalAligned( pToolBox
);
3452 aDockingData
.TrackingRectangle
.X
= e
.MousePos
.X
;
3453 aDockingData
.TrackingRectangle
.Y
= e
.MousePos
.Y
;
3456 aDockingData
.bFloating
= ( eDockingArea
== -1 );
3458 // Write current data to the member docking progress data
3460 m_aDockUIElement
.m_bFloating
= aDockingData
.bFloating
;
3461 if ( !aDockingData
.bFloating
)
3463 m_aDockUIElement
.m_aDockedData
= aUIDockingElement
.m_aDockedData
;
3465 m_eDockOperation
= eDockingOperation
;
3468 m_aDockUIElement
.m_aFloatingData
= aUIDockingElement
.m_aFloatingData
;
3470 catch (const uno::Exception
&)
3475 return aDockingData
;
3478 void SAL_CALL
ToolbarLayoutManager::endDocking( const awt::EndDockingEvent
& e
)
3479 throw (uno::RuntimeException
, std::exception
)
3481 bool bDockingInProgress( false );
3482 bool bStartDockFloated( false );
3483 bool bFloating( false );
3484 UIElement aUIDockingElement
;
3486 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3487 SolarMutexResettableGuard aWriteLock
;
3488 bDockingInProgress
= m_bDockingInProgress
;
3489 aUIDockingElement
= m_aDockUIElement
;
3490 bFloating
= aUIDockingElement
.m_bFloating
;
3492 UIElement
& rUIElement
= impl_findToolbar( aUIDockingElement
.m_aName
);
3493 if ( rUIElement
.m_aName
== aUIDockingElement
.m_aName
)
3495 if ( aUIDockingElement
.m_bFloating
)
3497 // Write last position into position data
3498 uno::Reference
< awt::XWindow
> xWindow( aUIDockingElement
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
3499 rUIElement
.m_aFloatingData
= aUIDockingElement
.m_aFloatingData
;
3500 awt::Rectangle aTmpRect
= xWindow
->getPosSize();
3501 rUIElement
.m_aFloatingData
.m_aPos
= awt::Point(aTmpRect
.X
, aTmpRect
.Y
);
3502 // make changes also for our local data as we use it to make data persistent
3503 aUIDockingElement
.m_aFloatingData
= rUIElement
.m_aFloatingData
;
3507 rUIElement
.m_aDockedData
= aUIDockingElement
.m_aDockedData
;
3508 rUIElement
.m_aFloatingData
.m_aSize
= aUIDockingElement
.m_aFloatingData
.m_aSize
;
3510 if ( m_eDockOperation
!= DOCKOP_ON_COLROW
)
3512 // we have to renumber our row/column data to insert a new row/column
3513 implts_renumberRowColumnData((ui::DockingArea
)aUIDockingElement
.m_aDockedData
.m_nDockedArea
, m_eDockOperation
, aUIDockingElement
);
3517 bStartDockFloated
= rUIElement
.m_bFloating
;
3518 rUIElement
.m_bFloating
= m_aDockUIElement
.m_bFloating
;
3519 rUIElement
.m_bUserActive
= true;
3522 // reset member for next docking operation
3523 m_aDockUIElement
.m_xUIElement
.clear();
3524 m_eDockOperation
= DOCKOP_ON_COLROW
;
3526 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3528 implts_writeWindowStateData( aUIDockingElement
);
3530 if ( bDockingInProgress
)
3532 SolarMutexGuard aGuard
;
3533 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( uno::Reference
< awt::XWindow
>( e
.Source
, uno::UNO_QUERY
));
3534 ToolBox
* pToolBox
= 0;
3535 if ( pWindow
&& pWindow
->GetType() == WINDOW_TOOLBOX
)
3536 pToolBox
= static_cast<ToolBox
*>(pWindow
);
3542 if ( aUIDockingElement
.m_aFloatingData
.m_bIsHorizontal
)
3543 pToolBox
->SetAlign( WINDOWALIGN_TOP
);
3545 pToolBox
->SetAlign( WINDOWALIGN_LEFT
);
3551 pToolBox
->SetAlign( ImplConvertAlignment( aUIDockingElement
.m_aDockedData
.m_nDockedArea
) );
3553 // Docked toolbars have always one line
3554 aSize
= pToolBox
->CalcWindowSizePixel( 1 );
3556 // Lock layouting updates as our listener would be called due to SetSizePixel
3557 pToolBox
->SetOutputSizePixel( aSize
);
3562 implts_sortUIElements();
3565 m_bDockingInProgress
= false;
3566 m_bLayoutDirty
= !bStartDockFloated
|| !bFloating
;
3567 bool bNotify
= m_bLayoutDirty
;
3571 m_pParentLayouter
->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED
);
3574 sal_Bool SAL_CALL
ToolbarLayoutManager::prepareToggleFloatingMode( const lang::EventObject
& e
)
3575 throw (uno::RuntimeException
, std::exception
)
3577 SolarMutexClearableGuard aReadLock
;
3578 bool bDockingInProgress
= m_bDockingInProgress
;
3581 UIElement aUIDockingElement
= implts_findToolbar( e
.Source
);
3582 bool bWinFound( !aUIDockingElement
.m_aName
.isEmpty() );
3583 uno::Reference
< awt::XWindow
> xWindow( e
.Source
, uno::UNO_QUERY
);
3585 if ( bWinFound
&& xWindow
.is() )
3587 if ( !bDockingInProgress
)
3589 awt::Rectangle aRect
;
3590 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
3591 if ( xDockWindow
->isFloating() )
3594 SolarMutexGuard aGuard
;
3595 vcl::Window
* pWindow
= VCLUnoHelper::GetWindow( xWindow
);
3596 if ( pWindow
&& pWindow
->GetType() == WINDOW_TOOLBOX
)
3598 ToolBox
* pToolBox
= static_cast< ToolBox
*>( pWindow
);
3599 aUIDockingElement
.m_aFloatingData
.m_aPos
= AWTPoint(pToolBox
->GetPosPixel());
3600 aUIDockingElement
.m_aFloatingData
.m_aSize
= AWTSize(pToolBox
->GetOutputSizePixel());
3601 aUIDockingElement
.m_aFloatingData
.m_nLines
= pToolBox
->GetFloatingLines();
3602 aUIDockingElement
.m_aFloatingData
.m_bIsHorizontal
= isToolboxHorizontalAligned( pToolBox
);
3606 UIElement aUIElement
= implts_findToolbar( aUIDockingElement
.m_aName
);
3607 if ( aUIElement
.m_aName
== aUIDockingElement
.m_aName
)
3608 implts_setToolbar( aUIDockingElement
);
3616 void SAL_CALL
ToolbarLayoutManager::toggleFloatingMode( const lang::EventObject
& e
)
3617 throw (uno::RuntimeException
, std::exception
)
3619 UIElement aUIDockingElement
;
3621 SolarMutexResettableGuard aReadLock
;
3622 bool bDockingInProgress( m_bDockingInProgress
);
3623 if ( bDockingInProgress
)
3624 aUIDockingElement
= m_aDockUIElement
;
3627 vcl::Window
* pWindow( 0 );
3628 ToolBox
* pToolBox( 0 );
3629 uno::Reference
< awt::XWindow2
> xWindow
;
3632 SolarMutexGuard aGuard
;
3633 xWindow
= uno::Reference
< awt::XWindow2
>( e
.Source
, uno::UNO_QUERY
);
3634 pWindow
= VCLUnoHelper::GetWindow( xWindow
);
3636 if ( pWindow
&& pWindow
->GetType() == WINDOW_TOOLBOX
)
3637 pToolBox
= static_cast<ToolBox
*>(pWindow
);
3640 if ( !bDockingInProgress
)
3642 aUIDockingElement
= implts_findToolbar( e
.Source
);
3643 bool bWinFound
= ( !aUIDockingElement
.m_aName
.isEmpty() );
3645 if ( bWinFound
&& xWindow
.is() )
3647 aUIDockingElement
.m_bFloating
= !aUIDockingElement
.m_bFloating
;
3648 aUIDockingElement
.m_bUserActive
= true;
3650 implts_setLayoutInProgress( true );
3651 if ( aUIDockingElement
.m_bFloating
)
3653 SolarMutexGuard aGuard
;
3656 pToolBox
->SetLineCount( aUIDockingElement
.m_aFloatingData
.m_nLines
);
3657 if ( aUIDockingElement
.m_aFloatingData
.m_bIsHorizontal
)
3658 pToolBox
->SetAlign( WINDOWALIGN_TOP
);
3660 pToolBox
->SetAlign( WINDOWALIGN_LEFT
);
3663 bool bUndefPos
= hasDefaultPosValue( aUIDockingElement
.m_aFloatingData
.m_aPos
);
3664 bool bSetSize
= !hasEmptySize( aUIDockingElement
.m_aFloatingData
.m_aSize
);
3667 aUIDockingElement
.m_aFloatingData
.m_aPos
= implts_findNextCascadeFloatingPos();
3672 aUIDockingElement
.m_aFloatingData
.m_aSize
= AWTSize(pToolBox
->CalcFloatingWindowSizePixel());
3674 aUIDockingElement
.m_aFloatingData
.m_aSize
= AWTSize(pWindow
->GetOutputSizePixel());
3677 xWindow
->setPosSize( aUIDockingElement
.m_aFloatingData
.m_aPos
.X
,
3678 aUIDockingElement
.m_aFloatingData
.m_aPos
.Y
,
3679 0, 0, awt::PosSize::POS
);
3680 xWindow
->setOutputSize(aUIDockingElement
.m_aFloatingData
.m_aSize
);
3684 if ( isDefaultPos( aUIDockingElement
.m_aDockedData
.m_aPos
))
3686 // Docking on its default position without a preset position -
3687 // we have to find a good place for it.
3689 awt::Point aDockPos
;
3693 SolarMutexGuard aGuard
;
3695 aSize
= pToolBox
->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIDockingElement
.m_aDockedData
.m_nDockedArea
) );
3697 aSize
= pWindow
->GetSizePixel();
3700 implts_findNextDockingPos((ui::DockingArea
)aUIDockingElement
.m_aDockedData
.m_nDockedArea
, aSize
, aDockPos
, aPixelPos
);
3701 aUIDockingElement
.m_aDockedData
.m_aPos
= aDockPos
;
3704 SolarMutexGuard aGuard
;
3707 pToolBox
->SetAlign( ImplConvertAlignment( aUIDockingElement
.m_aDockedData
.m_nDockedArea
) );
3708 ::Size aSize
= pToolBox
->CalcWindowSizePixel( 1 );
3709 awt::Rectangle aRect
= xWindow
->getPosSize();
3710 xWindow
->setPosSize( aRect
.X
, aRect
.Y
, 0, 0, awt::PosSize::POS
);
3711 xWindow
->setOutputSize( AWTSize( aSize
) );
3715 implts_setLayoutInProgress( false );
3716 implts_setToolbar( aUIDockingElement
);
3717 implts_writeWindowStateData( aUIDockingElement
);
3718 implts_sortUIElements();
3719 implts_setLayoutDirty();
3722 ILayoutNotifications
* pParentLayouter( m_pParentLayouter
);
3725 if ( pParentLayouter
)
3726 pParentLayouter
->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED
);
3731 SolarMutexGuard aGuard
;
3734 if ( aUIDockingElement
.m_bFloating
)
3736 if ( aUIDockingElement
.m_aFloatingData
.m_bIsHorizontal
)
3737 pToolBox
->SetAlign( WINDOWALIGN_TOP
);
3739 pToolBox
->SetAlign( WINDOWALIGN_LEFT
);
3742 pToolBox
->SetAlign( ImplConvertAlignment( aUIDockingElement
.m_aDockedData
.m_nDockedArea
) );
3747 void SAL_CALL
ToolbarLayoutManager::closed( const lang::EventObject
& e
)
3748 throw (uno::RuntimeException
, std::exception
)
3751 UIElement aUIElement
;
3752 UIElementVector::iterator pIter
;
3754 SolarMutexClearableGuard aWriteLock
;
3755 for ( pIter
= m_aUIElements
.begin(); pIter
!= m_aUIElements
.end(); ++pIter
)
3757 uno::Reference
< ui::XUIElement
> xUIElement( pIter
->m_xUIElement
);
3758 if ( xUIElement
.is() )
3760 uno::Reference
< uno::XInterface
> xIfac( xUIElement
->getRealInterface(), uno::UNO_QUERY
);
3761 if ( xIfac
== e
.Source
)
3763 aName
= pIter
->m_aName
;
3765 // user closes a toolbar =>
3766 // context sensitive toolbar: only destroy toolbar and store state.
3767 // non context sensitive toolbar: make it invisible, store state and destroy it.
3768 if ( !pIter
->m_bContextSensitive
)
3769 pIter
->m_bVisible
= false;
3771 aUIElement
= *pIter
;
3779 if ( !aName
.isEmpty() )
3781 implts_writeWindowStateData( aUIElement
);
3782 destroyToolbar( aName
);
3784 SolarMutexClearableGuard aReadLock
;
3785 bool bLayoutDirty
= m_bLayoutDirty
;
3786 ILayoutNotifications
* pParentLayouter( m_pParentLayouter
);
3789 if ( bLayoutDirty
&& pParentLayouter
)
3790 pParentLayouter
->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED
);
3794 void SAL_CALL
ToolbarLayoutManager::endPopupMode( const awt::EndPopupModeEvent
& /*e*/ )
3795 throw (uno::RuntimeException
, std::exception
)
3799 // XUIConfigurationListener
3801 void SAL_CALL
ToolbarLayoutManager::elementInserted( const ui::ConfigurationEvent
& rEvent
)
3802 throw (uno::RuntimeException
, std::exception
)
3804 UIElement aUIElement
= implts_findToolbar( rEvent
.ResourceURL
);
3806 uno::Reference
< ui::XUIElementSettings
> xElementSettings( aUIElement
.m_xUIElement
, uno::UNO_QUERY
);
3807 if ( xElementSettings
.is() )
3809 OUString
aConfigSourcePropName( "ConfigurationSource" );
3810 uno::Reference
< beans::XPropertySet
> xPropSet( xElementSettings
, uno::UNO_QUERY
);
3811 if ( xPropSet
.is() )
3813 if ( rEvent
.Source
== uno::Reference
< uno::XInterface
>( m_xDocCfgMgr
, uno::UNO_QUERY
))
3814 xPropSet
->setPropertyValue( aConfigSourcePropName
, makeAny( m_xDocCfgMgr
));
3816 xElementSettings
->updateSettings();
3820 OUString aElementType
;
3821 OUString aElementName
;
3822 parseResourceURL( rEvent
.ResourceURL
, aElementType
, aElementName
);
3823 if ( aElementName
.indexOf( "custom_" ) != -1 )
3825 // custom toolbar must be directly created, shown and layouted!
3826 createToolbar( rEvent
.ResourceURL
);
3827 uno::Reference
< ui::XUIElement
> xUIElement
= getToolbar( rEvent
.ResourceURL
);
3828 if ( xUIElement
.is() )
3831 uno::Reference
< ui::XUIConfigurationManager
> xCfgMgr
;
3832 uno::Reference
< beans::XPropertySet
> xPropSet
;
3836 xCfgMgr
= uno::Reference
< ui::XUIConfigurationManager
>( rEvent
.Source
, uno::UNO_QUERY
);
3837 xPropSet
= uno::Reference
< beans::XPropertySet
>( xCfgMgr
->getSettings( rEvent
.ResourceURL
, sal_False
), uno::UNO_QUERY
);
3839 if ( xPropSet
.is() )
3840 xPropSet
->getPropertyValue("UIName") >>= aUIName
;
3842 catch (const container::NoSuchElementException
&)
3845 catch (const beans::UnknownPropertyException
&)
3848 catch (const lang::WrappedTargetException
&)
3853 SolarMutexGuard aGuard
;
3854 vcl::Window
* pWindow
= getWindowFromXUIElement( xUIElement
);
3856 pWindow
->SetText( aUIName
);
3859 showToolbar( rEvent
.ResourceURL
);
3865 void SAL_CALL
ToolbarLayoutManager::elementRemoved( const ui::ConfigurationEvent
& rEvent
)
3866 throw (uno::RuntimeException
, std::exception
)
3868 SolarMutexClearableGuard aReadLock
;
3869 uno::Reference
< awt::XWindow
> xContainerWindow( m_xContainerWindow
, uno::UNO_QUERY
);
3870 uno::Reference
< ui::XUIConfigurationManager
> xModuleCfgMgr( m_xModuleCfgMgr
);
3871 uno::Reference
< ui::XUIConfigurationManager
> xDocCfgMgr( m_xDocCfgMgr
);
3874 UIElement aUIElement
= implts_findToolbar( rEvent
.ResourceURL
);
3875 uno::Reference
< ui::XUIElementSettings
> xElementSettings( aUIElement
.m_xUIElement
, uno::UNO_QUERY
);
3876 if ( xElementSettings
.is() )
3878 bool bNoSettings( false );
3879 OUString
aConfigSourcePropName( "ConfigurationSource" );
3880 uno::Reference
< uno::XInterface
> xElementCfgMgr
;
3881 uno::Reference
< beans::XPropertySet
> xPropSet( xElementSettings
, uno::UNO_QUERY
);
3883 if ( xPropSet
.is() )
3884 xPropSet
->getPropertyValue( aConfigSourcePropName
) >>= xElementCfgMgr
;
3886 if ( !xElementCfgMgr
.is() )
3889 // Check if the same UI configuration manager has changed => check further
3890 if ( rEvent
.Source
== xElementCfgMgr
)
3892 // Same UI configuration manager where our element has its settings
3893 if ( rEvent
.Source
== uno::Reference
< uno::XInterface
>( xDocCfgMgr
, uno::UNO_QUERY
))
3895 // document settings removed
3896 if ( xModuleCfgMgr
->hasSettings( rEvent
.ResourceURL
))
3898 xPropSet
->setPropertyValue( aConfigSourcePropName
, makeAny( xModuleCfgMgr
));
3899 xElementSettings
->updateSettings();
3907 // No settings anymore, element must be destroyed
3908 if ( xContainerWindow
.is() && bNoSettings
)
3909 destroyToolbar( rEvent
.ResourceURL
);
3913 void SAL_CALL
ToolbarLayoutManager::elementReplaced( const ui::ConfigurationEvent
& rEvent
)
3914 throw (uno::RuntimeException
, std::exception
)
3916 UIElement aUIElement
= implts_findToolbar( rEvent
.ResourceURL
);
3918 uno::Reference
< ui::XUIElementSettings
> xElementSettings( aUIElement
.m_xUIElement
, uno::UNO_QUERY
);
3919 if ( xElementSettings
.is() )
3921 OUString
aConfigSourcePropName( "ConfigurationSource" );
3922 uno::Reference
< uno::XInterface
> xElementCfgMgr
;
3923 uno::Reference
< beans::XPropertySet
> xPropSet( xElementSettings
, uno::UNO_QUERY
);
3925 if ( xPropSet
.is() )
3926 xPropSet
->getPropertyValue( aConfigSourcePropName
) >>= xElementCfgMgr
;
3928 if ( !xElementCfgMgr
.is() )
3931 // Check if the same UI configuration manager has changed => update settings
3932 if ( rEvent
.Source
== xElementCfgMgr
)
3934 xElementSettings
->updateSettings();
3936 SolarMutexClearableGuard aWriteLock
;
3937 bool bNotify
= !aUIElement
.m_bFloating
;
3938 m_bLayoutDirty
= bNotify
;
3939 ILayoutNotifications
* pParentLayouter( m_pParentLayouter
);
3942 if ( bNotify
&& pParentLayouter
)
3943 pParentLayouter
->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED
);
3948 uno::Reference
< ui::XUIElement
> ToolbarLayoutManager::getToolbar( const OUString
& aName
)
3950 return implts_findToolbar( aName
).m_xUIElement
;
3953 uno::Sequence
< uno::Reference
< ui::XUIElement
> > ToolbarLayoutManager::getToolbars()
3955 uno::Sequence
< uno::Reference
< ui::XUIElement
> > aSeq
;
3958 if ( m_aUIElements
.size() > 0 )
3960 sal_uInt32
nCount(0);
3961 UIElementVector::iterator pIter
;
3962 for ( pIter
= m_aUIElements
.begin(); pIter
!= m_aUIElements
.end(); ++pIter
)
3964 if ( pIter
->m_xUIElement
.is() )
3967 aSeq
.realloc( nCount
);
3968 aSeq
[nCount
-1] = pIter
->m_xUIElement
;
3976 bool ToolbarLayoutManager::floatToolbar( const OUString
& rResourceURL
)
3978 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
3979 if ( aUIElement
.m_xUIElement
.is() )
3983 uno::Reference
< awt::XDockableWindow
> xDockWindow( aUIElement
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
3984 if ( xDockWindow
.is() && !xDockWindow
->isFloating() )
3986 aUIElement
.m_bFloating
= true;
3987 implts_writeWindowStateData( aUIElement
);
3988 xDockWindow
->setFloatingMode( true );
3990 implts_setLayoutDirty();
3991 implts_setToolbar( aUIElement
);
3995 catch (const lang::DisposedException
&)
4003 bool ToolbarLayoutManager::lockToolbar( const OUString
& rResourceURL
)
4005 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
4006 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
= true;
4014 implts_writeWindowStateData( aUIElement
);
4015 xDockWindow
->lock();
4017 implts_setLayoutDirty();
4018 implts_setToolbar( aUIElement
);
4022 catch (const lang::DisposedException
&)
4030 bool ToolbarLayoutManager::unlockToolbar( const OUString
& rResourceURL
)
4032 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
4033 if ( aUIElement
.m_xUIElement
.is() )
4037 uno::Reference
< awt::XDockableWindow
> xDockWindow( aUIElement
.m_xUIElement
->getRealInterface(), uno::UNO_QUERY
);
4038 if ( xDockWindow
.is() && !xDockWindow
->isFloating() && xDockWindow
->isLocked() )
4040 aUIElement
.m_aDockedData
.m_bLocked
= false;
4041 implts_writeWindowStateData( aUIElement
);
4042 xDockWindow
->unlock();
4044 implts_setLayoutDirty();
4045 implts_setToolbar( aUIElement
);
4049 catch (const lang::DisposedException
&)
4057 bool ToolbarLayoutManager::isToolbarVisible( const OUString
& rResourceURL
)
4059 uno::Reference
< awt::XWindow2
> xWindow2( implts_getXWindow( rResourceURL
), uno::UNO_QUERY
);
4060 return ( xWindow2
.is() && xWindow2
->isVisible() );
4063 bool ToolbarLayoutManager::isToolbarFloating( const OUString
& rResourceURL
)
4065 uno::Reference
< awt::XDockableWindow
> xDockWindow( implts_getXWindow( rResourceURL
), uno::UNO_QUERY
);
4066 return ( xDockWindow
.is() && xDockWindow
->isFloating() );
4069 bool ToolbarLayoutManager::isToolbarDocked( const OUString
& rResourceURL
)
4071 return !isToolbarFloating( rResourceURL
);
4074 bool ToolbarLayoutManager::isToolbarLocked( const OUString
& rResourceURL
)
4076 uno::Reference
< awt::XDockableWindow
> xDockWindow( implts_getXWindow( rResourceURL
), uno::UNO_QUERY
);
4077 return ( xDockWindow
.is() && xDockWindow
->isLocked() );
4080 awt::Size
ToolbarLayoutManager::getToolbarSize( const OUString
& rResourceURL
)
4082 vcl::Window
* pWindow
= implts_getWindow( rResourceURL
);
4084 SolarMutexGuard aGuard
;
4087 ::Size aSize
= pWindow
->GetSizePixel();
4089 aWinSize
.Width
= aSize
.Width();
4090 aWinSize
.Height
= aSize
.Height();
4097 awt::Point
ToolbarLayoutManager::getToolbarPos( const OUString
& rResourceURL
)
4100 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
4102 uno::Reference
< awt::XWindow
> xWindow( implts_getXWindow( rResourceURL
));
4105 if ( aUIElement
.m_bFloating
)
4107 awt::Rectangle aRect
= xWindow
->getPosSize();
4112 aPos
= aUIElement
.m_aDockedData
.m_aPos
;
4118 void ToolbarLayoutManager::setToolbarSize( const OUString
& rResourceURL
, const awt::Size
& aSize
)
4120 uno::Reference
< awt::XWindow2
> xWindow( implts_getXWindow( rResourceURL
), uno::UNO_QUERY
);
4121 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
4122 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
4124 if ( xWindow
.is() && xDockWindow
.is() && xDockWindow
->isFloating() )
4126 xWindow
->setOutputSize( aSize
);
4127 aUIElement
.m_aFloatingData
.m_aSize
= aSize
;
4128 implts_setToolbar( aUIElement
);
4129 implts_writeWindowStateData( aUIElement
);
4130 implts_sortUIElements();
4134 void ToolbarLayoutManager::setToolbarPos( const OUString
& rResourceURL
, const awt::Point
& aPos
)
4136 uno::Reference
< awt::XWindow
> xWindow( implts_getXWindow( rResourceURL
));
4137 uno::Reference
< awt::XDockableWindow
> xDockWindow( xWindow
, uno::UNO_QUERY
);
4138 UIElement aUIElement
= implts_findToolbar( rResourceURL
);
4140 if ( xWindow
.is() && xDockWindow
.is() && xDockWindow
->isFloating() )
4142 xWindow
->setPosSize( aPos
.X
, aPos
.Y
, 0, 0, awt::PosSize::POS
);
4143 aUIElement
.m_aFloatingData
.m_aPos
= aPos
;
4144 implts_setToolbar( aUIElement
);
4145 implts_writeWindowStateData( aUIElement
);
4146 implts_sortUIElements();
4150 void ToolbarLayoutManager::setToolbarPosSize( const OUString
& rResourceURL
, const awt::Point
& aPos
, const awt::Size
& aSize
)
4152 setToolbarPos( rResourceURL
, aPos
);
4153 setToolbarSize( rResourceURL
, aSize
);
4156 } // namespace framework
4158 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */