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