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