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