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