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