1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sfx2.hxx" 30 31 #include <svl/eitem.hxx> 32 #include <vcl/decoview.hxx> 33 34 #include <vcl/svapp.hxx> 35 #include <vcl/timer.hxx> 36 #include <rtl/instance.hxx> 37 #include <toolkit/helper/vclunohelper.hxx> 38 #include <comphelper/processfactory.hxx> 39 40 #include <sfx2/dockwin.hxx> 41 #include <sfx2/bindings.hxx> 42 #include <sfx2/viewfrm.hxx> 43 #include <sfx2/dispatch.hxx> 44 #include "workwin.hxx" 45 #include "splitwin.hxx" 46 #include <sfx2/viewsh.hxx> 47 #include "sfx2/sfxhelp.hxx" 48 #include <sfx2/objsh.hxx> 49 #include <sfx2/msgpool.hxx> 50 51 #include <com/sun/star/frame/XController.hpp> 52 #include <com/sun/star/lang/XUnoTunnel.hpp> 53 #include <com/sun/star/lang/XSingleComponentFactory.hpp> 54 #include <com/sun/star/awt/XWindow.hpp> 55 #include <com/sun/star/uno/XComponentContext.hpp> 56 #include <com/sun/star/frame/XModuleManager.hpp> 57 #include <com/sun/star/container/XNameAccess.hpp> 58 59 #define MAX_TOGGLEAREA_WIDTH 20 60 #define MAX_TOGGLEAREA_HEIGHT 20 61 62 using namespace ::com::sun::star; 63 64 // implemented in 'sfx2/source/appl/childwin.cxx' 65 extern sal_Bool GetPosSizeFromString( const String& rStr, Point& rPos, Size& rSize ); 66 extern sal_Bool GetSplitSizeFromString( const String& rStr, Size& rSize ); 67 68 // If you want to change the number you also have to: 69 // - Add new slot ids to sfxsids.hrc 70 // - Add new slots to frmslots.sdi 71 // - Add new slot definitions to sfx.sdi 72 static const int NUM_OF_DOCKINGWINDOWS = 10; 73 74 class SfxTitleDockingWindow; 75 class SfxTitleDockingWindow : public SfxDockingWindow 76 { 77 Window* m_pWrappedWindow; 78 sal_uInt16 m_nID; 79 80 public: 81 SfxTitleDockingWindow( 82 SfxBindings* pBindings , 83 SfxChildWindow* pChildWin , 84 Window* pParent , 85 WinBits nBits, 86 sal_uInt16 nID); 87 virtual ~SfxTitleDockingWindow(); 88 89 Window* GetWrappedWindow() const { return m_pWrappedWindow; } 90 void SetWrappedWindow(Window* const pWindow); 91 92 virtual void StateChanged( StateChangedType nType ); 93 virtual long Notify( NotifyEvent& rNEvt ); 94 virtual void Resize(); 95 virtual void Resizing( Size& rSize ); 96 virtual sal_Bool Close(); 97 }; 98 99 namespace 100 { 101 struct WindowState 102 { 103 ::rtl::OUString sTitle; 104 }; 105 } 106 107 static uno::WeakReference< container::XNameAccess > m_xWindowStateConfiguration; 108 static uno::WeakReference< frame::XModuleManager > m_xModuleManager; 109 110 static bool lcl_getWindowState( const uno::Reference< container::XNameAccess >& xWindowStateMgr, const ::rtl::OUString& rResourceURL, WindowState& rWindowState ) 111 { 112 bool bResult = false; 113 114 try 115 { 116 uno::Any a; 117 uno::Sequence< beans::PropertyValue > aWindowState; 118 a = xWindowStateMgr->getByName( rResourceURL ); 119 if ( a >>= aWindowState ) 120 { 121 for ( sal_Int32 n = 0; n < aWindowState.getLength(); n++ ) 122 { 123 if ( aWindowState[n].Name.equalsAscii( "UIName" )) 124 { 125 aWindowState[n].Value >>= rWindowState.sTitle; 126 } 127 } 128 } 129 130 bResult = true; 131 } 132 catch ( container::NoSuchElementException& ) 133 { 134 bResult = false; 135 } 136 137 return bResult; 138 } 139 140 SfxDockingWrapper::SfxDockingWrapper( Window* pParentWnd , 141 sal_uInt16 nId , 142 SfxBindings* pBindings , 143 SfxChildWinInfo* pInfo ) 144 : SfxChildWindow( pParentWnd , nId ) 145 { 146 uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); 147 const rtl::OUString aDockWindowResourceURL( RTL_CONSTASCII_USTRINGPARAM( "private:resource/dockingwindow/" )); 148 149 SfxTitleDockingWindow* pTitleDockWindow = new SfxTitleDockingWindow( pBindings, this, pParentWnd, 150 WB_STDDOCKWIN | WB_CLIPCHILDREN | WB_SIZEABLE | WB_3DLOOK | WB_ROLLABLE, nId); 151 pWindow = pTitleDockWindow; 152 eChildAlignment = SFX_ALIGN_NOALIGNMENT; 153 154 // Use factory manager to retrieve XWindow factory. That can be used to instanciate 155 // the real window factory. 156 uno::Reference< lang::XSingleComponentFactory > xFactoryMgr( 157 xServiceManager->createInstance( 158 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 159 "com.sun.star.ui.WindowContentFactoryManager"))), 160 uno::UNO_QUERY ); 161 162 if (xFactoryMgr.is()) 163 { 164 SfxDispatcher* pDispatcher = pBindings->GetDispatcher(); 165 uno::Reference< frame::XFrame > xFrame( pDispatcher->GetFrame()->GetFrame().GetFrameInterface(), uno::UNO_QUERY ); 166 uno::Sequence< uno::Any > aArgs(2); 167 beans::PropertyValue aPropValue; 168 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Frame" )); 169 aPropValue.Value = uno::makeAny( xFrame ); 170 aArgs[0] <<= aPropValue; 171 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ResourceURL" )); 172 173 // create a resource URL from the nId provided by the sfx2 174 ::rtl::OUString aResourceURL( aDockWindowResourceURL ); 175 aResourceURL += ::rtl::OUString::valueOf(sal_Int32(nId)); 176 aPropValue.Value = uno::makeAny( aResourceURL ); 177 aArgs[1] <<= aPropValue; 178 179 uno::Reference< awt::XWindow > xWindow; 180 try 181 { 182 uno::Reference< beans::XPropertySet > xProps( xServiceManager, uno::UNO_QUERY ); 183 uno::Reference< uno::XComponentContext > xContext; 184 185 if ( xProps.is() ) 186 xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext; 187 if ( xContext.is() ) 188 { 189 xWindow = uno::Reference< awt::XWindow>( 190 xFactoryMgr->createInstanceWithArgumentsAndContext( aArgs, xContext ), 191 uno::UNO_QUERY ); 192 } 193 194 uno::Reference< frame::XModuleManager > xModuleManager( m_xModuleManager ); 195 if ( !xModuleManager.is() ) 196 { 197 xModuleManager = uno::Reference< frame::XModuleManager >( 198 xServiceManager->createInstance( 199 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.ModuleManager" ))), 200 uno::UNO_QUERY ); 201 m_xModuleManager = xModuleManager; 202 } 203 204 uno::Reference< container::XNameAccess > xWindowStateConfiguration( m_xWindowStateConfiguration ); 205 if ( !xWindowStateConfiguration.is() ) 206 { 207 xWindowStateConfiguration = uno::Reference< container::XNameAccess >( 208 xServiceManager->createInstance( 209 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.ui.WindowStateConfiguration" ))), 210 uno::UNO_QUERY ); 211 m_xWindowStateConfiguration = xWindowStateConfiguration; 212 } 213 214 ::rtl::OUString sModuleIdentifier = xModuleManager->identify( xFrame ); 215 216 uno::Reference< container::XNameAccess > xModuleWindowState( 217 xWindowStateConfiguration->getByName( sModuleIdentifier ), 218 uno::UNO_QUERY ); 219 if ( xModuleWindowState.is() ) 220 { 221 WindowState aDockWinState; 222 if ( lcl_getWindowState( xModuleWindowState, aResourceURL, aDockWinState )) 223 pTitleDockWindow->SetText( aDockWinState.sTitle ); 224 } 225 } 226 catch ( beans::UnknownPropertyException& ) 227 { 228 } 229 catch ( uno::RuntimeException& ) 230 { 231 } 232 catch ( uno::Exception& ) 233 { 234 } 235 236 Window* pContentWindow = VCLUnoHelper::GetWindow(xWindow); 237 if ( pContentWindow ) 238 pContentWindow->SetStyle( pContentWindow->GetStyle() | WB_DIALOGCONTROL | WB_CHILDDLGCTRL ); 239 pTitleDockWindow->SetWrappedWindow(pContentWindow); 240 } 241 242 pWindow->SetOutputSizePixel( Size( 270, 240 ) ); 243 244 ( ( SfxDockingWindow* ) pWindow )->Initialize( pInfo ); 245 SetHideNotDelete( sal_True ); 246 } 247 248 SfxChildWindow* SfxDockingWrapper::CreateImpl( 249 Window *pParent, sal_uInt16 nId, SfxBindings *pBindings, SfxChildWinInfo* pInfo ) 250 { 251 SfxChildWindow *pWin = new SfxDockingWrapper(pParent, nId, pBindings, pInfo); return pWin; 252 } 253 254 sal_uInt16 SfxDockingWrapper::GetChildWindowId () 255 { 256 DBG_ASSERT( false, "This method shouldn't be called!" ); 257 return 0; 258 } 259 260 void SfxDockingWrapper::RegisterChildWindow (sal_Bool bVis, SfxModule *pMod, sal_uInt16 nFlags) 261 { 262 // pre-register a couple of docking windows 263 for (int i=0; i < NUM_OF_DOCKINGWINDOWS; i++ ) 264 { 265 sal_uInt16 nID = sal_uInt16(SID_DOCKWIN_START+i); 266 SfxChildWinFactory *pFact = new SfxChildWinFactory( SfxDockingWrapper::CreateImpl, nID, 0xffff ); 267 pFact->aInfo.nFlags |= nFlags; 268 pFact->aInfo.bVisible = bVis; 269 SfxChildWindow::RegisterChildWindow(pMod, pFact); 270 } 271 } 272 273 SfxChildWinInfo SfxDockingWrapper::GetInfo() const 274 { 275 SfxChildWinInfo aInfo = SfxChildWindow::GetInfo(); 276 ((SfxDockingWindow*)GetWindow())->FillInfo( aInfo ); 277 return aInfo; 278 }; 279 280 SfxTitleDockingWindow::SfxTitleDockingWindow( SfxBindings* pBind , 281 SfxChildWindow* pChildWin , 282 Window* pParent , 283 WinBits nBits, 284 sal_uInt16 nID ) : 285 SfxDockingWindow( pBind , 286 pChildWin , 287 pParent , 288 nBits ), 289 m_pWrappedWindow(0), 290 m_nID(nID) 291 { 292 } 293 294 SfxTitleDockingWindow::~SfxTitleDockingWindow() 295 { 296 delete m_pWrappedWindow; 297 } 298 299 void SfxTitleDockingWindow::SetWrappedWindow( Window* const pWindow ) 300 { 301 m_pWrappedWindow = pWindow; 302 if (m_pWrappedWindow) 303 { 304 m_pWrappedWindow->SetParent(this); 305 m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() ); 306 m_pWrappedWindow->Show(); 307 } 308 } 309 310 long SfxTitleDockingWindow::Notify( NotifyEvent& rNEvt ) 311 { 312 return SfxDockingWindow::Notify( rNEvt ); 313 } 314 315 void SfxTitleDockingWindow::StateChanged( StateChangedType nType ) 316 { 317 if ( nType == STATE_CHANGE_INITSHOW ) 318 { 319 Window* pWindow = GetWrappedWindow(); 320 if ( pWindow ) 321 { 322 pWindow->SetSizePixel( GetOutputSizePixel() ); 323 pWindow->Show(); 324 } 325 } 326 327 SfxDockingWindow::StateChanged(nType); 328 } 329 330 void SfxTitleDockingWindow::Resize() 331 { 332 SfxDockingWindow::Resize(); 333 if (m_pWrappedWindow) 334 m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() ); 335 } 336 337 void SfxTitleDockingWindow::Resizing( Size &rSize ) 338 { 339 SfxDockingWindow::Resizing( rSize ); 340 if (m_pWrappedWindow) 341 m_pWrappedWindow->SetSizePixel( GetOutputSizePixel() ); 342 } 343 344 sal_Bool SfxTitleDockingWindow::Close() 345 { 346 return SfxDockingWindow::Close(); 347 } 348 349 namespace 350 { 351 struct ChildrenRegisteredMap : public rtl::Static< bool, ChildrenRegisteredMap > {}; 352 } 353 354 static bool lcl_checkDockingWindowID( sal_uInt16 nID ) 355 { 356 if (nID < SID_DOCKWIN_START || nID >= sal_uInt16(SID_DOCKWIN_START+NUM_OF_DOCKINGWINDOWS)) 357 return false; 358 else 359 return true; 360 } 361 362 static SfxWorkWindow* lcl_getWorkWindowFromXFrame( const uno::Reference< frame::XFrame >& rFrame ) 363 { 364 // We need to find the corresponding SfxFrame of our XFrame 365 SfxFrame* pFrame = SfxFrame::GetFirst(); 366 SfxFrame* pXFrame = 0; 367 while ( pFrame ) 368 { 369 uno::Reference< frame::XFrame > xViewShellFrame( pFrame->GetFrameInterface() ); 370 if ( xViewShellFrame == rFrame ) 371 { 372 pXFrame = pFrame; 373 break; 374 } 375 else 376 pFrame = SfxFrame::GetNext( *pFrame ); 377 } 378 379 // If we have a SfxFrame we can retrieve the work window (Sfx layout manager for docking windows) 380 if ( pXFrame ) 381 return pXFrame->GetWorkWindow_Impl(); 382 else 383 return NULL; 384 } 385 386 /* 387 Factory function used by the framework layout manager to "create" a docking window with a special name. 388 The string rDockingWindowName MUST BE a valid ID! The ID is pre-defined by a certain slot range located 389 in sfxsids.hrc (currently SID_DOCKWIN_START = 9800). 390 */ 391 void SAL_CALL SfxDockingWindowFactory( const uno::Reference< frame::XFrame >& rFrame, const rtl::OUString& rDockingWindowName ) 392 { 393 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 394 sal_uInt16 nID = sal_uInt16(rDockingWindowName.toInt32()); 395 396 // Check the range of the provided ID otherwise nothing will happen 397 if ( lcl_checkDockingWindowID( nID )) 398 { 399 SfxWorkWindow* pWorkWindow = lcl_getWorkWindowFromXFrame( rFrame ); 400 if ( pWorkWindow ) 401 { 402 SfxChildWindow* pChildWindow = pWorkWindow->GetChildWindow_Impl(nID); 403 if ( !pChildWindow ) 404 { 405 // Register window at the workwindow child window list 406 pWorkWindow->SetChildWindow_Impl( nID, true, false ); 407 } 408 } 409 } 410 } 411 412 /* 413 Function used by the framework layout manager to determine the visibility state of a docking window with 414 a special name. The string rDockingWindowName MUST BE a valid ID! The ID is pre-defined by a certain slot 415 range located in sfxsids.hrc (currently SID_DOCKWIN_START = 9800). 416 */ 417 bool SAL_CALL IsDockingWindowVisible( const uno::Reference< frame::XFrame >& rFrame, const rtl::OUString& rDockingWindowName ) 418 { 419 ::vos::OGuard aGuard( Application::GetSolarMutex() ); 420 421 sal_uInt16 nID = sal_uInt16(rDockingWindowName.toInt32()); 422 423 // Check the range of the provided ID otherwise nothing will happen 424 if ( lcl_checkDockingWindowID( nID )) 425 { 426 SfxWorkWindow* pWorkWindow = lcl_getWorkWindowFromXFrame( rFrame ); 427 if ( pWorkWindow ) 428 { 429 SfxChildWindow* pChildWindow = pWorkWindow->GetChildWindow_Impl(nID); 430 if ( pChildWindow ) 431 return true; 432 } 433 } 434 435 return false; 436 } 437 438 class SfxDockingWindow_Impl 439 { 440 friend class SfxDockingWindow; 441 442 SfxChildAlignment eLastAlignment; 443 SfxChildAlignment eDockAlignment; 444 sal_Bool bConstructed; 445 Size aMinSize; 446 SfxSplitWindow* pSplitWin; 447 sal_Bool bSplitable; 448 // sal_Bool bAutoHide; 449 Timer aMoveTimer; 450 451 // Folgende members sind nur in der Zeit von StartDocking bis EndDocking 452 // g"ultig: 453 sal_Bool bEndDocked; 454 Size aSplitSize; 455 long nHorizontalSize; 456 long nVerticalSize; 457 sal_uInt16 nLine; 458 sal_uInt16 nPos; 459 sal_uInt16 nDockLine; 460 sal_uInt16 nDockPos; 461 sal_Bool bNewLine; 462 sal_Bool bDockingPrevented; 463 ByteString aWinState; 464 465 SfxChildAlignment GetLastAlignment() const 466 { return eLastAlignment; } 467 void SetLastAlignment(SfxChildAlignment eAlign) 468 { eLastAlignment = eAlign; } 469 SfxChildAlignment GetDockAlignment() const 470 { return eDockAlignment; } 471 void SetDockAlignment(SfxChildAlignment eAlign) 472 { eDockAlignment = eAlign; } 473 }; 474 475 //------------------------------------------------------------------------- 476 477 void SfxDockingWindow::Resize() 478 479 /* [Beschreibung] 480 481 Diese virtuelle Methode der Klasse DockingWindow merkt sich ggf. eine 482 ver"anderte FloatingSize. 483 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s 484 auch SfxDockingWindow::Resize() gerufen werden. 485 */ 486 { 487 DockingWindow::Resize(); 488 Invalidate(); 489 if ( pImp->bConstructed && pMgr ) 490 { 491 if ( IsFloatingMode() ) 492 { 493 // start timer for saving window status information 494 pImp->aMoveTimer.Start(); 495 } 496 else 497 { 498 Size aSize( GetSizePixel() ); 499 switch ( pImp->GetDockAlignment() ) 500 { 501 case SFX_ALIGN_LEFT: 502 case SFX_ALIGN_FIRSTLEFT: 503 case SFX_ALIGN_LASTLEFT: 504 case SFX_ALIGN_RIGHT: 505 case SFX_ALIGN_FIRSTRIGHT: 506 case SFX_ALIGN_LASTRIGHT: 507 pImp->nHorizontalSize = aSize.Width(); 508 pImp->aSplitSize = aSize; 509 break; 510 case SFX_ALIGN_TOP: 511 case SFX_ALIGN_LOWESTTOP: 512 case SFX_ALIGN_HIGHESTTOP: 513 case SFX_ALIGN_BOTTOM: 514 case SFX_ALIGN_HIGHESTBOTTOM: 515 case SFX_ALIGN_LOWESTBOTTOM: 516 pImp->nVerticalSize = aSize.Height(); 517 pImp->aSplitSize = aSize; 518 break; 519 default: 520 break; 521 } 522 } 523 } 524 } 525 526 //------------------------------------------------------------------------- 527 528 sal_Bool SfxDockingWindow::PrepareToggleFloatingMode() 529 530 /* [Beschreibung] 531 532 Diese virtuelle Methode der Klasse DockingWindow erm"oglicht ein Eingreifen 533 in das Umschalten des floating mode. 534 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s 535 danach SfxDockingWindow::PrepareToggleFloatingMode() gerufen werden, 536 wenn nicht FALSE zur"uckgegeben wird. 537 */ 538 539 { 540 if (!pImp->bConstructed) 541 return sal_True; 542 543 if ( (Application::IsInModalMode() && IsFloatingMode()) || !pMgr ) 544 return sal_False; 545 546 if ( pImp->bDockingPrevented ) 547 return sal_False; 548 549 if (!IsFloatingMode()) 550 { 551 // Testen, ob FloatingMode erlaubt ist 552 if ( CheckAlignment(GetAlignment(),SFX_ALIGN_NOALIGNMENT) != SFX_ALIGN_NOALIGNMENT ) 553 return sal_False; 554 555 if ( pImp->pSplitWin ) 556 { 557 // Das DockingWindow sitzt in einem SplitWindow und wird abgerissen 558 pImp->pSplitWin->RemoveWindow(this/*, sal_False*/); 559 pImp->pSplitWin = 0; 560 } 561 } 562 else if ( pMgr ) 563 { 564 pImp->aWinState = GetFloatingWindow()->GetWindowState(); 565 566 // Testen, ob es erlaubt ist, anzudocken 567 if (CheckAlignment(GetAlignment(),pImp->GetLastAlignment()) == SFX_ALIGN_NOALIGNMENT) 568 return sal_False; 569 570 // Testen, ob das Workwindow gerade ein Andocken erlaubt 571 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); 572 if ( !pWorkWin->IsDockingAllowed() || !pWorkWin->IsInternalDockingAllowed() ) 573 return sal_False; 574 } 575 576 return sal_True; 577 } 578 579 //------------------------------------------------------------------------- 580 581 void SfxDockingWindow::ToggleFloatingMode() 582 583 /* [Beschreibung] 584 585 Diese virtuelle Methode der Klasse DockingWindow setzt die internen 586 Daten des SfxDockingWindow und sorgt f"ur korrektes Alignment am 587 parent window. 588 Durch PrepareToggleFloatMode und Initialize ist sichergestellt, da\s 589 pImp->GetLastAlignment() immer eine erlaubtes Alignment liefert. 590 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s 591 zuerst SfxDockingWindow::ToggleFloatingMode() gerufen werden. 592 */ 593 { 594 if ( !pImp->bConstructed || !pMgr ) 595 return; // Kein Handler-Aufruf 596 597 // Altes Alignment merken und dann umschalten. 598 // Sv hat jetzt schon umgeschaltet, aber Alignment am SfxDockingWindow 599 // ist noch das alte! 600 // Was war ich bisher ? 601 SfxChildAlignment eLastAlign = GetAlignment(); 602 603 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); 604 SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW; 605 if ( pImp->bSplitable ) 606 eIdent = SFX_CHILDWIN_SPLITWINDOW; 607 608 if (IsFloatingMode()) 609 { 610 SetAlignment(SFX_ALIGN_NOALIGNMENT); 611 if ( pImp->aWinState.Len() ) 612 GetFloatingWindow()->SetWindowState( pImp->aWinState ); 613 else 614 GetFloatingWindow()->SetOutputSizePixel( GetFloatingSize() ); 615 /* 616 if ( pImp->bSplitable && !pImp->bEndDocked ) 617 // Wenn das Fenster vorher in einem SplitWindow lag, kommt von 618 // Sv kein Show 619 Show(); 620 */ 621 } 622 else 623 { 624 if (pImp->GetDockAlignment() == eLastAlign) 625 { 626 // Wenn ToggleFloatingMode aufgerufen wurde, das DockAlignment 627 // aber noch unver"andert ist, mu\s das ein Toggeln durch DClick 628 // gewesen sein, also LastAlignment verwenden 629 SetAlignment (pImp->GetLastAlignment()); 630 if ( !pImp->bSplitable ) 631 SetSizePixel( CalcDockingSize(GetAlignment()) ); 632 } 633 else 634 { 635 // Toggeln wurde durch Draggen ausgel"ost 636 pImp->nLine = pImp->nDockLine; 637 pImp->nPos = pImp->nDockPos; 638 SetAlignment (pImp->GetDockAlignment()); 639 } 640 641 if ( pImp->bSplitable ) 642 { 643 // Das DockingWindow kommt jetzt in ein SplitWindow 644 pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(GetAlignment()); 645 646 // Das LastAlignment ist jetzt immer noch das zuletzt angedockte 647 SfxSplitWindow *pSplit = pWorkWin->GetSplitWindow_Impl(pImp->GetLastAlignment()); 648 649 DBG_ASSERT( pSplit, "LastAlignment kann nicht stimmen!" ); 650 if ( pSplit && pSplit != pImp->pSplitWin ) 651 pSplit->ReleaseWindow_Impl(this); 652 if ( pImp->GetDockAlignment() == eLastAlign ) 653 pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize ); 654 else 655 pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize, pImp->nLine, pImp->nPos, pImp->bNewLine ); 656 if ( !pImp->pSplitWin->IsFadeIn() ) 657 pImp->pSplitWin->FadeIn(); 658 } 659 } 660 661 // altes Alignment festhalten f"ur n"achstes Togglen; erst jetzt setzen 662 // wg. Abmelden beim SplitWindow! 663 pImp->SetLastAlignment(eLastAlign); 664 665 // DockAlignment zur"ucksetzen, falls noch EndDocking gerufen wird 666 pImp->SetDockAlignment(GetAlignment()); 667 668 // SfxChildWindow korrekt andocken bzw. entdocken 669 if ( pMgr ) 670 pWorkWin->ConfigChild_Impl( eIdent, SFX_TOGGLEFLOATMODE, pMgr->GetType() ); 671 } 672 673 //------------------------------------------------------------------------- 674 675 void SfxDockingWindow::StartDocking() 676 677 /* [Beschreibung] 678 679 Diese virtuelle Methode der Klasse DockingWindow holt vom parent window 680 das innere und "au\sere docking rectangle. 681 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s 682 am Ende SfxDockingWindow::StartDocking() gerufen werden. 683 */ 684 { 685 if ( !pImp->bConstructed || !pMgr ) 686 return; 687 SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW; 688 if ( pImp->bSplitable ) 689 eIdent = SFX_CHILDWIN_SPLITWINDOW; 690 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); 691 pWorkWin->ConfigChild_Impl( eIdent, SFX_SETDOCKINGRECTS, pMgr->GetType() ); 692 pImp->SetDockAlignment(GetAlignment()); 693 694 if ( pImp->pSplitWin ) 695 { 696 // Die aktuellen Docking-Daten besorgen 697 pImp->pSplitWin->GetWindowPos(this, pImp->nLine, pImp->nPos); 698 pImp->nDockLine = pImp->nLine; 699 pImp->nDockPos = pImp->nPos; 700 pImp->bNewLine = sal_False; 701 } 702 } 703 704 //------------------------------------------------------------------------- 705 706 sal_Bool SfxDockingWindow::Docking( const Point& rPos, Rectangle& rRect ) 707 708 /* [Beschreibung] 709 710 Diese virtuelle Methode der Klasse DockingWindow berechnet das aktuelle 711 tracking rectangle. Dazu benutzt sie die Methode CalcAlignment(rPos,rRect), 712 deren Verhalten von abgeleiteten Klassen beeinflu\st werden kann (s.u.). 713 Diese Methode sollte nach M"oglichkeit nicht "uberschrieben werden. 714 */ 715 { 716 if ( Application::IsInModalMode() ) 717 return sal_True; 718 719 if ( !pImp->bConstructed || !pMgr ) 720 { 721 rRect.SetSize( Size() ); 722 return IsFloatingMode(); 723 } 724 725 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); 726 if ( pImp->bDockingPrevented || !pWorkWin->IsInternalDockingAllowed() ) 727 return sal_False; 728 729 sal_Bool bFloatMode = sal_False; 730 731 if ( GetOuterRect().IsInside( rPos ) && !IsDockingPrevented() ) 732 { 733 // Maus innerhalb OuterRect : Alignment und Rectangle berechnen 734 SfxChildAlignment eAlign = CalcAlignment(rPos, rRect); 735 if (eAlign == SFX_ALIGN_NOALIGNMENT) 736 bFloatMode = sal_True; 737 pImp->SetDockAlignment(eAlign); 738 } 739 else 740 { 741 // Maus nicht innerhalb OuterRect : muss FloatingWindow sein 742 // Ist das erlaubt ? 743 if (CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_NOALIGNMENT) != SFX_ALIGN_NOALIGNMENT) 744 return sal_False; 745 bFloatMode = sal_True; 746 if ( SFX_ALIGN_NOALIGNMENT != pImp->GetDockAlignment() ) 747 { 748 // wg. SV-Bug darf rRect nur ver"andert werden, wenn sich das 749 // Alignment "andert ! 750 pImp->SetDockAlignment(SFX_ALIGN_NOALIGNMENT); 751 rRect.SetSize(CalcDockingSize(SFX_ALIGN_NOALIGNMENT)); 752 } 753 } 754 755 if ( !pImp->bSplitable ) 756 { 757 // Bei individuell angedocktem Window wird die Position durch das 758 // Alignment und die docking rects festgelegt. 759 Size aSize = rRect.GetSize(); 760 Point aPos; 761 762 switch ( pImp->GetDockAlignment() ) 763 { 764 case SFX_ALIGN_LEFT: 765 case SFX_ALIGN_FIRSTLEFT: 766 case SFX_ALIGN_LASTLEFT: 767 aPos = aInnerRect.TopLeft(); 768 if ( pImp->GetDockAlignment() == GetAlignment() ) 769 aPos.X() -= aSize.Width(); 770 break; 771 772 case SFX_ALIGN_TOP: 773 case SFX_ALIGN_LOWESTTOP: 774 case SFX_ALIGN_HIGHESTTOP: 775 aPos = Point(aOuterRect.Left(), aInnerRect.Top()); 776 if ( pImp->GetDockAlignment() == GetAlignment() ) 777 aPos.Y() -= aSize.Height(); 778 break; 779 780 case SFX_ALIGN_RIGHT: 781 case SFX_ALIGN_FIRSTRIGHT: 782 case SFX_ALIGN_LASTRIGHT: 783 aPos = Point(aInnerRect.Right() - rRect.GetSize().Width(), 784 aInnerRect.Top()); 785 if ( pImp->GetDockAlignment() == GetAlignment() ) 786 aPos.X() += aSize.Width(); 787 break; 788 789 case SFX_ALIGN_BOTTOM: 790 case SFX_ALIGN_HIGHESTBOTTOM: 791 case SFX_ALIGN_LOWESTBOTTOM: 792 aPos = Point(aOuterRect.Left(), 793 aInnerRect.Bottom() - rRect.GetSize().Height()); 794 if ( pImp->GetDockAlignment() == GetAlignment() ) 795 aPos.Y() += aSize.Height(); 796 break; 797 default: 798 break; 799 } 800 801 rRect.SetPos(aPos); 802 } 803 804 return bFloatMode; 805 } 806 807 //------------------------------------------------------------------------- 808 809 void SfxDockingWindow::EndDocking( const Rectangle& rRect, sal_Bool bFloatMode ) 810 811 /* [Beschreibung] 812 813 Diese virtuelle Methode der Klasse DockingWindow sorgt f"ur das korrekte 814 Alignment am parent window. 815 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s 816 zuerst SfxDockingWindow::EndDocking() gerufen werden. 817 */ 818 { 819 if ( !pImp->bConstructed || IsDockingCanceled() || !pMgr ) 820 return; 821 822 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); 823 sal_Bool bReArrange = sal_False; 824 SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW; 825 if ( pImp->bSplitable ) 826 { 827 eIdent = SFX_CHILDWIN_SPLITWINDOW; 828 829 // Wenn sich das Alignment "andert und das Fenster befindet sich 830 // im angedockten Zustand in einem SplitWindow, mu\s umgemeldet werden 831 // Wenn neu angedockt wird, machen PrepareToggleFloatingMode() 832 // und ToggleFloatingMode() das Ummelden. 833 if ( !bFloatMode ) 834 bReArrange = sal_True; 835 } 836 837 if ( bReArrange ) 838 { 839 if ( GetAlignment() != pImp->GetDockAlignment() ) 840 { 841 // Vor dem Show() mu\s das Ummelden passiert sein, daher kann nicht 842 // die Basisklasse gerufen werden 843 if ( IsFloatingMode() || !pImp->bSplitable ) 844 Show( sal_False, SHOW_NOFOCUSCHANGE ); 845 846 // Die Gr"o\se f"urs Toggeln setzen 847 pImp->aSplitSize = rRect.GetSize(); 848 if ( IsFloatingMode() ) 849 { 850 SetFloatingMode( bFloatMode ); 851 if ( IsFloatingMode() || !pImp->bSplitable ) 852 Show( sal_True, SHOW_NOFOCUSCHANGE ); 853 } 854 else 855 { 856 pImp->pSplitWin->RemoveWindow(this,sal_False); 857 pImp->nLine = pImp->nDockLine; 858 pImp->nPos = pImp->nDockPos; 859 pImp->pSplitWin->ReleaseWindow_Impl(this); 860 pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(pImp->GetDockAlignment()); 861 pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize, pImp->nDockLine, pImp->nDockPos, pImp->bNewLine ); 862 if ( !pImp->pSplitWin->IsFadeIn() ) 863 pImp->pSplitWin->FadeIn(); 864 } 865 } 866 else if ( pImp->nLine != pImp->nDockLine || pImp->nPos != pImp->nDockPos || pImp->bNewLine ) 867 { 868 // Ich wurde innerhalb meines Splitwindows verschoben. 869 if ( pImp->nLine != pImp->nDockLine ) 870 pImp->aSplitSize = rRect.GetSize(); 871 pImp->pSplitWin->MoveWindow( this, pImp->aSplitSize, pImp->nDockLine, pImp->nDockPos, pImp->bNewLine ); 872 } 873 } 874 else 875 { 876 pImp->bEndDocked = sal_True; 877 DockingWindow::EndDocking(rRect, bFloatMode); 878 pImp->bEndDocked = sal_False; 879 } 880 881 SetAlignment( IsFloatingMode() ? SFX_ALIGN_NOALIGNMENT : pImp->GetDockAlignment() ); 882 } 883 884 //------------------------------------------------------------------------- 885 886 void SfxDockingWindow::Resizing( Size& /*rSize*/ ) 887 888 /* [Beschreibung] 889 890 Virtuelle Methode der Klasse DockingWindow. 891 Hier kann das interaktive Umgr"o\sern im FloatingMode beeinflu\t werden, 892 z.B. indem nur diskrete Werte f"ur Breite und/oder H"ohe zugelassen werden. 893 Die Basisimplementation verhindert, da\s die OutputSize kleiner wird als 894 eine mit SetMinOutputSizePixel() gesetzte Gr"o\se. 895 */ 896 897 { 898 /* 899 if(rSize.Width() < pImp->aMinSize.Width()) 900 rSize.Width() = pImp->aMinSize.Width(); 901 if(rSize.Height() < pImp->aMinSize.Height()) 902 rSize.Height() = pImp->aMinSize.Height(); 903 */ 904 } 905 906 //------------------------------------------------------------------------- 907 908 SfxDockingWindow::SfxDockingWindow( SfxBindings *pBindinx, SfxChildWindow *pCW, 909 Window* pParent, WinBits nWinBits) : 910 DockingWindow (pParent, nWinBits), 911 pBindings(pBindinx), 912 pMgr(pCW), 913 pImp(NULL) 914 915 /* [Beschreibung] 916 917 ctor der Klasse SfxDockingWindow. Es wird ein SfxChildWindow ben"otigt, 918 da das Andocken im Sfx "uber SfxChildWindows realisiert wird. 919 */ 920 921 { 922 if ( GetHelpId().getLength() ) 923 { 924 SetUniqueId( GetHelpId() ); 925 SetHelpId(""); 926 } 927 else 928 { 929 SfxViewFrame* pViewFrame = pBindings->GetDispatcher()->GetFrame(); 930 SfxSlotPool* pSlotPool = pViewFrame->GetObjectShell()->GetModule()->GetSlotPool(); 931 const SfxSlot* pSlot = pSlotPool->GetSlot( pCW->GetType() ); 932 if ( pSlot ) 933 { 934 rtl::OString aCmd("SFXDOCKINGWINDOW_"); 935 aCmd += pSlot->GetUnoName(); 936 SetUniqueId( aCmd ); 937 } 938 } 939 940 pImp = new SfxDockingWindow_Impl; 941 pImp->bConstructed = sal_False; 942 pImp->pSplitWin = 0; 943 pImp->bEndDocked = sal_False; 944 pImp->bDockingPrevented = sal_False; 945 946 pImp->bSplitable = sal_True; 947 // pImp->bAutoHide = sal_False; 948 949 // Zun"achst auf Defaults setzen; das Alignment wird in der Subklasse gesetzt 950 pImp->nLine = pImp->nDockLine = 0; 951 pImp->nPos = pImp->nDockPos = 0; 952 pImp->bNewLine = sal_False; 953 pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT); 954 pImp->aMoveTimer.SetTimeout(50); 955 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxDockingWindow,TimerHdl)); 956 957 // DBG_ASSERT(pMgr,"DockingWindow erfordert ein SfxChildWindow!"); 958 } 959 960 //------------------------------------------------------------------------- 961 962 SfxDockingWindow::SfxDockingWindow( SfxBindings *pBindinx, SfxChildWindow *pCW, 963 Window* pParent, const ResId& rResId) : 964 DockingWindow(pParent, rResId), 965 pBindings(pBindinx), 966 pMgr(pCW), 967 pImp(NULL) 968 969 /* [Beschreibung] 970 971 ctor der Klasse SfxDockingWindow. Es wird ein SfxChildWindow ben"otigt, 972 da das Andocken im Sfx "uber SfxChildWindows realisiert wird. 973 */ 974 975 { 976 if ( GetHelpId().getLength() ) 977 { 978 SetUniqueId( GetHelpId() ); 979 SetHelpId(""); 980 } 981 else 982 { 983 SfxViewFrame* pViewFrame = pBindings->GetDispatcher()->GetFrame(); 984 SfxSlotPool* pSlotPool = pViewFrame->GetObjectShell()->GetModule()->GetSlotPool(); 985 const SfxSlot* pSlot = pSlotPool->GetSlot( pCW->GetType() ); 986 if ( pSlot ) 987 { 988 rtl::OString aCmd("SFXDOCKINGWINDOW_"); 989 aCmd += pSlot->GetUnoName(); 990 SetUniqueId( aCmd ); 991 } 992 } 993 994 pImp = new SfxDockingWindow_Impl; 995 pImp->bConstructed = sal_False; 996 pImp->pSplitWin = 0; 997 pImp->bEndDocked = sal_False; 998 pImp->bDockingPrevented = sal_False; 999 1000 pImp->bSplitable = sal_True; 1001 // pImp->bAutoHide = sal_False; 1002 1003 // Zun"achst auf Defaults setzen; das Alignment wird in der Subklasse gesetzt 1004 pImp->nLine = pImp->nDockLine = 0; 1005 pImp->nPos = pImp->nDockPos = 0; 1006 pImp->bNewLine = sal_False; 1007 pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT); 1008 pImp->aMoveTimer.SetTimeout(50); 1009 pImp->aMoveTimer.SetTimeoutHdl(LINK(this,SfxDockingWindow,TimerHdl)); 1010 1011 // DBG_ASSERT(pMgr,"DockingWindow erfordert ein SfxChildWindow!"); 1012 } 1013 1014 //------------------------------------------------------------------------- 1015 1016 void SfxDockingWindow::Initialize(SfxChildWinInfo *pInfo) 1017 /* [Beschreibung] 1018 1019 Initialisierung der Klasse SfxDockingWindow "uber ein SfxChildWinInfo. 1020 Die Initialisierung erfolgt erst in einem 2.Schritt nach dem ctor und sollte 1021 vom ctor der abgeleiteten Klasse oder vom ctor des SfxChildWindows 1022 aufgerufen werden. 1023 */ 1024 { 1025 if ( !pMgr ) 1026 { 1027 // Bugfix #39771 1028 pImp->SetDockAlignment( SFX_ALIGN_NOALIGNMENT ); 1029 pImp->bConstructed = sal_True; 1030 return; 1031 } 1032 1033 if ( pInfo->nFlags & SFX_CHILDWIN_FORCEDOCK ) 1034 pImp->bDockingPrevented = sal_True; 1035 1036 pImp->aSplitSize = GetOutputSizePixel(); 1037 if ( !GetFloatingSize().Width() ) 1038 { 1039 Size aMinSize( GetMinOutputSizePixel() ); 1040 SetFloatingSize( pImp->aSplitSize ); 1041 if ( pImp->aSplitSize.Width() < aMinSize.Width() ) 1042 pImp->aSplitSize.Width() = aMinSize.Width(); 1043 if ( pImp->aSplitSize.Height() < aMinSize.Height() ) 1044 pImp->aSplitSize.Height() = aMinSize.Height(); 1045 } 1046 1047 sal_Bool bVertHorzRead( sal_False ); 1048 if ( pInfo->aExtraString.Len() ) 1049 { 1050 // get information about alignment, split size and position in SplitWindow 1051 String aStr; 1052 sal_uInt16 nPos = pInfo->aExtraString.SearchAscii("AL:"); 1053 if ( nPos != STRING_NOTFOUND ) 1054 { 1055 // alignment information 1056 sal_uInt16 n1 = pInfo->aExtraString.Search('(', nPos); 1057 if ( n1 != STRING_NOTFOUND ) 1058 { 1059 sal_uInt16 n2 = pInfo->aExtraString.Search(')', n1); 1060 if ( n2 != STRING_NOTFOUND ) 1061 { 1062 // extract alignment information from extrastring 1063 aStr = pInfo->aExtraString.Copy(nPos, n2 - nPos + 1); 1064 pInfo->aExtraString.Erase(nPos, n2 - nPos + 1); 1065 aStr.Erase(nPos, n1-nPos+1); 1066 } 1067 } 1068 } 1069 1070 if ( aStr.Len() ) 1071 { 1072 // accept window state only if alignment is also set 1073 pImp->aWinState = pInfo->aWinState; 1074 1075 // check for valid alignment 1076 SfxChildAlignment eLocalAlignment = (SfxChildAlignment) (sal_uInt16) aStr.ToInt32(); 1077 if ( pImp->bDockingPrevented ) 1078 // docking prevented, ignore old configuration and take alignment from default 1079 aStr.Erase(); 1080 else 1081 SetAlignment( eLocalAlignment ); 1082 1083 SfxChildAlignment eAlign = CheckAlignment(GetAlignment(),GetAlignment()); 1084 if ( eAlign != GetAlignment() ) 1085 { 1086 DBG_ERROR("Invalid Alignment!"); 1087 SetAlignment( eAlign ); 1088 aStr.Erase(); 1089 } 1090 1091 // get last alignment (for toggeling) 1092 nPos = aStr.Search(','); 1093 if ( nPos != STRING_NOTFOUND ) 1094 { 1095 aStr.Erase(0, nPos+1); 1096 pImp->SetLastAlignment( (SfxChildAlignment) (sal_uInt16) aStr.ToInt32() ); 1097 } 1098 1099 nPos = aStr.Search(','); 1100 if ( nPos != STRING_NOTFOUND ) 1101 { 1102 // get split size and position in SplitWindow 1103 Point aPos; 1104 aStr.Erase(0, nPos+1); 1105 if ( GetPosSizeFromString( aStr, aPos, pImp->aSplitSize ) ) 1106 { 1107 pImp->nLine = pImp->nDockLine = (sal_uInt16) aPos.X(); 1108 pImp->nPos = pImp->nDockPos = (sal_uInt16) aPos.Y(); 1109 pImp->nVerticalSize = pImp->aSplitSize.Height(); 1110 pImp->nHorizontalSize = pImp->aSplitSize.Width(); 1111 if ( GetSplitSizeFromString( aStr, pImp->aSplitSize )) 1112 bVertHorzRead = sal_True; 1113 } 1114 } 1115 } 1116 else { 1117 DBG_ERROR( "Information is missing!" ); 1118 } 1119 } 1120 1121 if ( !bVertHorzRead ) 1122 { 1123 pImp->nVerticalSize = pImp->aSplitSize.Height(); 1124 pImp->nHorizontalSize = pImp->aSplitSize.Width(); 1125 } 1126 1127 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); 1128 if ( GetAlignment() != SFX_ALIGN_NOALIGNMENT ) 1129 { 1130 // check if SfxWorkWindow is able to allow docking at its border 1131 if ( 1132 !pWorkWin->IsDockingAllowed() || 1133 !pWorkWin->IsInternalDockingAllowed() || 1134 ( (GetFloatStyle() & WB_STANDALONE) && Application::IsInModalMode()) ) 1135 { 1136 SetAlignment( SFX_ALIGN_NOALIGNMENT ); 1137 } 1138 } 1139 1140 // detect floating mode 1141 // toggeling mode will not execute code in handlers, because pImp->bConstructed is not set yet 1142 sal_Bool bFloatMode = IsFloatingMode(); 1143 if ( bFloatMode != ((GetAlignment() == SFX_ALIGN_NOALIGNMENT)) ) 1144 { 1145 bFloatMode = !bFloatMode; 1146 SetFloatingMode( bFloatMode ); 1147 if ( bFloatMode ) 1148 { 1149 if ( pImp->aWinState.Len() ) 1150 GetFloatingWindow()->SetWindowState( pImp->aWinState ); 1151 else 1152 GetFloatingWindow()->SetOutputSizePixel( GetFloatingSize() ); 1153 } 1154 } 1155 1156 if ( IsFloatingMode() ) 1157 { 1158 // validate last alignment 1159 SfxChildAlignment eLastAlign = pImp->GetLastAlignment(); 1160 if ( eLastAlign == SFX_ALIGN_NOALIGNMENT) 1161 eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_LEFT); 1162 if ( eLastAlign == SFX_ALIGN_NOALIGNMENT) 1163 eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_RIGHT); 1164 if ( eLastAlign == SFX_ALIGN_NOALIGNMENT) 1165 eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_TOP); 1166 if ( eLastAlign == SFX_ALIGN_NOALIGNMENT) 1167 eLastAlign = CheckAlignment(eLastAlign, SFX_ALIGN_BOTTOM); 1168 pImp->SetLastAlignment(eLastAlign); 1169 } 1170 else 1171 { 1172 // docked window must have NOALIGNMENT as last alignment 1173 pImp->SetLastAlignment(SFX_ALIGN_NOALIGNMENT); 1174 1175 if ( pImp->bSplitable ) 1176 { 1177 // pImp->bAutoHide = ( pInfo->nFlags & SFX_CHILDWIN_AUTOHIDE) != 0; 1178 pImp->pSplitWin = pWorkWin->GetSplitWindow_Impl(GetAlignment()); 1179 pImp->pSplitWin->InsertWindow(this, pImp->aSplitSize); 1180 } 1181 else 1182 { 1183 //?????? Currently not supported 1184 // Fenster ist individuell angedockt; Gr"o\se berechnen. 1185 // Dazu mu\s sie mit der FloatingSize initialisiert werden, falls 1186 // irgendwer sich darauf verl"a\st, da\s eine vern"unftige Gr"o\se 1187 // gesetzt ist 1188 SetSizePixel(GetFloatingSize()); 1189 SetSizePixel(CalcDockingSize(GetAlignment())); 1190 } 1191 } 1192 1193 // save alignment 1194 pImp->SetDockAlignment( GetAlignment() ); 1195 } 1196 1197 void SfxDockingWindow::Initialize_Impl() 1198 { 1199 if ( !pMgr ) 1200 { 1201 // Bugfix #39771 1202 pImp->bConstructed = sal_True; 1203 return; 1204 } 1205 1206 FloatingWindow* pFloatWin = GetFloatingWindow(); 1207 sal_Bool bSet = sal_False; 1208 if ( pFloatWin ) 1209 { 1210 bSet = !pFloatWin->IsDefaultPos(); 1211 } 1212 else 1213 { 1214 Point aPos = GetFloatingPos(); 1215 if ( aPos != Point() ) 1216 bSet = sal_True; 1217 } 1218 1219 if ( !bSet) 1220 { 1221 SfxViewFrame *pFrame = pBindings->GetDispatcher_Impl()->GetFrame(); 1222 Window* pEditWin = pFrame->GetViewShell()->GetWindow(); 1223 Point aPos = pEditWin->OutputToScreenPixel( pEditWin->GetPosPixel() ); 1224 aPos = GetParent()->ScreenToOutputPixel( aPos ); 1225 SetFloatingPos( aPos ); 1226 } 1227 1228 if ( pFloatWin ) 1229 { 1230 // initialize floating window 1231 if ( !pImp->aWinState.Len() ) 1232 // window state never set before, get if from defaults 1233 pImp->aWinState = pFloatWin->GetWindowState(); 1234 1235 // trick: use VCL method SetWindowState to adjust position and size 1236 pFloatWin->SetWindowState( pImp->aWinState ); 1237 1238 // remember floating size for calculating alignment and tracking rectangle 1239 SetFloatingSize( pFloatWin->GetSizePixel() ); 1240 1241 // some versions of VCL didn't call resize in the current situation 1242 //Resize(); 1243 } 1244 1245 // allow calling of docking handlers 1246 pImp->bConstructed = sal_True; 1247 } 1248 1249 //------------------------------------------------------------------------- 1250 1251 void SfxDockingWindow::FillInfo(SfxChildWinInfo& rInfo) const 1252 1253 /* [Beschreibung] 1254 1255 F"ullt ein SfxChildWinInfo mit f"ur SfxDockingWindow spezifischen Daten, 1256 damit sie in die INI-Datei geschrieben werden koennen. 1257 Es wird angenommen, da\s rInfo alle anderen evt. relevanten Daten in 1258 der ChildWindow-Klasse erh"alt. 1259 Eingetragen werden hier gemerkten Gr"o\sen, das ZoomIn-Flag und die 1260 f"ur das Docking relevanten Informationen. 1261 Wird diese Methode "uberschrieben, mu\s zuerst die Basisimplementierung 1262 gerufen werden. 1263 */ 1264 1265 { 1266 if ( !pMgr ) 1267 return; 1268 1269 if ( GetFloatingWindow() && pImp->bConstructed ) 1270 pImp->aWinState = GetFloatingWindow()->GetWindowState(); 1271 1272 rInfo.aWinState = pImp->aWinState; 1273 rInfo.aExtraString = DEFINE_CONST_UNICODE("AL:("); 1274 rInfo.aExtraString += String::CreateFromInt32((sal_uInt16) GetAlignment()); 1275 rInfo.aExtraString += ','; 1276 rInfo.aExtraString += String::CreateFromInt32 ((sal_uInt16) pImp->GetLastAlignment()); 1277 if ( pImp->bSplitable ) 1278 { 1279 Point aPos(pImp->nLine, pImp->nPos); 1280 rInfo.aExtraString += ','; 1281 rInfo.aExtraString += String::CreateFromInt32( aPos.X() ); 1282 rInfo.aExtraString += '/'; 1283 rInfo.aExtraString += String::CreateFromInt32( aPos.Y() ); 1284 rInfo.aExtraString += '/'; 1285 rInfo.aExtraString += String::CreateFromInt32( pImp->nHorizontalSize ); 1286 rInfo.aExtraString += '/'; 1287 rInfo.aExtraString += String::CreateFromInt32( pImp->nVerticalSize ); 1288 rInfo.aExtraString += ','; 1289 rInfo.aExtraString += String::CreateFromInt32( pImp->aSplitSize.Width() ); 1290 rInfo.aExtraString += ';'; 1291 rInfo.aExtraString += String::CreateFromInt32( pImp->aSplitSize.Height() ); 1292 } 1293 1294 rInfo.aExtraString += ')'; 1295 } 1296 1297 //------------------------------------------------------------------------- 1298 1299 SfxDockingWindow::~SfxDockingWindow() 1300 { 1301 ReleaseChildWindow_Impl(); 1302 delete pImp; 1303 } 1304 1305 void SfxDockingWindow::ReleaseChildWindow_Impl() 1306 { 1307 if ( pMgr && pMgr->GetFrame() == pBindings->GetActiveFrame() ) 1308 pBindings->SetActiveFrame( NULL ); 1309 1310 if ( pMgr && pImp->pSplitWin && pImp->pSplitWin->IsItemValid( GetType() ) ) 1311 pImp->pSplitWin->RemoveWindow(this); 1312 1313 pMgr=NULL; 1314 } 1315 1316 //------------------------------------------------------------------------- 1317 1318 SfxChildAlignment SfxDockingWindow::CalcAlignment(const Point& rPos, Rectangle& rRect) 1319 1320 /* [Beschreibung] 1321 1322 Diese Methode berechnet f"ur gegebene Mausposition und tracking rectangle, 1323 welches Alignment sich daraus ergeben w"urde. Beim Wechsel des Alignments 1324 kann sich auch das tracking rectangle "andern, so dass ein ver"andertes 1325 rectangle zur"uckgegeben wird. 1326 1327 Der Klassenbenutzer kann das Verhalten dieser Methode und damit das Verhalten 1328 seiner DockinWindow-Klasse beim Docken beeinflussen, indem er die hier 1329 aufgerufene virtuelle Methode 1330 1331 SfxDockingWindow::CalcDockingSize(SfxChildAlignment eAlign) 1332 1333 "uberschreibt (s.u.). 1334 */ 1335 1336 { 1337 // calculate hypothetical sizes for different modes 1338 Size aFloatingSize(CalcDockingSize(SFX_ALIGN_NOALIGNMENT)); 1339 Size aVerticalSize(CalcDockingSize(SFX_ALIGN_LEFT)); 1340 Size aHorizontalSize(CalcDockingSize(SFX_ALIGN_TOP)); 1341 1342 // check if docking is permitted 1343 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); 1344 if ( !pWorkWin->IsDockingAllowed() ) 1345 { 1346 rRect.SetSize( aFloatingSize ); 1347 return pImp->GetDockAlignment(); 1348 } 1349 1350 // calculate borders to shrink inner area before checking for intersection with tracking rectangle 1351 long nLRBorder, nTBBorder; 1352 if ( pImp->bSplitable ) 1353 { 1354 // take the smaller size of docked and floating mode 1355 Size aSize = pImp->aSplitSize; 1356 if ( GetFloatingSize().Height() < aSize.Height() ) 1357 aSize.Height() = GetFloatingSize().Height(); 1358 if ( GetFloatingSize().Width() < aSize.Width() ) 1359 aSize.Width() = GetFloatingSize().Width(); 1360 1361 nLRBorder = aSize.Width(); 1362 nTBBorder = aSize.Height(); 1363 } 1364 else 1365 { 1366 nLRBorder = aVerticalSize.Width(); 1367 nTBBorder = aHorizontalSize.Height(); 1368 } 1369 1370 // limit border to predefined constant values 1371 if ( nLRBorder > MAX_TOGGLEAREA_WIDTH ) 1372 nLRBorder = MAX_TOGGLEAREA_WIDTH; 1373 if ( nTBBorder > MAX_TOGGLEAREA_WIDTH ) 1374 nTBBorder = MAX_TOGGLEAREA_WIDTH; 1375 1376 // shrink area for floating mode if possible 1377 Rectangle aInRect = GetInnerRect(); 1378 if ( aInRect.GetWidth() > nLRBorder ) 1379 aInRect.Left() += nLRBorder/2; 1380 if ( aInRect.GetWidth() > nLRBorder ) 1381 aInRect.Right() -= nLRBorder/2; 1382 if ( aInRect.GetHeight() > nTBBorder ) 1383 aInRect.Top() += nTBBorder/2; 1384 if ( aInRect.GetHeight() > nTBBorder ) 1385 aInRect.Bottom() -= nTBBorder/2; 1386 1387 // calculate alignment resulting from docking rectangle 1388 sal_Bool bBecomesFloating = sal_False; 1389 SfxChildAlignment eDockAlign = pImp->GetDockAlignment(); 1390 Rectangle aDockingRect( rRect ); 1391 if ( !IsFloatingMode() ) 1392 { 1393 // don't use tracking rectangle for alignment check, because it will be too large 1394 // to get a floating mode as result - switch to floating size 1395 // so the calculation only depends on the position of the rectangle, not the current 1396 // docking state of the window 1397 aDockingRect.SetSize( GetFloatingSize() ); 1398 1399 // in this mode docking is never done by keyboard, so it's OK to use the mouse position 1400 aDockingRect.SetPos( pWorkWin->GetWindow()->OutputToScreenPixel( pWorkWin->GetWindow()->GetPointerPosPixel() ) ); 1401 } 1402 1403 Point aPos = aDockingRect.TopLeft(); 1404 Rectangle aIntersect = GetOuterRect().GetIntersection( aDockingRect ); 1405 if ( aIntersect.IsEmpty() ) 1406 // docking rectangle completely outside docking area -> floating mode 1407 bBecomesFloating = sal_True; 1408 else 1409 { 1410 // create a small test rect around the mouse position and use this one 1411 // instead of the passed rRect to not dock too easily or by accident 1412 Rectangle aSmallDockingRect; 1413 aSmallDockingRect.SetSize( Size( MAX_TOGGLEAREA_WIDTH, MAX_TOGGLEAREA_HEIGHT ) ); 1414 Point aNewPos(rPos); 1415 aNewPos.X() -= aSmallDockingRect.GetWidth()/2; 1416 aNewPos.Y() -= aSmallDockingRect.GetHeight()/2; 1417 aSmallDockingRect.SetPos(rPos); 1418 Rectangle aIntersectRect = aInRect.GetIntersection( aSmallDockingRect ); 1419 if ( aIntersectRect == aSmallDockingRect ) 1420 // docking rectangle completely inside (shrinked) inner area -> floating mode 1421 bBecomesFloating = sal_True; 1422 } 1423 1424 if ( bBecomesFloating ) 1425 { 1426 eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_NOALIGNMENT); 1427 } 1428 else 1429 { 1430 // docking rectangle is in the "sensible area" 1431 Point aInPosTL( aPos.X()-aInRect.Left(), aPos.Y()-aInRect.Top() ); 1432 Point aInPosBR( aPos.X()-aInRect.Left() + aDockingRect.GetWidth(), aPos.Y()-aInRect.Top() + aDockingRect.GetHeight() ); 1433 Size aInSize = aInRect.GetSize(); 1434 sal_Bool bNoChange = sal_False; 1435 1436 // check if alignment is still unchanged 1437 switch ( GetAlignment() ) 1438 { 1439 case SFX_ALIGN_LEFT: 1440 case SFX_ALIGN_FIRSTLEFT: 1441 case SFX_ALIGN_LASTLEFT: 1442 if (aInPosTL.X() <= 0) 1443 { 1444 eDockAlign = GetAlignment(); 1445 bNoChange = sal_True; 1446 } 1447 break; 1448 case SFX_ALIGN_TOP: 1449 case SFX_ALIGN_LOWESTTOP: 1450 case SFX_ALIGN_HIGHESTTOP: 1451 if ( aInPosTL.Y() <= 0) 1452 { 1453 eDockAlign = GetAlignment(); 1454 bNoChange = sal_True; 1455 } 1456 break; 1457 case SFX_ALIGN_RIGHT: 1458 case SFX_ALIGN_FIRSTRIGHT: 1459 case SFX_ALIGN_LASTRIGHT: 1460 if ( aInPosBR.X() >= aInSize.Width()) 1461 { 1462 eDockAlign = GetAlignment(); 1463 bNoChange = sal_True; 1464 } 1465 break; 1466 case SFX_ALIGN_BOTTOM: 1467 case SFX_ALIGN_LOWESTBOTTOM: 1468 case SFX_ALIGN_HIGHESTBOTTOM: 1469 if ( aInPosBR.Y() >= aInSize.Height()) 1470 { 1471 eDockAlign = GetAlignment(); 1472 bNoChange = sal_True; 1473 } 1474 break; 1475 default: 1476 break; 1477 } 1478 1479 if ( !bNoChange ) 1480 { 1481 // alignment will change, test alignment according to distance of the docking rectangles edges 1482 sal_Bool bForbidden = sal_True; 1483 if ( aInPosTL.X() <= 0) 1484 { 1485 eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_LEFT); 1486 bForbidden = ( eDockAlign != SFX_ALIGN_LEFT && 1487 eDockAlign != SFX_ALIGN_FIRSTLEFT && 1488 eDockAlign != SFX_ALIGN_LASTLEFT ); 1489 } 1490 1491 if ( bForbidden && aInPosTL.Y() <= 0) 1492 { 1493 eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_TOP); 1494 bForbidden = ( eDockAlign != SFX_ALIGN_TOP && 1495 eDockAlign != SFX_ALIGN_HIGHESTTOP && 1496 eDockAlign != SFX_ALIGN_LOWESTTOP ); 1497 } 1498 1499 if ( bForbidden && aInPosBR.X() >= aInSize.Width()) 1500 { 1501 eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_RIGHT); 1502 bForbidden = ( eDockAlign != SFX_ALIGN_RIGHT && 1503 eDockAlign != SFX_ALIGN_FIRSTRIGHT && 1504 eDockAlign != SFX_ALIGN_LASTRIGHT ); 1505 } 1506 1507 if ( bForbidden && aInPosBR.Y() >= aInSize.Height()) 1508 { 1509 eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_BOTTOM); 1510 bForbidden = ( eDockAlign != SFX_ALIGN_BOTTOM && 1511 eDockAlign != SFX_ALIGN_HIGHESTBOTTOM && 1512 eDockAlign != SFX_ALIGN_LOWESTBOTTOM ); 1513 } 1514 1515 // the calculated alignment was rejected by the window -> take floating mode 1516 if ( bForbidden ) 1517 eDockAlign = CheckAlignment(pImp->GetDockAlignment(),SFX_ALIGN_NOALIGNMENT); 1518 } 1519 } 1520 1521 if ( eDockAlign == SFX_ALIGN_NOALIGNMENT ) 1522 { 1523 //Im FloatingMode erh"alt das tracking rectangle die floating size 1524 // wg. SV-Bug darf rRect nur ver"andert werden, wenn sich das 1525 // Alignment "andert ! 1526 if ( eDockAlign != pImp->GetDockAlignment() ) 1527 aDockingRect.SetSize( aFloatingSize ); 1528 } 1529 else if ( pImp->bSplitable ) 1530 { 1531 sal_uInt16 nLine, nPos; 1532 SfxSplitWindow *pSplitWin = pWorkWin->GetSplitWindow_Impl(eDockAlign); 1533 aPos = pSplitWin->ScreenToOutputPixel( aPos ); 1534 if ( pSplitWin->GetWindowPos( aPos, nLine, nPos ) ) 1535 { 1536 // mouse over splitwindow, get line and position 1537 pImp->nDockLine = nLine; 1538 pImp->nDockPos = nPos; 1539 pImp->bNewLine = sal_False; 1540 } 1541 else 1542 { 1543 if ( 0 ) 1544 { 1545 // mouse touches outer border -> treated as floating mode 1546 eDockAlign = SFX_ALIGN_NOALIGNMENT; 1547 aDockingRect.SetSize( aFloatingSize ); 1548 rRect = aDockingRect; 1549 return eDockAlign; 1550 } 1551 1552 // mouse touches inner border -> create new line 1553 if ( eDockAlign == GetAlignment() && pImp->pSplitWin && 1554 pImp->nLine == pImp->pSplitWin->GetLineCount()-1 && pImp->pSplitWin->GetWindowCount(pImp->nLine) == 1 ) 1555 { 1556 // if this window is the only one in the last line, it can't be docked as new line in the same splitwindow 1557 pImp->nDockLine = pImp->nLine; 1558 pImp->nDockPos = pImp->nPos; 1559 pImp->bNewLine = sal_False; 1560 } 1561 else 1562 { 1563 // create new line 1564 pImp->nDockLine = pSplitWin->GetLineCount(); 1565 pImp->nDockPos = 0; 1566 pImp->bNewLine = sal_True; 1567 } 1568 } 1569 1570 sal_Bool bChanged = pImp->nLine != pImp->nDockLine || pImp->nPos != pImp->nDockPos || eDockAlign != GetAlignment(); 1571 if ( !bChanged && !IsFloatingMode() ) 1572 { 1573 // window only sightly moved, no change of any property 1574 rRect.SetSize( pImp->aSplitSize ); 1575 rRect.SetPos( aDockingRect.TopLeft() ); 1576 return eDockAlign; 1577 } 1578 1579 // calculate new size and position 1580 Size aSize; 1581 Point aPoint = aDockingRect.TopLeft(); 1582 Size aInnerSize = GetInnerRect().GetSize(); 1583 if ( eDockAlign == SFX_ALIGN_LEFT || eDockAlign == SFX_ALIGN_RIGHT ) 1584 { 1585 if ( pImp->bNewLine ) 1586 { 1587 // set height to height of free area 1588 aSize.Height() = aInnerSize.Height(); 1589 aSize.Width() = pImp->nHorizontalSize; 1590 if ( eDockAlign == SFX_ALIGN_LEFT ) 1591 { 1592 aPoint = aInnerRect.TopLeft(); 1593 } 1594 else 1595 { 1596 aPoint = aInnerRect.TopRight(); 1597 aPoint.X() -= aSize.Width(); 1598 } 1599 } 1600 else 1601 { 1602 // get width from splitwindow 1603 aSize.Width() = pSplitWin->GetLineSize(nLine); 1604 aSize.Height() = pImp->aSplitSize.Height(); 1605 } 1606 } 1607 else 1608 { 1609 if ( pImp->bNewLine ) 1610 { 1611 // set width to width of free area 1612 aSize.Width() = aInnerSize.Width(); 1613 aSize.Height() = pImp->nVerticalSize; 1614 if ( eDockAlign == SFX_ALIGN_TOP ) 1615 { 1616 aPoint = aInnerRect.TopLeft(); 1617 } 1618 else 1619 { 1620 aPoint = aInnerRect.BottomLeft(); 1621 aPoint.Y() -= aSize.Height(); 1622 } 1623 } 1624 else 1625 { 1626 // get height from splitwindow 1627 aSize.Height() = pSplitWin->GetLineSize(nLine); 1628 aSize.Width() = pImp->aSplitSize.Width(); 1629 } 1630 } 1631 1632 aDockingRect.SetSize( aSize ); 1633 aDockingRect.SetPos( aPoint ); 1634 } 1635 else 1636 { 1637 // window can be docked, but outside our splitwindows 1638 // tracking rectangle only needs to be modified if alignment was changed 1639 if ( eDockAlign != pImp->GetDockAlignment() ) 1640 { 1641 switch ( eDockAlign ) 1642 { 1643 case SFX_ALIGN_LEFT: 1644 case SFX_ALIGN_RIGHT: 1645 case SFX_ALIGN_FIRSTLEFT: 1646 aDockingRect.SetPos( aInnerRect.TopLeft() ); 1647 aDockingRect.SetSize( aVerticalSize ); 1648 break; 1649 case SFX_ALIGN_LASTLEFT: 1650 case SFX_ALIGN_FIRSTRIGHT: 1651 case SFX_ALIGN_LASTRIGHT: 1652 { 1653 Point aPt( aInnerRect.TopRight() ); 1654 aPt.X() -= aDockingRect.GetWidth(); 1655 aDockingRect.SetPos( aPt ); 1656 aDockingRect.SetSize( aVerticalSize ); 1657 break; 1658 } 1659 1660 case SFX_ALIGN_TOP: 1661 case SFX_ALIGN_BOTTOM: 1662 case SFX_ALIGN_LOWESTTOP: 1663 aDockingRect.SetPos( aInnerRect.TopLeft() ); 1664 aDockingRect.SetSize( aHorizontalSize ); 1665 break; 1666 case SFX_ALIGN_HIGHESTTOP: 1667 case SFX_ALIGN_LOWESTBOTTOM: 1668 case SFX_ALIGN_HIGHESTBOTTOM: 1669 { 1670 Point aPt( aInnerRect.BottomLeft() ); 1671 aPt.Y() -= aDockingRect.GetHeight(); 1672 aDockingRect.SetPos( aPt ); 1673 aDockingRect.SetSize( aHorizontalSize ); 1674 break; 1675 } 1676 default: 1677 break; 1678 } 1679 } 1680 } 1681 1682 rRect = aDockingRect; 1683 return eDockAlign; 1684 } 1685 1686 //------------------------------------------------------------------------- 1687 1688 Size SfxDockingWindow::CalcDockingSize(SfxChildAlignment eAlign) 1689 1690 /* [Beschreibung] 1691 1692 Virtuelle Methode der Klasse SfxDockingWindow. 1693 Hier wird festgelegt, wie sich die Gr"o\se des DockingWindows abh"angig vom 1694 Alignment "andert. 1695 Die Basisimplementation setzt im Floating Mode die Gr"o\se auf die gemerkte 1696 Floating Size. 1697 Bei horizontalem Alignment wird die Breite auf die Breite des "au\seren 1698 DockingRects, bei vertikalem Alignment die H"ohe auf die H"ohe des inneren 1699 DockingRects (ergibt sich aus der Reihenfolge, in der im SFX ChildWindows 1700 ausgegeben werden). Die jeweils andere Gr"o\se wird auf die aktuelle 1701 Floating Size gesetzt, hier k"onnte eine abgeleitete Klasse "andernd 1702 eingreifen. 1703 Die DockingSize mu\s f"ur Left/Right und Top/Bottom jeweils gleich sein. 1704 */ 1705 1706 { 1707 // Achtung: falls das Resizing auch im angedockten Zustand geht, mu\s dabei 1708 // auch die Floating Size angepa\st werden !? 1709 1710 Size aSize = GetFloatingSize(); 1711 switch (eAlign) 1712 { 1713 case SFX_ALIGN_TOP: 1714 case SFX_ALIGN_BOTTOM: 1715 case SFX_ALIGN_LOWESTTOP: 1716 case SFX_ALIGN_HIGHESTTOP: 1717 case SFX_ALIGN_LOWESTBOTTOM: 1718 case SFX_ALIGN_HIGHESTBOTTOM: 1719 aSize.Width() = aOuterRect.Right() - aOuterRect.Left(); 1720 break; 1721 case SFX_ALIGN_LEFT: 1722 case SFX_ALIGN_RIGHT: 1723 case SFX_ALIGN_FIRSTLEFT: 1724 case SFX_ALIGN_LASTLEFT: 1725 case SFX_ALIGN_FIRSTRIGHT: 1726 case SFX_ALIGN_LASTRIGHT: 1727 aSize.Height() = aInnerRect.Bottom() - aInnerRect.Top(); 1728 break; 1729 case SFX_ALIGN_NOALIGNMENT: 1730 break; 1731 default: 1732 break; 1733 } 1734 1735 return aSize; 1736 } 1737 1738 //------------------------------------------------------------------------- 1739 1740 SfxChildAlignment SfxDockingWindow::CheckAlignment(SfxChildAlignment, 1741 SfxChildAlignment eAlign) 1742 1743 /* [Beschreibung] 1744 1745 Virtuelle Methode der Klasse SfxDockingWindow. 1746 Hier kann eine abgeleitete Klasse bestimmte Alignments verbieten. 1747 Die Basisimplementation verbietet kein Alignment. 1748 */ 1749 1750 { 1751 return eAlign; 1752 } 1753 1754 //------------------------------------------------------------------------- 1755 1756 sal_Bool SfxDockingWindow::Close() 1757 1758 /* [Beschreibung] 1759 1760 Das Fenster wird geschlossen, indem das ChildWindow durch Ausf"uhren des 1761 ChildWindow-Slots zerst"ort wird. 1762 Wird diese Methode von einer abgeleiteten Klasse "uberschrieben, mu\s 1763 danach SfxDockingWindow::Close() gerufen werden, wenn nicht das Close() 1764 mit "return FALSE" abgebrochen wird. 1765 1766 */ 1767 { 1768 // Execute mit Parametern, da Toggle von einigen ChildWindows ignoriert 1769 // werden kann 1770 if ( !pMgr ) 1771 return sal_True; 1772 1773 SfxBoolItem aValue( pMgr->GetType(), sal_False); 1774 pBindings->GetDispatcher_Impl()->Execute( 1775 pMgr->GetType(), SFX_CALLMODE_RECORD | SFX_CALLMODE_ASYNCHRON, &aValue, 0L ); 1776 return sal_True; 1777 } 1778 1779 //------------------------------------------------------------------------- 1780 1781 void SfxDockingWindow::Paint(const Rectangle& /*rRect*/) 1782 1783 /* [Beschreibung] 1784 1785 Es wird im angedockten Zustand eine Begrenzungslinie an der angedockten 1786 Kante und ein Rahmen ausgegeben. Dabei wird SVLOOK ber"ucksichtigt. 1787 */ 1788 1789 { 1790 if ( pImp->bSplitable || IsFloatingMode() ) 1791 return; 1792 1793 Rectangle aRect = Rectangle(Point(0, 0), 1794 GetOutputSizePixel()); 1795 switch (GetAlignment()) 1796 { 1797 case SFX_ALIGN_TOP: 1798 { 1799 DrawLine(aRect.BottomLeft(), aRect.BottomRight()); 1800 aRect.Bottom()--; 1801 break; 1802 } 1803 1804 case SFX_ALIGN_BOTTOM: 1805 { 1806 DrawLine(aRect.TopLeft(), aRect.TopRight()); 1807 aRect.Top()++; 1808 break; 1809 } 1810 1811 case SFX_ALIGN_LEFT: 1812 { 1813 DrawLine(aRect.TopRight(), aRect.BottomRight()); 1814 aRect.Right()--; 1815 break; 1816 } 1817 1818 case SFX_ALIGN_RIGHT: 1819 { 1820 DrawLine(aRect.TopLeft(), aRect.BottomLeft()); 1821 aRect.Left()++; 1822 break; 1823 } 1824 default: 1825 break; 1826 } 1827 1828 DecorationView aView( this ); 1829 aView.DrawFrame( aRect, FRAME_DRAW_OUT ); 1830 } 1831 1832 //------------------------------------------------------------------------- 1833 1834 void SfxDockingWindow::SetMinOutputSizePixel( const Size& rSize ) 1835 1836 /* [Beschreibung] 1837 1838 Mit dieser Methode kann eine minimale OutpuSize gesetzt werden, die 1839 im Resizing()-Handler abgefragt wird. 1840 */ 1841 1842 { 1843 pImp->aMinSize = rSize; 1844 DockingWindow::SetMinOutputSizePixel( rSize ); 1845 } 1846 1847 //------------------------------------------------------------------------- 1848 1849 Size SfxDockingWindow::GetMinOutputSizePixel() const 1850 1851 /* [Beschreibung] 1852 1853 Die gesetzte minimale Gr"o\se wird zur"uckgegeben. 1854 */ 1855 1856 { 1857 return pImp->aMinSize; 1858 } 1859 1860 //------------------------------------------------------------------------- 1861 1862 long SfxDockingWindow::Notify( NotifyEvent& rEvt ) 1863 { 1864 if ( rEvt.GetType() == EVENT_GETFOCUS ) 1865 { 1866 pBindings->SetActiveFrame( pMgr->GetFrame() ); 1867 1868 if ( pImp->pSplitWin ) 1869 pImp->pSplitWin->SetActiveWindow_Impl( this ); 1870 else 1871 pMgr->Activate_Impl(); 1872 1873 Window* pWindow = rEvt.GetWindow(); 1874 rtl::OString sHelpId; 1875 while ( !sHelpId.getLength() && pWindow ) 1876 { 1877 sHelpId = pWindow->GetHelpId(); 1878 pWindow = pWindow->GetParent(); 1879 } 1880 1881 if ( sHelpId.getLength() ) 1882 SfxHelp::OpenHelpAgent( &pBindings->GetDispatcher_Impl()->GetFrame()->GetFrame(), sHelpId ); 1883 1884 // In VCL geht Notify zun"achst an das Fenster selbst, 1885 // also base class rufen, sonst erf"ahrt der parent nichts 1886 // if ( rEvt.GetWindow() == this ) PB: #i74693# not necessary any longer 1887 DockingWindow::Notify( rEvt ); 1888 return sal_True; 1889 } 1890 else if( rEvt.GetType() == EVENT_KEYINPUT ) 1891 { 1892 // KeyInput zuerst f"ur Dialogfunktionen zulassen 1893 if ( !DockingWindow::Notify( rEvt ) && SfxViewShell::Current() ) 1894 // dann auch global g"ultige Acceleratoren verwenden 1895 return SfxViewShell::Current()->GlobalKeyInput_Impl( *rEvt.GetKeyEvent() ); 1896 return sal_True; 1897 } 1898 else if ( rEvt.GetType() == EVENT_LOSEFOCUS && !HasChildPathFocus() ) 1899 { 1900 pBindings->SetActiveFrame( NULL ); 1901 pMgr->Deactivate_Impl(); 1902 } 1903 1904 return DockingWindow::Notify( rEvt ); 1905 } 1906 1907 1908 sal_uInt16 SfxDockingWindow::GetWinBits_Impl() const 1909 { 1910 sal_uInt16 nBits = 0; 1911 // if ( pImp->bAutoHide ) 1912 // nBits |= SWIB_AUTOHIDE; 1913 return nBits; 1914 } 1915 1916 //------------------------------------------------------------------------- 1917 1918 void SfxDockingWindow::SetItemSize_Impl( const Size& rSize ) 1919 { 1920 pImp->aSplitSize = rSize; 1921 1922 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); 1923 SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW; 1924 if ( pImp->bSplitable ) 1925 eIdent = SFX_CHILDWIN_SPLITWINDOW; 1926 pWorkWin->ConfigChild_Impl( eIdent, SFX_ALIGNDOCKINGWINDOW, pMgr->GetType() ); 1927 } 1928 1929 void SfxDockingWindow::Disappear_Impl() 1930 { 1931 if ( pImp->pSplitWin && pImp->pSplitWin->IsItemValid( GetType() ) ) 1932 pImp->pSplitWin->RemoveWindow(this); 1933 } 1934 1935 void SfxDockingWindow::Reappear_Impl() 1936 { 1937 if ( pImp->pSplitWin && !pImp->pSplitWin->IsItemValid( GetType() ) ) 1938 { 1939 pImp->pSplitWin->InsertWindow( this, pImp->aSplitSize ); 1940 } 1941 } 1942 1943 sal_Bool SfxDockingWindow::IsAutoHide_Impl() const 1944 { 1945 if ( pImp->pSplitWin ) 1946 return !pImp->pSplitWin->IsFadeIn(); 1947 else 1948 return sal_False; 1949 } 1950 1951 sal_Bool SfxDockingWindow::IsPinned_Impl() const 1952 { 1953 if ( pImp->pSplitWin ) 1954 return pImp->pSplitWin->IsPinned(); 1955 else 1956 return sal_True; 1957 } 1958 void SfxDockingWindow::AutoShow( sal_Bool bShow ) 1959 { 1960 AutoShow_Impl(bShow); 1961 } 1962 1963 void SfxDockingWindow::AutoShow_Impl( sal_Bool bShow ) 1964 { 1965 if ( pImp->pSplitWin ) 1966 { 1967 if ( bShow ) 1968 pImp->pSplitWin->FadeIn(); 1969 else 1970 pImp->pSplitWin->FadeOut(); 1971 } 1972 } 1973 1974 /* 1975 void SfxDockingWindow::Pin_Impl( sal_Bool bPinned ) 1976 { 1977 if ( pImp->pSplitWin ) 1978 pImp->pSplitWin->Pin_Impl( bPinned ); 1979 } 1980 */ 1981 1982 SfxSplitWindow* SfxDockingWindow::GetSplitWindow_Impl() const 1983 { 1984 return pImp->pSplitWin; 1985 } 1986 1987 void SfxDockingWindow::FadeIn( sal_Bool /*bFadeIn*/ ) 1988 { 1989 } 1990 1991 void SfxDockingWindow::StateChanged( StateChangedType nStateChange ) 1992 { 1993 if ( nStateChange == STATE_CHANGE_INITSHOW ) 1994 Initialize_Impl(); 1995 1996 DockingWindow::StateChanged( nStateChange ); 1997 } 1998 1999 void SfxDockingWindow::Move() 2000 { 2001 if ( pImp ) 2002 pImp->aMoveTimer.Start(); 2003 } 2004 2005 IMPL_LINK( SfxDockingWindow, TimerHdl, Timer*, EMPTYARG) 2006 { 2007 pImp->aMoveTimer.Stop(); 2008 if ( IsReallyVisible() && IsFloatingMode() ) 2009 { 2010 if( !GetFloatingWindow()->IsRollUp() ) 2011 SetFloatingSize( GetOutputSizePixel() ); 2012 pImp->aWinState = GetFloatingWindow()->GetWindowState(); 2013 SfxChildIdentifier eIdent = SFX_CHILDWIN_DOCKINGWINDOW; 2014 if ( pImp->bSplitable ) 2015 eIdent = SFX_CHILDWIN_SPLITWINDOW; 2016 SfxWorkWindow *pWorkWin = pBindings->GetWorkWindow_Impl(); 2017 pWorkWin->ConfigChild_Impl( eIdent, SFX_ALIGNDOCKINGWINDOW, pMgr->GetType() ); 2018 } 2019 return 0; 2020 } 2021 2022