Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
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>
28 :
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>
37 :
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>
45 :
46 : #include <boost/bind.hpp>
47 :
48 : using namespace ::com::sun::star;
49 :
50 : namespace framework
51 : {
52 :
53 3281 : 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 3281 : m_bToolbarCreation( false )
72 : {
73 : // initialize rectangles to zero values
74 3281 : setZeroRectangle( m_aDockingAreaOffsets );
75 3281 : setZeroRectangle( m_aDockingArea );
76 3281 : }
77 :
78 9759 : ToolbarLayoutManager::~ToolbarLayoutManager()
79 : {
80 3253 : delete m_pGlobalSettings;
81 3253 : delete m_pAddonOptions;
82 6506 : }
83 :
84 : // XInterface
85 :
86 142960 : void SAL_CALL ToolbarLayoutManager::acquire() throw()
87 : {
88 142960 : OWeakObject::acquire();
89 142960 : }
90 :
91 142906 : void SAL_CALL ToolbarLayoutManager::release() throw()
92 : {
93 142906 : OWeakObject::release();
94 142906 : }
95 :
96 50866 : uno::Any SAL_CALL ToolbarLayoutManager::queryInterface( const uno::Type & rType ) throw( uno::RuntimeException, std::exception )
97 : {
98 : uno::Any a = ::cppu::queryInterface( rType,
99 : (static_cast< awt::XDockableWindowListener* >(this)),
100 : (static_cast< ui::XUIConfigurationListener* >(this)),
101 50866 : (static_cast< awt::XWindowListener* >(this)));
102 :
103 50866 : if ( a.hasValue() )
104 22327 : return a;
105 :
106 28539 : return OWeakObject::queryInterface( rType );
107 : }
108 :
109 0 : void SAL_CALL ToolbarLayoutManager::disposing( const lang::EventObject& aEvent ) throw( uno::RuntimeException, std::exception )
110 : {
111 0 : if ( aEvent.Source == m_xFrame )
112 : {
113 : // Reset all internal references
114 0 : reset();
115 0 : implts_destroyDockingAreaWindows();
116 : }
117 0 : }
118 :
119 11456 : awt::Rectangle ToolbarLayoutManager::getDockingArea()
120 : {
121 11456 : SolarMutexResettableGuard aWriteLock;
122 11456 : Rectangle aNewDockingArea( m_aDockingArea );
123 11456 : aWriteLock.clear();
124 :
125 11456 : if ( isLayoutDirty() )
126 8353 : aNewDockingArea = implts_calcDockingArea();
127 :
128 11456 : aWriteLock.reset();
129 11456 : m_aDockingArea = aNewDockingArea;
130 11456 : aWriteLock.clear();
131 :
132 11456 : return putRectangleValueToAWT(aNewDockingArea);
133 : }
134 :
135 11410 : void ToolbarLayoutManager::setDockingArea( const awt::Rectangle& rDockingArea )
136 : {
137 11410 : SolarMutexGuard g;
138 11410 : m_aDockingArea = putAWTToRectangle( rDockingArea );
139 11410 : m_bLayoutDirty = true;
140 11410 : }
141 :
142 11410 : void ToolbarLayoutManager::implts_setDockingAreaWindowSizes( const awt::Rectangle& rBorderSpace )
143 : {
144 11410 : SolarMutexClearableGuard aReadLock;
145 11410 : Rectangle aDockOffsets = m_aDockingAreaOffsets;
146 22820 : uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
147 22820 : uno::Reference< awt::XWindow > xTopDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
148 22820 : uno::Reference< awt::XWindow > xBottomDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
149 22820 : uno::Reference< awt::XWindow > xLeftDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
150 22820 : uno::Reference< awt::XWindow > xRightDockAreaWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
151 11410 : aReadLock.clear();
152 :
153 22820 : uno::Reference< awt::XDevice > xDevice( xContainerWindow, uno::UNO_QUERY );
154 :
155 : // Convert relativ size to output size.
156 11410 : awt::Rectangle aRectangle = xContainerWindow->getPosSize();
157 11410 : awt::DeviceInfo aInfo = xDevice->getInfo();
158 11410 : awt::Size aContainerClientSize = awt::Size( aRectangle.Width - aInfo.LeftInset - aInfo.RightInset ,
159 22820 : aRectangle.Height - aInfo.TopInset - aInfo.BottomInset );
160 11410 : long aStatusBarHeight = aDockOffsets.GetHeight();
161 :
162 11410 : sal_Int32 nLeftRightDockingAreaHeight( aContainerClientSize.Height );
163 11410 : if ( rBorderSpace.Y >= 0 )
164 : {
165 : // Top docking area window
166 11410 : xTopDockAreaWindow->setPosSize( 0, 0, aContainerClientSize.Width, rBorderSpace.Y, awt::PosSize::POSSIZE );
167 11410 : xTopDockAreaWindow->setVisible( sal_True );
168 11410 : nLeftRightDockingAreaHeight -= rBorderSpace.Y;
169 : }
170 :
171 11410 : if ( rBorderSpace.Height >= 0 )
172 : {
173 : // Bottom docking area window
174 11410 : sal_Int32 nBottomPos = std::max( sal_Int32( aContainerClientSize.Height - rBorderSpace.Height - aStatusBarHeight + 1 ), sal_Int32( 0 ));
175 11410 : sal_Int32 nHeight = ( nBottomPos == 0 ) ? 0 : rBorderSpace.Height;
176 :
177 11410 : xBottomDockAreaWindow->setPosSize( 0, nBottomPos, aContainerClientSize.Width, nHeight, awt::PosSize::POSSIZE );
178 11410 : xBottomDockAreaWindow->setVisible( sal_True );
179 11410 : nLeftRightDockingAreaHeight -= nHeight - 1;
180 : }
181 :
182 11410 : nLeftRightDockingAreaHeight -= aStatusBarHeight;
183 11410 : if ( rBorderSpace.X >= 0 || nLeftRightDockingAreaHeight > 0 )
184 : {
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 11410 : sal_Int32 nHeight = std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight ));
188 :
189 11410 : xLeftDockAreaWindow->setPosSize( 0, rBorderSpace.Y, rBorderSpace.X, nHeight, awt::PosSize::POSSIZE );
190 11410 : xLeftDockAreaWindow->setVisible( sal_True );
191 : }
192 11410 : if ( rBorderSpace.Width >= 0 || nLeftRightDockingAreaHeight > 0 )
193 : {
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 11410 : sal_Int32 nLeftPos = std::max( sal_Int32( 0 ), sal_Int32( aContainerClientSize.Width - rBorderSpace.Width ));
197 11410 : sal_Int32 nHeight = std::max( sal_Int32( 0 ), sal_Int32( nLeftRightDockingAreaHeight ));
198 11410 : sal_Int32 nWidth = ( nLeftPos == 0 ) ? 0 : rBorderSpace.Width;
199 :
200 11410 : xRightDockAreaWindow->setPosSize( nLeftPos, rBorderSpace.Y, nWidth, nHeight, awt::PosSize::POSSIZE );
201 11410 : xRightDockAreaWindow->setVisible( sal_True );
202 11410 : }
203 11410 : }
204 :
205 :
206 11410 : void ToolbarLayoutManager::doLayout(const ::Size& aContainerSize)
207 : {
208 11410 : SolarMutexResettableGuard aWriteLock;
209 11410 : bool bLayoutInProgress( m_bLayoutInProgress );
210 11410 : m_bLayoutInProgress = true;
211 11410 : awt::Rectangle aDockingArea = putRectangleValueToAWT( m_aDockingArea );
212 11410 : aWriteLock.clear();
213 :
214 11410 : if ( bLayoutInProgress )
215 11410 : return;
216 :
217 : // Retrieve row/column dependent data from all docked user-interface elements
218 57050 : for ( sal_Int32 i = 0; i < DOCKINGAREAS_COUNT; i++ )
219 : {
220 45640 : bool bReverse( isReverseOrderDockingArea( i ));
221 45640 : std::vector< SingleRowColumnWindowData > aRowColumnsWindowData;
222 :
223 45640 : implts_getDockingAreaElementInfos( (ui::DockingArea)i, aRowColumnsWindowData );
224 :
225 45640 : sal_Int32 nOffset( 0 );
226 45640 : const sal_uInt32 nCount = aRowColumnsWindowData.size();
227 57164 : for ( sal_uInt32 j = 0; j < nCount; ++j )
228 : {
229 11524 : sal_uInt32 nIndex = bReverse ? nCount-j-1 : j;
230 11524 : implts_calcWindowPosSizeOnSingleRowColumn( i, nOffset, aRowColumnsWindowData[nIndex], aContainerSize );
231 11524 : nOffset += aRowColumnsWindowData[j].nStaticSize;
232 : }
233 45640 : }
234 :
235 11410 : implts_setDockingAreaWindowSizes( aDockingArea );
236 :
237 11410 : aWriteLock.reset();
238 11410 : m_bLayoutDirty = false;
239 11410 : m_bLayoutInProgress = false;
240 11410 : aWriteLock.clear();
241 : }
242 :
243 6743 : bool ToolbarLayoutManager::implts_isParentWindowVisible() const
244 : {
245 6743 : SolarMutexGuard g;
246 6743 : bool bVisible( false );
247 6743 : if ( m_xContainerWindow.is() )
248 6743 : bVisible = m_xContainerWindow->isVisible();
249 :
250 6743 : return bVisible;
251 : }
252 :
253 8353 : Rectangle ToolbarLayoutManager::implts_calcDockingArea()
254 : {
255 8353 : SolarMutexClearableGuard aReadLock;
256 16706 : UIElementVector aWindowVector( m_aUIElements );
257 8353 : aReadLock.clear();
258 :
259 8353 : Rectangle aBorderSpace;
260 8353 : sal_Int32 nCurrRowColumn( 0 );
261 8353 : sal_Int32 nCurrPos( 0 );
262 8353 : sal_Int32 nCurrDockingArea( ui::DockingArea_DOCKINGAREA_TOP );
263 16706 : std::vector< sal_Int32 > aRowColumnSizes[DOCKINGAREAS_COUNT];
264 8353 : UIElementVector::const_iterator pConstIter;
265 :
266 : // initialize rectangle with zero values!
267 8353 : aBorderSpace.setWidth(0);
268 8353 : aBorderSpace.setHeight(0);
269 :
270 8353 : aRowColumnSizes[nCurrDockingArea].clear();
271 8353 : aRowColumnSizes[nCurrDockingArea].push_back( 0 );
272 :
273 26074 : for ( pConstIter = aWindowVector.begin(); pConstIter != aWindowVector.end(); ++pConstIter )
274 : {
275 17721 : uno::Reference< ui::XUIElement > xUIElement( pConstIter->m_xUIElement, uno::UNO_QUERY );
276 17721 : if ( xUIElement.is() )
277 : {
278 17720 : uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
279 35440 : uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
280 17720 : if ( xWindow.is() && xDockWindow.is() )
281 : {
282 17720 : SolarMutexGuard aGuard;
283 :
284 17720 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
285 17720 : if ( pWindow && !xDockWindow->isFloating() && pConstIter->m_bVisible && !pConstIter->m_bMasterHide )
286 : {
287 10327 : awt::Rectangle aPosSize = xWindow->getPosSize();
288 10327 : if ( pConstIter->m_aDockedData.m_nDockedArea != nCurrDockingArea )
289 : {
290 526 : nCurrDockingArea = pConstIter->m_aDockedData.m_nDockedArea;
291 526 : nCurrRowColumn = 0;
292 526 : nCurrPos = 0;
293 526 : aRowColumnSizes[nCurrDockingArea].clear();
294 526 : aRowColumnSizes[nCurrDockingArea].push_back( 0 );
295 : }
296 :
297 10327 : if ( pConstIter->m_aDockedData.m_nDockedArea == nCurrDockingArea )
298 : {
299 10327 : if ( isHorizontalDockingArea( pConstIter->m_aDockedData.m_nDockedArea ))
300 : {
301 10241 : if ( pConstIter->m_aDockedData.m_aPos.Y > nCurrPos )
302 : {
303 3732 : ++nCurrRowColumn;
304 3732 : nCurrPos = pConstIter->m_aDockedData.m_aPos.Y;
305 3732 : aRowColumnSizes[nCurrDockingArea].push_back( 0 );
306 : }
307 :
308 10241 : if ( aPosSize.Height > aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] )
309 10166 : aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] = aPosSize.Height;
310 : }
311 : else
312 : {
313 86 : if ( pConstIter->m_aDockedData.m_aPos.X > nCurrPos )
314 : {
315 0 : ++nCurrRowColumn;
316 0 : nCurrPos = pConstIter->m_aDockedData.m_aPos.X;
317 0 : aRowColumnSizes[nCurrDockingArea].push_back( 0 );
318 : }
319 :
320 86 : if ( aPosSize.Width > aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] )
321 86 : aRowColumnSizes[nCurrDockingArea][nCurrRowColumn] = aPosSize.Width;
322 : }
323 : }
324 17720 : }
325 17720 : }
326 : }
327 17721 : }
328 :
329 : // Sum up max heights from every row/column
330 8353 : if ( !aWindowVector.empty() )
331 : {
332 40815 : for ( sal_Int32 i = 0; i <= ui::DockingArea_DOCKINGAREA_RIGHT; i++ )
333 : {
334 32652 : sal_Int32 nSize( 0 );
335 32652 : const sal_uInt32 nCount = aRowColumnSizes[i].size();
336 45073 : for ( sal_uInt32 j = 0; j < nCount; j++ )
337 12421 : nSize += aRowColumnSizes[i][j];
338 :
339 32652 : if ( i == ui::DockingArea_DOCKINGAREA_TOP )
340 8163 : aBorderSpace.Top() = nSize;
341 24489 : else if ( i == ui::DockingArea_DOCKINGAREA_BOTTOM )
342 8163 : aBorderSpace.Bottom() = nSize;
343 16326 : else if ( i == ui::DockingArea_DOCKINGAREA_LEFT )
344 8163 : aBorderSpace.Left() = nSize;
345 : else
346 8163 : aBorderSpace.Right() = nSize;
347 : }
348 : }
349 :
350 16706 : return aBorderSpace;
351 : }
352 :
353 3278 : void ToolbarLayoutManager::reset()
354 : {
355 3278 : SolarMutexClearableGuard aWriteLock;
356 6556 : uno::Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr );
357 6556 : uno::Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr );
358 3278 : m_xModuleCfgMgr.clear();
359 3278 : m_xDocCfgMgr.clear();
360 3278 : m_ePreviewDetection = PREVIEWFRAME_UNKNOWN;
361 3278 : m_bComponentAttached = false;
362 3278 : aWriteLock.clear();
363 :
364 3278 : destroyToolbars();
365 6556 : resetDockingArea();
366 3278 : }
367 :
368 3292 : 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 )
373 : {
374 : // reset toolbar manager if we lose our current frame
375 3292 : if ( m_xFrame.is() && m_xFrame != xFrame )
376 0 : reset();
377 :
378 3292 : SolarMutexGuard g;
379 3292 : m_xFrame = xFrame;
380 3292 : m_xModuleCfgMgr = xModuleCfgMgr;
381 3292 : m_xDocCfgMgr = xDocCfgMgr;
382 3292 : m_xPersistentWindowState = xPersistentWindowState;
383 3292 : m_bComponentAttached = true;
384 3292 : }
385 :
386 60257 : bool ToolbarLayoutManager::isPreviewFrame()
387 : {
388 60257 : SolarMutexGuard g;
389 60257 : if (m_ePreviewDetection == PREVIEWFRAME_UNKNOWN)
390 : {
391 3296 : uno::Reference< frame::XFrame > xFrame( m_xFrame );
392 :
393 6592 : uno::Reference< frame::XModel > xModel( impl_getModelFromFrame( xFrame ));
394 :
395 6592 : m_ePreviewDetection = (implts_isPreviewModel( xModel ) ? PREVIEWFRAME_YES : PREVIEWFRAME_NO);
396 : }
397 60257 : return m_ePreviewDetection == PREVIEWFRAME_YES;
398 : }
399 :
400 6572 : void ToolbarLayoutManager::createStaticToolbars()
401 : {
402 6572 : resetDockingArea();
403 6572 : implts_createCustomToolBars();
404 6572 : implts_createAddonsToolBars();
405 6572 : implts_createNonContextSensitiveToolBars();
406 6568 : implts_sortUIElements();
407 6568 : }
408 :
409 30882 : bool ToolbarLayoutManager::requestToolbar( const OUString& rResourceURL )
410 : {
411 30882 : if (isPreviewFrame())
412 0 : return false; // no toolbars for preview frame!
413 :
414 30882 : bool bNotify( false );
415 30882 : bool bMustCallCreate( false );
416 30882 : uno::Reference< ui::XUIElement > xUIElement;
417 :
418 61764 : UIElement aRequestedToolbar = impl_findToolbar( rResourceURL );
419 30882 : if ( aRequestedToolbar.m_aName != rResourceURL )
420 : {
421 26116 : bMustCallCreate = true;
422 26116 : aRequestedToolbar.m_aName = rResourceURL;
423 26116 : aRequestedToolbar.m_aType = UIRESOURCETYPE_TOOLBAR;
424 26116 : aRequestedToolbar.m_xUIElement = xUIElement;
425 26116 : implts_readWindowStateData( rResourceURL, aRequestedToolbar );
426 : }
427 :
428 30882 : xUIElement = aRequestedToolbar.m_xUIElement;
429 30882 : if ( !xUIElement.is() )
430 26116 : bMustCallCreate = true;
431 :
432 30882 : bool bCreateOrShowToolbar( aRequestedToolbar.m_bVisible && !aRequestedToolbar.m_bMasterHide );
433 :
434 61764 : uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow, uno::UNO_QUERY );
435 30882 : if ( xContainerWindow.is() && aRequestedToolbar.m_bFloating )
436 16062 : bCreateOrShowToolbar &= bool( xContainerWindow->isActive());
437 :
438 30882 : if ( bCreateOrShowToolbar )
439 11486 : bNotify = ( bMustCallCreate ) ? createToolbar( rResourceURL ) : showToolbar( rResourceURL );
440 :
441 61760 : return bNotify;
442 : }
443 :
444 6802 : bool ToolbarLayoutManager::createToolbar( const OUString& rResourceURL )
445 : {
446 6802 : bool bNotify( false );
447 :
448 6802 : SolarMutexClearableGuard aReadLock;
449 13604 : uno::Reference< frame::XFrame > xFrame( m_xFrame );
450 13604 : uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
451 6802 : aReadLock.clear();
452 :
453 6802 : bNotify = false;
454 :
455 6802 : if ( !xFrame.is() || !xContainerWindow.is() )
456 0 : return false;
457 :
458 13604 : UIElement aToolbarElement = implts_findToolbar( rResourceURL );
459 6802 : if ( !aToolbarElement.m_xUIElement.is() )
460 : {
461 6768 : uno::Reference< ui::XUIElement > xUIElement;
462 :
463 13536 : uno::Sequence< beans::PropertyValue > aPropSeq( 2 );
464 6768 : aPropSeq[0].Name = "Frame";
465 6768 : aPropSeq[0].Value <<= m_xFrame;
466 6768 : aPropSeq[1].Name = "Persistent";
467 6768 : aPropSeq[1].Value <<= true;
468 13536 : uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager );
469 6768 : aReadLock.clear();
470 :
471 6768 : implts_setToolbarCreation( true );
472 : try
473 : {
474 6768 : if ( xUIElementFactory.is() )
475 6768 : xUIElement = xUIElementFactory->createUIElement( rResourceURL, aPropSeq );
476 : }
477 0 : catch (const container::NoSuchElementException&)
478 : {
479 : }
480 0 : catch (const lang::IllegalArgumentException&)
481 : {
482 : }
483 6764 : implts_setToolbarCreation( false );
484 :
485 6764 : if ( xUIElement.is() )
486 : {
487 6764 : uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
488 13528 : uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
489 6764 : if ( xDockWindow.is() && xWindow.is() )
490 : {
491 : try
492 : {
493 6764 : xDockWindow->addDockableWindowListener( uno::Reference< awt::XDockableWindowListener >(
494 6764 : static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
495 6764 : xWindow->addWindowListener( uno::Reference< awt::XWindowListener >(
496 6764 : static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
497 6764 : xDockWindow->enableDocking( sal_True );
498 : }
499 0 : catch (const uno::Exception&)
500 : {
501 : }
502 : }
503 :
504 6764 : bool bVisible = false;
505 6764 : bool bFloating = false;
506 :
507 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
508 13528 : SolarMutexClearableGuard aWriteLock;
509 :
510 6764 : UIElement& rElement = impl_findToolbar( rResourceURL );
511 6764 : if ( !rElement.m_aName.isEmpty() )
512 : {
513 : // Reuse a local entry so we are able to use the latest
514 : // UI changes for this document.
515 0 : implts_setElementData( rElement, xDockWindow );
516 0 : rElement.m_xUIElement = xUIElement;
517 0 : bVisible = rElement.m_bVisible;
518 0 : bFloating = rElement.m_bFloating;
519 : }
520 : else
521 : {
522 : // Create new UI element and try to read its state data
523 6764 : UIElement aNewToolbar( rResourceURL, UIRESOURCETYPE_TOOLBAR, xUIElement );
524 6764 : implts_readWindowStateData( rResourceURL, aNewToolbar );
525 6764 : implts_setElementData( aNewToolbar, xDockWindow );
526 6764 : implts_insertToolbar( aNewToolbar );
527 6764 : bVisible = aNewToolbar.m_bVisible;
528 6764 : bFloating = rElement.m_bFloating;
529 : }
530 6764 : aWriteLock.clear();
531 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
532 :
533 : // set toolbar menu style according to customize command state
534 13528 : SvtCommandOptions aCmdOptions;
535 :
536 13528 : SolarMutexGuard aGuard;
537 6764 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
538 6764 : if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
539 : {
540 6764 : ToolBox* pToolbar = static_cast<ToolBox *>(pWindow);
541 6764 : sal_uInt16 nMenuType = pToolbar->GetMenuType();
542 6764 : if ( aCmdOptions.Lookup( SvtCommandOptions::CMDOPTION_DISABLED, "ConfigureDialog" ))
543 0 : pToolbar->SetMenuType( nMenuType & ~TOOLBOX_MENUTYPE_CUSTOMIZE );
544 : else
545 6764 : pToolbar->SetMenuType( nMenuType | TOOLBOX_MENUTYPE_CUSTOMIZE );
546 : }
547 6764 : bNotify = true;
548 :
549 6764 : implts_sortUIElements();
550 :
551 6764 : if ( bVisible && !bFloating )
552 13507 : implts_setLayoutDirty();
553 6768 : }
554 : }
555 :
556 13600 : return bNotify;
557 : }
558 :
559 6913 : bool ToolbarLayoutManager::destroyToolbar( const OUString& rResourceURL )
560 : {
561 6913 : UIElementVector::iterator pIter;
562 6913 : uno::Reference< lang::XComponent > xComponent;
563 :
564 6913 : bool bNotify( false );
565 6913 : bool bMustBeSorted( false );
566 6913 : bool bMustLayouted( false );
567 6913 : bool bMustBeDestroyed( !rResourceURL.startsWith("private:resource/toolbar/addon_") );
568 :
569 13826 : SolarMutexClearableGuard aWriteLock;
570 17628 : for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); ++pIter )
571 : {
572 10716 : if ( pIter->m_aName == rResourceURL )
573 : {
574 1 : xComponent.set( pIter->m_xUIElement, uno::UNO_QUERY );
575 1 : if ( bMustBeDestroyed )
576 1 : pIter->m_xUIElement.clear();
577 : else
578 0 : pIter->m_bVisible = false;
579 1 : break;
580 : }
581 : }
582 6913 : aWriteLock.clear();
583 :
584 13826 : uno::Reference< ui::XUIElement > xUIElement( xComponent, uno::UNO_QUERY );
585 6913 : if ( xUIElement.is() )
586 : {
587 1 : uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
588 2 : uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
589 :
590 1 : if ( bMustBeDestroyed )
591 : {
592 : try
593 : {
594 1 : if ( xWindow.is() )
595 1 : xWindow->removeWindowListener( uno::Reference< awt::XWindowListener >(
596 1 : static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
597 : }
598 0 : catch (const uno::Exception&)
599 : {
600 : }
601 :
602 : try
603 : {
604 1 : if ( xDockWindow.is() )
605 1 : xDockWindow->removeDockableWindowListener( uno::Reference< awt::XDockableWindowListener >(
606 1 : static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
607 : }
608 0 : catch (const uno::Exception&)
609 : {
610 : }
611 : }
612 : else
613 : {
614 0 : if ( xWindow.is() )
615 0 : xWindow->setVisible( sal_False );
616 0 : bNotify = true;
617 : }
618 :
619 1 : if ( !xDockWindow->isFloating() )
620 1 : bMustLayouted = true;
621 2 : bMustBeSorted = true;
622 : }
623 :
624 6913 : if ( bMustBeDestroyed )
625 : {
626 6913 : if ( xComponent.is() )
627 1 : xComponent->dispose();
628 6913 : bNotify = true;
629 : }
630 :
631 6913 : if ( bMustLayouted )
632 1 : implts_setLayoutDirty();
633 :
634 6913 : if ( bMustBeSorted )
635 1 : implts_sortUIElements();
636 :
637 13826 : return bNotify;
638 : }
639 :
640 9828 : void ToolbarLayoutManager::destroyToolbars()
641 : {
642 9828 : UIElementVector aUIElementVector;
643 9828 : implts_getUIElementVectorCopy( aUIElementVector );
644 :
645 19656 : SolarMutexClearableGuard aWriteLock;
646 9828 : m_aUIElements.clear();
647 9828 : m_bLayoutDirty = true;
648 9828 : aWriteLock.clear();
649 :
650 9828 : UIElementVector::iterator pIter;
651 19337 : for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); ++pIter )
652 : {
653 9509 : uno::Reference< lang::XComponent > xComponent( pIter->m_xUIElement, uno::UNO_QUERY );
654 9509 : if ( xComponent.is() )
655 9508 : xComponent->dispose();
656 19337 : }
657 9828 : }
658 :
659 4754 : bool ToolbarLayoutManager::showToolbar( const OUString& rResourceURL )
660 : {
661 4754 : UIElement aUIElement = implts_findToolbar( rResourceURL );
662 :
663 9508 : SolarMutexGuard aGuard;
664 4754 : vcl::Window* pWindow = getWindowFromXUIElement( aUIElement.m_xUIElement );
665 :
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 4754 : pAddOns = dynamic_cast<AddonsToolBarWrapper *>( aUIElement.m_xUIElement.get());
670 4754 : if (pAddOns)
671 0 : pAddOns->populateImages();
672 :
673 4754 : if ( pWindow )
674 : {
675 4754 : if ( !aUIElement.m_bFloating )
676 4754 : implts_setLayoutDirty();
677 : else
678 0 : pWindow->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
679 :
680 4754 : aUIElement.m_bVisible = true;
681 4754 : implts_writeWindowStateData( aUIElement );
682 4754 : implts_setToolbar( aUIElement );
683 4754 : implts_sortUIElements();
684 4754 : return true;
685 : }
686 :
687 4754 : return false;
688 : }
689 :
690 0 : bool ToolbarLayoutManager::hideToolbar( const OUString& rResourceURL )
691 : {
692 0 : UIElement aUIElement = implts_findToolbar( rResourceURL );
693 :
694 0 : SolarMutexGuard aGuard;
695 0 : vcl::Window* pWindow = getWindowFromXUIElement( aUIElement.m_xUIElement );
696 0 : if ( pWindow )
697 : {
698 0 : pWindow->Show( false );
699 0 : if ( !aUIElement.m_bFloating )
700 0 : implts_setLayoutDirty();
701 :
702 0 : aUIElement.m_bVisible = false;
703 0 : implts_writeWindowStateData( aUIElement );
704 0 : implts_setToolbar( aUIElement );
705 0 : return true;
706 : }
707 :
708 0 : return false;
709 : }
710 :
711 0 : void ToolbarLayoutManager::refreshToolbarsVisibility( bool bAutomaticToolbars )
712 : {
713 0 : UIElementVector aUIElementVector;
714 :
715 0 : SolarMutexClearableGuard aReadLock;
716 0 : bool bVisible( m_bVisible );
717 0 : aReadLock.clear();
718 :
719 0 : if ( !bVisible || !bAutomaticToolbars )
720 0 : return;
721 :
722 0 : implts_getUIElementVectorCopy( aUIElementVector );
723 :
724 0 : UIElement aUIElement;
725 0 : SolarMutexGuard aGuard;
726 0 : UIElementVector::iterator pIter;
727 0 : for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); ++pIter )
728 : {
729 0 : if ( implts_readWindowStateData( pIter->m_aName, aUIElement ) &&
730 0 : ( pIter->m_bVisible != aUIElement.m_bVisible ) && !pIter->m_bMasterHide )
731 : {
732 0 : SolarMutexGuard g;
733 0 : UIElement& rUIElement = impl_findToolbar( pIter->m_aName );
734 0 : if ( rUIElement.m_aName == pIter->m_aName )
735 : {
736 0 : rUIElement.m_bVisible = aUIElement.m_bVisible;
737 0 : implts_setLayoutDirty();
738 0 : }
739 : }
740 0 : }
741 : }
742 :
743 2905 : void ToolbarLayoutManager::setFloatingToolbarsVisibility( bool bVisible )
744 : {
745 2905 : UIElementVector aUIElementVector;
746 2905 : implts_getUIElementVectorCopy( aUIElementVector );
747 :
748 5810 : SolarMutexGuard aGuard;
749 2905 : UIElementVector::iterator pIter;
750 4414 : for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); ++pIter )
751 : {
752 1509 : vcl::Window* pWindow = getWindowFromXUIElement( pIter->m_xUIElement );
753 1509 : if ( pWindow && pIter->m_bFloating )
754 : {
755 0 : if ( bVisible )
756 : {
757 0 : if ( pIter->m_bVisible && !pIter->m_bMasterHide )
758 0 : pWindow->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
759 : }
760 : else
761 0 : pWindow->Show( false );
762 : }
763 2905 : }
764 2905 : }
765 :
766 3177 : void ToolbarLayoutManager::setVisible( bool bVisible )
767 : {
768 3177 : UIElementVector aUIElementVector;
769 3177 : implts_getUIElementVectorCopy( aUIElementVector );
770 :
771 6354 : SolarMutexGuard aGuard;
772 3177 : UIElementVector::iterator pIter;
773 5321 : for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); ++pIter )
774 : {
775 2144 : if (!pIter->m_bFloating)
776 : {
777 2144 : UIElement aUIElement(*pIter);
778 2144 : aUIElement.m_bMasterHide = !bVisible;
779 2144 : implts_setToolbar(aUIElement);
780 2144 : implts_setLayoutDirty();
781 : }
782 :
783 2144 : vcl::Window* pWindow = getWindowFromXUIElement( pIter->m_xUIElement );
784 2144 : if ( pWindow )
785 : {
786 2144 : bool bSetVisible( pIter->m_bVisible && bVisible );
787 2144 : if ( !bSetVisible )
788 509 : pWindow->Hide();
789 : else
790 : {
791 1635 : if ( pIter->m_bFloating )
792 0 : pWindow->Show(true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
793 : }
794 : }
795 : }
796 :
797 3177 : if ( !bVisible )
798 3183 : resetDockingArea();
799 3177 : }
800 :
801 0 : bool ToolbarLayoutManager::dockToolbar( const OUString& rResourceURL, ui::DockingArea eDockingArea, const awt::Point& aPos )
802 : {
803 0 : UIElement aUIElement = implts_findToolbar( rResourceURL );
804 :
805 0 : if ( aUIElement.m_xUIElement.is() )
806 : {
807 : try
808 : {
809 0 : uno::Reference< awt::XWindow > xWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
810 0 : uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
811 0 : if ( xDockWindow.is() )
812 : {
813 0 : if ( eDockingArea != ui::DockingArea_DOCKINGAREA_DEFAULT )
814 0 : aUIElement.m_aDockedData.m_nDockedArea = sal_Int16( eDockingArea );
815 :
816 0 : if ( !isDefaultPos( aPos ))
817 0 : aUIElement.m_aDockedData.m_aPos = aPos;
818 :
819 0 : if ( !xDockWindow->isFloating() )
820 : {
821 0 : vcl::Window* pWindow( 0 );
822 0 : ToolBox* pToolBox( 0 );
823 :
824 : {
825 0 : SolarMutexGuard aGuard;
826 0 : pWindow = VCLUnoHelper::GetWindow( xWindow );
827 0 : if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
828 : {
829 0 : pToolBox = static_cast<ToolBox *>(pWindow);
830 :
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 0 : pToolBox->SetAlign( ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea ));
834 0 : }
835 : }
836 :
837 0 : if ( hasDefaultPosValue( aUIElement.m_aDockedData.m_aPos ))
838 : {
839 : // Docking on its default position without a preset position -
840 : // we have to find a good place for it.
841 0 : ::Size aSize;
842 :
843 0 : SolarMutexGuard aGuard;
844 : {
845 0 : if (pToolBox)
846 0 : aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIElement.m_aDockedData.m_nDockedArea ) );
847 0 : else if (pWindow)
848 0 : aSize = pWindow->GetSizePixel();
849 : }
850 :
851 0 : ::Point aPixelPos;
852 0 : awt::Point aDockPos;
853 0 : implts_findNextDockingPos((ui::DockingArea)aUIElement.m_aDockedData.m_nDockedArea, aSize, aDockPos, aPixelPos );
854 0 : aUIElement.m_aDockedData.m_aPos = aDockPos;
855 : }
856 : }
857 :
858 0 : implts_setToolbar( aUIElement );
859 :
860 0 : if ( xDockWindow->isFloating() )
861 : {
862 : // ATTENTION: This will call toggleFloatingMode() via notifications which
863 : // sets the floating member of the UIElement correctly!
864 0 : xDockWindow->setFloatingMode( sal_False );
865 : }
866 : else
867 : {
868 0 : implts_writeWindowStateData( aUIElement );
869 0 : implts_sortUIElements();
870 :
871 0 : if ( aUIElement.m_bVisible )
872 0 : implts_setLayoutDirty();
873 : }
874 0 : return true;
875 0 : }
876 : }
877 0 : catch (const lang::DisposedException&)
878 : {
879 : }
880 : }
881 :
882 0 : return false;
883 : }
884 :
885 0 : bool ToolbarLayoutManager::dockAllToolbars()
886 : {
887 0 : std::vector< OUString > aToolBarNameVector;
888 :
889 0 : SolarMutexClearableGuard aReadLock;
890 0 : UIElementVector::iterator pIter;
891 0 : for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); ++pIter )
892 : {
893 0 : if ( pIter->m_aType == "toolbar" && pIter->m_xUIElement.is() && pIter->m_bFloating && pIter->m_bVisible )
894 0 : aToolBarNameVector.push_back( pIter->m_aName );
895 : }
896 0 : aReadLock.clear();
897 :
898 0 : bool bResult(true);
899 0 : const sal_uInt32 nCount = aToolBarNameVector.size();
900 0 : for ( sal_uInt32 i = 0; i < nCount; ++i )
901 : {
902 0 : awt::Point aPoint;
903 0 : aPoint.X = aPoint.Y = SAL_MAX_INT32;
904 0 : bResult &= dockToolbar( aToolBarNameVector[i], ui::DockingArea_DOCKINGAREA_DEFAULT, aPoint );
905 : }
906 :
907 0 : return bResult;
908 : }
909 :
910 871773 : long ToolbarLayoutManager::childWindowEvent( VclSimpleEvent* pEvent )
911 : {
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 871773 : if ( pEvent && pEvent->ISA( VclWindowEvent ))
916 : {
917 871773 : if ( pEvent->GetId() == VCLEVENT_TOOLBOX_SELECT )
918 : {
919 2 : OUString aToolbarName;
920 4 : OUString aCommand;
921 2 : ToolBox* pToolBox = getToolboxPtr( static_cast<VclWindowEvent*>(pEvent)->GetWindow() );
922 :
923 2 : if ( pToolBox )
924 : {
925 2 : aToolbarName = retrieveToolbarNameFromHelpURL( pToolBox );
926 2 : sal_uInt16 nId = pToolBox->GetCurItemId();
927 2 : if ( nId > 0 )
928 2 : aCommand = pToolBox->GetItemCommand( nId );
929 : }
930 :
931 2 : if ( !aToolbarName.isEmpty() && !aCommand.isEmpty() )
932 : {
933 2 : SolarMutexClearableGuard aReadLock;
934 4 : ::std::vector< uno::Reference< ui::XUIFunctionListener > > aListenerArray;
935 2 : UIElementVector::iterator pIter;
936 :
937 6 : for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); ++pIter )
938 : {
939 4 : if ( pIter->m_xUIElement.is() )
940 : {
941 4 : uno::Reference< ui::XUIFunctionListener > xListener( pIter->m_xUIElement, uno::UNO_QUERY );
942 4 : if ( xListener.is() )
943 4 : aListenerArray.push_back( xListener );
944 : }
945 : }
946 2 : aReadLock.clear();
947 :
948 2 : const sal_uInt32 nCount = aListenerArray.size();
949 6 : for ( sal_uInt32 i = 0; i < nCount; ++i )
950 : {
951 : try
952 : {
953 4 : aListenerArray[i]->functionExecute( aToolbarName, aCommand );
954 : }
955 0 : catch (const uno::RuntimeException&)
956 : {
957 0 : throw;
958 : }
959 0 : catch (const uno::Exception&)
960 : {
961 : }
962 2 : }
963 2 : }
964 : }
965 871771 : else if ( pEvent->GetId() == VCLEVENT_TOOLBOX_FORMATCHANGED )
966 : {
967 271272 : if ( !implts_isToolbarCreationActive() )
968 : {
969 175116 : ToolBox* pToolBox = getToolboxPtr( static_cast<VclWindowEvent*>(pEvent)->GetWindow() );
970 175116 : if ( pToolBox )
971 : {
972 175116 : OUString aToolbarName = retrieveToolbarNameFromHelpURL( pToolBox );
973 175116 : if ( !aToolbarName.isEmpty() )
974 : {
975 130065 : OUStringBuffer aBuf(100);
976 130065 : aBuf.appendAscii( "private:resource/toolbar/" );
977 130065 : aBuf.append( aToolbarName );
978 :
979 260130 : UIElement aToolbar = implts_findToolbar( aBuf.makeStringAndClear() );
980 130065 : if ( aToolbar.m_xUIElement.is() && !aToolbar.m_bFloating )
981 : {
982 86 : implts_setLayoutDirty();
983 86 : m_pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
984 130065 : }
985 175116 : }
986 : }
987 : }
988 : }
989 : }
990 :
991 871773 : return 1;
992 : }
993 :
994 13129 : void ToolbarLayoutManager::resetDockingArea()
995 : {
996 13129 : SolarMutexClearableGuard aReadLock;
997 26258 : uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
998 26258 : uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
999 26258 : uno::Reference< awt::XWindow > xRightDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
1000 26258 : uno::Reference< awt::XWindow > xBottomDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
1001 13129 : aReadLock.clear();
1002 :
1003 13129 : if ( xTopDockingWindow.is() )
1004 13129 : xTopDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE );
1005 13129 : if ( xLeftDockingWindow.is() )
1006 13129 : xLeftDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE );
1007 13129 : if ( xRightDockingWindow.is() )
1008 13129 : xRightDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE );
1009 13129 : if ( xBottomDockingWindow.is() )
1010 26258 : xBottomDockingWindow->setPosSize( 0, 0, 0, 0, awt::PosSize::POSSIZE );
1011 13129 : }
1012 :
1013 6573 : void ToolbarLayoutManager::setParentWindow(
1014 : const uno::Reference< awt::XWindowPeer >& xParentWindow )
1015 : {
1016 : static const char DOCKINGAREASTRING[] = "dockingarea";
1017 :
1018 6573 : uno::Reference< awt::XWindow > xTopDockWindow = uno::Reference< awt::XWindow >( createToolkitWindow( m_xContext, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY );
1019 13146 : uno::Reference< awt::XWindow > xLeftDockWindow = uno::Reference< awt::XWindow >( createToolkitWindow( m_xContext, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY );
1020 13146 : uno::Reference< awt::XWindow > xRightDockWindow = uno::Reference< awt::XWindow >( createToolkitWindow( m_xContext, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY );
1021 13146 : uno::Reference< awt::XWindow > xBottomDockWindow = uno::Reference< awt::XWindow >( createToolkitWindow( m_xContext, xParentWindow, DOCKINGAREASTRING ), uno::UNO_QUERY );
1022 :
1023 13146 : SolarMutexClearableGuard aWriteLock;
1024 6573 : m_xContainerWindow = uno::Reference< awt::XWindow2 >( xParentWindow, uno::UNO_QUERY );
1025 6573 : m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] = xTopDockWindow;
1026 6573 : m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] = xLeftDockWindow;
1027 6573 : m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] = xRightDockWindow;
1028 6573 : m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] = xBottomDockWindow;
1029 6573 : aWriteLock.clear();
1030 :
1031 6573 : if ( xParentWindow.is() )
1032 : {
1033 6573 : SolarMutexGuard aGuard;
1034 13146 : VclPtr< ::DockingAreaWindow > pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xTopDockWindow ).get() );
1035 6573 : if( pWindow ) pWindow->SetAlign( WINDOWALIGN_TOP );
1036 6573 : pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xBottomDockWindow ).get() );
1037 6573 : if( pWindow ) pWindow->SetAlign( WINDOWALIGN_BOTTOM );
1038 6573 : pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xLeftDockWindow ).get() );
1039 6573 : if( pWindow ) pWindow->SetAlign( WINDOWALIGN_LEFT );
1040 6573 : pWindow = dynamic_cast< ::DockingAreaWindow* >(VCLUnoHelper::GetWindow( xRightDockWindow ).get() );
1041 6573 : if( pWindow ) pWindow->SetAlign( WINDOWALIGN_RIGHT );
1042 13146 : implts_reparentToolbars();
1043 : }
1044 : else
1045 : {
1046 0 : destroyToolbars();
1047 0 : resetDockingArea();
1048 6573 : }
1049 6573 : }
1050 :
1051 16161 : void ToolbarLayoutManager::setDockingAreaOffsets( const ::Rectangle& rOffsets )
1052 : {
1053 16161 : SolarMutexGuard g;
1054 16161 : m_aDockingAreaOffsets = rOffsets;
1055 16161 : m_bLayoutDirty = true;
1056 16161 : }
1057 :
1058 2758 : OUString ToolbarLayoutManager::implts_generateGenericAddonToolbarTitle( sal_Int32 nNumber ) const
1059 : {
1060 2758 : OUString aAddonGenericTitle(FWK_RESSTR(STR_TOOLBAR_TITLE_ADDON));
1061 2758 : const vcl::I18nHelper& rI18nHelper = Application::GetSettings().GetUILocaleI18nHelper();
1062 :
1063 5516 : OUString aNumStr = rI18nHelper.GetNum( nNumber, 0, false, false );
1064 2758 : aAddonGenericTitle = aAddonGenericTitle.replaceFirst( "%num%", aNumStr );
1065 :
1066 5516 : return OUString( aAddonGenericTitle );
1067 : }
1068 :
1069 6572 : void ToolbarLayoutManager::implts_createAddonsToolBars()
1070 : {
1071 6572 : SolarMutexClearableGuard aWriteLock;
1072 6572 : if ( !m_pAddonOptions )
1073 3279 : m_pAddonOptions = new AddonsOptions;
1074 :
1075 13144 : uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager );
1076 13144 : uno::Reference< frame::XFrame > xFrame( m_xFrame );
1077 6572 : aWriteLock.clear();
1078 :
1079 6572 : if (isPreviewFrame())
1080 6572 : return; // no addon toolbars for preview frame!
1081 :
1082 13144 : uno::Sequence< uno::Sequence< beans::PropertyValue > > aAddonToolBarData;
1083 13144 : uno::Reference< ui::XUIElement > xUIElement;
1084 :
1085 6572 : sal_uInt32 nCount = m_pAddonOptions->GetAddonsToolBarCount();
1086 13144 : OUString aElementType( "toolbar" );
1087 :
1088 13144 : uno::Sequence< beans::PropertyValue > aPropSeq( 2 );
1089 6572 : aPropSeq[0].Name = "Frame";
1090 6572 : aPropSeq[0].Value <<= xFrame;
1091 6572 : aPropSeq[1].Name = "ConfigurationData";
1092 13144 : for ( sal_uInt32 i = 0; i < nCount; i++ )
1093 : {
1094 13144 : OUString aAddonToolBarName( "private:resource/toolbar/addon_" +
1095 19716 : m_pAddonOptions->GetAddonsToolbarResourceName(i) );
1096 6572 : aAddonToolBarData = m_pAddonOptions->GetAddonsToolBarPart( i );
1097 6572 : aPropSeq[1].Value <<= aAddonToolBarData;
1098 :
1099 13143 : UIElement aElement = implts_findToolbar( aAddonToolBarName );
1100 :
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 6572 : if ( aElement.m_xUIElement.is() )
1105 1 : continue;
1106 :
1107 : try
1108 : {
1109 6571 : xUIElement = xUIElementFactory->createUIElement( aAddonToolBarName, aPropSeq );
1110 6568 : if ( xUIElement.is() )
1111 : {
1112 2758 : uno::Reference< awt::XDockableWindow > xDockWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
1113 2758 : if ( xDockWindow.is() )
1114 : {
1115 : try
1116 : {
1117 2758 : xDockWindow->addDockableWindowListener( uno::Reference< awt::XDockableWindowListener >( static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
1118 2758 : xDockWindow->enableDocking( sal_True );
1119 2758 : uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY );
1120 2758 : if ( xWindow.is() )
1121 2758 : xWindow->addWindowListener( uno::Reference< awt::XWindowListener >( static_cast< OWeakObject * >( this ), uno::UNO_QUERY ));
1122 : }
1123 0 : catch (const uno::Exception&)
1124 : {
1125 : }
1126 : }
1127 :
1128 5516 : OUString aGenericAddonTitle = implts_generateGenericAddonToolbarTitle( i+1 );
1129 :
1130 2758 : if ( !aElement.m_aName.isEmpty() )
1131 : {
1132 : // Reuse a local entry so we are able to use the latest
1133 : // UI changes for this document.
1134 0 : implts_setElementData( aElement, xDockWindow );
1135 0 : aElement.m_xUIElement = xUIElement;
1136 0 : if ( aElement.m_aUIName.isEmpty() )
1137 : {
1138 0 : aElement.m_aUIName = aGenericAddonTitle;
1139 0 : implts_writeWindowStateData( aElement );
1140 : }
1141 : }
1142 : else
1143 : {
1144 : // Create new UI element and try to read its state data
1145 2758 : UIElement aNewToolbar( aAddonToolBarName, aElementType, xUIElement );
1146 2758 : aNewToolbar.m_bFloating = true;
1147 2758 : implts_readWindowStateData( aAddonToolBarName, aNewToolbar );
1148 2758 : implts_setElementData( aNewToolbar, xDockWindow );
1149 2758 : if ( aNewToolbar.m_aUIName.isEmpty() )
1150 : {
1151 0 : aNewToolbar.m_aUIName = aGenericAddonTitle;
1152 0 : implts_writeWindowStateData( aNewToolbar );
1153 : }
1154 2758 : implts_insertToolbar( aNewToolbar );
1155 : }
1156 :
1157 5516 : uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY );
1158 2758 : if ( xWindow.is() )
1159 : {
1160 : // Set generic title for add-on toolbar
1161 2758 : SolarMutexGuard aGuard;
1162 2758 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
1163 2758 : if ( pWindow->GetText().isEmpty() )
1164 0 : pWindow->SetText( aGenericAddonTitle );
1165 2758 : if ( pWindow->GetType() == WINDOW_TOOLBOX )
1166 : {
1167 2758 : ToolBox* pToolbar = static_cast<ToolBox *>(pWindow);
1168 2758 : pToolbar->SetMenuType();
1169 2758 : }
1170 2758 : }
1171 : }
1172 : }
1173 3 : catch (const container::NoSuchElementException&)
1174 : {
1175 : }
1176 0 : catch (const lang::IllegalArgumentException&)
1177 : {
1178 : }
1179 13143 : }
1180 : }
1181 :
1182 6572 : void ToolbarLayoutManager::implts_createCustomToolBars()
1183 : {
1184 6572 : SolarMutexClearableGuard aReadLock;
1185 6572 : if ( !m_bComponentAttached )
1186 3280 : return;
1187 :
1188 6584 : uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager );
1189 6584 : uno::Reference< frame::XFrame > xFrame( m_xFrame );
1190 6584 : uno::Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr, uno::UNO_QUERY );
1191 6584 : uno::Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr, uno::UNO_QUERY );
1192 3292 : aReadLock.clear();
1193 :
1194 3292 : if ( xFrame.is() )
1195 : {
1196 3292 : if (isPreviewFrame())
1197 0 : return; // no custom toolbars for preview frame!
1198 :
1199 3292 : uno::Sequence< uno::Sequence< beans::PropertyValue > > aTbxSeq;
1200 3292 : if ( xDocCfgMgr.is() )
1201 : {
1202 3271 : aTbxSeq = xDocCfgMgr->getUIElementsInfo( ui::UIElementType::TOOLBAR );
1203 3271 : implts_createCustomToolBars( aTbxSeq ); // first create all document based toolbars
1204 : }
1205 3292 : if ( xModuleCfgMgr.is() )
1206 : {
1207 3285 : aTbxSeq = xModuleCfgMgr->getUIElementsInfo( ui::UIElementType::TOOLBAR );
1208 3285 : implts_createCustomToolBars( aTbxSeq ); // second create module based toolbars
1209 3292 : }
1210 3292 : }
1211 : }
1212 :
1213 6572 : void ToolbarLayoutManager::implts_createNonContextSensitiveToolBars()
1214 : {
1215 6572 : SolarMutexClearableGuard aReadLock;
1216 :
1217 6572 : if ( !m_xPersistentWindowState.is() || !m_xFrame.is() || !m_bComponentAttached )
1218 3282 : return;
1219 :
1220 6580 : uno::Reference< ui::XUIElementFactory > xUIElementFactory( m_xUIElementFactoryManager );
1221 6580 : uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
1222 3290 : aReadLock.clear();
1223 :
1224 3290 : if (isPreviewFrame())
1225 0 : return;
1226 :
1227 6580 : std::vector< OUString > aMakeVisibleToolbars;
1228 :
1229 : try
1230 : {
1231 3290 : uno::Sequence< OUString > aToolbarNames = xPersistentWindowState->getElementNames();
1232 :
1233 3290 : if ( aToolbarNames.getLength() > 0 )
1234 : {
1235 3290 : OUString aElementType;
1236 6580 : OUString aElementName;
1237 6580 : OUString aName;
1238 :
1239 6580 : uno::Reference< ui::XUIElement > xUIElement;
1240 3290 : aMakeVisibleToolbars.reserve(aToolbarNames.getLength());
1241 :
1242 6580 : SolarMutexGuard g;
1243 :
1244 3290 : const OUString* pTbNames = aToolbarNames.getConstArray();
1245 131555 : for ( sal_Int32 i = 0; i < aToolbarNames.getLength(); i++ )
1246 : {
1247 128265 : aName = pTbNames[i];
1248 128265 : parseResourceURL( aName, aElementType, aElementName );
1249 :
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 256530 : if ( aElementType.equalsIgnoreAsciiCase("toolbar") &&
1254 128265 : aElementName.indexOf( "custom_" ) == -1 )
1255 : {
1256 128265 : UIElement aNewToolbar = implts_findToolbar( aName );
1257 128265 : bool bFound = ( aNewToolbar.m_aName == aName );
1258 128265 : if ( !bFound )
1259 125501 : implts_readWindowStateData( aName, aNewToolbar );
1260 :
1261 128265 : if ( aNewToolbar.m_bVisible && !aNewToolbar.m_bContextSensitive )
1262 : {
1263 57 : if ( !bFound )
1264 55 : implts_insertToolbar( aNewToolbar );
1265 57 : aMakeVisibleToolbars.push_back( aName );
1266 128265 : }
1267 : }
1268 3290 : }
1269 3290 : }
1270 : }
1271 0 : catch (const uno::RuntimeException&)
1272 : {
1273 0 : throw;
1274 : }
1275 0 : catch (const uno::Exception&)
1276 : {
1277 : }
1278 :
1279 3290 : if ( !aMakeVisibleToolbars.empty() )
1280 : ::std::for_each( aMakeVisibleToolbars.begin(), aMakeVisibleToolbars.end(),
1281 3329 : ::boost::bind( &ToolbarLayoutManager::requestToolbar, this, _1));
1282 : }
1283 :
1284 6556 : void ToolbarLayoutManager::implts_createCustomToolBars( const uno::Sequence< uno::Sequence< beans::PropertyValue > >& aTbxSeqSeq )
1285 : {
1286 6556 : const uno::Sequence< beans::PropertyValue >* pTbxSeq = aTbxSeqSeq.getConstArray();
1287 29073 : for ( sal_Int32 i = 0; i < aTbxSeqSeq.getLength(); i++ )
1288 : {
1289 22517 : const uno::Sequence< beans::PropertyValue >& rTbxSeq = pTbxSeq[i];
1290 22517 : OUString aTbxResName;
1291 45034 : OUString aTbxTitle;
1292 67551 : for ( sal_Int32 j = 0; j < rTbxSeq.getLength(); j++ )
1293 : {
1294 45034 : if ( rTbxSeq[j].Name == "ResourceURL" )
1295 22517 : rTbxSeq[j].Value >>= aTbxResName;
1296 22517 : else if ( rTbxSeq[j].Name == "UIName" )
1297 22517 : rTbxSeq[j].Value >>= aTbxTitle;
1298 : }
1299 :
1300 : // Only create custom toolbars. Their name have to start with "custom_"!
1301 22517 : if ( !aTbxResName.isEmpty() && ( aTbxResName.indexOf( "custom_" ) != -1 ) )
1302 0 : implts_createCustomToolBar( aTbxResName, aTbxTitle );
1303 22517 : }
1304 6556 : }
1305 :
1306 0 : void ToolbarLayoutManager::implts_createCustomToolBar( const OUString& aTbxResName, const OUString& aTitle )
1307 : {
1308 0 : if ( !aTbxResName.isEmpty() )
1309 : {
1310 0 : if ( !createToolbar( aTbxResName ) )
1311 : SAL_WARN("fwk.uielement", "ToolbarLayoutManager cannot create custom toolbar");
1312 :
1313 0 : uno::Reference< ui::XUIElement > xUIElement = getToolbar( aTbxResName );
1314 :
1315 0 : if ( !aTitle.isEmpty() && xUIElement.is() )
1316 : {
1317 0 : SolarMutexGuard aGuard;
1318 :
1319 0 : vcl::Window* pWindow = getWindowFromXUIElement( xUIElement );
1320 0 : if ( pWindow )
1321 0 : pWindow->SetText( aTitle );
1322 0 : }
1323 : }
1324 0 : }
1325 :
1326 6573 : void ToolbarLayoutManager::implts_reparentToolbars()
1327 : {
1328 6573 : SolarMutexClearableGuard aWriteLock;
1329 13146 : UIElementVector aUIElementVector = m_aUIElements;
1330 6573 : vcl::Window* pContainerWindow = VCLUnoHelper::GetWindow( m_xContainerWindow );
1331 6573 : vcl::Window* pTopDockWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
1332 6573 : vcl::Window* pBottomDockWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
1333 6573 : vcl::Window* pLeftDockWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
1334 6573 : vcl::Window* pRightDockWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
1335 6573 : aWriteLock.clear();
1336 :
1337 13146 : SolarMutexGuard aGuard;
1338 6573 : if ( pContainerWindow )
1339 : {
1340 6573 : UIElementVector::iterator pIter;
1341 6579 : for ( pIter = aUIElementVector.begin(); pIter != aUIElementVector.end(); ++pIter )
1342 : {
1343 6 : uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement );
1344 6 : if ( xUIElement.is() )
1345 : {
1346 6 : uno::Reference< awt::XWindow > xWindow;
1347 : try
1348 : {
1349 : // We have to retrieve the window reference with try/catch as it is
1350 : // possible that all elements have been disposed!
1351 6 : xWindow = uno::Reference< awt::XWindow >( xUIElement->getRealInterface(), uno::UNO_QUERY );
1352 : }
1353 0 : catch (const uno::RuntimeException&)
1354 : {
1355 0 : throw;
1356 : }
1357 0 : catch (const uno::Exception&)
1358 : {
1359 : }
1360 :
1361 6 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
1362 6 : if ( pWindow )
1363 : {
1364 : // Reparent our child windows according to their current state.
1365 6 : if ( pIter->m_bFloating )
1366 0 : pWindow->SetParent( pContainerWindow );
1367 : else
1368 : {
1369 6 : if ( pIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_TOP )
1370 5 : pWindow->SetParent( pTopDockWindow );
1371 1 : else if ( pIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
1372 1 : pWindow->SetParent( pBottomDockWindow );
1373 0 : else if ( pIter->m_aDockedData.m_nDockedArea == ui::DockingArea_DOCKINGAREA_LEFT )
1374 0 : pWindow->SetParent( pLeftDockWindow );
1375 : else
1376 0 : pWindow->SetParent( pRightDockWindow );
1377 : }
1378 6 : }
1379 : }
1380 6 : }
1381 6573 : }
1382 6573 : }
1383 :
1384 13532 : void ToolbarLayoutManager::implts_setToolbarCreation( bool bStart )
1385 : {
1386 13532 : SolarMutexGuard g;
1387 13532 : m_bToolbarCreation = bStart;
1388 13532 : }
1389 :
1390 271272 : bool ToolbarLayoutManager::implts_isToolbarCreationActive()
1391 : {
1392 271272 : SolarMutexGuard g;
1393 271272 : return m_bToolbarCreation;
1394 : }
1395 :
1396 9522 : void ToolbarLayoutManager::implts_setElementData( UIElement& rElement, const uno::Reference< awt::XDockableWindow >& rDockWindow )
1397 : {
1398 9522 : SolarMutexClearableGuard aReadLock;
1399 9522 : bool bShowElement( rElement.m_bVisible && !rElement.m_bMasterHide && implts_isParentWindowVisible() );
1400 9522 : aReadLock.clear();
1401 :
1402 19044 : uno::Reference< awt::XDockableWindow > xDockWindow( rDockWindow );
1403 19044 : uno::Reference< awt::XWindow2 > xWindow( xDockWindow, uno::UNO_QUERY );
1404 :
1405 9522 : vcl::Window* pWindow( 0 );
1406 9522 : ToolBox* pToolBox( 0 );
1407 :
1408 9522 : if ( xDockWindow.is() && xWindow.is() )
1409 : {
1410 : {
1411 9522 : SolarMutexGuard aGuard;
1412 9522 : pWindow = VCLUnoHelper::GetWindow( xWindow );
1413 9522 : if ( pWindow )
1414 : {
1415 9522 : OUString aText = pWindow->GetText();
1416 9522 : if ( aText.isEmpty() )
1417 9522 : pWindow->SetText( rElement.m_aUIName );
1418 9522 : if ( rElement.m_bNoClose )
1419 9 : pWindow->SetStyle( pWindow->GetStyle() & ~WB_CLOSEABLE );
1420 9522 : if ( pWindow->GetType() == WINDOW_TOOLBOX )
1421 9522 : pToolBox = static_cast<ToolBox *>(pWindow);
1422 : }
1423 9522 : if ( pToolBox )
1424 : {
1425 9522 : pToolBox->SetButtonType( (ButtonType)rElement.m_nStyle );
1426 9522 : if ( rElement.m_bNoClose )
1427 9 : pToolBox->SetFloatStyle( pToolBox->GetFloatStyle() & ~WB_CLOSEABLE );
1428 9522 : }
1429 : }
1430 :
1431 9522 : if ( rElement.m_bFloating )
1432 : {
1433 0 : if ( pWindow )
1434 : {
1435 0 : SolarMutexGuard aGuard;
1436 0 : OUString aText = pWindow->GetText();
1437 0 : if ( aText.isEmpty() )
1438 0 : pWindow->SetText( rElement.m_aUIName );
1439 : }
1440 :
1441 0 : awt::Point aPos(rElement.m_aFloatingData.m_aPos);
1442 0 : bool bWriteData( false );
1443 0 : bool bUndefPos = hasDefaultPosValue( rElement.m_aFloatingData.m_aPos );
1444 0 : bool bSetSize = ( rElement.m_aFloatingData.m_aSize.Width != 0 &&
1445 0 : rElement.m_aFloatingData.m_aSize.Height != 0 );
1446 0 : xDockWindow->setFloatingMode( sal_True );
1447 0 : if ( bUndefPos )
1448 : {
1449 0 : aPos = implts_findNextCascadeFloatingPos();
1450 0 : rElement.m_aFloatingData.m_aPos = aPos; // set new cascaded position
1451 0 : bWriteData = true;
1452 : }
1453 :
1454 0 : if( bSetSize )
1455 0 : xWindow->setOutputSize(rElement.m_aFloatingData.m_aSize);
1456 : else
1457 : {
1458 0 : if( pToolBox )
1459 : {
1460 : // set an optimal initial floating size
1461 0 : SolarMutexGuard aGuard;
1462 0 : ::Size aSize( pToolBox->CalcFloatingWindowSizePixel() );
1463 0 : pToolBox->SetOutputSizePixel( aSize );
1464 : }
1465 : }
1466 :
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 0 : xWindow->setPosSize( aPos.X, aPos.Y, 0, 0, awt::PosSize::POS );
1476 :
1477 0 : if ( bWriteData )
1478 0 : implts_writeWindowStateData( rElement );
1479 0 : if ( bShowElement && pWindow )
1480 : {
1481 0 : SolarMutexGuard aGuard;
1482 0 : pWindow->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
1483 : }
1484 : }
1485 : else
1486 : {
1487 9522 : bool bSetSize( false );
1488 9522 : awt::Point aDockPos;
1489 9522 : ::Point aPixelPos;
1490 9522 : ::Size aSize;
1491 :
1492 9522 : if ( pToolBox )
1493 : {
1494 9522 : SolarMutexGuard aGuard;
1495 9522 : pToolBox->SetAlign( ImplConvertAlignment(rElement.m_aDockedData.m_nDockedArea ) );
1496 9522 : pToolBox->SetLineCount( 1 );
1497 9522 : xDockWindow->setFloatingMode( sal_False );
1498 9522 : if ( rElement.m_aDockedData.m_bLocked )
1499 0 : xDockWindow->lock();
1500 9522 : aSize = pToolBox->CalcWindowSizePixel();
1501 9522 : bSetSize = true;
1502 :
1503 9522 : if ( isDefaultPos( rElement.m_aDockedData.m_aPos ))
1504 : {
1505 2886 : implts_findNextDockingPos( (ui::DockingArea)rElement.m_aDockedData.m_nDockedArea, aSize, aDockPos, aPixelPos );
1506 2886 : rElement.m_aDockedData.m_aPos = aDockPos;
1507 9522 : }
1508 : }
1509 :
1510 9522 : xWindow->setPosSize( aPixelPos.X(), aPixelPos.Y(), 0, 0, awt::PosSize::POS );
1511 9522 : if( bSetSize )
1512 9522 : xWindow->setOutputSize( AWTSize( aSize) );
1513 :
1514 9522 : if ( pWindow )
1515 : {
1516 9522 : SolarMutexGuard aGuard;
1517 9522 : if ( !bShowElement )
1518 4467 : pWindow->Hide();
1519 : }
1520 : }
1521 9522 : }
1522 9522 : }
1523 :
1524 0 : void ToolbarLayoutManager::implts_destroyDockingAreaWindows()
1525 : {
1526 0 : SolarMutexClearableGuard aWriteLock;
1527 0 : uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
1528 0 : uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
1529 0 : uno::Reference< awt::XWindow > xRightDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
1530 0 : uno::Reference< awt::XWindow > xBottomDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
1531 0 : m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP].clear();
1532 0 : m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT].clear();
1533 0 : m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT].clear();
1534 0 : m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM].clear();
1535 0 : aWriteLock.clear();
1536 :
1537 : // destroy windows
1538 0 : xTopDockingWindow->dispose();
1539 0 : xLeftDockingWindow->dispose();
1540 0 : xRightDockingWindow->dispose();
1541 0 : xBottomDockingWindow->dispose();
1542 0 : }
1543 :
1544 : // persistence methods
1545 :
1546 161139 : bool ToolbarLayoutManager::implts_readWindowStateData( const OUString& aName, UIElement& rElementData )
1547 : {
1548 : return LayoutManager::readWindowStateData( aName, rElementData, m_xPersistentWindowState,
1549 161139 : m_pGlobalSettings, m_bGlobalSettings, m_xContext );
1550 : }
1551 :
1552 4754 : void ToolbarLayoutManager::implts_writeWindowStateData( const UIElement& rElementData )
1553 : {
1554 4754 : SolarMutexResettableGuard aWriteLock;
1555 9508 : uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
1556 4754 : m_bStoreWindowState = true; // set flag to determine that we triggered the notification
1557 4754 : aWriteLock.clear();
1558 :
1559 4754 : bool bPersistent( false );
1560 9508 : uno::Reference< beans::XPropertySet > xPropSet( rElementData.m_xUIElement, uno::UNO_QUERY );
1561 4754 : if ( xPropSet.is() )
1562 : {
1563 : try
1564 : {
1565 : // Check persistent flag of the user interface element
1566 4754 : xPropSet->getPropertyValue("Persistent") >>= bPersistent;
1567 : }
1568 0 : catch (const beans::UnknownPropertyException&)
1569 : {
1570 0 : bPersistent = true; // Non-configurable elements should at least store their dimension/position
1571 : }
1572 0 : catch (const lang::WrappedTargetException&)
1573 : {
1574 : }
1575 : }
1576 :
1577 4754 : if ( bPersistent && xPersistentWindowState.is() )
1578 : {
1579 : try
1580 : {
1581 1772 : uno::Sequence< beans::PropertyValue > aWindowState( 9 );
1582 :
1583 1772 : aWindowState[0].Name = WINDOWSTATE_PROPERTY_DOCKED;
1584 1772 : aWindowState[0].Value = ::uno::makeAny( !rElementData.m_bFloating );
1585 1772 : aWindowState[1].Name = WINDOWSTATE_PROPERTY_VISIBLE;
1586 1772 : aWindowState[1].Value = uno::makeAny( rElementData.m_bVisible );
1587 1772 : aWindowState[2].Name = WINDOWSTATE_PROPERTY_DOCKINGAREA;
1588 1772 : aWindowState[2].Value = uno::makeAny( static_cast< ui::DockingArea >( rElementData.m_aDockedData.m_nDockedArea ) );
1589 :
1590 1772 : awt::Point aPos = rElementData.m_aDockedData.m_aPos;
1591 1772 : aWindowState[3].Name = WINDOWSTATE_PROPERTY_DOCKPOS;
1592 1772 : aWindowState[3].Value <<= aPos;
1593 :
1594 1772 : aPos = rElementData.m_aFloatingData.m_aPos;
1595 1772 : aWindowState[4].Name = WINDOWSTATE_PROPERTY_POS;
1596 1772 : aWindowState[4].Value <<= aPos;
1597 :
1598 1772 : aWindowState[5].Name = WINDOWSTATE_PROPERTY_SIZE;
1599 1772 : aWindowState[5].Value <<= rElementData.m_aFloatingData.m_aSize;
1600 1772 : aWindowState[6].Name = WINDOWSTATE_PROPERTY_UINAME;
1601 1772 : aWindowState[6].Value = uno::makeAny( rElementData.m_aUIName );
1602 1772 : aWindowState[7].Name = WINDOWSTATE_PROPERTY_LOCKED;
1603 1772 : aWindowState[7].Value = uno::makeAny( rElementData.m_aDockedData.m_bLocked );
1604 1772 : aWindowState[8].Name = WINDOWSTATE_PROPERTY_STYLE;
1605 1772 : aWindowState[8].Value = uno::makeAny( static_cast<sal_uInt16>(rElementData.m_nStyle) );
1606 :
1607 3544 : OUString aName = rElementData.m_aName;
1608 1772 : if ( xPersistentWindowState->hasByName( aName ))
1609 : {
1610 1772 : uno::Reference< container::XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY );
1611 1772 : xReplace->replaceByName( aName, uno::makeAny( aWindowState ));
1612 : }
1613 : else
1614 : {
1615 0 : uno::Reference< container::XNameContainer > xInsert( xPersistentWindowState, uno::UNO_QUERY );
1616 0 : xInsert->insertByName( aName, uno::makeAny( aWindowState ));
1617 1772 : }
1618 : }
1619 0 : catch (const uno::Exception&)
1620 : {
1621 : }
1622 : }
1623 :
1624 : // Reset flag
1625 4754 : aWriteLock.reset();
1626 4754 : m_bStoreWindowState = false;
1627 9508 : aWriteLock.clear();
1628 4754 : }
1629 :
1630 : /******************************************************************************
1631 : LOOKUP PART FOR TOOLBARS
1632 : ******************************************************************************/
1633 :
1634 330629 : UIElement& ToolbarLayoutManager::impl_findToolbar( const OUString& aName )
1635 : {
1636 330629 : static UIElement aEmptyElement;
1637 330629 : UIElementVector::iterator pIter;
1638 :
1639 330629 : SolarMutexGuard g;
1640 522381 : for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); ++pIter )
1641 : {
1642 211080 : if ( pIter->m_aName == aName )
1643 19328 : return *pIter;
1644 : }
1645 :
1646 311301 : return aEmptyElement;
1647 : }
1648 :
1649 286085 : UIElement ToolbarLayoutManager::implts_findToolbar( const OUString& aName )
1650 : {
1651 286085 : SolarMutexGuard g;
1652 286085 : return impl_findToolbar( aName );
1653 : }
1654 :
1655 0 : UIElement ToolbarLayoutManager::implts_findToolbar( const uno::Reference< uno::XInterface >& xToolbar )
1656 : {
1657 0 : UIElement aToolbar;
1658 0 : UIElementVector::const_iterator pIter;
1659 :
1660 0 : SolarMutexGuard g;
1661 0 : for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); ++pIter )
1662 : {
1663 0 : if ( pIter->m_xUIElement.is() )
1664 : {
1665 0 : uno::Reference< uno::XInterface > xIfac( pIter->m_xUIElement->getRealInterface(), uno::UNO_QUERY );
1666 0 : if ( xIfac == xToolbar )
1667 : {
1668 0 : aToolbar = *pIter;
1669 0 : break;
1670 0 : }
1671 : }
1672 : }
1673 :
1674 0 : return aToolbar;
1675 : }
1676 :
1677 820 : uno::Reference< awt::XWindow > ToolbarLayoutManager::implts_getXWindow( const OUString& aName )
1678 : {
1679 820 : UIElementVector::iterator pIter;
1680 820 : uno::Reference< awt::XWindow > xWindow;
1681 :
1682 1640 : SolarMutexGuard g;
1683 3075 : for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); ++pIter )
1684 : {
1685 2258 : if ( pIter->m_aName == aName && pIter->m_xUIElement.is() )
1686 : {
1687 3 : xWindow = uno::Reference< awt::XWindow >( pIter->m_xUIElement->getRealInterface(), uno::UNO_QUERY );
1688 3 : break;
1689 : }
1690 : }
1691 :
1692 1640 : return xWindow;
1693 : }
1694 :
1695 0 : vcl::Window* ToolbarLayoutManager::implts_getWindow( const OUString& aName )
1696 : {
1697 0 : uno::Reference< awt::XWindow > xWindow = implts_getXWindow( aName );
1698 0 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
1699 :
1700 0 : return pWindow;
1701 : }
1702 :
1703 9577 : bool ToolbarLayoutManager::implts_insertToolbar( const UIElement& rUIElement )
1704 : {
1705 9577 : UIElement aTempData;
1706 9577 : bool bFound( false );
1707 9577 : bool bResult( false );
1708 :
1709 9577 : aTempData = implts_findToolbar( rUIElement.m_aName );
1710 9577 : if ( aTempData.m_aName == rUIElement.m_aName )
1711 55 : bFound = true;
1712 :
1713 9577 : if ( !bFound )
1714 : {
1715 9522 : SolarMutexGuard g;
1716 9522 : m_aUIElements.push_back( rUIElement );
1717 9522 : bResult = true;
1718 : }
1719 :
1720 9577 : return bResult;
1721 : }
1722 :
1723 6898 : void ToolbarLayoutManager::implts_setToolbar( const UIElement& rUIElement )
1724 : {
1725 6898 : SolarMutexGuard g;
1726 6898 : UIElement& rData = impl_findToolbar( rUIElement.m_aName );
1727 6898 : if ( rData.m_aName == rUIElement.m_aName )
1728 6898 : rData = rUIElement;
1729 : else
1730 0 : m_aUIElements.push_back( rUIElement );
1731 6898 : }
1732 :
1733 : /******************************************************************************
1734 : LAYOUT CODE PART FOR TOOLBARS
1735 : ******************************************************************************/
1736 :
1737 0 : awt::Point ToolbarLayoutManager::implts_findNextCascadeFloatingPos()
1738 : {
1739 0 : const sal_Int32 nHotZoneX = 50;
1740 0 : const sal_Int32 nHotZoneY = 50;
1741 0 : const sal_Int32 nCascadeIndentX = 15;
1742 0 : const sal_Int32 nCascadeIndentY = 15;
1743 :
1744 0 : SolarMutexClearableGuard aReadLock;
1745 0 : uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
1746 0 : uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
1747 0 : uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
1748 0 : aReadLock.clear();
1749 :
1750 0 : awt::Point aStartPos( nCascadeIndentX, nCascadeIndentY );
1751 0 : awt::Point aCurrPos( aStartPos );
1752 0 : awt::Rectangle aRect;
1753 :
1754 0 : if ( xContainerWindow.is() )
1755 : {
1756 0 : SolarMutexGuard aGuard;
1757 0 : vcl::Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
1758 0 : if ( pContainerWindow )
1759 0 : aStartPos = AWTPoint(pContainerWindow->OutputToScreenPixel(VCLPoint(aStartPos)));
1760 : }
1761 :
1762 : // Determine size of top and left docking area
1763 0 : awt::Rectangle aTopRect( xTopDockingWindow->getPosSize() );
1764 0 : awt::Rectangle aLeftRect( xLeftDockingWindow->getPosSize() );
1765 :
1766 0 : aStartPos.X += aLeftRect.Width + nCascadeIndentX;
1767 0 : aStartPos.Y += aTopRect.Height + nCascadeIndentY;
1768 0 : aCurrPos = aStartPos;
1769 :
1770 : // Try to find a cascaded position for the new floating window
1771 0 : UIElementVector::const_iterator pIter;
1772 0 : for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); ++pIter )
1773 : {
1774 0 : if ( pIter->m_xUIElement.is() )
1775 : {
1776 0 : uno::Reference< awt::XDockableWindow > xDockWindow( pIter->m_xUIElement->getRealInterface(), uno::UNO_QUERY );
1777 0 : uno::Reference< awt::XWindow > xWindow( xDockWindow, uno::UNO_QUERY );
1778 0 : if ( xDockWindow.is() && xDockWindow->isFloating() )
1779 : {
1780 0 : SolarMutexGuard aGuard;
1781 0 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
1782 0 : if ( pWindow && pWindow->IsVisible() )
1783 : {
1784 0 : awt::Rectangle aFloatRect = xWindow->getPosSize();
1785 0 : if ((( aFloatRect.X - nHotZoneX ) <= aCurrPos.X ) &&
1786 0 : ( aFloatRect.X >= aCurrPos.X ) &&
1787 0 : (( aFloatRect.Y - nHotZoneY ) <= aCurrPos.Y ) &&
1788 0 : ( aFloatRect.Y >= aCurrPos.Y ))
1789 : {
1790 0 : aCurrPos.X = aFloatRect.X + nCascadeIndentX;
1791 0 : aCurrPos.Y = aFloatRect.Y + nCascadeIndentY;
1792 : }
1793 0 : }
1794 0 : }
1795 : }
1796 : }
1797 :
1798 0 : return aCurrPos;
1799 : }
1800 :
1801 18087 : void ToolbarLayoutManager::implts_sortUIElements()
1802 : {
1803 18087 : SolarMutexGuard g;
1804 18087 : UIElementVector::iterator pIterStart = m_aUIElements.begin();
1805 18087 : UIElementVector::iterator pIterEnd = m_aUIElements.end();
1806 :
1807 18087 : std::stable_sort( pIterStart, pIterEnd ); // first created element should first
1808 :
1809 : // We have to reset our temporary flags.
1810 18087 : UIElementVector::iterator pIter;
1811 48304 : for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); ++pIter )
1812 48304 : pIter->m_bUserActive = false;
1813 18087 : }
1814 :
1815 15910 : void ToolbarLayoutManager::implts_getUIElementVectorCopy( UIElementVector& rCopy )
1816 : {
1817 15910 : SolarMutexGuard g;
1818 15910 : rCopy = m_aUIElements;
1819 15910 : }
1820 :
1821 378 : ::Size ToolbarLayoutManager::implts_getTopBottomDockingAreaSizes()
1822 : {
1823 378 : ::Size aSize;
1824 378 : uno::Reference< awt::XWindow > xTopDockingAreaWindow;
1825 756 : uno::Reference< awt::XWindow > xBottomDockingAreaWindow;
1826 :
1827 756 : SolarMutexClearableGuard aReadLock;
1828 378 : xTopDockingAreaWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP];
1829 378 : xBottomDockingAreaWindow = m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM];
1830 378 : aReadLock.clear();
1831 :
1832 378 : if ( xTopDockingAreaWindow.is() )
1833 378 : aSize.Width() = xTopDockingAreaWindow->getPosSize().Height;
1834 378 : if ( xBottomDockingAreaWindow.is() )
1835 378 : aSize.Height() = xBottomDockingAreaWindow->getPosSize().Height;
1836 :
1837 756 : return aSize;
1838 : }
1839 :
1840 48526 : void ToolbarLayoutManager::implts_getDockingAreaElementInfos( ui::DockingArea eDockingArea, std::vector< SingleRowColumnWindowData >& rRowColumnsWindowData )
1841 : {
1842 48526 : std::vector< UIElement > aWindowVector;
1843 :
1844 48526 : if (( eDockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( eDockingArea > ui::DockingArea_DOCKINGAREA_RIGHT ))
1845 0 : eDockingArea = ui::DockingArea_DOCKINGAREA_TOP;
1846 :
1847 97052 : uno::Reference< awt::XWindow > xDockAreaWindow;
1848 :
1849 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1850 97052 : SolarMutexClearableGuard aReadLock;
1851 48526 : aWindowVector.reserve(m_aUIElements.size());
1852 48526 : xDockAreaWindow = m_xDockAreaWindows[eDockingArea];
1853 48526 : UIElementVector::iterator pIter;
1854 134709 : for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); ++pIter )
1855 : {
1856 86183 : if ( pIter->m_aDockedData.m_nDockedArea == eDockingArea && pIter->m_bVisible && !pIter->m_bFloating )
1857 : {
1858 11715 : uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement );
1859 11715 : if ( xUIElement.is() )
1860 : {
1861 11714 : uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
1862 23428 : uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
1863 11714 : if ( xDockWindow.is() )
1864 : {
1865 : // docked windows
1866 11714 : aWindowVector.push_back( *pIter );
1867 11714 : }
1868 11715 : }
1869 : }
1870 : }
1871 48526 : aReadLock.clear();
1872 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
1873 :
1874 48526 : rRowColumnsWindowData.clear();
1875 :
1876 : // Collect data from windows that are on the same row/column
1877 : sal_Int32 j;
1878 48526 : sal_Int32 nIndex( 0 );
1879 48526 : sal_Int32 nLastPos( 0 );
1880 48526 : sal_Int32 nCurrPos( -1 );
1881 48526 : sal_Int32 nLastRowColPixelPos( 0 );
1882 48526 : awt::Rectangle aDockAreaRect;
1883 :
1884 48526 : if ( xDockAreaWindow.is() )
1885 48526 : aDockAreaRect = xDockAreaWindow->getPosSize();
1886 :
1887 48526 : if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP )
1888 14218 : nLastRowColPixelPos = 0;
1889 34308 : else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
1890 11438 : nLastRowColPixelPos = aDockAreaRect.Height;
1891 22870 : else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
1892 11460 : nLastRowColPixelPos = 0;
1893 : else
1894 11410 : nLastRowColPixelPos = aDockAreaRect.Width;
1895 :
1896 48526 : const sal_uInt32 nCount = aWindowVector.size();
1897 60240 : for ( j = 0; j < sal_Int32( nCount); j++ )
1898 : {
1899 11714 : const UIElement& rElement = aWindowVector[j];
1900 11714 : uno::Reference< awt::XWindow > xWindow;
1901 23428 : uno::Reference< ui::XUIElement > xUIElement( rElement.m_xUIElement );
1902 11714 : awt::Rectangle aPosSize;
1903 :
1904 11714 : if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) )
1905 0 : continue;
1906 11714 : if ( isHorizontalDockingArea( eDockingArea ))
1907 : {
1908 11550 : if ( nCurrPos == -1 )
1909 : {
1910 7213 : nCurrPos = rElement.m_aDockedData.m_aPos.Y;
1911 7213 : nLastPos = 0;
1912 :
1913 7213 : SingleRowColumnWindowData aRowColumnWindowData;
1914 7213 : aRowColumnWindowData.nRowColumn = nCurrPos;
1915 7213 : rRowColumnsWindowData.push_back( aRowColumnWindowData );
1916 : }
1917 :
1918 11550 : sal_Int32 nSpace( 0 );
1919 11550 : if ( rElement.m_aDockedData.m_aPos.Y != nCurrPos )
1920 : {
1921 4197 : if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP )
1922 4197 : nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize;
1923 : else
1924 0 : nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize;
1925 4197 : ++nIndex;
1926 4197 : nLastPos = 0;
1927 4197 : nCurrPos = rElement.m_aDockedData.m_aPos.Y;
1928 4197 : SingleRowColumnWindowData aRowColumnWindowData;
1929 4197 : aRowColumnWindowData.nRowColumn = nCurrPos;
1930 4197 : rRowColumnsWindowData.push_back( aRowColumnWindowData );
1931 : }
1932 :
1933 : // Calc space before an element and store it
1934 11550 : nSpace = ( rElement.m_aDockedData.m_aPos.X - nLastPos );
1935 11550 : if ( rElement.m_aDockedData.m_aPos.X >= nLastPos )
1936 : {
1937 11462 : rRowColumnsWindowData[nIndex].nSpace += nSpace;
1938 11462 : nLastPos = rElement.m_aDockedData.m_aPos.X + aPosSize.Width;
1939 : }
1940 : else
1941 : {
1942 88 : nSpace = 0;
1943 88 : nLastPos += aPosSize.Width;
1944 : }
1945 11550 : rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace );
1946 :
1947 11550 : rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow );
1948 11550 : rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName );
1949 11550 : 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 23100 : aPosSize.Height ));
1954 11550 : if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Height )
1955 11410 : rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Height;
1956 11550 : if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP )
1957 11082 : rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( 0, nLastRowColPixelPos,
1958 11082 : aDockAreaRect.Width, aPosSize.Height );
1959 : else
1960 468 : rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( 0, ( nLastRowColPixelPos - aPosSize.Height ),
1961 468 : aDockAreaRect.Width, aPosSize.Height );
1962 11550 : rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Width + nSpace;
1963 : }
1964 : else
1965 : {
1966 164 : if ( nCurrPos == -1 )
1967 : {
1968 164 : nCurrPos = rElement.m_aDockedData.m_aPos.X;
1969 164 : nLastPos = 0;
1970 :
1971 164 : SingleRowColumnWindowData aRowColumnWindowData;
1972 164 : aRowColumnWindowData.nRowColumn = nCurrPos;
1973 164 : rRowColumnsWindowData.push_back( aRowColumnWindowData );
1974 : }
1975 :
1976 164 : sal_Int32 nSpace( 0 );
1977 164 : if ( rElement.m_aDockedData.m_aPos.X != nCurrPos )
1978 : {
1979 0 : if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
1980 0 : nLastRowColPixelPos += rRowColumnsWindowData[nIndex].nStaticSize;
1981 : else
1982 0 : nLastRowColPixelPos -= rRowColumnsWindowData[nIndex].nStaticSize;
1983 0 : ++nIndex;
1984 0 : nLastPos = 0;
1985 0 : nCurrPos = rElement.m_aDockedData.m_aPos.X;
1986 0 : SingleRowColumnWindowData aRowColumnWindowData;
1987 0 : aRowColumnWindowData.nRowColumn = nCurrPos;
1988 0 : rRowColumnsWindowData.push_back( aRowColumnWindowData );
1989 : }
1990 :
1991 : // Calc space before an element and store it
1992 164 : nSpace = ( rElement.m_aDockedData.m_aPos.Y - nLastPos );
1993 164 : if ( rElement.m_aDockedData.m_aPos.Y > nLastPos )
1994 : {
1995 0 : rRowColumnsWindowData[nIndex].nSpace += nSpace;
1996 0 : nLastPos = rElement.m_aDockedData.m_aPos.Y + aPosSize.Height;
1997 : }
1998 : else
1999 : {
2000 164 : nSpace = 0;
2001 164 : nLastPos += aPosSize.Height;
2002 : }
2003 164 : rRowColumnsWindowData[nIndex].aRowColumnSpace.push_back( nSpace );
2004 :
2005 164 : rRowColumnsWindowData[nIndex].aRowColumnWindows.push_back( xWindow );
2006 164 : rRowColumnsWindowData[nIndex].aUIElementNames.push_back( rElement.m_aName );
2007 164 : 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 328 : aPosSize.Height ));
2012 164 : if ( rRowColumnsWindowData[nIndex].nStaticSize < aPosSize.Width )
2013 164 : rRowColumnsWindowData[nIndex].nStaticSize = aPosSize.Width;
2014 164 : if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
2015 164 : rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( nLastRowColPixelPos, 0,
2016 164 : aPosSize.Width, aDockAreaRect.Height );
2017 : else
2018 0 : rRowColumnsWindowData[nIndex].aRowColumnRect = awt::Rectangle( ( nLastRowColPixelPos - aPosSize.Width ), 0,
2019 0 : aPosSize.Width, aDockAreaRect.Height );
2020 164 : rRowColumnsWindowData[nIndex].nVarSize += aPosSize.Height + nSpace;
2021 : }
2022 60240 : }
2023 48526 : }
2024 :
2025 0 : void ToolbarLayoutManager::implts_getDockingAreaElementInfoOnSingleRowCol( ui::DockingArea eDockingArea, sal_Int32 nRowCol, SingleRowColumnWindowData& rRowColumnWindowData )
2026 : {
2027 0 : std::vector< UIElement > aWindowVector;
2028 :
2029 0 : if (( eDockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( eDockingArea > ui::DockingArea_DOCKINGAREA_RIGHT ))
2030 0 : eDockingArea = ui::DockingArea_DOCKINGAREA_TOP;
2031 :
2032 0 : bool bHorzDockArea = isHorizontalDockingArea( eDockingArea );
2033 :
2034 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2035 0 : SolarMutexClearableGuard aReadLock;
2036 0 : UIElementVector::iterator pIter;
2037 0 : UIElementVector::iterator pEnd = m_aUIElements.end();
2038 0 : for ( pIter = m_aUIElements.begin(); pIter != pEnd; ++pIter )
2039 : {
2040 0 : if ( pIter->m_aDockedData.m_nDockedArea == eDockingArea )
2041 : {
2042 0 : bool bSameRowCol = bHorzDockArea ? ( pIter->m_aDockedData.m_aPos.Y == nRowCol ) : ( pIter->m_aDockedData.m_aPos.X == nRowCol );
2043 0 : uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement );
2044 :
2045 0 : if ( bSameRowCol && xUIElement.is() )
2046 : {
2047 0 : uno::Reference< awt::XWindow > xWindow( xUIElement->getRealInterface(), uno::UNO_QUERY );
2048 0 : if ( xWindow.is() )
2049 : {
2050 0 : SolarMutexGuard aGuard;
2051 0 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
2052 0 : uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
2053 0 : if ( pWindow && pIter->m_bVisible && xDockWindow.is() && !pIter->m_bFloating )
2054 0 : aWindowVector.push_back( *pIter ); // docked windows
2055 0 : }
2056 0 : }
2057 : }
2058 : }
2059 0 : aReadLock.clear();
2060 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
2061 :
2062 : // Initialize structure
2063 0 : rRowColumnWindowData.aUIElementNames.clear();
2064 0 : rRowColumnWindowData.aRowColumnWindows.clear();
2065 0 : rRowColumnWindowData.aRowColumnWindowSizes.clear();
2066 0 : rRowColumnWindowData.aRowColumnSpace.clear();
2067 0 : rRowColumnWindowData.nVarSize = 0;
2068 0 : rRowColumnWindowData.nStaticSize = 0;
2069 0 : rRowColumnWindowData.nSpace = 0;
2070 0 : rRowColumnWindowData.nRowColumn = nRowCol;
2071 :
2072 : // Collect data from windows that are on the same row/column
2073 : sal_Int32 j;
2074 0 : sal_Int32 nLastPos( 0 );
2075 :
2076 0 : const sal_uInt32 nCount = aWindowVector.size();
2077 0 : for ( j = 0; j < sal_Int32( nCount); j++ )
2078 : {
2079 0 : const UIElement& rElement = aWindowVector[j];
2080 0 : uno::Reference< awt::XWindow > xWindow;
2081 0 : uno::Reference< ui::XUIElement > xUIElement( rElement.m_xUIElement );
2082 0 : awt::Rectangle aPosSize;
2083 0 : if ( !lcl_checkUIElement(xUIElement,aPosSize,xWindow) )
2084 0 : continue;
2085 :
2086 : sal_Int32 nSpace;
2087 0 : if ( isHorizontalDockingArea( eDockingArea ))
2088 : {
2089 0 : nSpace = ( rElement.m_aDockedData.m_aPos.X - nLastPos );
2090 :
2091 : // Calc space before an element and store it
2092 0 : if ( rElement.m_aDockedData.m_aPos.X > nLastPos )
2093 0 : rRowColumnWindowData.nSpace += nSpace;
2094 : else
2095 0 : nSpace = 0;
2096 :
2097 0 : nLastPos = rElement.m_aDockedData.m_aPos.X + aPosSize.Width;
2098 :
2099 : rRowColumnWindowData.aRowColumnWindowSizes.push_back(
2100 : awt::Rectangle( rElement.m_aDockedData.m_aPos.X, rElement.m_aDockedData.m_aPos.Y,
2101 0 : aPosSize.Width, aPosSize.Height ));
2102 0 : if ( rRowColumnWindowData.nStaticSize < aPosSize.Height )
2103 0 : rRowColumnWindowData.nStaticSize = aPosSize.Height;
2104 0 : rRowColumnWindowData.nVarSize += aPosSize.Width;
2105 : }
2106 : else
2107 : {
2108 : // Calc space before an element and store it
2109 0 : nSpace = ( rElement.m_aDockedData.m_aPos.Y - nLastPos );
2110 0 : if ( rElement.m_aDockedData.m_aPos.Y > nLastPos )
2111 0 : rRowColumnWindowData.nSpace += nSpace;
2112 : else
2113 0 : nSpace = 0;
2114 :
2115 0 : nLastPos = rElement.m_aDockedData.m_aPos.Y + aPosSize.Height;
2116 :
2117 : rRowColumnWindowData.aRowColumnWindowSizes.push_back(
2118 : awt::Rectangle( rElement.m_aDockedData.m_aPos.X, rElement.m_aDockedData.m_aPos.Y,
2119 0 : aPosSize.Width, aPosSize.Height ));
2120 0 : if ( rRowColumnWindowData.nStaticSize < aPosSize.Width )
2121 0 : rRowColumnWindowData.nStaticSize = aPosSize.Width;
2122 0 : rRowColumnWindowData.nVarSize += aPosSize.Height;
2123 : }
2124 :
2125 0 : rRowColumnWindowData.aUIElementNames.push_back( rElement.m_aName );
2126 0 : rRowColumnWindowData.aRowColumnWindows.push_back( xWindow );
2127 0 : rRowColumnWindowData.aRowColumnSpace.push_back( nSpace );
2128 0 : rRowColumnWindowData.nVarSize += nSpace;
2129 0 : }
2130 0 : }
2131 :
2132 0 : ::Rectangle ToolbarLayoutManager::implts_getWindowRectFromRowColumn(
2133 : ui::DockingArea DockingArea,
2134 : const SingleRowColumnWindowData& rRowColumnWindowData,
2135 : const ::Point& rMousePos,
2136 : const OUString& rExcludeElementName )
2137 : {
2138 0 : ::Rectangle aWinRect;
2139 :
2140 0 : if (( DockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( DockingArea > ui::DockingArea_DOCKINGAREA_RIGHT ))
2141 0 : DockingArea = ui::DockingArea_DOCKINGAREA_TOP;
2142 :
2143 0 : if ( rRowColumnWindowData.aRowColumnWindows.empty() )
2144 0 : return aWinRect;
2145 : else
2146 : {
2147 0 : SolarMutexClearableGuard aReadLock;
2148 0 : vcl::Window* pContainerWindow( VCLUnoHelper::GetWindow( m_xContainerWindow ));
2149 0 : vcl::Window* pDockingAreaWindow( VCLUnoHelper::GetWindow( m_xDockAreaWindows[DockingArea] ));
2150 0 : aReadLock.clear();
2151 :
2152 : // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect
2153 0 : SolarMutexGuard aGuard;
2154 :
2155 : // Retrieve output size from container Window
2156 0 : if ( pDockingAreaWindow && pContainerWindow )
2157 : {
2158 0 : const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindows.size();
2159 0 : for ( sal_uInt32 i = 0; i < nCount; i++ )
2160 : {
2161 0 : awt::Rectangle aWindowRect = rRowColumnWindowData.aRowColumnWindows[i]->getPosSize();
2162 0 : ::Rectangle aRect( aWindowRect.X, aWindowRect.Y, aWindowRect.X+aWindowRect.Width, aWindowRect.Y+aWindowRect.Height );
2163 0 : aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() )));
2164 0 : if ( aRect.IsInside( rMousePos ))
2165 : {
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 0 : if ( rExcludeElementName != rRowColumnWindowData.aUIElementNames[i] )
2169 0 : return aRect;
2170 : else
2171 0 : break;
2172 : }
2173 : }
2174 0 : }
2175 : }
2176 :
2177 0 : return aWinRect;
2178 : }
2179 :
2180 0 : ::Rectangle ToolbarLayoutManager::implts_determineFrontDockingRect(
2181 : ui::DockingArea eDockingArea,
2182 : sal_Int32 nRowCol,
2183 : const ::Rectangle& rDockedElementRect,
2184 : const OUString& rMovedElementName,
2185 : const ::Rectangle& rMovedElementRect )
2186 : {
2187 0 : SingleRowColumnWindowData aRowColumnWindowData;
2188 :
2189 0 : bool bHorzDockArea( isHorizontalDockingArea( eDockingArea ));
2190 0 : implts_getDockingAreaElementInfoOnSingleRowCol( eDockingArea, nRowCol, aRowColumnWindowData );
2191 0 : if ( aRowColumnWindowData.aRowColumnWindows.empty() )
2192 0 : return rMovedElementRect;
2193 : else
2194 : {
2195 0 : sal_Int32 nSpace( 0 );
2196 0 : ::Rectangle aFrontDockingRect( rMovedElementRect );
2197 0 : const sal_uInt32 nCount = aRowColumnWindowData.aRowColumnWindows.size();
2198 0 : for ( sal_uInt32 i = 0; i < nCount; i++ )
2199 : {
2200 0 : if ( bHorzDockArea )
2201 : {
2202 0 : if ( aRowColumnWindowData.aRowColumnWindowSizes[i].X >= rDockedElementRect.Left() )
2203 : {
2204 0 : nSpace += aRowColumnWindowData.aRowColumnSpace[i];
2205 0 : break;
2206 : }
2207 0 : else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName )
2208 0 : nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Width +
2209 0 : aRowColumnWindowData.aRowColumnSpace[i];
2210 : else
2211 0 : nSpace = 0;
2212 : }
2213 : else
2214 : {
2215 0 : if ( aRowColumnWindowData.aRowColumnWindowSizes[i].Y >= rDockedElementRect.Top() )
2216 : {
2217 0 : nSpace += aRowColumnWindowData.aRowColumnSpace[i];
2218 0 : break;
2219 : }
2220 0 : else if ( aRowColumnWindowData.aUIElementNames[i] == rMovedElementName )
2221 0 : nSpace += aRowColumnWindowData.aRowColumnWindowSizes[i].Height +
2222 0 : aRowColumnWindowData.aRowColumnSpace[i];
2223 : else
2224 0 : nSpace = 0;
2225 : }
2226 : }
2227 :
2228 0 : if ( nSpace > 0 )
2229 : {
2230 0 : sal_Int32 nMove = std::min( nSpace, static_cast<sal_Int32>(aFrontDockingRect.getWidth()) );
2231 0 : if ( bHorzDockArea )
2232 0 : aFrontDockingRect.Move( -nMove, 0 );
2233 : else
2234 0 : aFrontDockingRect.Move( 0, -nMove );
2235 : }
2236 :
2237 0 : return aFrontDockingRect;
2238 0 : }
2239 : }
2240 :
2241 2886 : void ToolbarLayoutManager::implts_findNextDockingPos( ui::DockingArea DockingArea, const ::Size& aUIElementSize, awt::Point& rVirtualPos, ::Point& rPixelPos )
2242 : {
2243 2886 : SolarMutexClearableGuard aReadLock;
2244 2886 : if (( DockingArea < ui::DockingArea_DOCKINGAREA_TOP ) || ( DockingArea > ui::DockingArea_DOCKINGAREA_RIGHT ))
2245 0 : DockingArea = ui::DockingArea_DOCKINGAREA_TOP;
2246 5750 : uno::Reference< awt::XWindow > xDockingWindow( m_xDockAreaWindows[DockingArea] );
2247 2886 : ::Size aDockingWinSize;
2248 2886 : vcl::Window* pDockingWindow( 0 );
2249 2886 : aReadLock.clear();
2250 :
2251 : {
2252 : // Retrieve output size from container Window
2253 2886 : SolarMutexGuard aGuard;
2254 2886 : pDockingWindow = VCLUnoHelper::GetWindow( xDockingWindow );
2255 2886 : if ( pDockingWindow )
2256 2886 : aDockingWinSize = pDockingWindow->GetOutputSizePixel();
2257 : }
2258 :
2259 2886 : sal_Int32 nFreeRowColPixelPos( 0 );
2260 2886 : sal_Int32 nMaxSpace( 0 );
2261 2886 : sal_Int32 nNeededSpace( 0 );
2262 2886 : sal_Int32 nTopDockingAreaSize( 0 );
2263 :
2264 2886 : if ( isHorizontalDockingArea( DockingArea ))
2265 : {
2266 2836 : nMaxSpace = aDockingWinSize.Width();
2267 2836 : nNeededSpace = aUIElementSize.Width();
2268 : }
2269 : else
2270 : {
2271 50 : nMaxSpace = aDockingWinSize.Height();
2272 50 : nNeededSpace = aUIElementSize.Height();
2273 50 : nTopDockingAreaSize = implts_getTopBottomDockingAreaSizes().Width();
2274 : }
2275 :
2276 5750 : std::vector< SingleRowColumnWindowData > aRowColumnsWindowData;
2277 :
2278 2886 : implts_getDockingAreaElementInfos( DockingArea, aRowColumnsWindowData );
2279 2886 : sal_Int32 nPixelPos( 0 );
2280 2886 : const sal_uInt32 nCount = aRowColumnsWindowData.size();
2281 2914 : for ( sal_uInt32 i = 0; i < nCount; i++ )
2282 : {
2283 50 : SingleRowColumnWindowData& rRowColumnWindowData = aRowColumnsWindowData[i];
2284 :
2285 100 : if (( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) ||
2286 50 : ( DockingArea == ui::DockingArea_DOCKINGAREA_RIGHT ))
2287 0 : nPixelPos += rRowColumnWindowData.nStaticSize;
2288 :
2289 78 : if ((( nMaxSpace - rRowColumnWindowData.nVarSize ) >= nNeededSpace ) ||
2290 28 : ( rRowColumnWindowData.nSpace >= nNeededSpace ))
2291 : {
2292 : // Check current row where we can find the needed space
2293 22 : sal_Int32 nCurrPos( 0 );
2294 22 : const sal_uInt32 nWindowSizesCount = rRowColumnWindowData.aRowColumnWindowSizes.size();
2295 88 : for ( sal_uInt32 j = 0; j < nWindowSizesCount; j++ )
2296 : {
2297 22 : awt::Rectangle rRect = rRowColumnWindowData.aRowColumnWindowSizes[j];
2298 22 : sal_Int32& rSpace = rRowColumnWindowData.aRowColumnSpace[j];
2299 22 : if ( isHorizontalDockingArea( DockingArea ))
2300 : {
2301 22 : if ( rSpace >= nNeededSpace )
2302 : {
2303 0 : rVirtualPos = awt::Point( nCurrPos, rRowColumnWindowData.nRowColumn );
2304 0 : if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP )
2305 0 : rPixelPos = ::Point( nCurrPos, nPixelPos );
2306 : else
2307 0 : rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos );
2308 0 : return;
2309 : }
2310 22 : nCurrPos = rRect.X + rRect.Width;
2311 : }
2312 : else
2313 : {
2314 0 : if ( rSpace >= nNeededSpace )
2315 : {
2316 0 : rVirtualPos = awt::Point( rRowColumnWindowData.nRowColumn, nCurrPos );
2317 0 : if ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
2318 0 : rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos );
2319 : else
2320 0 : rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos );
2321 0 : return;
2322 : }
2323 0 : nCurrPos = rRect.Y + rRect.Height;
2324 : }
2325 : }
2326 :
2327 22 : if (( nCurrPos + nNeededSpace ) <= nMaxSpace )
2328 : {
2329 22 : if ( isHorizontalDockingArea( DockingArea ))
2330 : {
2331 22 : rVirtualPos = awt::Point( nCurrPos, rRowColumnWindowData.nRowColumn );
2332 22 : if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP )
2333 22 : rPixelPos = ::Point( nCurrPos, nPixelPos );
2334 : else
2335 0 : rPixelPos = ::Point( nCurrPos, aDockingWinSize.Height() - nPixelPos );
2336 22 : return;
2337 : }
2338 : else
2339 : {
2340 0 : rVirtualPos = awt::Point( rRowColumnWindowData.nRowColumn, nCurrPos );
2341 0 : if ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
2342 0 : rPixelPos = ::Point( nPixelPos, nTopDockingAreaSize + nCurrPos );
2343 : else
2344 0 : rPixelPos = ::Point( aDockingWinSize.Width() - nPixelPos , nTopDockingAreaSize + nCurrPos );
2345 0 : return;
2346 : }
2347 : }
2348 : }
2349 :
2350 28 : if (( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) || ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ))
2351 28 : nPixelPos += rRowColumnWindowData.nStaticSize;
2352 : }
2353 :
2354 2864 : sal_Int32 nNextFreeRowCol( 0 );
2355 2864 : sal_Int32 nRowColumnsCount = aRowColumnsWindowData.size();
2356 2864 : if ( nRowColumnsCount > 0 )
2357 28 : nNextFreeRowCol = aRowColumnsWindowData[nRowColumnsCount-1].nRowColumn+1;
2358 : else
2359 2836 : nNextFreeRowCol = 0;
2360 :
2361 2864 : if ( nNextFreeRowCol == 0 )
2362 : {
2363 2836 : if ( DockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
2364 28 : nFreeRowColPixelPos = aDockingWinSize.Height() - aUIElementSize.Height();
2365 2808 : else if ( DockingArea == ui::DockingArea_DOCKINGAREA_RIGHT )
2366 0 : nFreeRowColPixelPos = aDockingWinSize.Width() - aUIElementSize.Width();
2367 : }
2368 :
2369 2864 : if ( isHorizontalDockingArea( DockingArea ))
2370 : {
2371 2814 : rVirtualPos = awt::Point( 0, nNextFreeRowCol );
2372 2814 : if ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP )
2373 2786 : rPixelPos = ::Point( 0, nFreeRowColPixelPos );
2374 : else
2375 28 : rPixelPos = ::Point( 0, aDockingWinSize.Height() - nFreeRowColPixelPos );
2376 : }
2377 : else
2378 : {
2379 50 : rVirtualPos = awt::Point( nNextFreeRowCol, 0 );
2380 50 : rPixelPos = ::Point( aDockingWinSize.Width() - nFreeRowColPixelPos, 0 );
2381 2864 : }
2382 : }
2383 :
2384 11524 : void ToolbarLayoutManager::implts_calcWindowPosSizeOnSingleRowColumn(
2385 : sal_Int32 nDockingArea,
2386 : sal_Int32 nOffset,
2387 : SingleRowColumnWindowData& rRowColumnWindowData,
2388 : const ::Size& rContainerSize )
2389 : {
2390 11524 : sal_Int32 nDiff(0);
2391 11524 : sal_Int32 nRCSpace( rRowColumnWindowData.nSpace );
2392 11524 : sal_Int32 nTopDockingAreaSize(0);
2393 11524 : sal_Int32 nBottomDockingAreaSize(0);
2394 11524 : sal_Int32 nContainerClientSize(0);
2395 :
2396 11524 : if ( rRowColumnWindowData.aRowColumnWindows.empty() )
2397 11524 : return;
2398 :
2399 11524 : if ( isHorizontalDockingArea( nDockingArea ))
2400 : {
2401 11360 : nContainerClientSize = rContainerSize.Width();
2402 11360 : nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize;
2403 : }
2404 : else
2405 : {
2406 164 : nTopDockingAreaSize = implts_getTopBottomDockingAreaSizes().Width();
2407 164 : nBottomDockingAreaSize = implts_getTopBottomDockingAreaSizes().Height();
2408 164 : nContainerClientSize = ( rContainerSize.Height() - nTopDockingAreaSize - nBottomDockingAreaSize );
2409 164 : nDiff = nContainerClientSize - rRowColumnWindowData.nVarSize;
2410 : }
2411 :
2412 11524 : const sal_uInt32 nCount = rRowColumnWindowData.aRowColumnWindowSizes.size();
2413 11524 : if (( nDiff < 0 ) && ( nRCSpace > 0 ))
2414 : {
2415 : // First we try to reduce the size of blank space before/behind docked windows
2416 0 : sal_Int32 i = nCount - 1;
2417 0 : while ( i >= 0 )
2418 : {
2419 0 : sal_Int32 nSpace = rRowColumnWindowData.aRowColumnSpace[i];
2420 0 : if ( nSpace >= -nDiff )
2421 : {
2422 0 : if ( isHorizontalDockingArea( nDockingArea ))
2423 : {
2424 : // Try to move this and all user elements behind with the calculated difference
2425 0 : for ( sal_uInt32 j = i; j < nCount; j++ )
2426 0 : rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff;
2427 : }
2428 : else
2429 : {
2430 : // Try to move this and all user elements behind with the calculated difference
2431 0 : for ( sal_uInt32 j = i; j < nCount; j++ )
2432 0 : rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff;
2433 : }
2434 0 : nDiff = 0;
2435 :
2436 0 : break;
2437 : }
2438 0 : else if ( nSpace > 0 )
2439 : {
2440 0 : if ( isHorizontalDockingArea( nDockingArea ))
2441 : {
2442 : // Try to move this and all user elements behind with the calculated difference
2443 0 : for ( sal_uInt32 j = i; j < nCount; j++ )
2444 0 : rRowColumnWindowData.aRowColumnWindowSizes[j].X -= nSpace;
2445 : }
2446 : else
2447 : {
2448 : // Try to move this and all user elements behind with the calculated difference
2449 0 : for ( sal_uInt32 j = i; j < nCount; j++ )
2450 0 : rRowColumnWindowData.aRowColumnWindowSizes[j].Y -= nSpace;
2451 : }
2452 0 : nDiff += nSpace;
2453 : }
2454 0 : --i;
2455 : }
2456 : }
2457 :
2458 : // Check if we have to reduce further
2459 11524 : if ( nDiff < 0 )
2460 : {
2461 : // Now we have to reduce the size of certain docked windows
2462 2740 : sal_Int32 i = sal_Int32( nCount - 1 );
2463 5480 : while ( i >= 0 )
2464 : {
2465 2740 : awt::Rectangle& rWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i];
2466 2740 : ::Size aMinSize;
2467 :
2468 2740 : SolarMutexGuard aGuard;
2469 : {
2470 2740 : uno::Reference< awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i];
2471 2740 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
2472 2740 : if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
2473 2740 : aMinSize = static_cast<ToolBox *>(pWindow)->CalcMinimumWindowSizePixel();
2474 : }
2475 :
2476 2740 : if (( aMinSize.Width() > 0 ) && ( aMinSize.Height() > 0 ))
2477 : {
2478 2740 : if ( isHorizontalDockingArea( nDockingArea ))
2479 : {
2480 2656 : sal_Int32 nMaxReducation = ( rWinRect.Width - aMinSize.Width() );
2481 2656 : if ( nMaxReducation >= -nDiff )
2482 : {
2483 2656 : rWinRect.Width = rWinRect.Width + nDiff;
2484 2656 : nDiff = 0;
2485 : }
2486 : else
2487 : {
2488 0 : rWinRect.Width = aMinSize.Width();
2489 0 : nDiff += nMaxReducation;
2490 : }
2491 :
2492 : // Try to move this and all user elements behind with the calculated difference
2493 5312 : for ( sal_uInt32 j = i; j < nCount; j++ )
2494 2656 : rRowColumnWindowData.aRowColumnWindowSizes[j].X += nDiff;
2495 : }
2496 : else
2497 : {
2498 84 : sal_Int32 nMaxReducation = ( rWinRect.Height - aMinSize.Height() );
2499 84 : if ( nMaxReducation >= -nDiff )
2500 : {
2501 84 : rWinRect.Height = rWinRect.Height + nDiff;
2502 84 : nDiff = 0;
2503 : }
2504 : else
2505 : {
2506 0 : rWinRect.Height = aMinSize.Height();
2507 0 : nDiff += nMaxReducation;
2508 : }
2509 :
2510 : // Try to move this and all user elements behind with the calculated difference
2511 168 : for ( sal_uInt32 j = i; j < nCount; j++ )
2512 84 : rRowColumnWindowData.aRowColumnWindowSizes[j].Y += nDiff;
2513 : }
2514 : }
2515 :
2516 2740 : if ( nDiff >= 0 )
2517 2740 : break;
2518 :
2519 0 : --i;
2520 0 : }
2521 : }
2522 :
2523 11524 : SolarMutexClearableGuard aReadLock;
2524 11524 : vcl::Window* pDockAreaWindow = VCLUnoHelper::GetWindow( m_xDockAreaWindows[nDockingArea] );
2525 11524 : aReadLock.clear();
2526 :
2527 11524 : sal_Int32 nCurrPos( 0 );
2528 :
2529 23048 : SolarMutexGuard aGuard;
2530 23188 : for ( sal_uInt32 i = 0; i < nCount; i++ )
2531 : {
2532 11664 : uno::Reference< awt::XWindow > xWindow = rRowColumnWindowData.aRowColumnWindows[i];
2533 11664 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
2534 11664 : vcl::Window* pOldParentWindow = pWindow->GetParent();
2535 :
2536 11664 : if ( pDockAreaWindow != pOldParentWindow )
2537 6672 : pWindow->SetParent( pDockAreaWindow );
2538 :
2539 11664 : awt::Rectangle aWinRect = rRowColumnWindowData.aRowColumnWindowSizes[i];
2540 11664 : if ( isHorizontalDockingArea( nDockingArea ))
2541 : {
2542 11500 : if ( aWinRect.X < nCurrPos )
2543 88 : aWinRect.X = nCurrPos;
2544 11500 : pWindow->SetPosSizePixel( ::Point( aWinRect.X, nOffset ), ::Size( aWinRect.Width, rRowColumnWindowData.nStaticSize ));
2545 11500 : pWindow->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
2546 11500 : nCurrPos += ( aWinRect.X - nCurrPos ) + aWinRect.Width;
2547 : }
2548 : else
2549 : {
2550 164 : if ( aWinRect.Y < nCurrPos )
2551 0 : aWinRect.Y = nCurrPos;
2552 164 : pWindow->SetPosSizePixel( ::Point( nOffset, aWinRect.Y ), ::Size( rRowColumnWindowData.nStaticSize, aWinRect.Height ));
2553 164 : pWindow->Show( true, ShowFlags::NoFocusChange | ShowFlags::NoActivate );
2554 164 : nCurrPos += ( aWinRect.Y - nCurrPos ) + aWinRect.Height;
2555 : }
2556 23188 : }
2557 : }
2558 :
2559 13728 : void ToolbarLayoutManager::implts_setLayoutDirty()
2560 : {
2561 13728 : SolarMutexGuard g;
2562 13728 : m_bLayoutDirty = true;
2563 13728 : }
2564 :
2565 0 : void ToolbarLayoutManager::implts_setLayoutInProgress( bool bInProgress )
2566 : {
2567 0 : SolarMutexGuard g;
2568 0 : m_bLayoutInProgress = bInProgress;
2569 0 : }
2570 :
2571 0 : ::Rectangle ToolbarLayoutManager::implts_calcHotZoneRect( const ::Rectangle& rRect, sal_Int32 nHotZoneOffset )
2572 : {
2573 0 : ::Rectangle aRect( rRect );
2574 :
2575 0 : aRect.Left() -= nHotZoneOffset;
2576 0 : aRect.Top() -= nHotZoneOffset;
2577 0 : aRect.Right() += nHotZoneOffset;
2578 0 : aRect.Bottom() += nHotZoneOffset;
2579 :
2580 0 : return aRect;
2581 : }
2582 :
2583 0 : void ToolbarLayoutManager::implts_calcDockingPosSize(
2584 : UIElement& rUIElement,
2585 : DockingOperation& rDockingOperation,
2586 : ::Rectangle& rTrackingRect,
2587 : const Point& rMousePos )
2588 : {
2589 0 : SolarMutexResettableGuard aReadLock;
2590 0 : uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
2591 0 : ::Size aContainerWinSize;
2592 0 : vcl::Window* pContainerWindow( 0 );
2593 0 : ::Rectangle aDockingAreaOffsets( m_aDockingAreaOffsets );
2594 0 : aReadLock.clear();
2595 :
2596 0 : if ( !rUIElement.m_xUIElement.is() )
2597 : {
2598 0 : rTrackingRect = ::Rectangle();
2599 0 : return;
2600 : }
2601 :
2602 : {
2603 : // Retrieve output size from container Window
2604 0 : SolarMutexGuard aGuard;
2605 0 : pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
2606 0 : aContainerWinSize = pContainerWindow->GetOutputSizePixel();
2607 : }
2608 :
2609 0 : vcl::Window* pDockingAreaWindow( 0 );
2610 0 : ToolBox* pToolBox( 0 );
2611 0 : uno::Reference< awt::XWindow > xWindow( rUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
2612 0 : uno::Reference< awt::XWindow > xDockingAreaWindow;
2613 0 : ::Rectangle aTrackingRect( rTrackingRect );
2614 0 : ui::DockingArea eDockedArea( (ui::DockingArea)rUIElement.m_aDockedData.m_nDockedArea );
2615 0 : sal_Int32 nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() );
2616 0 : sal_Int32 nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() );
2617 0 : bool bHorizontalDockArea(( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) ||
2618 0 : ( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM ));
2619 0 : sal_Int32 nMaxLeftRightDockAreaSize = aContainerWinSize.Height() -
2620 : nTopDockingAreaSize -
2621 : nBottomDockingAreaSize -
2622 0 : aDockingAreaOffsets.Top() -
2623 0 : aDockingAreaOffsets.Bottom();
2624 0 : ::Rectangle aDockingAreaRect;
2625 :
2626 0 : aReadLock.reset();
2627 0 : xDockingAreaWindow = m_xDockAreaWindows[eDockedArea];
2628 0 : aReadLock.clear();
2629 :
2630 : {
2631 0 : SolarMutexGuard aGuard;
2632 0 : pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow );
2633 0 : vcl::Window* pDockWindow = VCLUnoHelper::GetWindow( xWindow );
2634 0 : if ( pDockWindow && pDockWindow->GetType() == WINDOW_TOOLBOX )
2635 0 : pToolBox = static_cast<ToolBox *>(pDockWindow);
2636 :
2637 0 : aDockingAreaRect = ::Rectangle( pDockingAreaWindow->GetPosPixel(), pDockingAreaWindow->GetSizePixel() );
2638 0 : if ( pToolBox )
2639 : {
2640 : // docked toolbars always have one line
2641 0 : ::Size aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( sal_Int16( eDockedArea )) );
2642 0 : aTrackingRect.SetSize( ::Size( aSize.Width(), aSize.Height() ));
2643 0 : }
2644 : }
2645 :
2646 : // default docking operation, dock on the given row/column
2647 0 : bool bOpOutsideOfDockingArea( !aDockingAreaRect.IsInside( rMousePos ));
2648 :
2649 0 : std::vector< SingleRowColumnWindowData > aRowColumnsWindowData;
2650 :
2651 0 : rDockingOperation = DOCKOP_ON_COLROW;
2652 0 : implts_getDockingAreaElementInfos( eDockedArea, aRowColumnsWindowData );
2653 :
2654 : // determine current first row/column and last row/column
2655 0 : sal_Int32 nMaxRowCol( -1 );
2656 0 : sal_Int32 nMinRowCol( SAL_MAX_INT32 );
2657 0 : const sal_uInt32 nCount = aRowColumnsWindowData.size();
2658 0 : for ( sal_uInt32 i = 0; i < nCount; i++ )
2659 : {
2660 0 : if ( aRowColumnsWindowData[i].nRowColumn > nMaxRowCol )
2661 0 : nMaxRowCol = aRowColumnsWindowData[i].nRowColumn;
2662 0 : if ( aRowColumnsWindowData[i].nRowColumn < nMinRowCol )
2663 0 : nMinRowCol = aRowColumnsWindowData[i].nRowColumn;
2664 : }
2665 :
2666 0 : if ( !bOpOutsideOfDockingArea )
2667 : {
2668 : // docking inside our docking area
2669 0 : sal_Int32 nIndex( -1 );
2670 0 : sal_Int32 nRowCol( -1 );
2671 0 : ::Rectangle aWindowRect;
2672 0 : ::Rectangle aRowColumnRect;
2673 :
2674 0 : const sal_uInt32 nWindowDataCount = aRowColumnsWindowData.size();
2675 0 : for ( sal_uInt32 i = 0; i < nWindowDataCount; i++ )
2676 : {
2677 0 : ::Rectangle aRect( aRowColumnsWindowData[i].aRowColumnRect.X,
2678 0 : aRowColumnsWindowData[i].aRowColumnRect.Y,
2679 0 : aRowColumnsWindowData[i].aRowColumnRect.X + aRowColumnsWindowData[i].aRowColumnRect.Width,
2680 0 : aRowColumnsWindowData[i].aRowColumnRect.Y + aRowColumnsWindowData[i].aRowColumnRect.Height );
2681 :
2682 : {
2683 : // Calc correct position of the column/row rectangle to be able to compare it with mouse pos/tracking rect
2684 0 : SolarMutexGuard aGuard;
2685 0 : aRect.SetPos( pContainerWindow->ScreenToOutputPixel( pDockingAreaWindow->OutputToScreenPixel( aRect.TopLeft() )));
2686 : }
2687 :
2688 0 : bool bIsInsideRowCol( aRect.IsInside( rMousePos ) );
2689 0 : if ( bIsInsideRowCol )
2690 : {
2691 0 : nIndex = i;
2692 0 : nRowCol = aRowColumnsWindowData[i].nRowColumn;
2693 0 : rDockingOperation = implts_determineDockingOperation( eDockedArea, aRect, rMousePos );
2694 0 : aWindowRect = implts_getWindowRectFromRowColumn( eDockedArea, aRowColumnsWindowData[i], rMousePos, rUIElement.m_aName );
2695 0 : aRowColumnRect = aRect;
2696 0 : break;
2697 : }
2698 : }
2699 :
2700 : OSL_ENSURE( ( nIndex >= 0 ) && ( nRowCol >= 0 ), "Impossible case - no row/column found but mouse pointer is inside our docking area" );
2701 0 : if (( nIndex >= 0 ) && ( nRowCol >= 0 ))
2702 : {
2703 0 : if ( rDockingOperation == DOCKOP_ON_COLROW )
2704 : {
2705 0 : if ( !aWindowRect.IsEmpty())
2706 : {
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.
2709 :
2710 0 : ::Rectangle aUIElementRect( aWindowRect );
2711 0 : sal_Int32 nMiddle( bHorizontalDockArea ? ( aWindowRect.Left() + aWindowRect.getWidth() / 2 ) :
2712 0 : ( aWindowRect.Top() + aWindowRect.getHeight() / 2 ));
2713 0 : bool bInsertBefore( bHorizontalDockArea ? ( rMousePos.X() < nMiddle ) : ( rMousePos.Y() < nMiddle ));
2714 0 : if ( bInsertBefore )
2715 : {
2716 0 : if ( bHorizontalDockArea )
2717 : {
2718 0 : sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( aContainerWinSize.Width() - aWindowRect.Left() ),
2719 0 : sal_Int32( aTrackingRect.getWidth() )));
2720 0 : if ( nSize == 0 )
2721 0 : nSize = aWindowRect.getWidth();
2722 :
2723 0 : aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() ));
2724 0 : aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect,rUIElement.m_aName, aUIElementRect );
2725 :
2726 : // Set virtual position
2727 0 : rUIElement.m_aDockedData.m_aPos.X = aWindowRect.Left();
2728 0 : rUIElement.m_aDockedData.m_aPos.Y = nRowCol;
2729 : }
2730 : else
2731 : {
2732 : sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32(
2733 0 : nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Top() ),
2734 0 : sal_Int32( aTrackingRect.getHeight() )));
2735 0 : if ( nSize == 0 )
2736 0 : nSize = aWindowRect.getHeight();
2737 :
2738 0 : aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize ));
2739 0 : aWindowRect = implts_determineFrontDockingRect( eDockedArea, nRowCol, aWindowRect, rUIElement.m_aName, aUIElementRect );
2740 :
2741 : // Set virtual position
2742 : sal_Int32 nPosY = pDockingAreaWindow->ScreenToOutputPixel(
2743 0 : pContainerWindow->OutputToScreenPixel( aWindowRect.TopLeft() )).Y();
2744 0 : rUIElement.m_aDockedData.m_aPos.X = nRowCol;
2745 0 : rUIElement.m_aDockedData.m_aPos.Y = nPosY;
2746 : }
2747 :
2748 0 : rTrackingRect = aWindowRect;
2749 0 : return;
2750 : }
2751 : else
2752 : {
2753 0 : if ( bHorizontalDockArea )
2754 : {
2755 0 : sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32(( aContainerWinSize.Width() ) - aWindowRect.Right() ),
2756 0 : sal_Int32( aTrackingRect.getWidth() )));
2757 0 : if ( nSize == 0 )
2758 : {
2759 0 : aUIElementRect.SetPos( ::Point( aContainerWinSize.Width() - aTrackingRect.getWidth(), aWindowRect.Top() ));
2760 0 : aUIElementRect.SetSize( ::Size( aTrackingRect.getWidth(), aWindowRect.getHeight() ));
2761 0 : rUIElement.m_aDockedData.m_aPos.X = aUIElementRect.Left();
2762 :
2763 : }
2764 : else
2765 : {
2766 0 : aUIElementRect.SetPos( ::Point( aWindowRect.Right(), aWindowRect.Top() ));
2767 0 : aUIElementRect.SetSize( ::Size( nSize, aWindowRect.getHeight() ));
2768 0 : rUIElement.m_aDockedData.m_aPos.X = aWindowRect.Right();
2769 : }
2770 :
2771 : // Set virtual position
2772 0 : rUIElement.m_aDockedData.m_aPos.Y = nRowCol;
2773 : }
2774 : else
2775 : {
2776 0 : sal_Int32 nSize = ::std::max( sal_Int32( 0 ), std::min( sal_Int32( nTopDockingAreaSize + nMaxLeftRightDockAreaSize - aWindowRect.Bottom() ),
2777 0 : sal_Int32( aTrackingRect.getHeight() )));
2778 0 : aUIElementRect.SetPos( ::Point( aWindowRect.Left(), aWindowRect.Bottom() ));
2779 0 : aUIElementRect.SetSize( ::Size( aWindowRect.getWidth(), nSize ));
2780 :
2781 : // Set virtual position
2782 0 : sal_Int32 nPosY( 0 );
2783 : {
2784 0 : SolarMutexGuard aGuard;
2785 : nPosY = pDockingAreaWindow->ScreenToOutputPixel(
2786 0 : pContainerWindow->OutputToScreenPixel( aWindowRect.BottomRight() )).Y();
2787 : }
2788 0 : rUIElement.m_aDockedData.m_aPos.X = nRowCol;
2789 0 : rUIElement.m_aDockedData.m_aPos.Y = nPosY;
2790 : }
2791 :
2792 0 : rTrackingRect = aUIElementRect;
2793 0 : return;
2794 : }
2795 : }
2796 : else
2797 : {
2798 0 : implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect );
2799 : rTrackingRect = implts_calcTrackingAndElementRect(
2800 : eDockedArea, nRowCol, rUIElement,
2801 0 : aTrackingRect, aRowColumnRect, aContainerWinSize );
2802 0 : return;
2803 : }
2804 : }
2805 : else
2806 : {
2807 0 : if ((( nRowCol == nMinRowCol ) && ( rDockingOperation == DOCKOP_BEFORE_COLROW )) ||
2808 0 : (( nRowCol == nMaxRowCol ) && ( rDockingOperation == DOCKOP_AFTER_COLROW )))
2809 0 : bOpOutsideOfDockingArea = true;
2810 : else
2811 : {
2812 : // handle docking before/after a row
2813 0 : implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect );
2814 : rTrackingRect = implts_calcTrackingAndElementRect(
2815 : eDockedArea, nRowCol, rUIElement,
2816 0 : aTrackingRect, aRowColumnRect, aContainerWinSize );
2817 :
2818 0 : sal_Int32 nOffsetX( 0 );
2819 0 : sal_Int32 nOffsetY( 0 );
2820 0 : if ( bHorizontalDockArea )
2821 0 : nOffsetY = sal_Int32( floor( aRowColumnRect.getHeight() / 2.0 + 0.5 ));
2822 : else
2823 0 : nOffsetX = sal_Int32( floor( aRowColumnRect.getWidth() / 2.0 + 0.5 ));
2824 :
2825 0 : if ( rDockingOperation == DOCKOP_BEFORE_COLROW )
2826 : {
2827 0 : if (( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP ) || ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT ))
2828 : {
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 0 : nOffsetX *= -1;
2833 0 : nOffsetY *= -1;
2834 : }
2835 : }
2836 : else
2837 : {
2838 0 : if (( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM ) || ( eDockedArea == ui::DockingArea_DOCKINGAREA_RIGHT ))
2839 : {
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 0 : nOffsetX *= -1;
2844 0 : nOffsetY *= -1;
2845 : }
2846 0 : nRowCol++;
2847 : }
2848 :
2849 0 : if ( bHorizontalDockArea )
2850 0 : rUIElement.m_aDockedData.m_aPos.Y = nRowCol;
2851 : else
2852 0 : rUIElement.m_aDockedData.m_aPos.X = nRowCol;
2853 :
2854 0 : rTrackingRect.Move( nOffsetX, nOffsetY );
2855 0 : rTrackingRect.SetSize( aTrackingRect.GetSize() );
2856 : }
2857 : }
2858 : }
2859 : }
2860 :
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 0 : if ( bOpOutsideOfDockingArea )
2864 : {
2865 : // set correct size for docking
2866 0 : implts_setTrackingRect( eDockedArea, rMousePos, aTrackingRect );
2867 0 : rTrackingRect = aTrackingRect;
2868 :
2869 0 : if ( bHorizontalDockArea )
2870 : {
2871 0 : sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 )));
2872 0 : if (( nPosX + rTrackingRect.getWidth()) > aContainerWinSize.Width() )
2873 : nPosX = std::min( nPosX,
2874 0 : std::max( sal_Int32( aContainerWinSize.Width() - rTrackingRect.getWidth() ),
2875 0 : sal_Int32( 0 )));
2876 :
2877 0 : sal_Int32 nSize = std::min( aContainerWinSize.Width(), rTrackingRect.getWidth() );
2878 0 : sal_Int32 nDockHeight = std::max( static_cast<sal_Int32>(aDockingAreaRect.getHeight()), sal_Int32( 0 ));
2879 0 : if ( nDockHeight == 0 )
2880 : {
2881 0 : sal_Int32 nPosY( std::max( aDockingAreaRect.Top(), aDockingAreaRect.Bottom() ));
2882 0 : if ( eDockedArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
2883 0 : nPosY -= rTrackingRect.getHeight();
2884 0 : rTrackingRect.SetPos( Point( nPosX, nPosY ));
2885 0 : rUIElement.m_aDockedData.m_aPos.Y = 0;
2886 : }
2887 0 : else if ( rMousePos.Y() < ( aDockingAreaRect.Top() + ( nDockHeight / 2 )))
2888 : {
2889 0 : rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Top() - rTrackingRect.getHeight() ));
2890 0 : if ( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP )
2891 0 : rUIElement.m_aDockedData.m_aPos.Y = 0;
2892 : else
2893 0 : rUIElement.m_aDockedData.m_aPos.Y = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
2894 0 : rDockingOperation = DOCKOP_BEFORE_COLROW;
2895 : }
2896 : else
2897 : {
2898 0 : rTrackingRect.SetPos( Point( nPosX, aDockingAreaRect.Bottom() ));
2899 0 : if ( eDockedArea == ui::DockingArea_DOCKINGAREA_TOP )
2900 0 : rUIElement.m_aDockedData.m_aPos.Y = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
2901 : else
2902 0 : rUIElement.m_aDockedData.m_aPos.Y = 0;
2903 0 : rDockingOperation = DOCKOP_AFTER_COLROW;
2904 : }
2905 0 : rTrackingRect.setWidth( nSize );
2906 :
2907 : {
2908 0 : SolarMutexGuard aGuard;
2909 : nPosX = pDockingAreaWindow->ScreenToOutputPixel(
2910 0 : pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).X();
2911 : }
2912 0 : rUIElement.m_aDockedData.m_aPos.X = nPosX;
2913 : }
2914 : else
2915 : {
2916 0 : sal_Int32 nMaxDockingAreaHeight = std::max( sal_Int32( 0 ), sal_Int32( nMaxLeftRightDockAreaSize ));
2917 0 : sal_Int32 nPosY( std::max( sal_Int32( aTrackingRect.Top()), sal_Int32( nTopDockingAreaSize )));
2918 0 : if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight ))
2919 : nPosY = std::min( nPosY,
2920 0 : std::max( sal_Int32( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() )),
2921 0 : sal_Int32( nTopDockingAreaSize )));
2922 :
2923 0 : sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) );
2924 0 : sal_Int32 nDockWidth = std::max( static_cast<sal_Int32>(aDockingAreaRect.getWidth()), sal_Int32( 0 ));
2925 0 : if ( nDockWidth == 0 )
2926 : {
2927 0 : sal_Int32 nPosX( std::max( aDockingAreaRect.Left(), aDockingAreaRect.Right() ));
2928 0 : if ( eDockedArea == ui::DockingArea_DOCKINGAREA_RIGHT )
2929 0 : nPosX -= rTrackingRect.getWidth();
2930 0 : rTrackingRect.SetPos( Point( nPosX, nPosY ));
2931 0 : rUIElement.m_aDockedData.m_aPos.X = 0;
2932 : }
2933 0 : else if ( rMousePos.X() < ( aDockingAreaRect.Left() + ( nDockWidth / 2 )))
2934 : {
2935 0 : rTrackingRect.SetPos( Point( aDockingAreaRect.Left() - rTrackingRect.getWidth(), nPosY ));
2936 0 : if ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT )
2937 0 : rUIElement.m_aDockedData.m_aPos.X = 0;
2938 : else
2939 0 : rUIElement.m_aDockedData.m_aPos.X = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
2940 0 : rDockingOperation = DOCKOP_BEFORE_COLROW;
2941 : }
2942 : else
2943 : {
2944 0 : rTrackingRect.SetPos( Point( aDockingAreaRect.Right(), nPosY ));
2945 0 : if ( eDockedArea == ui::DockingArea_DOCKINGAREA_LEFT )
2946 0 : rUIElement.m_aDockedData.m_aPos.X = ( nMaxRowCol >= 0 ) ? nMaxRowCol+1 : 0;
2947 : else
2948 0 : rUIElement.m_aDockedData.m_aPos.X = 0;
2949 0 : rDockingOperation = DOCKOP_AFTER_COLROW;
2950 : }
2951 0 : rTrackingRect.setHeight( nSize );
2952 :
2953 : {
2954 0 : SolarMutexGuard aGuard;
2955 : nPosY = pDockingAreaWindow->ScreenToOutputPixel(
2956 0 : pContainerWindow->OutputToScreenPixel( rTrackingRect.TopLeft() )).Y();
2957 : }
2958 0 : rUIElement.m_aDockedData.m_aPos.Y = nPosY;
2959 : }
2960 0 : }
2961 : }
2962 :
2963 0 : framework::ToolbarLayoutManager::DockingOperation ToolbarLayoutManager::implts_determineDockingOperation(
2964 : ui::DockingArea DockingArea,
2965 : const ::Rectangle& rRowColRect,
2966 : const Point& rMousePos )
2967 : {
2968 0 : const sal_Int32 nHorzVerticalRegionSize = 6;
2969 0 : const sal_Int32 nHorzVerticalMoveRegion = 4;
2970 :
2971 0 : if ( rRowColRect.IsInside( rMousePos ))
2972 : {
2973 0 : if ( isHorizontalDockingArea( DockingArea ))
2974 : {
2975 0 : sal_Int32 nRegion = rRowColRect.getHeight() / nHorzVerticalRegionSize;
2976 0 : sal_Int32 nPosY = rRowColRect.Top() + nRegion;
2977 :
2978 0 : if ( rMousePos.Y() < nPosY )
2979 0 : return ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW;
2980 0 : else if ( rMousePos.Y() < ( nPosY + nRegion*nHorzVerticalMoveRegion ))
2981 0 : return DOCKOP_ON_COLROW;
2982 : else
2983 0 : return ( DockingArea == ui::DockingArea_DOCKINGAREA_TOP ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW;
2984 : }
2985 : else
2986 : {
2987 0 : sal_Int32 nRegion = rRowColRect.getWidth() / nHorzVerticalRegionSize;
2988 0 : sal_Int32 nPosX = rRowColRect.Left() + nRegion;
2989 :
2990 0 : if ( rMousePos.X() < nPosX )
2991 0 : return ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_BEFORE_COLROW : DOCKOP_AFTER_COLROW;
2992 0 : else if ( rMousePos.X() < ( nPosX + nRegion*nHorzVerticalMoveRegion ))
2993 0 : return DOCKOP_ON_COLROW;
2994 : else
2995 0 : return ( DockingArea == ui::DockingArea_DOCKINGAREA_LEFT ) ? DOCKOP_AFTER_COLROW : DOCKOP_BEFORE_COLROW;
2996 : }
2997 : }
2998 : else
2999 0 : return DOCKOP_ON_COLROW;
3000 : }
3001 :
3002 0 : ::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 )
3009 : {
3010 0 : SolarMutexResettableGuard aReadGuard;
3011 0 : ::Rectangle aDockingAreaOffsets( m_aDockingAreaOffsets );
3012 0 : aReadGuard.clear();
3013 :
3014 0 : bool bHorizontalDockArea( isHorizontalDockingArea( eDockingArea ));
3015 :
3016 0 : sal_Int32 nTopDockingAreaSize( implts_getTopBottomDockingAreaSizes().Width() );
3017 0 : sal_Int32 nBottomDockingAreaSize( implts_getTopBottomDockingAreaSizes().Height() );
3018 :
3019 0 : sal_Int32 nMaxLeftRightDockAreaSize = rContainerWinSize.Height() -
3020 : nTopDockingAreaSize -
3021 : nBottomDockingAreaSize -
3022 0 : aDockingAreaOffsets.Top() -
3023 0 : aDockingAreaOffsets.Bottom();
3024 :
3025 0 : ::Rectangle aTrackingRect( rTrackingRect );
3026 0 : if ( bHorizontalDockArea )
3027 : {
3028 0 : sal_Int32 nPosX( std::max( sal_Int32( rTrackingRect.Left()), sal_Int32( 0 )));
3029 0 : if (( nPosX + rTrackingRect.getWidth()) > rContainerWinSize.Width() )
3030 : nPosX = std::min( nPosX,
3031 0 : std::max( sal_Int32( rContainerWinSize.Width() - rTrackingRect.getWidth() ),
3032 0 : sal_Int32( 0 )));
3033 :
3034 0 : sal_Int32 nSize = std::min( rContainerWinSize.Width(), rTrackingRect.getWidth() );
3035 :
3036 0 : aTrackingRect.SetPos( ::Point( nPosX, rRowColumnRect.Top() ));
3037 0 : aTrackingRect.setWidth( nSize );
3038 0 : aTrackingRect.setHeight( rRowColumnRect.getHeight() );
3039 :
3040 : // Set virtual position
3041 0 : rUIElement.m_aDockedData.m_aPos.X = nPosX;
3042 0 : rUIElement.m_aDockedData.m_aPos.Y = nRowCol;
3043 : }
3044 : else
3045 : {
3046 : sal_Int32 nMaxDockingAreaHeight = std::max( sal_Int32( 0 ),
3047 0 : sal_Int32( nMaxLeftRightDockAreaSize ));
3048 :
3049 0 : sal_Int32 nPosY( std::max( sal_Int32( aTrackingRect.Top()), sal_Int32( nTopDockingAreaSize )));
3050 0 : if (( nPosY + aTrackingRect.getHeight()) > ( nTopDockingAreaSize + nMaxDockingAreaHeight ))
3051 : nPosY = std::min( nPosY,
3052 0 : std::max( sal_Int32( nTopDockingAreaSize + ( nMaxDockingAreaHeight - aTrackingRect.getHeight() )),
3053 0 : sal_Int32( nTopDockingAreaSize )));
3054 :
3055 0 : sal_Int32 nSize = std::min( nMaxDockingAreaHeight, static_cast<sal_Int32>(aTrackingRect.getHeight()) );
3056 :
3057 0 : aTrackingRect.SetPos( ::Point( rRowColumnRect.Left(), nPosY ));
3058 0 : aTrackingRect.setWidth( rRowColumnRect.getWidth() );
3059 0 : aTrackingRect.setHeight( nSize );
3060 :
3061 0 : aReadGuard.reset();
3062 0 : uno::Reference< awt::XWindow > xDockingAreaWindow( m_xDockAreaWindows[eDockingArea] );
3063 0 : uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
3064 0 : aReadGuard.clear();
3065 :
3066 0 : sal_Int32 nDockPosY( 0 );
3067 0 : vcl::Window* pDockingAreaWindow( 0 );
3068 : {
3069 0 : SolarMutexGuard aGuard;
3070 0 : pDockingAreaWindow = VCLUnoHelper::GetWindow( xDockingAreaWindow );
3071 0 : vcl::Window* pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
3072 0 : nDockPosY = pDockingAreaWindow->ScreenToOutputPixel( pContainerWindow->OutputToScreenPixel( ::Point( 0, nPosY ))).Y();
3073 : }
3074 :
3075 : // Set virtual position
3076 0 : rUIElement.m_aDockedData.m_aPos.X = nRowCol;
3077 0 : rUIElement.m_aDockedData.m_aPos.Y = nDockPosY;
3078 : }
3079 :
3080 0 : return aTrackingRect;
3081 : }
3082 :
3083 0 : void ToolbarLayoutManager::implts_setTrackingRect( ui::DockingArea eDockingArea, const ::Point& rMousePos, ::Rectangle& rTrackingRect )
3084 : {
3085 0 : ::Point aPoint( rTrackingRect.TopLeft());
3086 0 : if ( isHorizontalDockingArea( eDockingArea ))
3087 0 : aPoint.X() = rMousePos.X();
3088 : else
3089 0 : aPoint.Y() = rMousePos.Y();
3090 0 : rTrackingRect.SetPos( aPoint );
3091 0 : }
3092 :
3093 0 : void ToolbarLayoutManager::implts_renumberRowColumnData(
3094 : ui::DockingArea eDockingArea,
3095 : DockingOperation /*eDockingOperation*/,
3096 : const UIElement& rUIElement )
3097 : {
3098 0 : SolarMutexClearableGuard aReadLock;
3099 0 : uno::Reference< container::XNameAccess > xPersistentWindowState( m_xPersistentWindowState );
3100 0 : aReadLock.clear();
3101 :
3102 0 : bool bHorzDockingArea( isHorizontalDockingArea( eDockingArea ));
3103 0 : sal_Int32 nRowCol( bHorzDockingArea ? rUIElement.m_aDockedData.m_aPos.Y : rUIElement.m_aDockedData.m_aPos.X );
3104 :
3105 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3106 0 : SolarMutexClearableGuard aWriteLock;
3107 0 : UIElementVector::iterator pIter;
3108 0 : for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); ++pIter )
3109 : {
3110 0 : if (( pIter->m_aDockedData.m_nDockedArea == sal_Int16( eDockingArea )) && ( pIter->m_aName != rUIElement.m_aName ))
3111 : {
3112 : // Don't change toolbars without a valid docking position!
3113 0 : if ( isDefaultPos( pIter->m_aDockedData.m_aPos ))
3114 0 : continue;
3115 :
3116 0 : sal_Int32 nWindowRowCol = ( bHorzDockingArea ) ? pIter->m_aDockedData.m_aPos.Y : pIter->m_aDockedData.m_aPos.X;
3117 0 : if ( nWindowRowCol >= nRowCol )
3118 : {
3119 0 : if ( bHorzDockingArea )
3120 0 : pIter->m_aDockedData.m_aPos.Y += 1;
3121 : else
3122 0 : pIter->m_aDockedData.m_aPos.X += 1;
3123 : }
3124 : }
3125 : }
3126 0 : aWriteLock.clear();
3127 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3128 :
3129 : // We have to change the persistent window state part
3130 0 : if ( xPersistentWindowState.is() )
3131 : {
3132 : try
3133 : {
3134 0 : uno::Sequence< OUString > aWindowElements = xPersistentWindowState->getElementNames();
3135 0 : for ( sal_Int32 i = 0; i < aWindowElements.getLength(); i++ )
3136 : {
3137 0 : if ( rUIElement.m_aName != aWindowElements[i] )
3138 : {
3139 : try
3140 : {
3141 0 : uno::Sequence< beans::PropertyValue > aPropValueSeq;
3142 0 : awt::Point aDockedPos;
3143 0 : ui::DockingArea nDockedArea( ui::DockingArea_DOCKINGAREA_DEFAULT );
3144 :
3145 0 : xPersistentWindowState->getByName( aWindowElements[i] ) >>= aPropValueSeq;
3146 0 : for ( sal_Int32 j = 0; j < aPropValueSeq.getLength(); j++ )
3147 : {
3148 0 : if ( aPropValueSeq[j].Name == WINDOWSTATE_PROPERTY_DOCKINGAREA )
3149 0 : aPropValueSeq[j].Value >>= nDockedArea;
3150 0 : else if ( aPropValueSeq[j].Name == WINDOWSTATE_PROPERTY_DOCKPOS )
3151 0 : aPropValueSeq[j].Value >>= aDockedPos;
3152 : }
3153 :
3154 : // Don't change toolbars without a valid docking position!
3155 0 : if ( isDefaultPos( aDockedPos ))
3156 0 : continue;
3157 :
3158 0 : sal_Int32 nWindowRowCol = ( bHorzDockingArea ) ? aDockedPos.Y : aDockedPos.X;
3159 0 : if (( nDockedArea == eDockingArea ) && ( nWindowRowCol >= nRowCol ))
3160 : {
3161 0 : if ( bHorzDockingArea )
3162 0 : aDockedPos.Y += 1;
3163 : else
3164 0 : aDockedPos.X += 1;
3165 :
3166 0 : uno::Reference< container::XNameReplace > xReplace( xPersistentWindowState, uno::UNO_QUERY );
3167 0 : xReplace->replaceByName( aWindowElements[i], makeAny( aPropValueSeq ));
3168 0 : }
3169 : }
3170 0 : catch (const uno::Exception&)
3171 : {
3172 : }
3173 : }
3174 0 : }
3175 : }
3176 0 : catch (const uno::Exception&)
3177 : {
3178 : }
3179 0 : }
3180 0 : }
3181 :
3182 : // XWindowListener
3183 :
3184 6801 : void SAL_CALL ToolbarLayoutManager::windowResized( const awt::WindowEvent& aEvent )
3185 : throw( uno::RuntimeException, std::exception )
3186 : {
3187 6801 : SolarMutexClearableGuard aWriteLock;
3188 6801 : bool bLocked( m_bDockingInProgress );
3189 6801 : bool bLayoutInProgress( m_bLayoutInProgress );
3190 6801 : aWriteLock.clear();
3191 :
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 6801 : if ( !bLocked && !bLayoutInProgress )
3197 : {
3198 0 : bool bNotify( false );
3199 0 : uno::Reference< awt::XWindow > xWindow( aEvent.Source, uno::UNO_QUERY );
3200 :
3201 0 : UIElement aUIElement = implts_findToolbar( aEvent.Source );
3202 0 : if ( aUIElement.m_xUIElement.is() )
3203 : {
3204 0 : if ( aUIElement.m_bFloating )
3205 : {
3206 0 : uno::Reference< awt::XWindow2 > xWindow2( xWindow, uno::UNO_QUERY );
3207 :
3208 0 : if( xWindow2.is() )
3209 : {
3210 0 : awt::Rectangle aPos = xWindow2->getPosSize();
3211 0 : awt::Size aSize = xWindow2->getOutputSize(); // always use output size for consistency
3212 0 : bool bVisible = xWindow2->isVisible();
3213 :
3214 : // update element data
3215 0 : aUIElement.m_aFloatingData.m_aPos = awt::Point(aPos.X, aPos.Y);
3216 0 : aUIElement.m_aFloatingData.m_aSize = aSize;
3217 0 : aUIElement.m_bVisible = bVisible;
3218 : }
3219 :
3220 0 : implts_writeWindowStateData( aUIElement );
3221 : }
3222 : else
3223 : {
3224 0 : implts_setLayoutDirty();
3225 0 : bNotify = true;
3226 : }
3227 : }
3228 :
3229 0 : if ( bNotify )
3230 0 : m_pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
3231 6801 : }
3232 6801 : }
3233 :
3234 6707 : void SAL_CALL ToolbarLayoutManager::windowMoved( const awt::WindowEvent& /*aEvent*/ )
3235 : throw( uno::RuntimeException, std::exception )
3236 : {
3237 6707 : }
3238 :
3239 8299 : void SAL_CALL ToolbarLayoutManager::windowShown( const lang::EventObject& /*aEvent*/ )
3240 : throw( uno::RuntimeException, std::exception )
3241 : {
3242 8299 : }
3243 :
3244 6669 : void SAL_CALL ToolbarLayoutManager::windowHidden( const lang::EventObject& /*aEvent*/ )
3245 : throw( uno::RuntimeException, std::exception )
3246 : {
3247 6669 : }
3248 :
3249 : // XDockableWindowListener
3250 :
3251 0 : void SAL_CALL ToolbarLayoutManager::startDocking( const awt::DockingEvent& e )
3252 : throw (uno::RuntimeException, std::exception)
3253 : {
3254 0 : bool bWinFound( false );
3255 :
3256 0 : SolarMutexClearableGuard aReadGuard;
3257 0 : uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
3258 0 : uno::Reference< awt::XWindow2 > xWindow( e.Source, uno::UNO_QUERY );
3259 0 : aReadGuard.clear();
3260 :
3261 0 : vcl::Window* pContainerWindow( 0 );
3262 0 : ::Point aMousePos;
3263 : {
3264 0 : SolarMutexGuard aGuard;
3265 0 : pContainerWindow = VCLUnoHelper::GetWindow( xContainerWindow );
3266 0 : aMousePos = pContainerWindow->ScreenToOutputPixel( ::Point( e.MousePos.X, e.MousePos.Y ));
3267 : }
3268 :
3269 0 : UIElement aUIElement = implts_findToolbar( e.Source );
3270 :
3271 0 : if ( aUIElement.m_xUIElement.is() && xWindow.is() )
3272 : {
3273 0 : awt::Rectangle aRect;
3274 :
3275 0 : bWinFound = true;
3276 0 : uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
3277 0 : if ( xDockWindow->isFloating() )
3278 : {
3279 0 : awt::Rectangle aPos = xWindow->getPosSize();
3280 0 : awt::Size aSize = xWindow->getOutputSize();
3281 :
3282 0 : aUIElement.m_aFloatingData.m_aPos = awt::Point(aPos.X, aPos.Y);
3283 0 : aUIElement.m_aFloatingData.m_aSize = aSize;
3284 :
3285 0 : SolarMutexGuard aGuard;
3286 :
3287 0 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
3288 0 : if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
3289 : {
3290 0 : ToolBox* pToolBox = static_cast<ToolBox *>(pWindow);
3291 0 : aUIElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines();
3292 0 : aUIElement.m_aFloatingData.m_bIsHorizontal = isToolboxHorizontalAligned( pToolBox );
3293 0 : }
3294 0 : }
3295 : }
3296 :
3297 0 : SolarMutexGuard g;
3298 0 : m_bDockingInProgress = bWinFound;
3299 0 : m_aDockUIElement = aUIElement;
3300 0 : m_aDockUIElement.m_bUserActive = true;
3301 0 : m_aStartDockMousePos = aMousePos;
3302 0 : }
3303 :
3304 0 : awt::DockingData SAL_CALL ToolbarLayoutManager::docking( const awt::DockingEvent& e )
3305 : throw (uno::RuntimeException, std::exception)
3306 : {
3307 0 : const sal_Int32 MAGNETIC_DISTANCE_UNDOCK = 25;
3308 0 : const sal_Int32 MAGNETIC_DISTANCE_DOCK = 20;
3309 :
3310 0 : SolarMutexClearableGuard aReadLock;
3311 0 : awt::DockingData aDockingData;
3312 0 : uno::Reference< awt::XDockableWindow > xDockWindow( e.Source, uno::UNO_QUERY );
3313 0 : uno::Reference< awt::XWindow > xWindow( e.Source, uno::UNO_QUERY );
3314 0 : uno::Reference< awt::XWindow > xTopDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_TOP] );
3315 0 : uno::Reference< awt::XWindow > xLeftDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_LEFT] );
3316 0 : uno::Reference< awt::XWindow > xRightDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_RIGHT] );
3317 0 : uno::Reference< awt::XWindow > xBottomDockingWindow( m_xDockAreaWindows[ui::DockingArea_DOCKINGAREA_BOTTOM] );
3318 0 : uno::Reference< awt::XWindow2 > xContainerWindow( m_xContainerWindow );
3319 0 : UIElement aUIDockingElement( m_aDockUIElement );
3320 :
3321 0 : DockingOperation eDockingOperation( DOCKOP_ON_COLROW );
3322 0 : bool bDockingInProgress( m_bDockingInProgress );
3323 0 : aReadLock.clear();
3324 :
3325 0 : if ( bDockingInProgress )
3326 0 : aDockingData.TrackingRectangle = e.TrackingRectangle;
3327 :
3328 0 : if ( bDockingInProgress && xDockWindow.is() && xWindow.is() )
3329 : {
3330 : try
3331 : {
3332 0 : SolarMutexGuard aGuard;
3333 :
3334 0 : sal_Int16 eDockingArea( -1 ); // none
3335 0 : sal_Int32 nMagneticZone( aUIDockingElement.m_bFloating ? MAGNETIC_DISTANCE_DOCK : MAGNETIC_DISTANCE_UNDOCK );
3336 0 : awt::Rectangle aNewTrackingRect;
3337 : ::Rectangle aTrackingRect( e.TrackingRectangle.X, e.TrackingRectangle.Y,
3338 0 : ( e.TrackingRectangle.X + e.TrackingRectangle.Width ),
3339 0 : ( e.TrackingRectangle.Y + e.TrackingRectangle.Height ));
3340 :
3341 0 : awt::Rectangle aTmpRect = xTopDockingWindow->getPosSize();
3342 0 : ::Rectangle aTopDockRect( aTmpRect.X, aTmpRect.Y, aTmpRect.Width, aTmpRect.Height );
3343 0 : ::Rectangle aHotZoneTopDockRect( implts_calcHotZoneRect( aTopDockRect, nMagneticZone ));
3344 :
3345 0 : aTmpRect = xBottomDockingWindow->getPosSize();
3346 0 : ::Rectangle aBottomDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width), ( aTmpRect.Y + aTmpRect.Height ));
3347 0 : ::Rectangle aHotZoneBottomDockRect( implts_calcHotZoneRect( aBottomDockRect, nMagneticZone ));
3348 :
3349 0 : aTmpRect = xLeftDockingWindow->getPosSize();
3350 0 : ::Rectangle aLeftDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height ));
3351 0 : ::Rectangle aHotZoneLeftDockRect( implts_calcHotZoneRect( aLeftDockRect, nMagneticZone ));
3352 :
3353 0 : aTmpRect = xRightDockingWindow->getPosSize();
3354 0 : ::Rectangle aRightDockRect( aTmpRect.X, aTmpRect.Y, ( aTmpRect.X + aTmpRect.Width ), ( aTmpRect.Y + aTmpRect.Height ));
3355 0 : ::Rectangle aHotZoneRightDockRect( implts_calcHotZoneRect( aRightDockRect, nMagneticZone ));
3356 :
3357 0 : vcl::Window* pContainerWindow( VCLUnoHelper::GetWindow( xContainerWindow ) );
3358 0 : ::Point aMousePos( pContainerWindow->ScreenToOutputPixel( ::Point( e.MousePos.X, e.MousePos.Y )));
3359 :
3360 0 : if ( aHotZoneTopDockRect.IsInside( aMousePos ))
3361 0 : eDockingArea = ui::DockingArea_DOCKINGAREA_TOP;
3362 0 : else if ( aHotZoneBottomDockRect.IsInside( aMousePos ))
3363 0 : eDockingArea = ui::DockingArea_DOCKINGAREA_BOTTOM;
3364 0 : else if ( aHotZoneLeftDockRect.IsInside( aMousePos ))
3365 0 : eDockingArea = ui::DockingArea_DOCKINGAREA_LEFT;
3366 0 : else if ( aHotZoneRightDockRect.IsInside( aMousePos ))
3367 0 : eDockingArea = ui::DockingArea_DOCKINGAREA_RIGHT;
3368 :
3369 : // Higher priority for movements inside the real docking area
3370 0 : if ( aTopDockRect.IsInside( aMousePos ))
3371 0 : eDockingArea = ui::DockingArea_DOCKINGAREA_TOP;
3372 0 : else if ( aBottomDockRect.IsInside( aMousePos ))
3373 0 : eDockingArea = ui::DockingArea_DOCKINGAREA_BOTTOM;
3374 0 : else if ( aLeftDockRect.IsInside( aMousePos ))
3375 0 : eDockingArea = ui::DockingArea_DOCKINGAREA_LEFT;
3376 0 : else if ( aRightDockRect.IsInside( aMousePos ))
3377 0 : eDockingArea = ui::DockingArea_DOCKINGAREA_RIGHT;
3378 :
3379 : // Determine if we have a toolbar and set alignment according to the docking area!
3380 0 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
3381 0 : ToolBox* pToolBox = 0;
3382 0 : if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
3383 0 : pToolBox = static_cast<ToolBox *>(pWindow);
3384 :
3385 0 : if ( eDockingArea != -1 )
3386 : {
3387 0 : if ( eDockingArea == ui::DockingArea_DOCKINGAREA_TOP )
3388 : {
3389 0 : aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_TOP;
3390 0 : aUIDockingElement.m_bFloating = false;
3391 : }
3392 0 : else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_BOTTOM )
3393 : {
3394 0 : aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_BOTTOM;
3395 0 : aUIDockingElement.m_bFloating = false;
3396 : }
3397 0 : else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_LEFT )
3398 : {
3399 0 : aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_LEFT;
3400 0 : aUIDockingElement.m_bFloating = false;
3401 : }
3402 0 : else if ( eDockingArea == ui::DockingArea_DOCKINGAREA_RIGHT )
3403 : {
3404 0 : aUIDockingElement.m_aDockedData.m_nDockedArea = ui::DockingArea_DOCKINGAREA_RIGHT;
3405 0 : aUIDockingElement.m_bFloating = false;
3406 : }
3407 :
3408 0 : ::Point aOutputPos = pContainerWindow->ScreenToOutputPixel( aTrackingRect.TopLeft() );
3409 0 : aTrackingRect.SetPos( aOutputPos );
3410 :
3411 0 : ::Rectangle aNewDockingRect( aTrackingRect );
3412 :
3413 0 : implts_calcDockingPosSize( aUIDockingElement, eDockingOperation, aNewDockingRect, aMousePos );
3414 :
3415 0 : ::Point aScreenPos = pContainerWindow->OutputToScreenPixel( aNewDockingRect.TopLeft() );
3416 0 : aNewTrackingRect = awt::Rectangle( aScreenPos.X(), aScreenPos.Y(),
3417 0 : aNewDockingRect.getWidth(), aNewDockingRect.getHeight() );
3418 0 : aDockingData.TrackingRectangle = aNewTrackingRect;
3419 : }
3420 0 : else if ( pToolBox && bDockingInProgress )
3421 : {
3422 0 : bool bIsHorizontal = isToolboxHorizontalAligned( pToolBox );
3423 0 : awt::Size aFloatSize = aUIDockingElement.m_aFloatingData.m_aSize;
3424 0 : if ( aFloatSize.Width > 0 && aFloatSize.Height > 0 )
3425 : {
3426 0 : aUIDockingElement.m_aFloatingData.m_aPos = AWTPoint(pContainerWindow->ScreenToOutputPixel(VCLPoint(e.MousePos)));
3427 0 : aDockingData.TrackingRectangle.Height = aFloatSize.Height;
3428 0 : aDockingData.TrackingRectangle.Width = aFloatSize.Width;
3429 : }
3430 : else
3431 : {
3432 0 : aFloatSize = AWTSize(pToolBox->CalcWindowSizePixel());
3433 0 : if ( !bIsHorizontal )
3434 : {
3435 : // Floating toolbars are always horizontal aligned! We have to swap
3436 : // width/height if we have a vertical aligned toolbar.
3437 0 : sal_Int32 nTemp = aFloatSize.Height;
3438 0 : aFloatSize.Height = aFloatSize.Width;
3439 0 : aFloatSize.Width = nTemp;
3440 : }
3441 :
3442 0 : aDockingData.TrackingRectangle.Height = aFloatSize.Height;
3443 0 : aDockingData.TrackingRectangle.Width = aFloatSize.Width;
3444 :
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 0 : aUIDockingElement.m_aFloatingData.m_aPos = AWTPoint(pContainerWindow->ScreenToOutputPixel(VCLPoint(e.MousePos)));
3448 0 : aUIDockingElement.m_aFloatingData.m_aSize = aFloatSize;
3449 0 : aUIDockingElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines();
3450 0 : aUIDockingElement.m_aFloatingData.m_bIsHorizontal = isToolboxHorizontalAligned( pToolBox );
3451 : }
3452 0 : aDockingData.TrackingRectangle.X = e.MousePos.X;
3453 0 : aDockingData.TrackingRectangle.Y = e.MousePos.Y;
3454 : }
3455 :
3456 0 : aDockingData.bFloating = ( eDockingArea == -1 );
3457 :
3458 : // Write current data to the member docking progress data
3459 0 : SolarMutexGuard g;
3460 0 : m_aDockUIElement.m_bFloating = aDockingData.bFloating;
3461 0 : if ( !aDockingData.bFloating )
3462 : {
3463 0 : m_aDockUIElement.m_aDockedData = aUIDockingElement.m_aDockedData;
3464 :
3465 0 : m_eDockOperation = eDockingOperation;
3466 : }
3467 : else
3468 0 : m_aDockUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData;
3469 : }
3470 0 : catch (const uno::Exception&)
3471 : {
3472 : }
3473 : }
3474 :
3475 0 : return aDockingData;
3476 : }
3477 :
3478 0 : void SAL_CALL ToolbarLayoutManager::endDocking( const awt::EndDockingEvent& e )
3479 : throw (uno::RuntimeException, std::exception)
3480 : {
3481 0 : bool bDockingInProgress( false );
3482 0 : bool bStartDockFloated( false );
3483 0 : bool bFloating( false );
3484 0 : UIElement aUIDockingElement;
3485 :
3486 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3487 0 : SolarMutexResettableGuard aWriteLock;
3488 0 : bDockingInProgress = m_bDockingInProgress;
3489 0 : aUIDockingElement = m_aDockUIElement;
3490 0 : bFloating = aUIDockingElement.m_bFloating;
3491 :
3492 0 : UIElement& rUIElement = impl_findToolbar( aUIDockingElement.m_aName );
3493 0 : if ( rUIElement.m_aName == aUIDockingElement.m_aName )
3494 : {
3495 0 : if ( aUIDockingElement.m_bFloating )
3496 : {
3497 : // Write last position into position data
3498 0 : uno::Reference< awt::XWindow > xWindow( aUIDockingElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
3499 0 : rUIElement.m_aFloatingData = aUIDockingElement.m_aFloatingData;
3500 0 : awt::Rectangle aTmpRect = xWindow->getPosSize();
3501 0 : 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 0 : aUIDockingElement.m_aFloatingData = rUIElement.m_aFloatingData;
3504 : }
3505 : else
3506 : {
3507 0 : rUIElement.m_aDockedData = aUIDockingElement.m_aDockedData;
3508 0 : rUIElement.m_aFloatingData.m_aSize = aUIDockingElement.m_aFloatingData.m_aSize;
3509 :
3510 0 : if ( m_eDockOperation != DOCKOP_ON_COLROW )
3511 : {
3512 : // we have to renumber our row/column data to insert a new row/column
3513 0 : implts_renumberRowColumnData((ui::DockingArea)aUIDockingElement.m_aDockedData.m_nDockedArea, m_eDockOperation, aUIDockingElement );
3514 : }
3515 : }
3516 :
3517 0 : bStartDockFloated = rUIElement.m_bFloating;
3518 0 : rUIElement.m_bFloating = m_aDockUIElement.m_bFloating;
3519 0 : rUIElement.m_bUserActive = true;
3520 : }
3521 :
3522 : // reset member for next docking operation
3523 0 : m_aDockUIElement.m_xUIElement.clear();
3524 0 : m_eDockOperation = DOCKOP_ON_COLROW;
3525 0 : aWriteLock.clear();
3526 : /* SAFE AREA ----------------------------------------------------------------------------------------------- */
3527 :
3528 0 : implts_writeWindowStateData( aUIDockingElement );
3529 :
3530 0 : if ( bDockingInProgress )
3531 : {
3532 0 : SolarMutexGuard aGuard;
3533 0 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( uno::Reference< awt::XWindow >( e.Source, uno::UNO_QUERY ));
3534 0 : ToolBox* pToolBox = 0;
3535 0 : if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
3536 0 : pToolBox = static_cast<ToolBox *>(pWindow);
3537 :
3538 0 : if ( pToolBox )
3539 : {
3540 0 : if( e.bFloating )
3541 : {
3542 0 : if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal )
3543 0 : pToolBox->SetAlign( WINDOWALIGN_TOP );
3544 : else
3545 0 : pToolBox->SetAlign( WINDOWALIGN_LEFT );
3546 : }
3547 : else
3548 : {
3549 0 : ::Size aSize;
3550 :
3551 0 : pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) );
3552 :
3553 : // Docked toolbars have always one line
3554 0 : aSize = pToolBox->CalcWindowSizePixel( 1 );
3555 :
3556 : // Lock layouting updates as our listener would be called due to SetSizePixel
3557 0 : pToolBox->SetOutputSizePixel( aSize );
3558 : }
3559 0 : }
3560 : }
3561 :
3562 0 : implts_sortUIElements();
3563 :
3564 0 : aWriteLock.reset();
3565 0 : m_bDockingInProgress = false;
3566 0 : m_bLayoutDirty = !bStartDockFloated || !bFloating;
3567 0 : bool bNotify = m_bLayoutDirty;
3568 0 : aWriteLock.clear();
3569 :
3570 0 : if ( bNotify )
3571 0 : m_pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
3572 0 : }
3573 :
3574 0 : sal_Bool SAL_CALL ToolbarLayoutManager::prepareToggleFloatingMode( const lang::EventObject& e )
3575 : throw (uno::RuntimeException, std::exception)
3576 : {
3577 0 : SolarMutexClearableGuard aReadLock;
3578 0 : bool bDockingInProgress = m_bDockingInProgress;
3579 0 : aReadLock.clear();
3580 :
3581 0 : UIElement aUIDockingElement = implts_findToolbar( e.Source );
3582 0 : bool bWinFound( !aUIDockingElement.m_aName.isEmpty() );
3583 0 : uno::Reference< awt::XWindow > xWindow( e.Source, uno::UNO_QUERY );
3584 :
3585 0 : if ( bWinFound && xWindow.is() )
3586 : {
3587 0 : if ( !bDockingInProgress )
3588 : {
3589 0 : awt::Rectangle aRect;
3590 0 : uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
3591 0 : if ( xDockWindow->isFloating() )
3592 : {
3593 : {
3594 0 : SolarMutexGuard aGuard;
3595 0 : vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
3596 0 : if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
3597 : {
3598 0 : ToolBox* pToolBox = static_cast< ToolBox *>( pWindow );
3599 0 : aUIDockingElement.m_aFloatingData.m_aPos = AWTPoint(pToolBox->GetPosPixel());
3600 0 : aUIDockingElement.m_aFloatingData.m_aSize = AWTSize(pToolBox->GetOutputSizePixel());
3601 0 : aUIDockingElement.m_aFloatingData.m_nLines = pToolBox->GetFloatingLines();
3602 0 : aUIDockingElement.m_aFloatingData.m_bIsHorizontal = isToolboxHorizontalAligned( pToolBox );
3603 0 : }
3604 : }
3605 :
3606 0 : UIElement aUIElement = implts_findToolbar( aUIDockingElement.m_aName );
3607 0 : if ( aUIElement.m_aName == aUIDockingElement.m_aName )
3608 0 : implts_setToolbar( aUIDockingElement );
3609 0 : }
3610 : }
3611 : }
3612 :
3613 0 : return sal_True;
3614 : }
3615 :
3616 0 : void SAL_CALL ToolbarLayoutManager::toggleFloatingMode( const lang::EventObject& e )
3617 : throw (uno::RuntimeException, std::exception)
3618 : {
3619 0 : UIElement aUIDockingElement;
3620 :
3621 0 : SolarMutexResettableGuard aReadLock;
3622 0 : bool bDockingInProgress( m_bDockingInProgress );
3623 0 : if ( bDockingInProgress )
3624 0 : aUIDockingElement = m_aDockUIElement;
3625 0 : aReadLock.clear();
3626 :
3627 0 : vcl::Window* pWindow( 0 );
3628 0 : ToolBox* pToolBox( 0 );
3629 0 : uno::Reference< awt::XWindow2 > xWindow;
3630 :
3631 : {
3632 0 : SolarMutexGuard aGuard;
3633 0 : xWindow = uno::Reference< awt::XWindow2 >( e.Source, uno::UNO_QUERY );
3634 0 : pWindow = VCLUnoHelper::GetWindow( xWindow );
3635 :
3636 0 : if ( pWindow && pWindow->GetType() == WINDOW_TOOLBOX )
3637 0 : pToolBox = static_cast<ToolBox *>(pWindow);
3638 : }
3639 :
3640 0 : if ( !bDockingInProgress )
3641 : {
3642 0 : aUIDockingElement = implts_findToolbar( e.Source );
3643 0 : bool bWinFound = ( !aUIDockingElement.m_aName.isEmpty() );
3644 :
3645 0 : if ( bWinFound && xWindow.is() )
3646 : {
3647 0 : aUIDockingElement.m_bFloating = !aUIDockingElement.m_bFloating;
3648 0 : aUIDockingElement.m_bUserActive = true;
3649 :
3650 0 : implts_setLayoutInProgress( true );
3651 0 : if ( aUIDockingElement.m_bFloating )
3652 : {
3653 0 : SolarMutexGuard aGuard;
3654 0 : if ( pToolBox )
3655 : {
3656 0 : pToolBox->SetLineCount( aUIDockingElement.m_aFloatingData.m_nLines );
3657 0 : if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal )
3658 0 : pToolBox->SetAlign( WINDOWALIGN_TOP );
3659 : else
3660 0 : pToolBox->SetAlign( WINDOWALIGN_LEFT );
3661 : }
3662 :
3663 0 : bool bUndefPos = hasDefaultPosValue( aUIDockingElement.m_aFloatingData.m_aPos );
3664 0 : bool bSetSize = !hasEmptySize( aUIDockingElement.m_aFloatingData.m_aSize );
3665 :
3666 0 : if ( bUndefPos )
3667 0 : aUIDockingElement.m_aFloatingData.m_aPos = implts_findNextCascadeFloatingPos();
3668 :
3669 0 : if ( !bSetSize )
3670 : {
3671 0 : if ( pToolBox )
3672 0 : aUIDockingElement.m_aFloatingData.m_aSize = AWTSize(pToolBox->CalcFloatingWindowSizePixel());
3673 0 : else if ( pWindow )
3674 0 : aUIDockingElement.m_aFloatingData.m_aSize = AWTSize(pWindow->GetOutputSizePixel());
3675 : }
3676 :
3677 0 : xWindow->setPosSize( aUIDockingElement.m_aFloatingData.m_aPos.X,
3678 : aUIDockingElement.m_aFloatingData.m_aPos.Y,
3679 0 : 0, 0, awt::PosSize::POS );
3680 0 : xWindow->setOutputSize(aUIDockingElement.m_aFloatingData.m_aSize);
3681 : }
3682 : else
3683 : {
3684 0 : if ( isDefaultPos( aUIDockingElement.m_aDockedData.m_aPos ))
3685 : {
3686 : // Docking on its default position without a preset position -
3687 : // we have to find a good place for it.
3688 0 : ::Point aPixelPos;
3689 0 : awt::Point aDockPos;
3690 0 : ::Size aSize;
3691 :
3692 : {
3693 0 : SolarMutexGuard aGuard;
3694 0 : if ( pToolBox )
3695 0 : aSize = pToolBox->CalcWindowSizePixel( 1, ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea ) );
3696 0 : else if ( pWindow )
3697 0 : aSize = pWindow->GetSizePixel();
3698 : }
3699 :
3700 0 : implts_findNextDockingPos((ui::DockingArea)aUIDockingElement.m_aDockedData.m_nDockedArea, aSize, aDockPos, aPixelPos );
3701 0 : aUIDockingElement.m_aDockedData.m_aPos = aDockPos;
3702 : }
3703 :
3704 0 : SolarMutexGuard aGuard;
3705 0 : if ( pToolBox )
3706 : {
3707 0 : pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) );
3708 0 : ::Size aSize = pToolBox->CalcWindowSizePixel( 1 );
3709 0 : awt::Rectangle aRect = xWindow->getPosSize();
3710 0 : xWindow->setPosSize( aRect.X, aRect.Y, 0, 0, awt::PosSize::POS );
3711 0 : xWindow->setOutputSize( AWTSize( aSize ) );
3712 0 : }
3713 : }
3714 :
3715 0 : implts_setLayoutInProgress( false );
3716 0 : implts_setToolbar( aUIDockingElement );
3717 0 : implts_writeWindowStateData( aUIDockingElement );
3718 0 : implts_sortUIElements();
3719 0 : implts_setLayoutDirty();
3720 :
3721 0 : aReadLock.reset();
3722 0 : ILayoutNotifications* pParentLayouter( m_pParentLayouter );
3723 0 : aReadLock.clear();
3724 :
3725 0 : if ( pParentLayouter )
3726 0 : pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
3727 : }
3728 : }
3729 : else
3730 : {
3731 0 : SolarMutexGuard aGuard;
3732 0 : if ( pToolBox )
3733 : {
3734 0 : if ( aUIDockingElement.m_bFloating )
3735 : {
3736 0 : if ( aUIDockingElement.m_aFloatingData.m_bIsHorizontal )
3737 0 : pToolBox->SetAlign( WINDOWALIGN_TOP );
3738 : else
3739 0 : pToolBox->SetAlign( WINDOWALIGN_LEFT );
3740 : }
3741 : else
3742 0 : pToolBox->SetAlign( ImplConvertAlignment( aUIDockingElement.m_aDockedData.m_nDockedArea) );
3743 0 : }
3744 0 : }
3745 0 : }
3746 :
3747 0 : void SAL_CALL ToolbarLayoutManager::closed( const lang::EventObject& e )
3748 : throw (uno::RuntimeException, std::exception)
3749 : {
3750 0 : OUString aName;
3751 0 : UIElement aUIElement;
3752 0 : UIElementVector::iterator pIter;
3753 :
3754 0 : SolarMutexClearableGuard aWriteLock;
3755 0 : for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); ++pIter )
3756 : {
3757 0 : uno::Reference< ui::XUIElement > xUIElement( pIter->m_xUIElement );
3758 0 : if ( xUIElement.is() )
3759 : {
3760 0 : uno::Reference< uno::XInterface > xIfac( xUIElement->getRealInterface(), uno::UNO_QUERY );
3761 0 : if ( xIfac == e.Source )
3762 : {
3763 0 : aName = pIter->m_aName;
3764 :
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 0 : if ( !pIter->m_bContextSensitive )
3769 0 : pIter->m_bVisible = false;
3770 :
3771 0 : aUIElement = *pIter;
3772 0 : break;
3773 0 : }
3774 : }
3775 0 : }
3776 0 : aWriteLock.clear();
3777 :
3778 : // destroy element
3779 0 : if ( !aName.isEmpty() )
3780 : {
3781 0 : implts_writeWindowStateData( aUIElement );
3782 0 : destroyToolbar( aName );
3783 :
3784 0 : SolarMutexClearableGuard aReadLock;
3785 0 : bool bLayoutDirty = m_bLayoutDirty;
3786 0 : ILayoutNotifications* pParentLayouter( m_pParentLayouter );
3787 0 : aWriteLock.clear();
3788 :
3789 0 : if ( bLayoutDirty && pParentLayouter )
3790 0 : pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
3791 0 : }
3792 0 : }
3793 :
3794 0 : void SAL_CALL ToolbarLayoutManager::endPopupMode( const awt::EndPopupModeEvent& /*e*/ )
3795 : throw (uno::RuntimeException, std::exception)
3796 : {
3797 0 : }
3798 :
3799 : // XUIConfigurationListener
3800 :
3801 0 : void SAL_CALL ToolbarLayoutManager::elementInserted( const ui::ConfigurationEvent& rEvent )
3802 : throw (uno::RuntimeException, std::exception)
3803 : {
3804 0 : UIElement aUIElement = implts_findToolbar( rEvent.ResourceURL );
3805 :
3806 0 : uno::Reference< ui::XUIElementSettings > xElementSettings( aUIElement.m_xUIElement, uno::UNO_QUERY );
3807 0 : if ( xElementSettings.is() )
3808 : {
3809 0 : OUString aConfigSourcePropName( "ConfigurationSource" );
3810 0 : uno::Reference< beans::XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY );
3811 0 : if ( xPropSet.is() )
3812 : {
3813 0 : if ( rEvent.Source == uno::Reference< uno::XInterface >( m_xDocCfgMgr, uno::UNO_QUERY ))
3814 0 : xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( m_xDocCfgMgr ));
3815 : }
3816 0 : xElementSettings->updateSettings();
3817 : }
3818 : else
3819 : {
3820 0 : OUString aElementType;
3821 0 : OUString aElementName;
3822 0 : parseResourceURL( rEvent.ResourceURL, aElementType, aElementName );
3823 0 : if ( aElementName.indexOf( "custom_" ) != -1 )
3824 : {
3825 : // custom toolbar must be directly created, shown and layouted!
3826 0 : createToolbar( rEvent.ResourceURL );
3827 0 : uno::Reference< ui::XUIElement > xUIElement = getToolbar( rEvent.ResourceURL );
3828 0 : if ( xUIElement.is() )
3829 : {
3830 0 : OUString aUIName;
3831 0 : uno::Reference< ui::XUIConfigurationManager > xCfgMgr;
3832 0 : uno::Reference< beans::XPropertySet > xPropSet;
3833 :
3834 : try
3835 : {
3836 0 : xCfgMgr = uno::Reference< ui::XUIConfigurationManager >( rEvent.Source, uno::UNO_QUERY );
3837 0 : xPropSet = uno::Reference< beans::XPropertySet >( xCfgMgr->getSettings( rEvent.ResourceURL, sal_False ), uno::UNO_QUERY );
3838 :
3839 0 : if ( xPropSet.is() )
3840 0 : xPropSet->getPropertyValue("UIName") >>= aUIName;
3841 : }
3842 0 : catch (const container::NoSuchElementException&)
3843 : {
3844 : }
3845 0 : catch (const beans::UnknownPropertyException&)
3846 : {
3847 : }
3848 0 : catch (const lang::WrappedTargetException&)
3849 : {
3850 : }
3851 :
3852 : {
3853 0 : SolarMutexGuard aGuard;
3854 0 : vcl::Window* pWindow = getWindowFromXUIElement( xUIElement );
3855 0 : if ( pWindow )
3856 0 : pWindow->SetText( aUIName );
3857 : }
3858 :
3859 0 : showToolbar( rEvent.ResourceURL );
3860 0 : }
3861 0 : }
3862 0 : }
3863 0 : }
3864 :
3865 0 : void SAL_CALL ToolbarLayoutManager::elementRemoved( const ui::ConfigurationEvent& rEvent )
3866 : throw (uno::RuntimeException, std::exception)
3867 : {
3868 0 : SolarMutexClearableGuard aReadLock;
3869 0 : uno::Reference< awt::XWindow > xContainerWindow( m_xContainerWindow, uno::UNO_QUERY );
3870 0 : uno::Reference< ui::XUIConfigurationManager > xModuleCfgMgr( m_xModuleCfgMgr );
3871 0 : uno::Reference< ui::XUIConfigurationManager > xDocCfgMgr( m_xDocCfgMgr );
3872 0 : aReadLock.clear();
3873 :
3874 0 : UIElement aUIElement = implts_findToolbar( rEvent.ResourceURL );
3875 0 : uno::Reference< ui::XUIElementSettings > xElementSettings( aUIElement.m_xUIElement, uno::UNO_QUERY );
3876 0 : if ( xElementSettings.is() )
3877 : {
3878 0 : bool bNoSettings( false );
3879 0 : OUString aConfigSourcePropName( "ConfigurationSource" );
3880 0 : uno::Reference< uno::XInterface > xElementCfgMgr;
3881 0 : uno::Reference< beans::XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY );
3882 :
3883 0 : if ( xPropSet.is() )
3884 0 : xPropSet->getPropertyValue( aConfigSourcePropName ) >>= xElementCfgMgr;
3885 :
3886 0 : if ( !xElementCfgMgr.is() )
3887 0 : return;
3888 :
3889 : // Check if the same UI configuration manager has changed => check further
3890 0 : if ( rEvent.Source == xElementCfgMgr )
3891 : {
3892 : // Same UI configuration manager where our element has its settings
3893 0 : if ( rEvent.Source == uno::Reference< uno::XInterface >( xDocCfgMgr, uno::UNO_QUERY ))
3894 : {
3895 : // document settings removed
3896 0 : if ( xModuleCfgMgr->hasSettings( rEvent.ResourceURL ))
3897 : {
3898 0 : xPropSet->setPropertyValue( aConfigSourcePropName, makeAny( xModuleCfgMgr ));
3899 0 : xElementSettings->updateSettings();
3900 0 : return;
3901 : }
3902 : }
3903 :
3904 0 : bNoSettings = true;
3905 : }
3906 :
3907 : // No settings anymore, element must be destroyed
3908 0 : if ( xContainerWindow.is() && bNoSettings )
3909 0 : destroyToolbar( rEvent.ResourceURL );
3910 0 : }
3911 : }
3912 :
3913 0 : void SAL_CALL ToolbarLayoutManager::elementReplaced( const ui::ConfigurationEvent& rEvent )
3914 : throw (uno::RuntimeException, std::exception)
3915 : {
3916 0 : UIElement aUIElement = implts_findToolbar( rEvent.ResourceURL );
3917 :
3918 0 : uno::Reference< ui::XUIElementSettings > xElementSettings( aUIElement.m_xUIElement, uno::UNO_QUERY );
3919 0 : if ( xElementSettings.is() )
3920 : {
3921 0 : OUString aConfigSourcePropName( "ConfigurationSource" );
3922 0 : uno::Reference< uno::XInterface > xElementCfgMgr;
3923 0 : uno::Reference< beans::XPropertySet > xPropSet( xElementSettings, uno::UNO_QUERY );
3924 :
3925 0 : if ( xPropSet.is() )
3926 0 : xPropSet->getPropertyValue( aConfigSourcePropName ) >>= xElementCfgMgr;
3927 :
3928 0 : if ( !xElementCfgMgr.is() )
3929 0 : return;
3930 :
3931 : // Check if the same UI configuration manager has changed => update settings
3932 0 : if ( rEvent.Source == xElementCfgMgr )
3933 : {
3934 0 : xElementSettings->updateSettings();
3935 :
3936 0 : SolarMutexClearableGuard aWriteLock;
3937 0 : bool bNotify = !aUIElement.m_bFloating;
3938 0 : m_bLayoutDirty = bNotify;
3939 0 : ILayoutNotifications* pParentLayouter( m_pParentLayouter );
3940 0 : aWriteLock.clear();
3941 :
3942 0 : if ( bNotify && pParentLayouter )
3943 0 : pParentLayouter->requestLayout( ILayoutNotifications::HINT_TOOLBARSPACE_HAS_CHANGED );
3944 0 : }
3945 0 : }
3946 : }
3947 :
3948 50 : uno::Reference< ui::XUIElement > ToolbarLayoutManager::getToolbar( const OUString& aName )
3949 : {
3950 50 : return implts_findToolbar( aName ).m_xUIElement;
3951 : }
3952 :
3953 2 : uno::Sequence< uno::Reference< ui::XUIElement > > ToolbarLayoutManager::getToolbars()
3954 : {
3955 2 : uno::Sequence< uno::Reference< ui::XUIElement > > aSeq;
3956 :
3957 4 : SolarMutexGuard g;
3958 2 : if ( m_aUIElements.size() > 0 )
3959 : {
3960 1 : sal_uInt32 nCount(0);
3961 1 : UIElementVector::iterator pIter;
3962 4 : for ( pIter = m_aUIElements.begin(); pIter != m_aUIElements.end(); ++pIter )
3963 : {
3964 3 : if ( pIter->m_xUIElement.is() )
3965 : {
3966 3 : ++nCount;
3967 3 : aSeq.realloc( nCount );
3968 3 : aSeq[nCount-1] = pIter->m_xUIElement;
3969 : }
3970 : }
3971 : }
3972 :
3973 4 : return aSeq;
3974 : }
3975 :
3976 0 : bool ToolbarLayoutManager::floatToolbar( const OUString& rResourceURL )
3977 : {
3978 0 : UIElement aUIElement = implts_findToolbar( rResourceURL );
3979 0 : if ( aUIElement.m_xUIElement.is() )
3980 : {
3981 : try
3982 : {
3983 0 : uno::Reference< awt::XDockableWindow > xDockWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
3984 0 : if ( xDockWindow.is() && !xDockWindow->isFloating() )
3985 : {
3986 0 : aUIElement.m_bFloating = true;
3987 0 : implts_writeWindowStateData( aUIElement );
3988 0 : xDockWindow->setFloatingMode( true );
3989 :
3990 0 : implts_setLayoutDirty();
3991 0 : implts_setToolbar( aUIElement );
3992 0 : return true;
3993 0 : }
3994 : }
3995 0 : catch (const lang::DisposedException&)
3996 : {
3997 : }
3998 : }
3999 :
4000 0 : return false;
4001 : }
4002 :
4003 0 : bool ToolbarLayoutManager::lockToolbar( const OUString& rResourceURL )
4004 : {
4005 0 : UIElement aUIElement = implts_findToolbar( rResourceURL );
4006 0 : if ( aUIElement.m_xUIElement.is() )
4007 : {
4008 : try
4009 : {
4010 0 : uno::Reference< awt::XDockableWindow > xDockWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
4011 0 : if ( xDockWindow.is() && !xDockWindow->isFloating() && !xDockWindow->isLocked() )
4012 : {
4013 0 : aUIElement.m_aDockedData.m_bLocked = true;
4014 0 : implts_writeWindowStateData( aUIElement );
4015 0 : xDockWindow->lock();
4016 :
4017 0 : implts_setLayoutDirty();
4018 0 : implts_setToolbar( aUIElement );
4019 0 : return true;
4020 0 : }
4021 : }
4022 0 : catch (const lang::DisposedException&)
4023 : {
4024 : }
4025 : }
4026 :
4027 0 : return false;
4028 : }
4029 :
4030 0 : bool ToolbarLayoutManager::unlockToolbar( const OUString& rResourceURL )
4031 : {
4032 0 : UIElement aUIElement = implts_findToolbar( rResourceURL );
4033 0 : if ( aUIElement.m_xUIElement.is() )
4034 : {
4035 : try
4036 : {
4037 0 : uno::Reference< awt::XDockableWindow > xDockWindow( aUIElement.m_xUIElement->getRealInterface(), uno::UNO_QUERY );
4038 0 : if ( xDockWindow.is() && !xDockWindow->isFloating() && xDockWindow->isLocked() )
4039 : {
4040 0 : aUIElement.m_aDockedData.m_bLocked = false;
4041 0 : implts_writeWindowStateData( aUIElement );
4042 0 : xDockWindow->unlock();
4043 :
4044 0 : implts_setLayoutDirty();
4045 0 : implts_setToolbar( aUIElement );
4046 0 : return true;
4047 0 : }
4048 : }
4049 0 : catch (const lang::DisposedException&)
4050 : {
4051 : }
4052 : }
4053 :
4054 0 : return false;
4055 : }
4056 :
4057 820 : bool ToolbarLayoutManager::isToolbarVisible( const OUString& rResourceURL )
4058 : {
4059 820 : uno::Reference< awt::XWindow2 > xWindow2( implts_getXWindow( rResourceURL ), uno::UNO_QUERY );
4060 820 : return ( xWindow2.is() && xWindow2->isVisible() );
4061 : }
4062 :
4063 0 : bool ToolbarLayoutManager::isToolbarFloating( const OUString& rResourceURL )
4064 : {
4065 0 : uno::Reference< awt::XDockableWindow > xDockWindow( implts_getXWindow( rResourceURL ), uno::UNO_QUERY );
4066 0 : return ( xDockWindow.is() && xDockWindow->isFloating() );
4067 : }
4068 :
4069 0 : bool ToolbarLayoutManager::isToolbarDocked( const OUString& rResourceURL )
4070 : {
4071 0 : return !isToolbarFloating( rResourceURL );
4072 : }
4073 :
4074 0 : bool ToolbarLayoutManager::isToolbarLocked( const OUString& rResourceURL )
4075 : {
4076 0 : uno::Reference< awt::XDockableWindow > xDockWindow( implts_getXWindow( rResourceURL ), uno::UNO_QUERY );
4077 0 : return ( xDockWindow.is() && xDockWindow->isLocked() );
4078 : }
4079 :
4080 0 : awt::Size ToolbarLayoutManager::getToolbarSize( const OUString& rResourceURL )
4081 : {
4082 0 : vcl::Window* pWindow = implts_getWindow( rResourceURL );
4083 :
4084 0 : SolarMutexGuard aGuard;
4085 0 : if ( pWindow )
4086 : {
4087 0 : ::Size aSize = pWindow->GetSizePixel();
4088 0 : awt::Size aWinSize;
4089 0 : aWinSize.Width = aSize.Width();
4090 0 : aWinSize.Height = aSize.Height();
4091 0 : return aWinSize;
4092 : }
4093 :
4094 0 : return awt::Size();
4095 : }
4096 :
4097 0 : awt::Point ToolbarLayoutManager::getToolbarPos( const OUString& rResourceURL )
4098 : {
4099 0 : awt::Point aPos;
4100 0 : UIElement aUIElement = implts_findToolbar( rResourceURL );
4101 :
4102 0 : uno::Reference< awt::XWindow > xWindow( implts_getXWindow( rResourceURL ));
4103 0 : if ( xWindow.is() )
4104 : {
4105 0 : if ( aUIElement.m_bFloating )
4106 : {
4107 0 : awt::Rectangle aRect = xWindow->getPosSize();
4108 0 : aPos.X = aRect.X;
4109 0 : aPos.Y = aRect.Y;
4110 : }
4111 : else
4112 0 : aPos = aUIElement.m_aDockedData.m_aPos;
4113 : }
4114 :
4115 0 : return aPos;
4116 : }
4117 :
4118 0 : void ToolbarLayoutManager::setToolbarSize( const OUString& rResourceURL, const awt::Size& aSize )
4119 : {
4120 0 : uno::Reference< awt::XWindow2 > xWindow( implts_getXWindow( rResourceURL ), uno::UNO_QUERY );
4121 0 : uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
4122 0 : UIElement aUIElement = implts_findToolbar( rResourceURL );
4123 :
4124 0 : if ( xWindow.is() && xDockWindow.is() && xDockWindow->isFloating() )
4125 : {
4126 0 : xWindow->setOutputSize( aSize );
4127 0 : aUIElement.m_aFloatingData.m_aSize = aSize;
4128 0 : implts_setToolbar( aUIElement );
4129 0 : implts_writeWindowStateData( aUIElement );
4130 0 : implts_sortUIElements();
4131 0 : }
4132 0 : }
4133 :
4134 0 : void ToolbarLayoutManager::setToolbarPos( const OUString& rResourceURL, const awt::Point& aPos )
4135 : {
4136 0 : uno::Reference< awt::XWindow > xWindow( implts_getXWindow( rResourceURL ));
4137 0 : uno::Reference< awt::XDockableWindow > xDockWindow( xWindow, uno::UNO_QUERY );
4138 0 : UIElement aUIElement = implts_findToolbar( rResourceURL );
4139 :
4140 0 : if ( xWindow.is() && xDockWindow.is() && xDockWindow->isFloating() )
4141 : {
4142 0 : xWindow->setPosSize( aPos.X, aPos.Y, 0, 0, awt::PosSize::POS );
4143 0 : aUIElement.m_aFloatingData.m_aPos = aPos;
4144 0 : implts_setToolbar( aUIElement );
4145 0 : implts_writeWindowStateData( aUIElement );
4146 0 : implts_sortUIElements();
4147 0 : }
4148 0 : }
4149 :
4150 0 : void ToolbarLayoutManager::setToolbarPosSize( const OUString& rResourceURL, const awt::Point& aPos, const awt::Size& aSize )
4151 : {
4152 0 : setToolbarPos( rResourceURL, aPos );
4153 0 : setToolbarSize( rResourceURL, aSize );
4154 0 : }
4155 :
4156 648 : } // namespace framework
4157 :
4158 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|