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