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