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