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