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