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_vcl.hxx" 30 31 #include <tools/time.hxx> 32 #include <tools/rc.h> 33 34 #include <vcl/event.hxx> 35 #include <vcl/floatwin.hxx> 36 #include <vcl/dockwin.hxx> 37 #include <vcl/svapp.hxx> 38 #include <vcl/timer.hxx> 39 #include <vcl/unowrap.hxx> 40 41 #include <svdata.hxx> 42 #include <window.h> 43 #include <brdwin.hxx> 44 #include <salframe.hxx> 45 46 47 48 // ======================================================================= 49 50 #define DOCKWIN_FLOATSTYLES (WB_SIZEABLE | WB_MOVEABLE | WB_CLOSEABLE | WB_STANDALONE | WB_PINABLE | WB_ROLLABLE ) 51 52 // ======================================================================= 53 54 // ----------------------------------------------------------------------- 55 56 class DockingWindow::ImplData 57 { 58 public: 59 ImplData(); 60 ~ImplData(); 61 62 Window* mpParent; 63 Size maMaxOutSize; 64 }; 65 66 DockingWindow::ImplData::ImplData() 67 { 68 mpParent = NULL; 69 maMaxOutSize = Size( SHRT_MAX, SHRT_MAX ); 70 } 71 72 DockingWindow::ImplData::~ImplData() 73 { 74 } 75 76 // ----------------------------------------------------------------------- 77 78 class ImplDockFloatWin : public FloatingWindow 79 { 80 private: 81 DockingWindow* mpDockWin; 82 sal_uLong mnLastTicks; 83 Timer maDockTimer; 84 Point maDockPos; 85 Rectangle maDockRect; 86 sal_Bool mbInMove; 87 sal_uLong mnLastUserEvent; 88 89 DECL_LINK( DockingHdl, ImplDockFloatWin* ); 90 DECL_LINK( DockTimerHdl, ImplDockFloatWin* ); 91 public: 92 ImplDockFloatWin( Window* pParent, WinBits nWinBits, 93 DockingWindow* pDockingWin ); 94 ~ImplDockFloatWin(); 95 96 virtual void Move(); 97 virtual void Resize(); 98 virtual void TitleButtonClick( sal_uInt16 nButton ); 99 virtual void Pin(); 100 virtual void Roll(); 101 virtual void PopupModeEnd(); 102 virtual void Resizing( Size& rSize ); 103 virtual sal_Bool Close(); 104 105 sal_uLong GetLastTicks() const { return mnLastTicks; } 106 }; 107 108 109 ImplDockFloatWin::ImplDockFloatWin( Window* pParent, WinBits nWinBits, 110 DockingWindow* pDockingWin ) : 111 FloatingWindow( pParent, nWinBits ), 112 mpDockWin( pDockingWin ), 113 mnLastTicks( Time::GetSystemTicks() ), 114 mbInMove( sal_False ), 115 mnLastUserEvent( 0 ) 116 { 117 // Daten vom DockingWindow uebernehmen 118 if ( pDockingWin ) 119 { 120 SetSettings( pDockingWin->GetSettings() ); 121 Enable( pDockingWin->IsEnabled(), sal_False ); 122 EnableInput( pDockingWin->IsInputEnabled(), sal_False ); 123 AlwaysEnableInput( pDockingWin->IsAlwaysEnableInput(), sal_False ); 124 EnableAlwaysOnTop( pDockingWin->IsAlwaysOnTopEnabled() ); 125 SetActivateMode( pDockingWin->GetActivateMode() ); 126 } 127 128 SetBackground(); 129 130 maDockTimer.SetTimeoutHdl( LINK( this, ImplDockFloatWin, DockTimerHdl ) ); 131 maDockTimer.SetTimeout( 50 ); 132 } 133 134 // ----------------------------------------------------------------------- 135 136 ImplDockFloatWin::~ImplDockFloatWin() 137 { 138 if( mnLastUserEvent ) 139 Application::RemoveUserEvent( mnLastUserEvent ); 140 } 141 142 // ----------------------------------------------------------------------- 143 144 IMPL_LINK( ImplDockFloatWin, DockTimerHdl, ImplDockFloatWin*, EMPTYARG ) 145 { 146 DBG_ASSERT( mpDockWin->IsFloatingMode(), "docktimer called but not floating" ); 147 148 maDockTimer.Stop(); 149 PointerState aState = GetPointerState(); 150 151 if( aState.mnState & KEY_MOD1 ) 152 { 153 // i43499 CTRL disables docking now 154 mpDockWin->GetParent()->ImplGetFrameWindow()->HideTracking(); 155 mpDockWin->EndDocking( maDockRect, sal_True ); 156 if( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) 157 maDockTimer.Start(); 158 } 159 else if( ! ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) ) 160 { 161 mpDockWin->GetParent()->ImplGetFrameWindow()->HideTracking(); 162 mpDockWin->EndDocking( maDockRect, sal_False ); 163 } 164 else 165 { 166 mpDockWin->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_BIG | SHOWTRACK_WINDOW ); 167 maDockTimer.Start(); 168 } 169 170 return 0; 171 } 172 173 IMPL_LINK( ImplDockFloatWin, DockingHdl, ImplDockFloatWin*, EMPTYARG ) 174 { 175 PointerState aState = mpDockWin->GetParent()->GetPointerState(); 176 177 mnLastUserEvent = 0; 178 if( mpDockWin->IsDockable() && 179 (Time::GetSystemTicks() - mnLastTicks > 500) && 180 ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) && 181 !(aState.mnState & KEY_MOD1) ) // i43499 CTRL disables docking now 182 { 183 maDockPos = Point( mpDockWin->GetParent()->AbsoluteScreenToOutputPixel( OutputToAbsoluteScreenPixel( Point() ) ) ); 184 maDockPos = mpDockWin->GetParent()->OutputToScreenPixel( maDockPos ); // sfx expects screen coordinates 185 186 if( ! mpDockWin->IsDocking() ) 187 mpDockWin->StartDocking(); 188 maDockRect = Rectangle( maDockPos, mpDockWin->GetSizePixel() ); 189 190 // mouse pos also in screen pixels 191 Point aMousePos = mpDockWin->GetParent()->OutputToScreenPixel( aState.maPos ); 192 193 sal_Bool bFloatMode = mpDockWin->Docking( aMousePos, maDockRect ); 194 if( ! bFloatMode ) 195 { 196 mpDockWin->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_OBJECT | SHOWTRACK_WINDOW ); 197 DockTimerHdl( this ); 198 } 199 else 200 { 201 mpDockWin->GetParent()->ImplGetFrameWindow()->HideTracking(); 202 maDockTimer.Stop(); 203 mpDockWin->EndDocking( maDockRect, sal_True ); 204 } 205 } 206 mbInMove = sal_False; 207 return 0; 208 } 209 // ----------------------------------------------------------------------- 210 211 void ImplDockFloatWin::Move() 212 { 213 if( mbInMove ) 214 return; 215 216 mbInMove = sal_True; 217 FloatingWindow::Move(); 218 mpDockWin->Move(); 219 220 /* 221 * note: the window should only dock if 222 * the user releases all mouse buttons. The real problem here 223 * is that we don't get mouse events (at least not on X) 224 * if the mouse is on the decoration. So we have to start an 225 * awkward timer based process that polls the modifier/buttons 226 * to see whether they are in the right condition shortly after the 227 * last Move message. 228 */ 229 if( ! mnLastUserEvent ) 230 mnLastUserEvent = Application::PostUserEvent( LINK( this, ImplDockFloatWin, DockingHdl ) ); 231 } 232 233 // ----------------------------------------------------------------------- 234 235 void ImplDockFloatWin::Resize() 236 { 237 FloatingWindow::Resize(); 238 Size aSize( GetSizePixel() ); 239 mpDockWin->ImplPosSizeWindow( 0, 0, aSize.Width(), aSize.Height(), WINDOW_POSSIZE_POSSIZE ); 240 } 241 242 // ----------------------------------------------------------------------- 243 244 void ImplDockFloatWin::TitleButtonClick( sal_uInt16 nButton ) 245 { 246 FloatingWindow::TitleButtonClick( nButton ); 247 mpDockWin->TitleButtonClick( nButton ); 248 } 249 250 // ----------------------------------------------------------------------- 251 252 void ImplDockFloatWin::Pin() 253 { 254 FloatingWindow::Pin(); 255 mpDockWin->Pin(); 256 } 257 258 // ----------------------------------------------------------------------- 259 260 void ImplDockFloatWin::Roll() 261 { 262 FloatingWindow::Roll(); 263 mpDockWin->Roll(); 264 } 265 266 // ----------------------------------------------------------------------- 267 268 void ImplDockFloatWin::PopupModeEnd() 269 { 270 FloatingWindow::PopupModeEnd(); 271 mpDockWin->PopupModeEnd(); 272 } 273 274 // ----------------------------------------------------------------------- 275 276 void ImplDockFloatWin::Resizing( Size& rSize ) 277 { 278 FloatingWindow::Resizing( rSize ); 279 mpDockWin->Resizing( rSize ); 280 } 281 282 // ----------------------------------------------------------------------- 283 284 sal_Bool ImplDockFloatWin::Close() 285 { 286 return mpDockWin->Close(); 287 } 288 289 // ======================================================================= 290 291 sal_Bool DockingWindow::ImplStartDocking( const Point& rPos ) 292 { 293 if ( !mbDockable ) 294 return sal_False; 295 296 maMouseOff = rPos; 297 maMouseStart = maMouseOff; 298 mbDocking = sal_True; 299 mbLastFloatMode = IsFloatingMode(); 300 mbStartFloat = mbLastFloatMode; 301 302 // FloatingBorder berechnen 303 FloatingWindow* pWin; 304 if ( mpFloatWin ) 305 pWin = mpFloatWin; 306 else 307 pWin = new ImplDockFloatWin( mpImplData->mpParent, mnFloatBits, NULL ); 308 pWin->GetBorder( mnDockLeft, mnDockTop, mnDockRight, mnDockBottom ); 309 if ( !mpFloatWin ) 310 delete pWin; 311 312 Point aPos = ImplOutputToFrame( Point() ); 313 Size aSize = Window::GetOutputSizePixel(); 314 mnTrackX = aPos.X(); 315 mnTrackY = aPos.Y(); 316 mnTrackWidth = aSize.Width(); 317 mnTrackHeight = aSize.Height(); 318 319 if ( mbLastFloatMode ) 320 { 321 maMouseOff.X() += mnDockLeft; 322 maMouseOff.Y() += mnDockTop; 323 mnTrackX -= mnDockLeft; 324 mnTrackY -= mnDockTop; 325 mnTrackWidth += mnDockLeft+mnDockRight; 326 mnTrackHeight += mnDockTop+mnDockBottom; 327 } 328 329 if ( GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_DOCKING && 330 !( mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ) ) // no full drag when migrating to system window 331 mbDragFull = sal_True; 332 else 333 { 334 StartDocking(); 335 mbDragFull = sal_False; 336 ImplUpdateAll(); 337 ImplGetFrameWindow()->ImplUpdateAll(); 338 } 339 340 StartTracking( STARTTRACK_KEYMOD ); 341 return sal_True; 342 } 343 344 // ======================================================================= 345 346 void DockingWindow::ImplInitDockingWindowData() 347 { 348 mpImplData = new ImplData; 349 mpWindowImpl->mbDockWin = sal_True; 350 351 mpFloatWin = NULL; 352 mbDockCanceled = sal_False; 353 mbDockPrevented = sal_False; 354 mbFloatPrevented = sal_False; 355 mbDocking = sal_False; 356 mbPined = sal_False; 357 mbRollUp = sal_False; 358 mbDockBtn = sal_False; 359 mbHideBtn = sal_False; 360 } 361 362 // ----------------------------------------------------------------------- 363 364 void DockingWindow::ImplInit( Window* pParent, WinBits nStyle ) 365 { 366 if ( !(nStyle & WB_NODIALOGCONTROL) ) 367 nStyle |= WB_DIALOGCONTROL; 368 369 mpImplData->mpParent = pParent; 370 mbDockable = (nStyle & WB_DOCKABLE) != 0; 371 mnFloatBits = WB_BORDER | (nStyle & DOCKWIN_FLOATSTYLES); 372 nStyle &= ~(DOCKWIN_FLOATSTYLES | WB_BORDER); 373 if ( nStyle & WB_DOCKBORDER ) 374 nStyle |= WB_BORDER; 375 376 Window::ImplInit( pParent, nStyle, NULL ); 377 378 ImplInitSettings(); 379 } 380 381 // ----------------------------------------------------------------------- 382 383 void DockingWindow::ImplInitSettings() 384 { 385 // Hack, damit man auch DockingWindows ohne Hintergrund bauen kann 386 // und noch nicht alles umgestellt ist 387 if ( IsBackground() ) 388 { 389 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings(); 390 391 Color aColor; 392 if ( IsControlBackground() ) 393 aColor = GetControlBackground(); 394 else if ( Window::GetStyle() & WB_3DLOOK ) 395 aColor = rStyleSettings.GetFaceColor(); 396 else 397 aColor = rStyleSettings.GetWindowColor(); 398 SetBackground( aColor ); 399 } 400 } 401 402 // ----------------------------------------------------------------------- 403 404 void DockingWindow::ImplLoadRes( const ResId& rResId ) 405 { 406 Window::ImplLoadRes( rResId ); 407 408 sal_uLong nMask = ReadLongRes(); 409 410 if ( (RSC_DOCKINGWINDOW_XYMAPMODE | RSC_DOCKINGWINDOW_X | 411 RSC_DOCKINGWINDOW_Y) & nMask ) 412 { 413 // Groessenangabe aus der Resource verwenden 414 Point aPos; 415 MapUnit ePosMap = MAP_PIXEL; 416 417 if ( RSC_DOCKINGWINDOW_XYMAPMODE & nMask ) 418 ePosMap = (MapUnit)ReadLongRes(); 419 420 if ( RSC_DOCKINGWINDOW_X & nMask ) 421 { 422 aPos.X() = ReadShortRes(); 423 aPos.X() = ImplLogicUnitToPixelX( aPos.X(), ePosMap ); 424 } 425 426 if ( RSC_DOCKINGWINDOW_Y & nMask ) 427 { 428 aPos.Y() = ReadShortRes(); 429 aPos.Y() = ImplLogicUnitToPixelY( aPos.Y(), ePosMap ); 430 } 431 432 SetFloatingPos( aPos ); 433 } 434 435 if ( nMask & RSC_DOCKINGWINDOW_FLOATING ) 436 { 437 if ( (sal_Bool)ReadShortRes() ) 438 SetFloatingMode( sal_True ); 439 } 440 } 441 442 // ----------------------------------------------------------------------- 443 444 DockingWindow::DockingWindow( WindowType nType ) : 445 Window( nType ) 446 { 447 ImplInitDockingWindowData(); 448 } 449 450 // ----------------------------------------------------------------------- 451 452 DockingWindow::DockingWindow( Window* pParent, WinBits nStyle ) : 453 Window( WINDOW_DOCKINGWINDOW ) 454 { 455 ImplInitDockingWindowData(); 456 ImplInit( pParent, nStyle ); 457 } 458 459 // ----------------------------------------------------------------------- 460 461 DockingWindow::DockingWindow( Window* pParent, const ResId& rResId ) : 462 Window( WINDOW_DOCKINGWINDOW ) 463 { 464 ImplInitDockingWindowData(); 465 rResId.SetRT( RSC_DOCKINGWINDOW ); 466 WinBits nStyle = ImplInitRes( rResId ); 467 ImplInit( pParent, nStyle ); 468 ImplLoadRes( rResId ); 469 470 if ( !(nStyle & WB_HIDE) ) 471 Show(); 472 } 473 474 // ----------------------------------------------------------------------- 475 476 DockingWindow::~DockingWindow() 477 { 478 if ( IsFloatingMode() ) 479 { 480 Show( sal_False, SHOW_NOFOCUSCHANGE ); 481 SetFloatingMode( sal_False ); 482 } 483 delete mpImplData; 484 } 485 486 // ----------------------------------------------------------------------- 487 488 void DockingWindow::Tracking( const TrackingEvent& rTEvt ) 489 { 490 if( GetDockingManager()->IsDockable( this ) ) // new docking interface 491 return Window::Tracking( rTEvt ); 492 493 if ( mbDocking ) 494 { 495 if ( rTEvt.IsTrackingEnded() ) 496 { 497 mbDocking = sal_False; 498 if ( mbDragFull ) 499 { 500 // Bei Abbruch alten Zustand wieder herstellen 501 if ( rTEvt.IsTrackingCanceled() ) 502 { 503 StartDocking(); 504 Rectangle aRect( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ); 505 EndDocking( aRect, mbStartFloat ); 506 } 507 } 508 else 509 { 510 HideTracking(); 511 if ( rTEvt.IsTrackingCanceled() ) 512 { 513 mbDockCanceled = sal_True; 514 EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode ); 515 mbDockCanceled = sal_False; 516 } 517 else 518 EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode ); 519 } 520 } 521 // Docking nur bei nicht synthetischen MouseEvents 522 else if ( !rTEvt.GetMouseEvent().IsSynthetic() || rTEvt.GetMouseEvent().IsModifierChanged() ) 523 { 524 Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel(); 525 Point aFrameMousePos = ImplOutputToFrame( aMousePos ); 526 Size aFrameSize = mpWindowImpl->mpFrameWindow->GetOutputSizePixel(); 527 if ( aFrameMousePos.X() < 0 ) 528 aFrameMousePos.X() = 0; 529 if ( aFrameMousePos.Y() < 0 ) 530 aFrameMousePos.Y() = 0; 531 if ( aFrameMousePos.X() > aFrameSize.Width()-1 ) 532 aFrameMousePos.X() = aFrameSize.Width()-1; 533 if ( aFrameMousePos.Y() > aFrameSize.Height()-1 ) 534 aFrameMousePos.Y() = aFrameSize.Height()-1; 535 aMousePos = ImplFrameToOutput( aFrameMousePos ); 536 aMousePos.X() -= maMouseOff.X(); 537 aMousePos.Y() -= maMouseOff.Y(); 538 Point aFramePos = ImplOutputToFrame( aMousePos ); 539 Rectangle aTrackRect( aFramePos, Size( mnTrackWidth, mnTrackHeight ) ); 540 Rectangle aCompRect = aTrackRect; 541 aFramePos.X() += maMouseOff.X(); 542 aFramePos.Y() += maMouseOff.Y(); 543 if ( mbDragFull ) 544 StartDocking(); 545 sal_Bool bFloatMode = Docking( aFramePos, aTrackRect ); 546 mbDockPrevented = sal_False; 547 mbFloatPrevented = sal_False; 548 if ( mbLastFloatMode != bFloatMode ) 549 { 550 if ( bFloatMode ) 551 { 552 aTrackRect.Left() -= mnDockLeft; 553 aTrackRect.Top() -= mnDockTop; 554 aTrackRect.Right() += mnDockRight; 555 aTrackRect.Bottom() += mnDockBottom; 556 } 557 else 558 { 559 if ( aCompRect == aTrackRect ) 560 { 561 aTrackRect.Left() += mnDockLeft; 562 aTrackRect.Top() += mnDockTop; 563 aTrackRect.Right() -= mnDockRight; 564 aTrackRect.Bottom() -= mnDockBottom; 565 } 566 } 567 mbLastFloatMode = bFloatMode; 568 } 569 if ( mbDragFull ) 570 { 571 Point aPos; 572 Point aOldPos = OutputToScreenPixel( aPos ); 573 EndDocking( aTrackRect, mbLastFloatMode ); 574 // Wenn der Status bzw. die Position sich 575 // geaendert hat, dann neu ausgeben 576 if ( aOldPos != OutputToScreenPixel( aPos ) ) 577 { 578 ImplUpdateAll(); 579 ImplGetFrameWindow()->ImplUpdateAll(); 580 } 581 // EndDocking( aTrackRect, mbLastFloatMode ); 582 } 583 else 584 { 585 sal_uInt16 nTrackStyle; 586 if ( bFloatMode ) 587 nTrackStyle = SHOWTRACK_BIG; 588 else 589 nTrackStyle = SHOWTRACK_OBJECT; 590 Rectangle aShowTrackRect = aTrackRect; 591 aShowTrackRect.SetPos( ImplFrameToOutput( aShowTrackRect.TopLeft() ) ); 592 ShowTracking( aShowTrackRect, nTrackStyle ); 593 594 // Maus-Offset neu berechnen, da Rechteck veraendert werden 595 // konnte 596 maMouseOff.X() = aFramePos.X() - aTrackRect.Left(); 597 maMouseOff.Y() = aFramePos.Y() - aTrackRect.Top(); 598 } 599 600 mnTrackX = aTrackRect.Left(); 601 mnTrackY = aTrackRect.Top(); 602 mnTrackWidth = aTrackRect.GetWidth(); 603 mnTrackHeight = aTrackRect.GetHeight(); 604 } 605 } 606 } 607 608 // ----------------------------------------------------------------------- 609 610 long DockingWindow::Notify( NotifyEvent& rNEvt ) 611 { 612 if( GetDockingManager()->IsDockable( this ) ) // new docking interface 613 return Window::Notify( rNEvt ); 614 615 if ( mbDockable ) 616 { 617 if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN ) 618 { 619 const MouseEvent* pMEvt = rNEvt.GetMouseEvent(); 620 if ( pMEvt->IsLeft() ) 621 { 622 if ( pMEvt->IsMod1() && (pMEvt->GetClicks() == 2) ) 623 { 624 SetFloatingMode( !IsFloatingMode() ); 625 return sal_True; 626 } 627 else if ( pMEvt->GetClicks() == 1 ) 628 { 629 // check if window is floating standalone (IsFloating()) 630 // or only partially floating and still docked with one border 631 // ( !mpWindowImpl->mbFrame) 632 if( ! IsFloatingMode() || ! mpFloatWin->mpWindowImpl->mbFrame ) 633 { 634 Point aPos = pMEvt->GetPosPixel(); 635 Window* pWindow = rNEvt.GetWindow(); 636 if ( pWindow != this ) 637 { 638 aPos = pWindow->OutputToScreenPixel( aPos ); 639 aPos = ScreenToOutputPixel( aPos ); 640 } 641 ImplStartDocking( aPos ); 642 } 643 return sal_True; 644 } 645 } 646 } 647 else if( rNEvt.GetType() == EVENT_KEYINPUT ) 648 { 649 const KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode(); 650 if( rKey.GetCode() == KEY_F10 && rKey.GetModifier() && 651 rKey.IsShift() && rKey.IsMod1() ) 652 { 653 SetFloatingMode( !IsFloatingMode() ); 654 return sal_True; 655 } 656 } 657 } 658 659 return Window::Notify( rNEvt ); 660 } 661 662 // ----------------------------------------------------------------------- 663 664 void DockingWindow::StartDocking() 665 { 666 mbDocking = sal_True; 667 } 668 669 // ----------------------------------------------------------------------- 670 671 sal_Bool DockingWindow::Docking( const Point&, Rectangle& ) 672 { 673 return IsFloatingMode(); 674 } 675 676 // ----------------------------------------------------------------------- 677 678 void DockingWindow::EndDocking( const Rectangle& rRect, sal_Bool bFloatMode ) 679 { 680 if ( !IsDockingCanceled() ) 681 { 682 sal_Bool bShow = sal_False; 683 if ( bFloatMode != IsFloatingMode() ) 684 { 685 Show( sal_False, SHOW_NOFOCUSCHANGE ); 686 SetFloatingMode( bFloatMode ); 687 bShow = sal_True; 688 if ( bFloatMode && mpFloatWin ) 689 mpFloatWin->SetPosSizePixel( rRect.TopLeft(), rRect.GetSize() ); 690 } 691 if ( !bFloatMode ) 692 { 693 Point aPos = rRect.TopLeft(); 694 aPos = GetParent()->ScreenToOutputPixel( aPos ); 695 Window::SetPosSizePixel( aPos, rRect.GetSize() ); 696 } 697 698 if ( bShow ) 699 Show(); 700 } 701 mbDocking = sal_False; 702 } 703 704 // ----------------------------------------------------------------------- 705 706 sal_Bool DockingWindow::PrepareToggleFloatingMode() 707 { 708 return sal_True; 709 } 710 711 // ----------------------------------------------------------------------- 712 713 sal_Bool DockingWindow::Close() 714 { 715 ImplDelData aDelData; 716 ImplAddDel( &aDelData ); 717 ImplCallEventListeners( VCLEVENT_WINDOW_CLOSE ); 718 if ( aDelData.IsDelete() ) 719 return sal_False; 720 ImplRemoveDel( &aDelData ); 721 722 if ( mpWindowImpl->mxWindowPeer.is() && IsCreatedWithToolkit() ) 723 return sal_False; 724 725 Show( sal_False, SHOW_NOFOCUSCHANGE ); 726 return sal_True; 727 } 728 729 // ----------------------------------------------------------------------- 730 731 void DockingWindow::ToggleFloatingMode() 732 { 733 } 734 735 // ----------------------------------------------------------------------- 736 737 void DockingWindow::TitleButtonClick( sal_uInt16 ) 738 { 739 } 740 741 // ----------------------------------------------------------------------- 742 743 void DockingWindow::Pin() 744 { 745 } 746 747 // ----------------------------------------------------------------------- 748 749 void DockingWindow::Roll() 750 { 751 } 752 753 // ----------------------------------------------------------------------- 754 755 void DockingWindow::PopupModeEnd() 756 { 757 } 758 759 // ----------------------------------------------------------------------- 760 761 void DockingWindow::Resizing( Size& ) 762 { 763 } 764 765 // ----------------------------------------------------------------------- 766 767 void DockingWindow::StateChanged( StateChangedType nType ) 768 { 769 if ( nType == STATE_CHANGE_CONTROLBACKGROUND ) 770 { 771 ImplInitSettings(); 772 Invalidate(); 773 } 774 775 Window::StateChanged( nType ); 776 } 777 778 // ----------------------------------------------------------------------- 779 780 void DockingWindow::DataChanged( const DataChangedEvent& rDCEvt ) 781 { 782 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && 783 (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 784 { 785 ImplInitSettings(); 786 Invalidate(); 787 } 788 else 789 Window::DataChanged( rDCEvt ); 790 } 791 792 // ----------------------------------------------------------------------- 793 794 void DockingWindow::ShowTitleButton( sal_uInt16 nButton, sal_Bool bVisible ) 795 { 796 if ( mpFloatWin ) 797 mpFloatWin->ShowTitleButton( nButton, bVisible ); 798 else 799 { 800 if ( nButton == TITLE_BUTTON_DOCKING ) 801 mbDockBtn = bVisible; 802 else /* if ( nButton == TITLE_BUTTON_HIDE ) */ 803 mbHideBtn = bVisible; 804 } 805 } 806 807 // ----------------------------------------------------------------------- 808 809 sal_Bool DockingWindow::IsTitleButtonVisible( sal_uInt16 nButton ) const 810 { 811 if ( mpFloatWin ) 812 return mpFloatWin->IsTitleButtonVisible( nButton ); 813 else 814 { 815 if ( nButton == TITLE_BUTTON_DOCKING ) 816 return mbDockBtn; 817 else /* if ( nButton == TITLE_BUTTON_HIDE ) */ 818 return mbHideBtn; 819 } 820 } 821 822 // ----------------------------------------------------------------------- 823 824 void DockingWindow::SetFloatingMode( sal_Bool bFloatMode ) 825 { 826 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 827 if( pWrapper ) 828 { 829 pWrapper->SetFloatingMode( bFloatMode ); 830 return; 831 } 832 if ( IsFloatingMode() != bFloatMode ) 833 { 834 if ( PrepareToggleFloatingMode() ) // changes to floating mode can be vetoed 835 { 836 sal_Bool bVisible = IsVisible(); 837 838 if ( bFloatMode ) 839 { 840 Show( sal_False, SHOW_NOFOCUSCHANGE ); 841 842 maDockPos = Window::GetPosPixel(); 843 844 Window* pRealParent = mpWindowImpl->mpRealParent; 845 mpOldBorderWin = mpWindowImpl->mpBorderWindow; 846 847 ImplDockFloatWin* pWin = 848 new ImplDockFloatWin( 849 mpImplData->mpParent, 850 mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ? mnFloatBits | WB_SYSTEMWINDOW : mnFloatBits, 851 this ); 852 mpFloatWin = pWin; 853 mpWindowImpl->mpBorderWindow = NULL; 854 mpWindowImpl->mnLeftBorder = 0; 855 mpWindowImpl->mnTopBorder = 0; 856 mpWindowImpl->mnRightBorder = 0; 857 mpWindowImpl->mnBottomBorder = 0; 858 // Falls Parent zerstoert wird, muessen wir auch vom 859 // BorderWindow den Parent umsetzen 860 if ( mpOldBorderWin ) 861 mpOldBorderWin->SetParent( pWin ); 862 SetParent( pWin ); 863 SetPosPixel( Point() ); 864 mpWindowImpl->mpBorderWindow = pWin; 865 pWin->mpWindowImpl->mpClientWindow = this; 866 mpWindowImpl->mpRealParent = pRealParent; 867 pWin->SetText( Window::GetText() ); 868 pWin->SetOutputSizePixel( Window::GetSizePixel() ); 869 pWin->SetPosPixel( maFloatPos ); 870 // DockingDaten ans FloatingWindow weiterreichen 871 pWin->ShowTitleButton( TITLE_BUTTON_DOCKING, mbDockBtn ); 872 pWin->ShowTitleButton( TITLE_BUTTON_HIDE, mbHideBtn ); 873 pWin->SetPin( mbPined ); 874 if ( mbRollUp ) 875 pWin->RollUp(); 876 else 877 pWin->RollDown(); 878 pWin->SetRollUpOutputSizePixel( maRollUpOutSize ); 879 pWin->SetMinOutputSizePixel( maMinOutSize ); 880 pWin->SetMaxOutputSizePixel( mpImplData->maMaxOutSize ); 881 882 ToggleFloatingMode(); 883 884 if ( bVisible ) 885 Show(); 886 } 887 else 888 { 889 Show( sal_False, SHOW_NOFOCUSCHANGE ); 890 891 // FloatingDaten wird im FloatingWindow speichern 892 maFloatPos = mpFloatWin->GetPosPixel(); 893 mbDockBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_DOCKING ); 894 mbHideBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_HIDE ); 895 mbPined = mpFloatWin->IsPined(); 896 mbRollUp = mpFloatWin->IsRollUp(); 897 maRollUpOutSize = mpFloatWin->GetRollUpOutputSizePixel(); 898 maMinOutSize = mpFloatWin->GetMinOutputSizePixel(); 899 mpImplData->maMaxOutSize = mpFloatWin->GetMaxOutputSizePixel(); 900 901 Window* pRealParent = mpWindowImpl->mpRealParent; 902 mpWindowImpl->mpBorderWindow = NULL; 903 if ( mpOldBorderWin ) 904 { 905 SetParent( mpOldBorderWin ); 906 ((ImplBorderWindow*)mpOldBorderWin)->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder ); 907 mpOldBorderWin->Resize(); 908 } 909 mpWindowImpl->mpBorderWindow = mpOldBorderWin; 910 SetParent( pRealParent ); 911 mpWindowImpl->mpRealParent = pRealParent; 912 delete static_cast<ImplDockFloatWin*>(mpFloatWin); 913 mpFloatWin = NULL; 914 SetPosPixel( maDockPos ); 915 916 ToggleFloatingMode(); 917 918 if ( bVisible ) 919 Show(); 920 } 921 } 922 } 923 } 924 925 // ----------------------------------------------------------------------- 926 927 void DockingWindow::SetFloatStyle( WinBits nStyle ) 928 { 929 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 930 if( pWrapper ) 931 { 932 pWrapper->SetFloatStyle( nStyle ); 933 return; 934 } 935 936 mnFloatBits = nStyle; 937 } 938 939 // ----------------------------------------------------------------------- 940 941 WinBits DockingWindow::GetFloatStyle() const 942 { 943 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 944 if( pWrapper ) 945 { 946 return pWrapper->GetFloatStyle(); 947 } 948 949 return mnFloatBits; 950 } 951 952 // ----------------------------------------------------------------------- 953 954 void DockingWindow::SetTabStop() 955 { 956 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 957 if( pWrapper ) 958 { 959 pWrapper->SetTabStop(); 960 return; 961 } 962 963 mpWindowImpl->mnStyle |= WB_GROUP | WB_TABSTOP; 964 } 965 966 // ----------------------------------------------------------------------- 967 968 void DockingWindow::SetPosSizePixel( long nX, long nY, 969 long nWidth, long nHeight, 970 sal_uInt16 nFlags ) 971 { 972 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 973 if( pWrapper ) 974 { 975 if ( pWrapper->mpFloatWin ) 976 pWrapper->mpFloatWin->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); 977 else 978 Window::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); 979 return; 980 } 981 982 if ( mpFloatWin ) 983 mpFloatWin->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); 984 else 985 Window::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); 986 } 987 988 // ----------------------------------------------------------------------- 989 990 Point DockingWindow::GetPosPixel() const 991 { 992 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 993 if( pWrapper ) 994 { 995 if ( pWrapper->mpFloatWin ) 996 return pWrapper->mpFloatWin->GetPosPixel(); 997 else 998 return Window::GetPosPixel(); 999 } 1000 1001 if ( mpFloatWin ) 1002 return mpFloatWin->GetPosPixel(); 1003 else 1004 return Window::GetPosPixel(); 1005 } 1006 1007 // ----------------------------------------------------------------------- 1008 1009 Size DockingWindow::GetSizePixel() const 1010 { 1011 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 1012 if( pWrapper ) 1013 { 1014 if ( pWrapper->mpFloatWin ) 1015 return pWrapper->mpFloatWin->GetSizePixel(); 1016 else 1017 return Window::GetSizePixel(); 1018 } 1019 1020 if ( mpFloatWin ) 1021 return mpFloatWin->GetSizePixel(); 1022 else 1023 return Window::GetSizePixel(); 1024 } 1025 1026 // ----------------------------------------------------------------------- 1027 1028 void DockingWindow::SetOutputSizePixel( const Size& rNewSize ) 1029 { 1030 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 1031 if( pWrapper ) 1032 { 1033 if ( pWrapper->mpFloatWin ) 1034 pWrapper->mpFloatWin->SetOutputSizePixel( rNewSize ); 1035 else 1036 Window::SetOutputSizePixel( rNewSize ); 1037 return; 1038 } 1039 1040 if ( mpFloatWin ) 1041 mpFloatWin->SetOutputSizePixel( rNewSize ); 1042 else 1043 Window::SetOutputSizePixel( rNewSize ); 1044 } 1045 1046 // ----------------------------------------------------------------------- 1047 1048 Size DockingWindow::GetOutputSizePixel() const 1049 { 1050 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 1051 if( pWrapper ) 1052 { 1053 if ( pWrapper->mpFloatWin ) 1054 return pWrapper->mpFloatWin->GetOutputSizePixel(); 1055 else 1056 return Window::GetOutputSizePixel(); 1057 } 1058 1059 if ( mpFloatWin ) 1060 return mpFloatWin->GetOutputSizePixel(); 1061 else 1062 return Window::GetOutputSizePixel(); 1063 } 1064 1065 Point DockingWindow::GetFloatingPos() const 1066 { 1067 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 1068 if( pWrapper ) 1069 { 1070 if ( pWrapper->mpFloatWin ) 1071 { 1072 WindowStateData aData; 1073 aData.SetMask( WINDOWSTATE_MASK_POS ); 1074 pWrapper->mpFloatWin->GetWindowStateData( aData ); 1075 Point aPos( aData.GetX(), aData.GetY() ); 1076 aPos = pWrapper->mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos ); 1077 return aPos; 1078 } 1079 else 1080 return maFloatPos; 1081 } 1082 1083 if ( mpFloatWin ) 1084 { 1085 WindowStateData aData; 1086 aData.SetMask( WINDOWSTATE_MASK_POS ); 1087 mpFloatWin->GetWindowStateData( aData ); 1088 Point aPos( aData.GetX(), aData.GetY() ); 1089 aPos = mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos ); 1090 return aPos; 1091 } 1092 else 1093 return maFloatPos; 1094 } 1095 1096 sal_Bool DockingWindow::IsFloatingMode() const 1097 { 1098 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this ); 1099 if( pWrapper ) 1100 return pWrapper->IsFloatingMode(); 1101 else 1102 return (mpFloatWin != NULL); 1103 } 1104 1105 void DockingWindow::SetMaxOutputSizePixel( const Size& rSize ) 1106 { 1107 if ( mpFloatWin ) 1108 mpFloatWin->SetMaxOutputSizePixel( rSize ); 1109 mpImplData->maMaxOutSize = rSize; 1110 } 1111 1112 const Size& DockingWindow::GetMaxOutputSizePixel() const 1113 { 1114 if ( mpFloatWin ) 1115 return mpFloatWin->GetMaxOutputSizePixel(); 1116 return mpImplData->maMaxOutSize; 1117 } 1118