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