fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / framework / source / layoutmanager / toolbarlayoutmanager.cxx
blob1b1b9fc41948e9268dc7c65f8c47e8508894fc97
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "toolbarlayoutmanager.hxx"
21 #include <uiconfiguration/windowstateproperties.hxx>
22 #include <uielement/addonstoolbarwrapper.hxx>
23 #include "helpers.hxx"
24 #include <services.h>
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;
50 namespace framework
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 ),
62 m_pAddonOptions( 0 ),
63 m_pGlobalSettings( 0 ),
64 m_bComponentAttached( false ),
65 m_bLayoutDirty( false ),
66 m_bStoreWindowState( false ),
67 m_bGlobalSettings( false ),
68 m_bDockingInProgress( false ),
69 m_bVisible( true ),
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;
84 // XInterface
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)));
103 if ( a.hasValue() )
104 return a;
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
114 reset();
115 implts_destroyDockingAreaWindows();
119 awt::Rectangle ToolbarLayoutManager::getDockingArea()
121 SolarMutexResettableGuard aWriteLock;
122 Rectangle aNewDockingArea( m_aDockingArea );
123 aWriteLock.clear();
125 if ( isLayoutDirty() )
126 aNewDockingArea = implts_calcDockingArea();
128 aWriteLock.reset();
129 m_aDockingArea = aNewDockingArea;
130 aWriteLock.clear();
132 return putRectangleValueToAWT(aNewDockingArea);
135 void ToolbarLayoutManager::setDockingArea( const awt::Rectangle& rDockingArea )
137 SolarMutexGuard g;
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] );
151 aReadLock.clear();
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 );
212 aWriteLock.clear();
214 if ( bLayoutInProgress )
215 return;
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 );
237 aWriteLock.reset();
238 m_bLayoutDirty = false;
239 m_bLayoutInProgress = false;
240 aWriteLock.clear();
243 bool ToolbarLayoutManager::implts_isParentWindowVisible() const
245 SolarMutexGuard g;
246 bool bVisible( false );
247 if ( m_xContainerWindow.is() )
248 bVisible = m_xContainerWindow->isVisible();
250 return bVisible;
253 Rectangle ToolbarLayoutManager::implts_calcDockingArea()
255 SolarMutexClearableGuard aReadLock;
256 UIElementVector aWindowVector( m_aUIElements );
257 aReadLock.clear();
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;
291 nCurrRowColumn = 0;
292 nCurrPos = 0;
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 )
303 ++nCurrRowColumn;
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;
311 else
313 if ( pConstIter->m_aDockedData.m_aPos.X > nCurrPos )
315 ++nCurrRowColumn;
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;
345 else
346 aBorderSpace.Right() = nSize;
350 return aBorderSpace;
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;
362 aWriteLock.clear();
364 destroyToolbars();
365 resetDockingArea();
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 )
376 reset();
378 SolarMutexGuard g;
379 m_xFrame = xFrame;
380 m_xModuleCfgMgr = xModuleCfgMgr;
381 m_xDocCfgMgr = xDocCfgMgr;
382 m_xPersistentWindowState = xPersistentWindowState;
383 m_bComponentAttached = true;
386 bool ToolbarLayoutManager::isPreviewFrame()
388 SolarMutexGuard g;
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()
402 resetDockingArea();
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 );
441 return bNotify;
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 );
451 aReadLock.clear();
453 bNotify = false;
455 if ( !xFrame.is() || !xContainerWindow.is() )
456 return false;
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 );
469 aReadLock.clear();
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;
520 else
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;
530 aWriteLock.clear();
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 );
544 else
545 pToolbar->SetMenuType( nMenuType | TOOLBOX_MENUTYPE_CUSTOMIZE );
547 bNotify = true;
549 implts_sortUIElements();
551 if ( bVisible && !bFloating )
552 implts_setLayoutDirty();
556 return bNotify;
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();
577 else
578 pIter->m_bVisible = false;
579 break;
582 aWriteLock.clear();
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 )
594 if ( xWindow.is() )
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&)
612 else
614 if ( xWindow.is() )
615 xWindow->setVisible( sal_False );
616 bNotify = true;
619 if ( !xDockWindow->isFloating() )
620 bMustLayouted = true;
621 bMustBeSorted = true;
624 if ( bMustBeDestroyed )
626 if ( xComponent.is() )
627 xComponent->dispose();
628 bNotify = true;
631 if ( bMustLayouted )
632 implts_setLayoutDirty();
634 if ( bMustBeSorted )
635 implts_sortUIElements();
637 return bNotify;
640 void ToolbarLayoutManager::destroyToolbars()
642 UIElementVector aUIElementVector;
643 implts_getUIElementVectorCopy( aUIElementVector );
645 SolarMutexClearableGuard aWriteLock;
646 m_aUIElements.clear();
647 m_bLayoutDirty = true;
648 aWriteLock.clear();
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());
670 if (pAddOns)
671 pAddOns->populateImages();
673 if ( pWindow )
675 if ( !aUIElement.m_bFloating )
676 implts_setLayoutDirty();
677 else
678 pWindow->Show( true, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
680 aUIElement.m_bVisible = true;
681 implts_writeWindowStateData( aUIElement );
682 implts_setToolbar( aUIElement );
683 implts_sortUIElements();
684 return true;
687 return false;
690 bool ToolbarLayoutManager::hideToolbar( const OUString& rResourceURL )
692 UIElement aUIElement = implts_findToolbar( rResourceURL );
694 SolarMutexGuard aGuard;
695 vcl::Window* pWindow = getWindowFromXUIElement( aUIElement.m_xUIElement );
696 if ( pWindow )
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 );
705 return true;
708 return false;
711 void ToolbarLayoutManager::refreshToolbarsVisibility( bool bAutomaticToolbars )
713 UIElementVector aUIElementVector;
715 SolarMutexClearableGuard aReadLock;
716 bool bVisible( m_bVisible );
717 aReadLock.clear();
719 if ( !bVisible || !bAutomaticToolbars )
720 return;
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 )
732 SolarMutexGuard g;
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 )
755 if ( bVisible )
757 if ( pIter->m_bVisible && !pIter->m_bMasterHide )
758 pWindow->Show( true, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
760 else
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 );
784 if ( pWindow )
786 bool bSetVisible( pIter->m_bVisible && bVisible );
787 if ( !bSetVisible )
788 pWindow->Hide();
789 else
791 if ( pIter->m_bFloating )
792 pWindow->Show(true, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
797 if ( !bVisible )
798 resetDockingArea();
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.
841 ::Size aSize;
843 SolarMutexGuard aGuard;
845 if (pToolBox)
846 aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea ) );
847 else if (pWindow)
848 aSize = pWindow->GetSizePixel();
851 ::Point aPixelPos;
852 awt::Point aDockPos;
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 );
866 else
868 implts_writeWindowStateData( aUIElement );
869 implts_sortUIElements();
871 if ( aUIElement.m_bVisible )
872 implts_setLayoutDirty();
874 return true;
877 catch (const lang::DisposedException&)
882 return false;
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 );
896 aReadLock.clear();
898 bool bResult(true);
899 const sal_uInt32 nCount = aToolBarNameVector.size();
900 for ( sal_uInt32 i = 0; i < nCount; ++i )
902 awt::Point aPoint;
903 aPoint.X = aPoint.Y = SAL_MAX_INT32;
904 bResult &= dockToolbar( aToolBarNameVector[i], ui::DockingArea_DOCKINGAREA_DEFAULT, aPoint );
907 return bResult;
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
914 // anymore!
915 if ( pEvent && pEvent->ISA( VclWindowEvent ))
917 if ( pEvent->GetId() == VCLEVENT_TOOLBOX_SELECT )
919 OUString aToolbarName;
920 OUString aCommand;
921 ToolBox* pToolBox = getToolboxPtr( static_cast<VclWindowEvent*>(pEvent)->GetWindow() );
923 if ( pToolBox )
925 aToolbarName = retrieveToolbarNameFromHelpURL( pToolBox );
926 sal_uInt16 nId = pToolBox->GetCurItemId();
927 if ( nId > 0 )
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 );
946 aReadLock.clear();
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&)
957 throw;
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() );
970 if ( pToolBox )
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 );
991 return 1;
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] );
1001 aReadLock.clear();
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;
1029 aWriteLock.clear();
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();
1044 else
1046 destroyToolbars();
1047 resetDockingArea();
1051 void ToolbarLayoutManager::setDockingAreaOffsets( const ::Rectangle& rOffsets )
1053 SolarMutexGuard g;
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 );
1077 aWriteLock.clear();
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 );
1101 // #i79828
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() )
1105 continue;
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 );
1120 if ( xWindow.is() )
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 );
1142 else
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 );
1158 if ( xWindow.is() )
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 )
1186 return;
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 );
1192 aReadLock.clear();
1194 if ( xFrame.is() )
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 )
1218 return;
1220 uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager );
1221 uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
1222 aReadLock.clear();
1224 if (isPreviewFrame())
1225 return;
1227 std::vector< OUString > aMakeVisibleToolbars;
1231 uno::Sequence< OUString > aToolbarNames = xPersistentWindowState->getElementNames();
1233 if ( aToolbarNames.getLength() > 0 )
1235 OUString aElementType;
1236 OUString aElementName;
1237 OUString aName;
1239 uno::Reference< ui::XUIElement > xUIElement;
1240 aMakeVisibleToolbars.reserve(aToolbarNames.getLength());
1242 SolarMutexGuard g;
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 );
1258 if ( !bFound )
1259 implts_readWindowStateData( aName, aNewToolbar );
1261 if ( aNewToolbar.m_bVisible && !aNewToolbar.m_bContextSensitive )
1263 if ( !bFound )
1264 implts_insertToolbar( aNewToolbar );
1265 aMakeVisibleToolbars.push_back( aName );
1271 catch (const uno::RuntimeException&)
1273 throw;
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;
1291 OUString aTbxTitle;
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 );
1320 if ( pWindow )
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] );
1335 aWriteLock.clear();
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&)
1355 throw;
1357 catch (const uno::Exception&)
1361 vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
1362 if ( pWindow )
1364 // Reparent our child windows according to their current state.
1365 if ( pIter->m_bFloating )
1366 pWindow->SetParent( pContainerWindow );
1367 else
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 );
1375 else
1376 pWindow->SetParent( pRightDockWindow );
1384 void ToolbarLayoutManager::implts_setToolbarCreation( bool bStart )
1386 SolarMutexGuard g;
1387 m_bToolbarCreation = bStart;
1390 bool ToolbarLayoutManager::implts_isToolbarCreationActive()
1392 SolarMutexGuard g;
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() );
1400 aReadLock.clear();
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 );
1413 if ( pWindow )
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);
1423 if ( pToolBox )
1425 pToolBox->SetButtonType( (ButtonType)rElement.m_nStyle );
1426 if ( rElement.m_bNoClose )
1427 pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() & ~WB_CLOSEABLE );
1431 if ( rElement.m_bFloating )
1433 if ( pWindow )
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 );
1447 if ( bUndefPos )
1449 aPos = implts_findNextCascadeFloatingPos();
1450 rElement.m_aFloatingData.m_aPos = aPos; // set new cascaded position
1451 bWriteData = true;
1454 if( bSetSize )
1455 xWindow->setOutputSize(rElement.m_aFloatingData.m_aSize);
1456 else
1458 if( pToolBox )
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
1474 // position.
1475 xWindow->setPosSize( aPos.X, aPos.Y, 0, 0, awt::PosSize::POS );
1477 if ( bWriteData )
1478 implts_writeWindowStateData( rElement );
1479 if ( bShowElement && pWindow )
1481 SolarMutexGuard aGuard;
1482 pWindow->Show( true, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
1485 else
1487 bool bSetSize( false );
1488 awt::Point aDockPos;
1489 ::Point aPixelPos;
1490 ::Size aSize;
1492 if ( pToolBox )
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();
1501 bSetSize = true;
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 );
1511 if( bSetSize )
1512 xWindow->setOutputSize( AWTSize( aSize) );
1514 if ( pWindow )
1516 SolarMutexGuard aGuard;
1517 if ( !bShowElement )
1518 pWindow->Hide();
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();
1535 aWriteLock.clear();
1537 // destroy windows
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
1557 aWriteLock.clear();
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 ));
1613 else
1615 uno::Reference< container::XNameContainer > xInsert( xPersistentWindowState, uno::UNO_QUERY );
1616 xInsert->insertByName( aName, uno::makeAny( aWindowState ));
1619 catch (const uno::Exception&)
1624 // Reset flag
1625 aWriteLock.reset();
1626 m_bStoreWindowState = false;
1627 aWriteLock.clear();
1630 /******************************************************************************
1631 LOOKUP PART FOR TOOLBARS
1632 ******************************************************************************/
1634 UIElement& ToolbarLayoutManager::impl_findToolbar( const OUString& aName )
1636 static UIElement aEmptyElement;
1637 UIElementVector::iterator pIter;
1639 SolarMutexGuard g;
1640 for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); ++pIter )
1642 if ( pIter->m_aName == aName )
1643 return *pIter;
1646 return aEmptyElement;
1649 UIElement ToolbarLayoutManager::implts_findToolbar( const OUString& aName )
1651 SolarMutexGuard g;
1652 return impl_findToolbar( aName );
1655 UIElement ToolbarLayoutManager::implts_findToolbar( const uno::Reference< uno::XInterface >& xToolbar )
1657 UIElement aToolbar;
1658 UIElementVector::const_iterator pIter;
1660 SolarMutexGuard g;
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 )
1668 aToolbar = *pIter;
1669 break;
1674 return aToolbar;
1677 uno::Reference< awt::XWindow > ToolbarLayoutManager::implts_getXWindow( const OUString& aName )
1679 UIElementVector::iterator pIter;
1680 uno::Reference< awt::XWindow > xWindow;
1682 SolarMutexGuard g;
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 );
1688 break;
1692 return xWindow;
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 );
1700 return pWindow;
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 )
1711 bFound = true;
1713 if ( !bFound )
1715 SolarMutexGuard g;
1716 m_aUIElements.push_back( rUIElement );
1717 bResult = true;
1720 return bResult;
1723 void ToolbarLayoutManager::implts_setToolbar( const UIElement& rUIElement )
1725 SolarMutexGuard g;
1726 UIElement& rData = impl_findToolbar( rUIElement.m_aName );
1727 if ( rData.m_aName == rUIElement.m_aName )
1728 rData = rUIElement;
1729 else
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] );
1748 aReadLock.clear();
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;
1798 return aCurrPos;
1801 void ToolbarLayoutManager::implts_sortUIElements()
1803 SolarMutexGuard g;
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 )
1817 SolarMutexGuard g;
1818 rCopy = m_aUIElements;
1821 ::Size ToolbarLayoutManager::implts_getTopBottomDockingAreaSizes()
1823 ::Size aSize;
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];
1830 aReadLock.clear();
1832 if ( xTopDockingAreaWindow.is() )
1833 aSize.Width() = xTopDockingAreaWindow->getPosSize().Height;
1834 if ( xBottomDockingAreaWindow.is() )
1835 aSize.Height() = xBottomDockingAreaWindow->getPosSize().Height;
1837 return aSize;
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() )
1865 // docked windows
1866 aWindowVector.push_back( *pIter );
1871 aReadLock.clear();
1872 /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1874 rRowColumnsWindowData.clear();
1876 // Collect data from windows that are on the same row/column
1877 sal_Int32 j;
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;
1893 else
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) )
1905 continue;
1906 if ( isHorizontalDockingArea( eDockingArea ))
1908 if ( nCurrPos == -1 )
1910 nCurrPos = rElement.m_aDockedData.m_aPos.Y;
1911 nLastPos = 0;
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;
1923 else
1924 nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize;
1925 ++nIndex;
1926 nLastPos = 0;
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;
1940 else
1942 nSpace = 0;
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,
1952 aPosSize.Width,
1953 aPosSize.Height ));
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 );
1959 else
1960 rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( 0, ( nLastRowColPixelPos - aPosSize.Height ),
1961 aDockAreaRect.Width, aPosSize.Height );
1962 rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Width + nSpace;
1964 else
1966 if ( nCurrPos == -1 )
1968 nCurrPos = rElement.m_aDockedData.m_aPos.X;
1969 nLastPos = 0;
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;
1981 else
1982 nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize;
1983 ++nIndex;
1984 nLastPos = 0;
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;
1998 else
2000 nSpace = 0;
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,
2010 aPosSize.Width,
2011 aPosSize.Height ));
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 );
2017 else
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 );
2048 if ( xWindow.is() )
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
2059 aReadLock.clear();
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
2073 sal_Int32 j;
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) )
2084 continue;
2086 sal_Int32 nSpace;
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;
2094 else
2095 nSpace = 0;
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;
2106 else
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;
2112 else
2113 nSpace = 0;
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() )
2144 return aWinRect;
2145 else
2147 SolarMutexClearableGuard aReadLock;
2148 vcl::Window* pContainerWindow( VCLUnoHelper::GetWindow( m_xContainerWindow ));
2149 vcl::Window* pDockingAreaWindow( VCLUnoHelper::GetWindow( m_xDockAreaWindows[DockingArea] ));
2150 aReadLock.clear();
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] )
2169 return aRect;
2170 else
2171 break;
2177 return aWinRect;
2180 ::Rectangle ToolbarLayoutManager::implts_determineFrontDockingRect(
2181 ui::DockingArea eDockingArea,
2182 sal_Int32 nRowCol,
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;
2193 else
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];
2205 break;
2207 else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName )
2208 nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Width +
2209 aRowColumnWindowData.aRowColumnSpace[i];
2210 else
2211 nSpace = 0;
2213 else
2215 if ( aRowColumnWindowData.aRowColumnWindowSizes[i].Y >= rDockedElementRect.Top() )
2217 nSpace += aRowColumnWindowData.aRowColumnSpace[i];
2218 break;
2220 else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName )
2221 nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Height +
2222 aRowColumnWindowData.aRowColumnSpace[i];
2223 else
2224 nSpace = 0;
2228 if ( nSpace > 0 )
2230 sal_Int32 nMove = std::min( nSpace, static_cast<sal_Int32>(aFrontDockingRect.getWidth()) );
2231 if ( bHorzDockArea )
2232 aFrontDockingRect.Move( -nMove, 0 );
2233 else
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 );
2249 aReadLock.clear();
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();
2269 else
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 );
2306 else
2307 rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos );
2308 return;
2310 nCurrPos = rRect.X + rRect.Width;
2312 else
2314 if ( rSpace >= nNeededSpace )
2316 rVirtualPos = awt::Point( rRowColumnWindowData.nRowColumn, nCurrPos );
2317 if ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
2318 rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos );
2319 else
2320 rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos );
2321 return;
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 );
2334 else
2335 rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos );
2336 return;
2338 else
2340 rVirtualPos = awt::Point( rRowColumnWindowData.nRowColumn, nCurrPos );
2341 if ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
2342 rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos );
2343 else
2344 rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos );
2345 return;
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;
2358 else
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 );
2374 else
2375 rPixelPos = ::Point( 0, aDockingWinSize.Height() - nFreeRowColPixelPos );
2377 else
2379 rVirtualPos = awt::Point( nNextFreeRowCol, 0 );
2380 rPixelPos = ::Point( aDockingWinSize.Width() - nFreeRowColPixelPos, 0 );
2384 void ToolbarLayoutManager::implts_calcWindowPosSizeOnSingleRowColumn(
2385 sal_Int32 nDockingArea,
2386 sal_Int32 nOffset,
2387 SingleRowColumnWindowData& rRowColumnWindowData,
2388 const ::Size& rContainerSize )
2390 sal_Int32 nDiff(0);
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() )
2397 return;
2399 if ( isHorizontalDockingArea( nDockingArea ))
2401 nContainerClientSize = rContainerSize.Width();
2402 nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize;
2404 else
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;
2417 while ( i >= 0 )
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;
2428 else
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;
2434 nDiff = 0;
2436 break;
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;
2446 else
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;
2452 nDiff += nSpace;
2454 --i;
2458 // Check if we have to reduce further
2459 if ( nDiff < 0 )
2461 // Now we have to reduce the size of certain docked windows
2462 sal_Int32 i = sal_Int32( nCount - 1 );
2463 while ( i >= 0 )
2465 awt::Rectangle& rWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i];
2466 ::Size aMinSize;
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;
2484 nDiff = 0;
2486 else
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;
2496 else
2498 sal_Int32 nMaxReducation = ( rWinRect.Height - aMinSize.Height() );
2499 if ( nMaxReducation >= -nDiff )
2501 rWinRect.Height = rWinRect.Height + nDiff;
2502 nDiff = 0;
2504 else
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;
2516 if ( nDiff >= 0 )
2517 break;
2519 --i;
2523 SolarMutexClearableGuard aReadLock;
2524 vcl::Window* pDockAreaWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[nDockingArea] );
2525 aReadLock.clear();
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;
2548 else
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()
2561 SolarMutexGuard g;
2562 m_bLayoutDirty = true;
2565 void ToolbarLayoutManager::implts_setLayoutInProgress( bool bInProgress )
2567 SolarMutexGuard g;
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;
2580 return aRect;
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 );
2594 aReadLock.clear();
2596 if ( !rUIElement.m_xUIElement.is() )
2598 rTrackingRect = ::Rectangle();
2599 return;
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;
2626 aReadLock.reset();
2627 xDockingAreaWindow = m_xDockAreaWindows[eDockedArea];
2628 aReadLock.clear();
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() );
2638 if ( pToolBox )
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 )
2691 nIndex = i;
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;
2696 break;
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() )));
2720 if ( nSize == 0 )
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;
2730 else
2732 sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32(
2733 nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Top() ),
2734 sal_Int32( aTrackingRect.getHeight() )));
2735 if ( nSize == 0 )
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;
2749 return;
2751 else
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() )));
2757 if ( nSize == 0 )
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();
2764 else
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;
2774 else
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;
2793 return;
2796 else
2798 implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect );
2799 rTrackingRect = implts_calcTrackingAndElementRect(
2800 eDockedArea, nRowCol, rUIElement,
2801 aTrackingRect, aRowColumnRect, aContainerWinSize );
2802 return;
2805 else
2807 if ((( nRowCol == nMinRowCol ) && ( rDockingOperation == DOCKOP_BEFORE_COLROW )) ||
2808 (( nRowCol == nMaxRowCol ) && ( rDockingOperation == DOCKOP_AFTER_COLROW )))
2809 bOpOutsideOfDockingArea = true;
2810 else
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 ));
2822 else
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.
2832 nOffsetX *= -1;
2833 nOffsetY *= -1;
2836 else
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.
2843 nOffsetX *= -1;
2844 nOffsetY *= -1;
2846 nRowCol++;
2849 if ( bHorizontalDockArea )
2850 rUIElement.m_aDockedData.m_aPos.Y = nRowCol;
2851 else
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() ),
2875 sal_Int32( 0 )));
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;
2892 else
2893 rUIElement.m_aDockedData.m_aPos.Y = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
2894 rDockingOperation = DOCKOP_BEFORE_COLROW;
2896 else
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;
2901 else
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;
2914 else
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;
2938 else
2939 rUIElement.m_aDockedData.m_aPos.X = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
2940 rDockingOperation = DOCKOP_BEFORE_COLROW;
2942 else
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;
2947 else
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;
2982 else
2983 return ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW;
2985 else
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;
2994 else
2995 return ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW;
2998 else
2999 return DOCKOP_ON_COLROW;
3002 ::Rectangle ToolbarLayoutManager::implts_calcTrackingAndElementRect(
3003 ui::DockingArea eDockingArea,
3004 sal_Int32 nRowCol,
3005 UIElement& rUIElement,
3006 const ::Rectangle& rTrackingRect,
3007 const ::Rectangle& rRowColumnRect,
3008 const ::Size& rContainerWinSize )
3010 SolarMutexResettableGuard aReadGuard;
3011 ::Rectangle aDockingAreaOffsets( m_aDockingAreaOffsets );
3012 aReadGuard.clear();
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() ),
3032 sal_Int32( 0 )));
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;
3044 else
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 );
3061 aReadGuard.reset();
3062 uno::Reference< awt::XWindow > xDockingAreaWindow( m_xDockAreaWindows[eDockingArea] );
3063 uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
3064 aReadGuard.clear();
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();
3088 else
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 );
3100 aReadLock.clear();
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 ))
3114 continue;
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;
3121 else
3122 pIter->m_aDockedData.m_aPos.X += 1;
3126 aWriteLock.clear();
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 ))
3156 continue;
3158 sal_Int32 nWindowRowCol = ( bHorzDockingArea ) ? aDockedPos.Y : aDockedPos.X;
3159 if (( nDockedArea == eDockingArea ) && ( nWindowRowCol >= nRowCol ))
3161 if ( bHorzDockingArea )
3162 aDockedPos.Y += 1;
3163 else
3164 aDockedPos.X += 1;
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&)
3182 // XWindowListener
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 );
3190 aWriteLock.clear();
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 );
3208 if( xWindow2.is() )
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 );
3222 else
3224 implts_setLayoutDirty();
3225 bNotify = true;
3229 if ( bNotify )
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 );
3259 aReadGuard.clear();
3261 vcl::Window* pContainerWindow( 0 );
3262 ::Point aMousePos;
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;
3275 bWinFound = true;
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 );
3297 SolarMutexGuard g;
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 );
3323 aReadLock.clear();
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;
3430 else
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
3459 SolarMutexGuard g;
3460 m_aDockUIElement.m_bFloating = aDockingData.bFloating;
3461 if ( !aDockingData.bFloating )
3463 m_aDockUIElement.m_aDockedData = aUIDockingElement.m_aDockedData;
3465 m_eDockOperation = eDockingOperation;
3467 else
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;
3505 else
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;
3525 aWriteLock.clear();
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);
3538 if ( pToolBox )
3540 if( e.bFloating )
3542 if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal )
3543 pToolBox->SetAlign( WINDOWALIGN_TOP );
3544 else
3545 pToolBox->SetAlign( WINDOWALIGN_LEFT );
3547 else
3549 ::Size aSize;
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();
3564 aWriteLock.reset();
3565 m_bDockingInProgress = false;
3566 m_bLayoutDirty = !bStartDockFloated || !bFloating;
3567 bool bNotify = m_bLayoutDirty;
3568 aWriteLock.clear();
3570 if ( bNotify )
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;
3579 aReadLock.clear();
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 );
3613 return sal_True;
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;
3625 aReadLock.clear();
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;
3654 if ( pToolBox )
3656 pToolBox->SetLineCount( aUIDockingElement.m_aFloatingData.m_nLines );
3657 if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal )
3658 pToolBox->SetAlign( WINDOWALIGN_TOP );
3659 else
3660 pToolBox->SetAlign( WINDOWALIGN_LEFT );
3663 bool bUndefPos = hasDefaultPosValue( aUIDockingElement.m_aFloatingData.m_aPos );
3664 bool bSetSize = !hasEmptySize( aUIDockingElement.m_aFloatingData.m_aSize );
3666 if ( bUndefPos )
3667 aUIDockingElement.m_aFloatingData.m_aPos = implts_findNextCascadeFloatingPos();
3669 if ( !bSetSize )
3671 if ( pToolBox )
3672 aUIDockingElement.m_aFloatingData.m_aSize = AWTSize(pToolBox->CalcFloatingWindowSizePixel());
3673 else if ( pWindow )
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);
3682 else
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.
3688 ::Point aPixelPos;
3689 awt::Point aDockPos;
3690 ::Size aSize;
3693 SolarMutexGuard aGuard;
3694 if ( pToolBox )
3695 aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea ) );
3696 else if ( pWindow )
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;
3705 if ( pToolBox )
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();
3721 aReadLock.reset();
3722 ILayoutNotifications* pParentLayouter( m_pParentLayouter );
3723 aReadLock.clear();
3725 if ( pParentLayouter )
3726 pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
3729 else
3731 SolarMutexGuard aGuard;
3732 if ( pToolBox )
3734 if ( aUIDockingElement.m_bFloating )
3736 if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal )
3737 pToolBox->SetAlign( WINDOWALIGN_TOP );
3738 else
3739 pToolBox->SetAlign( WINDOWALIGN_LEFT );
3741 else
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)
3750 OUString aName;
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;
3772 break;
3776 aWriteLock.clear();
3778 // destroy element
3779 if ( !aName.isEmpty() )
3781 implts_writeWindowStateData( aUIElement );
3782 destroyToolbar( aName );
3784 SolarMutexClearableGuard aReadLock;
3785 bool bLayoutDirty = m_bLayoutDirty;
3786 ILayoutNotifications* pParentLayouter( m_pParentLayouter );
3787 aWriteLock.clear();
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();
3818 else
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() )
3830 OUString aUIName;
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 );
3855 if ( pWindow )
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 );
3872 aReadLock.clear();
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() )
3887 return;
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();
3900 return;
3904 bNoSettings = true;
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() )
3929 return;
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 );
3940 aWriteLock.clear();
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;
3957 SolarMutexGuard g;
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() )
3966 ++nCount;
3967 aSeq.realloc( nCount );
3968 aSeq[nCount-1] = pIter->m_xUIElement;
3973 return aSeq;
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 );
3992 return true;
3995 catch (const lang::DisposedException&)
4000 return false;
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 );
4019 return true;
4022 catch (const lang::DisposedException&)
4027 return false;
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 );
4046 return true;
4049 catch (const lang::DisposedException&)
4054 return false;
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;
4085 if ( pWindow )
4087 ::Size aSize = pWindow->GetSizePixel();
4088 awt::Size aWinSize;
4089 aWinSize.Width = aSize.Width();
4090 aWinSize.Height = aSize.Height();
4091 return aWinSize;
4094 return awt::Size();
4097 awt::Point ToolbarLayoutManager::getToolbarPos( const OUString& rResourceURL )
4099 awt::Point aPos;
4100 UIElement aUIElement = implts_findToolbar( rResourceURL );
4102 uno::Reference< awt::XWindow > xWindow( implts_getXWindow( rResourceURL ));
4103 if ( xWindow.is() )
4105 if ( aUIElement.m_bFloating )
4107 awt::Rectangle aRect = xWindow->getPosSize();
4108 aPos.X = aRect.X;
4109 aPos.Y = aRect.Y;
4111 else
4112 aPos = aUIElement.m_aDockedData.m_aPos;
4115 return 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: */