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