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 #ifndef _SV_RC_H 33 #include <tools/rc.h> 34 #endif 35 36 #include <brdwin.hxx> 37 #include <svdata.hxx> 38 #include <salframe.hxx> 39 #include <window.h> 40 41 #include <vcl/event.hxx> 42 #include <vcl/floatwin.hxx> 43 #include <vcl/dockwin.hxx> 44 #include <vcl/toolbox.hxx> 45 #include <vcl/svapp.hxx> 46 #include <vcl/timer.hxx> 47 #include <vcl/lineinfo.hxx> 48 #include <vcl/unowrap.hxx> 49 50 51 // ======================================================================= 52 53 #define DOCKWIN_FLOATSTYLES (WB_SIZEABLE | WB_MOVEABLE | WB_CLOSEABLE | WB_STANDALONE | WB_PINABLE | WB_ROLLABLE ) 54 55 // ======================================================================= 56 57 58 // ======================================================================= 59 60 class ImplDockFloatWin2 : public FloatingWindow 61 { 62 private: 63 ImplDockingWindowWrapper* mpDockWin; 64 sal_uLong mnLastTicks; 65 Timer maDockTimer; 66 Timer maEndDockTimer; 67 Point maDockPos; 68 Rectangle maDockRect; 69 sal_Bool mbInMove; 70 sal_uLong mnLastUserEvent; 71 72 DECL_LINK( DockingHdl, ImplDockFloatWin2* ); 73 DECL_LINK( DockTimerHdl, ImplDockFloatWin2* ); 74 DECL_LINK( EndDockTimerHdl, ImplDockFloatWin2* ); 75 public: 76 ImplDockFloatWin2( Window* pParent, WinBits nWinBits, 77 ImplDockingWindowWrapper* pDockingWin ); 78 ~ImplDockFloatWin2(); 79 80 virtual void Move(); 81 virtual void Resize(); 82 virtual void TitleButtonClick( sal_uInt16 nButton ); 83 virtual void Pin(); 84 virtual void Roll(); 85 virtual void PopupModeEnd(); 86 virtual void Resizing( Size& rSize ); 87 virtual sal_Bool Close(); 88 using Window::SetPosSizePixel; 89 virtual void SetPosSizePixel( long nX, long nY, 90 long nWidth, long nHeight, 91 sal_uInt16 nFlags = WINDOW_POSSIZE_ALL ); 92 93 sal_uLong GetLastTicks() const { return mnLastTicks; } 94 }; 95 96 // ======================================================================= 97 98 ImplDockFloatWin2::ImplDockFloatWin2( Window* pParent, WinBits nWinBits, 99 ImplDockingWindowWrapper* pDockingWin ) : 100 FloatingWindow( pParent, nWinBits ), 101 mpDockWin( pDockingWin ), 102 mnLastTicks( Time::GetSystemTicks() ), 103 mbInMove( sal_False ), 104 mnLastUserEvent( 0 ) 105 { 106 // Daten vom DockingWindow uebernehmen 107 if ( pDockingWin ) 108 { 109 SetSettings( pDockingWin->GetWindow()->GetSettings() ); 110 Enable( pDockingWin->GetWindow()->IsEnabled(), sal_False ); 111 EnableInput( pDockingWin->GetWindow()->IsInputEnabled(), sal_False ); 112 AlwaysEnableInput( pDockingWin->GetWindow()->IsAlwaysEnableInput(), sal_False ); 113 EnableAlwaysOnTop( pDockingWin->GetWindow()->IsAlwaysOnTopEnabled() ); 114 SetActivateMode( pDockingWin->GetWindow()->GetActivateMode() ); 115 } 116 117 SetBackground( GetSettings().GetStyleSettings().GetFaceColor() ); 118 119 maDockTimer.SetTimeoutHdl( LINK( this, ImplDockFloatWin2, DockTimerHdl ) ); 120 maDockTimer.SetTimeout( 50 ); 121 maEndDockTimer.SetTimeoutHdl( LINK( this, ImplDockFloatWin2, EndDockTimerHdl ) ); 122 maEndDockTimer.SetTimeout( 50 ); 123 } 124 125 // ----------------------------------------------------------------------- 126 127 ImplDockFloatWin2::~ImplDockFloatWin2() 128 { 129 if( mnLastUserEvent ) 130 Application::RemoveUserEvent( mnLastUserEvent ); 131 } 132 133 // ----------------------------------------------------------------------- 134 135 IMPL_LINK( ImplDockFloatWin2, DockTimerHdl, ImplDockFloatWin2*, EMPTYARG ) 136 { 137 DBG_ASSERT( mpDockWin->IsFloatingMode(), "docktimer called but not floating" ); 138 139 maDockTimer.Stop(); 140 PointerState aState = GetPointerState(); 141 142 if( aState.mnState & KEY_MOD1 ) 143 { 144 // i43499 CTRL disables docking now 145 mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking(); 146 if( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) 147 maDockTimer.Start(); 148 } 149 else if( ! ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) ) 150 { 151 mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking(); 152 mpDockWin->EndDocking( maDockRect, sal_False ); 153 } 154 else 155 { 156 mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_BIG | SHOWTRACK_WINDOW ); 157 maDockTimer.Start(); 158 } 159 160 return 0; 161 } 162 163 IMPL_LINK( ImplDockFloatWin2, EndDockTimerHdl, ImplDockFloatWin2*, EMPTYARG ) 164 { 165 DBG_ASSERT( mpDockWin->IsFloatingMode(), "enddocktimer called but not floating" ); 166 167 maEndDockTimer.Stop(); 168 PointerState aState = GetPointerState(); 169 if( ! ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) ) 170 { 171 mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking(); 172 mpDockWin->EndDocking( maDockRect, sal_True ); 173 } 174 else 175 { 176 maEndDockTimer.Start(); 177 } 178 179 return 0; 180 } 181 182 183 IMPL_LINK( ImplDockFloatWin2, DockingHdl, ImplDockFloatWin2*, EMPTYARG ) 184 { 185 // called during move of a floating window 186 mnLastUserEvent = 0; 187 188 Window *pDockingArea = mpDockWin->GetWindow()->GetParent(); 189 PointerState aState = pDockingArea->GetPointerState(); 190 191 sal_Bool bRealMove = sal_True; 192 if( GetStyle() & WB_OWNERDRAWDECORATION ) 193 { 194 // for windows with ownerdraw decoration 195 // we allow docking only when the window was moved 196 // by dragging its caption 197 // and ignore move request due to resizing 198 Window *pBorder = GetWindow( WINDOW_BORDER ); 199 if( pBorder != this ) 200 { 201 Point aPt; 202 Rectangle aBorderRect( aPt, pBorder->GetSizePixel() ); 203 sal_Int32 nLeft, nTop, nRight, nBottom; 204 GetBorder( nLeft, nTop, nRight, nBottom ); 205 // limit borderrect to the caption part only and without the resizing borders 206 aBorderRect.nBottom = aBorderRect.nTop + nTop; 207 aBorderRect.nLeft += nLeft; 208 aBorderRect.nRight -= nRight; 209 210 PointerState aBorderState = pBorder->GetPointerState(); 211 if( aBorderRect.IsInside( aBorderState.maPos ) ) 212 bRealMove = sal_True; 213 else 214 bRealMove = sal_False; 215 } 216 } 217 218 if( mpDockWin->IsDockable() && 219 mpDockWin->GetWindow()->IsVisible() && 220 (Time::GetSystemTicks() - mnLastTicks > 500) && 221 ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) && 222 !(aState.mnState & KEY_MOD1) && // i43499 CTRL disables docking now 223 bRealMove ) 224 { 225 maDockPos = Point( pDockingArea->OutputToScreenPixel( pDockingArea->AbsoluteScreenToOutputPixel( OutputToAbsoluteScreenPixel( Point() ) ) ) ); 226 maDockRect = Rectangle( maDockPos, mpDockWin->GetSizePixel() ); 227 228 // mouse pos in screen pixels 229 Point aMousePos = pDockingArea->OutputToScreenPixel( aState.maPos ); 230 231 if( ! mpDockWin->IsDocking() ) 232 mpDockWin->StartDocking( aMousePos, maDockRect ); 233 234 sal_Bool bFloatMode = mpDockWin->Docking( aMousePos, maDockRect ); 235 236 if( ! bFloatMode ) 237 { 238 // indicates that the window could be docked at maDockRect 239 maDockRect.SetPos( mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->ScreenToOutputPixel( 240 maDockRect.TopLeft() ) ); 241 mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_BIG | SHOWTRACK_WINDOW ); 242 maEndDockTimer.Stop(); 243 DockTimerHdl( this ); 244 } 245 else 246 { 247 mpDockWin->GetWindow()->GetParent()->ImplGetFrameWindow()->HideTracking(); 248 maDockTimer.Stop(); 249 EndDockTimerHdl( this ); 250 } 251 } 252 mbInMove = sal_False; 253 return 0; 254 } 255 // ----------------------------------------------------------------------- 256 257 void ImplDockFloatWin2::Move() 258 { 259 if( mbInMove ) 260 return; 261 262 mbInMove = sal_True; 263 FloatingWindow::Move(); 264 mpDockWin->GetWindow()->Move(); 265 266 /* 267 * note: the window should only dock if KEY_MOD1 is pressed 268 * and the user releases all mouse buttons. The real problem here 269 * is that we don't get mouse events (at least not on X) 270 * if the mouse is on the decoration. So we have to start an 271 * awkward timer based process that polls the modifier/buttons 272 * to see whether they are in the right condition shortly after the 273 * last Move message. 274 */ 275 if( ! mnLastUserEvent ) 276 mnLastUserEvent = Application::PostUserEvent( LINK( this, ImplDockFloatWin2, DockingHdl ) ); 277 } 278 279 // ----------------------------------------------------------------------- 280 281 void ImplDockFloatWin2::Resize() 282 { 283 // forwarding of resize only required if we have no borderwindow ( GetWindow() then returns 'this' ) 284 if( GetWindow( WINDOW_BORDER ) == this ) 285 { 286 FloatingWindow::Resize(); 287 Size aSize( GetSizePixel() ); 288 mpDockWin->GetWindow()->ImplPosSizeWindow( 0, 0, aSize.Width(), aSize.Height(), WINDOW_POSSIZE_POSSIZE ); // is this needed ??? 289 } 290 } 291 292 void ImplDockFloatWin2::SetPosSizePixel( long nX, long nY, 293 long nWidth, long nHeight, 294 sal_uInt16 nFlags ) 295 { 296 FloatingWindow::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); 297 } 298 299 // ----------------------------------------------------------------------- 300 301 302 void ImplDockFloatWin2::TitleButtonClick( sal_uInt16 nButton ) 303 { 304 FloatingWindow::TitleButtonClick( nButton ); 305 mpDockWin->TitleButtonClick( nButton ); 306 } 307 308 // ----------------------------------------------------------------------- 309 310 void ImplDockFloatWin2::Pin() 311 { 312 FloatingWindow::Pin(); 313 mpDockWin->Pin(); 314 } 315 316 // ----------------------------------------------------------------------- 317 318 void ImplDockFloatWin2::Roll() 319 { 320 FloatingWindow::Roll(); 321 mpDockWin->Roll(); 322 } 323 324 // ----------------------------------------------------------------------- 325 326 void ImplDockFloatWin2::PopupModeEnd() 327 { 328 FloatingWindow::PopupModeEnd(); 329 mpDockWin->PopupModeEnd(); 330 } 331 332 // ----------------------------------------------------------------------- 333 334 void ImplDockFloatWin2::Resizing( Size& rSize ) 335 { 336 FloatingWindow::Resizing( rSize ); 337 mpDockWin->Resizing( rSize ); 338 } 339 340 // ----------------------------------------------------------------------- 341 342 sal_Bool ImplDockFloatWin2::Close() 343 { 344 return mpDockWin->Close(); 345 } 346 347 // ======================================================================= 348 349 DockingManager::DockingManager() 350 { 351 } 352 353 DockingManager::~DockingManager() 354 { 355 ::std::vector< ImplDockingWindowWrapper* >::iterator p; 356 p = mDockingWindows.begin(); 357 for(; p != mDockingWindows.end(); ++p ) 358 { 359 delete (*p); 360 } 361 mDockingWindows.clear(); 362 } 363 364 ImplDockingWindowWrapper* DockingManager::GetDockingWindowWrapper( const Window *pWindow ) 365 { 366 ::std::vector< ImplDockingWindowWrapper* >::iterator p; 367 p = mDockingWindows.begin(); 368 while( p != mDockingWindows.end() ) 369 { 370 if( (*p)->mpDockingWindow == pWindow ) 371 return (*p); 372 else 373 p++; 374 } 375 return NULL; 376 } 377 378 sal_Bool DockingManager::IsDockable( const Window *pWindow ) 379 { 380 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 381 382 /* 383 if( pWindow->HasDockingHandler() ) 384 return sal_True; 385 */ 386 return (pWrapper != NULL); 387 } 388 389 sal_Bool DockingManager::IsFloating( const Window *pWindow ) 390 { 391 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 392 if( pWrapper ) 393 return pWrapper->IsFloatingMode(); 394 else 395 return sal_False; 396 } 397 398 sal_Bool DockingManager::IsLocked( const Window *pWindow ) 399 { 400 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 401 if( pWrapper && pWrapper->IsLocked() ) 402 return sal_True; 403 else 404 return sal_False; 405 } 406 407 void DockingManager::Lock( const Window *pWindow ) 408 { 409 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 410 if( pWrapper ) 411 pWrapper->Lock(); 412 } 413 414 void DockingManager::Unlock( const Window *pWindow ) 415 { 416 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 417 if( pWrapper ) 418 pWrapper->Unlock(); 419 } 420 421 void DockingManager::SetFloatingMode( const Window *pWindow, sal_Bool bFloating ) 422 { 423 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 424 if( pWrapper ) 425 pWrapper->SetFloatingMode( bFloating ); 426 } 427 428 void DockingManager::StartPopupMode( ToolBox *pParentToolBox, const Window *pWindow, sal_uLong nFlags ) 429 { 430 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 431 if( pWrapper ) 432 pWrapper->StartPopupMode( pParentToolBox, nFlags ); 433 } 434 435 void DockingManager::StartPopupMode( ToolBox *pParentToolBox, const Window *pWindow ) 436 { 437 StartPopupMode( pParentToolBox, pWindow, FLOATWIN_POPUPMODE_ALLOWTEAROFF | 438 FLOATWIN_POPUPMODE_NOFOCUSCLOSE | 439 FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE | 440 FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE ); 441 } 442 443 sal_Bool DockingManager::IsInPopupMode( const Window *pWindow ) 444 { 445 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 446 if( pWrapper && pWrapper->IsInPopupMode() ) 447 return sal_True; 448 else 449 return sal_False; 450 } 451 452 // ----------------------------------------------------------------------- 453 454 void DockingManager::EndPopupMode( const Window *pWin ) 455 { 456 ImplDockingWindowWrapper *pWrapper = GetDockingWindowWrapper( pWin ); 457 if( pWrapper && pWrapper->GetFloatingWindow() && pWrapper->GetFloatingWindow()->IsInPopupMode() ) 458 pWrapper->GetFloatingWindow()->EndPopupMode(); 459 } 460 461 // ----------------------------------------------------------------------- 462 463 void DockingManager::AddWindow( const Window *pWindow ) 464 { 465 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 466 if( pWrapper ) 467 return; 468 else 469 pWrapper = new ImplDockingWindowWrapper( pWindow ); 470 471 mDockingWindows.push_back( pWrapper ); 472 } 473 474 void DockingManager::RemoveWindow( const Window *pWindow ) 475 { 476 ::std::vector< ImplDockingWindowWrapper* >::iterator p; 477 p = mDockingWindows.begin(); 478 while( p != mDockingWindows.end() ) 479 { 480 if( (*p)->mpDockingWindow == pWindow ) 481 { 482 delete (*p); 483 mDockingWindows.erase( p ); 484 break; 485 } 486 else 487 p++; 488 } 489 } 490 491 void DockingManager::SetPosSizePixel( Window *pWindow, long nX, long nY, 492 long nWidth, long nHeight, 493 sal_uInt16 nFlags ) 494 { 495 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 496 if( pWrapper ) 497 pWrapper->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); 498 } 499 500 Rectangle DockingManager::GetPosSizePixel( const Window *pWindow ) 501 { 502 Rectangle aRect; 503 ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow ); 504 if( pWrapper ) 505 aRect = Rectangle( pWrapper->GetPosPixel(), pWrapper->GetSizePixel() ); 506 507 return aRect; 508 } 509 510 // ======================================================================= 511 // special floating window for popup mode 512 // main purpose: provides tear-off area for undocking 513 // ======================================================================= 514 515 // if TEAROFF_DASHED defined a single dashed line is used 516 // otherwise multiple smaller lines will be painted 517 //#define TEAROFF_DASHED 518 519 // size of the drag area 520 #ifdef TEAROFF_DASHED 521 #define POPUP_DRAGBORDER 2 522 #define POPUP_DRAGGRIP 5 523 #else 524 #define POPUP_DRAGBORDER 3 525 #define POPUP_DRAGGRIP 5 526 #endif 527 #define POPUP_DRAGHEIGHT (POPUP_DRAGGRIP+POPUP_DRAGBORDER+POPUP_DRAGBORDER) 528 #define POPUP_DRAGWIDTH 20 529 530 class ImplPopupFloatWin : public FloatingWindow 531 { 532 private: 533 ImplDockingWindowWrapper* mpDockingWin; 534 sal_Bool mbHighlight; 535 sal_Bool mbMoving; 536 bool mbTrackingEnabled; 537 Point maDelta; 538 Point maTearOffPosition; 539 bool mbGripAtBottom; 540 bool mbHasGrip; 541 void ImplSetBorder(); 542 543 public: 544 ImplPopupFloatWin( Window* pParent, ImplDockingWindowWrapper* pDockingWin, bool bHasGrip ); 545 ~ImplPopupFloatWin(); 546 547 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible(); 548 virtual void Paint( const Rectangle& rRect ); 549 virtual void MouseMove( const MouseEvent& rMEvt ); 550 virtual void MouseButtonDown( const MouseEvent& rMEvt ); 551 virtual void MouseButtonUp( const MouseEvent& rMEvt ); 552 virtual void Tracking( const TrackingEvent& rTEvt ); 553 virtual void Resize(); 554 virtual Window* GetPreferredKeyInputWindow(); 555 556 Rectangle GetDragRect() const; 557 Point GetToolboxPosition() const; 558 Point GetTearOffPosition() const; 559 void DrawGrip(); 560 void DrawBorder(); 561 562 bool hasGrip() const { return mbHasGrip; } 563 }; 564 565 ImplPopupFloatWin::ImplPopupFloatWin( Window* pParent, ImplDockingWindowWrapper* pDockingWin, bool bHasGrip ) : 566 FloatingWindow( pParent, WB_NOBORDER | WB_SYSTEMWINDOW | WB_NOSHADOW) 567 { 568 mpWindowImpl->mbToolbarFloatingWindow = sal_True; // indicate window type, required for accessibility 569 // which should not see this window as a toplevel window 570 mpDockingWin = pDockingWin; 571 mbHighlight = sal_False; 572 mbMoving = sal_False; 573 mbTrackingEnabled = sal_False; 574 mbGripAtBottom = sal_True; 575 mbHasGrip = bHasGrip; 576 577 ImplSetBorder(); 578 } 579 580 ImplPopupFloatWin::~ImplPopupFloatWin() 581 { 582 mpDockingWin = NULL; 583 } 584 585 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ImplPopupFloatWin::CreateAccessible() 586 { 587 // switch off direct accessibilty support for this window 588 589 // this is to avoid appearance of this window as standalone window in the accessibility hierarchy 590 // as this window is only used as a helper for subtoolbars that are not teared-off, the parent toolbar 591 // has to provide accessibility support (as implemented in the toolkit) 592 // so the contained toolbar should appear as child of the correponsing toolbar item of the parent toolbar 593 return ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >(); 594 } 595 596 Window* ImplPopupFloatWin::GetPreferredKeyInputWindow() 597 { 598 if( mpWindowImpl->mpClientWindow ) 599 return mpWindowImpl->mpClientWindow; 600 else 601 return FloatingWindow::GetPreferredKeyInputWindow(); 602 } 603 604 605 void ImplPopupFloatWin::ImplSetBorder() 606 { 607 // although we have no border in the sense of a borderwindow 608 // we're using a special border for the grip 609 // by setting those members the method SetOutputSizePixel() can 610 // be used to set the proper window size 611 mpWindowImpl->mnTopBorder = 1; 612 if( hasGrip() ) 613 mpWindowImpl->mnTopBorder += POPUP_DRAGHEIGHT+2; 614 mpWindowImpl->mnBottomBorder = 1; 615 mpWindowImpl->mnLeftBorder = 1; 616 mpWindowImpl->mnRightBorder = 1; 617 } 618 619 void ImplPopupFloatWin::Resize() 620 { 621 // the borderview overwrites the border during resize so restore it 622 ImplSetBorder(); 623 } 624 625 Rectangle ImplPopupFloatWin::GetDragRect() const 626 { 627 Rectangle aRect; 628 if( hasGrip() ) 629 { 630 aRect = Rectangle( 1,1, GetOutputSizePixel().Width()-1, 2+POPUP_DRAGHEIGHT ); 631 if( mbGripAtBottom ) 632 { 633 int height = GetOutputSizePixel().Height(); 634 aRect.Top() = height - 3 - POPUP_DRAGHEIGHT; 635 aRect.Bottom() = aRect.Top() + 1 + POPUP_DRAGHEIGHT; 636 } 637 } 638 return aRect; 639 } 640 641 Point ImplPopupFloatWin::GetToolboxPosition() const 642 { 643 // return inner position where a toolbox could be placed 644 Point aPt( 1, 1 + ((mbGripAtBottom || !hasGrip()) ? 0 : GetDragRect().getHeight()) ); // grip + border 645 646 return aPt; 647 } 648 649 Point ImplPopupFloatWin::GetTearOffPosition() const 650 { 651 Point aPt( maTearOffPosition ); 652 //aPt += GetToolboxPosition(); // remove 'decoration' 653 return aPt; 654 } 655 656 void ImplPopupFloatWin::DrawBorder() 657 { 658 SetFillColor(); 659 Point aPt; 660 Rectangle aRect( aPt, GetOutputSizePixel() ); 661 662 Region oldClipRgn( GetClipRegion( ) ); 663 Region aClipRgn( aRect ); 664 Rectangle aItemClipRect( ImplGetItemEdgeClipRect() ); 665 if( !aItemClipRect.IsEmpty() ) 666 { 667 aItemClipRect.SetPos( AbsoluteScreenToOutputPixel( aItemClipRect.TopLeft() ) ); 668 669 // draw the excluded border part with the background color of a toolbox 670 SetClipRegion( Region( aItemClipRect ) ); 671 SetLineColor( GetSettings().GetStyleSettings().GetFaceColor() ); 672 DrawRect( aRect ); 673 674 aClipRgn.Exclude( aItemClipRect ); 675 SetClipRegion( aClipRgn ); 676 } 677 SetLineColor( GetSettings().GetStyleSettings().GetShadowColor() ); 678 DrawRect( aRect ); 679 SetClipRegion( oldClipRgn ); 680 } 681 682 void ImplPopupFloatWin::DrawGrip() 683 { 684 sal_Bool bLinecolor = IsLineColor(); 685 Color aLinecolor = GetLineColor(); 686 sal_Bool bFillcolor = IsFillColor(); 687 Color aFillcolor = GetFillColor(); 688 689 // draw background 690 Rectangle aRect( GetDragRect() ); 691 aRect.nTop += POPUP_DRAGBORDER; 692 aRect.nBottom -= POPUP_DRAGBORDER; 693 aRect.nLeft+=3; 694 aRect.nRight-=3; 695 696 if( mbHighlight ) 697 { 698 Erase( aRect ); 699 DrawSelectionBackground( aRect, 2, sal_False, sal_True, sal_False ); 700 } 701 else 702 { 703 SetFillColor( GetSettings().GetStyleSettings().GetFaceColor() ); 704 SetLineColor(); 705 DrawRect( aRect ); 706 } 707 708 if( !ToolBox::AlwaysLocked() ) // no grip if toolboxes are locked 709 { 710 #ifdef TEAROFF_DASHED 711 // draw single dashed line 712 LineInfo aLineInfo( LINE_DASH ); 713 aLineInfo.SetDistance( 4 ); 714 aLineInfo.SetDashLen( 12 ); 715 aLineInfo.SetDashCount( 1 ); 716 717 aRect.nLeft+=2; aRect.nRight-=2; 718 719 aRect.nTop+=2; 720 aRect.nBottom = aRect.nTop; 721 SetLineColor( GetSettings().GetStyleSettings().GetDarkShadowColor() ); 722 DrawLine( aRect.TopLeft(), aRect.TopRight(), aLineInfo ); 723 724 if( !mbHighlight ) 725 { 726 aRect.nTop++; aRect.nBottom++; 727 SetLineColor( GetSettings().GetStyleSettings().GetLightColor() ); 728 DrawLine( aRect.TopLeft(), aRect.TopRight(), aLineInfo ); 729 } 730 731 #else 732 // draw several grip lines 733 SetFillColor( GetSettings().GetStyleSettings().GetShadowColor() ); 734 aRect.nTop++; 735 aRect.nBottom = aRect.nTop; 736 737 int width = POPUP_DRAGWIDTH; 738 while( width >= aRect.getWidth() ) 739 width -= 4; 740 if( width <= 0 ) 741 width = aRect.getWidth(); 742 //aRect.nLeft = aRect.nLeft + (aRect.getWidth() - width) / 2; 743 aRect.nLeft = (aRect.nLeft + aRect.nRight - width) / 2; 744 aRect.nRight = aRect.nLeft + width; 745 746 int i=0; 747 while( i< POPUP_DRAGGRIP ) 748 { 749 DrawRect( aRect ); 750 aRect.nTop+=2; 751 aRect.nBottom+=2; 752 i+=2; 753 } 754 #endif 755 } 756 757 if( bLinecolor ) 758 SetLineColor( aLinecolor ); 759 else 760 SetLineColor(); 761 if( bFillcolor ) 762 SetFillColor( aFillcolor ); 763 else 764 SetFillColor(); 765 } 766 767 void ImplPopupFloatWin::Paint( const Rectangle& ) 768 { 769 Point aPt; 770 Rectangle aRect( aPt, GetOutputSizePixel() ); 771 DrawWallpaper( aRect, Wallpaper( GetSettings().GetStyleSettings().GetFaceGradientColor() ) ); 772 DrawBorder(); 773 if( hasGrip() ) 774 DrawGrip(); 775 } 776 777 void ImplPopupFloatWin::MouseMove( const MouseEvent& rMEvt ) 778 { 779 Point aMousePos = rMEvt.GetPosPixel(); 780 781 if( !ToolBox::AlwaysLocked() ) // no tear off if locking is enabled 782 { 783 if( mbTrackingEnabled && rMEvt.IsLeft() && GetDragRect().IsInside( aMousePos ) ) 784 { 785 // start window move 786 mbMoving = sal_True; 787 StartTracking( STARTTRACK_NOKEYCANCEL ); 788 return; 789 } 790 if( !mbHighlight && GetDragRect().IsInside( aMousePos ) ) 791 { 792 mbHighlight = sal_True; 793 DrawGrip(); 794 } 795 if( mbHighlight && ( rMEvt.IsLeaveWindow() || !GetDragRect().IsInside( aMousePos ) ) ) 796 { 797 mbHighlight = sal_False; 798 DrawGrip(); 799 } 800 } 801 } 802 803 void ImplPopupFloatWin::MouseButtonUp( const MouseEvent& rMEvt ) 804 { 805 mbTrackingEnabled = false; 806 FloatingWindow::MouseButtonUp( rMEvt ); 807 } 808 809 void ImplPopupFloatWin::MouseButtonDown( const MouseEvent& rMEvt ) 810 { 811 Point aMousePos = rMEvt.GetPosPixel(); 812 if( GetDragRect().IsInside( aMousePos ) ) 813 { 814 // get mouse pos at a static window to have a fixed reference point 815 PointerState aState = GetParent()->GetPointerState(); 816 if (ImplHasMirroredGraphics() && IsRTLEnabled()) 817 ImplMirrorFramePos(aState.maPos); 818 maTearOffPosition = GetWindow( WINDOW_BORDER )->GetPosPixel(); 819 maDelta = aState.maPos - maTearOffPosition; 820 mbTrackingEnabled = true; 821 } 822 else 823 { 824 mbTrackingEnabled = false; 825 } 826 } 827 828 void ImplPopupFloatWin::Tracking( const TrackingEvent& rTEvt ) 829 { 830 if( mbMoving ) 831 { 832 if ( rTEvt.IsTrackingEnded() ) 833 { 834 mbMoving = sal_False; 835 EndPopupMode( FLOATWIN_POPUPMODEEND_TEAROFF ); 836 } 837 else if ( !rTEvt.GetMouseEvent().IsSynthetic() ) 838 { 839 // move the window according to mouse pos 840 PointerState aState = GetParent()->GetPointerState(); 841 if (ImplHasMirroredGraphics() && IsRTLEnabled()) 842 ImplMirrorFramePos(aState.maPos); 843 maTearOffPosition = aState.maPos - maDelta; 844 GetWindow( WINDOW_BORDER )->SetPosPixel( maTearOffPosition ); 845 } 846 } 847 } 848 849 850 // ======================================================================= 851 852 ImplDockingWindowWrapper::ImplDockingWindowWrapper( const Window *pWindow ) 853 { 854 ImplInitData(); 855 856 mpDockingWindow = (Window*) pWindow; 857 mpParent = pWindow->GetParent(); 858 mbDockable = sal_True; 859 mbLocked = sal_False; 860 mnFloatBits = WB_BORDER | WB_CLOSEABLE | WB_SIZEABLE | (pWindow->GetStyle() & DOCKWIN_FLOATSTYLES); 861 DockingWindow *pDockWin = dynamic_cast< DockingWindow* > ( mpDockingWindow ); 862 if( pDockWin ) 863 mnFloatBits = pDockWin->GetFloatStyle(); 864 865 // must be enabled in Window::Notify to prevent permanent docking during mouse move 866 mbStartDockingEnabled = sal_False; 867 } 868 869 ImplDockingWindowWrapper::~ImplDockingWindowWrapper() 870 { 871 if ( IsFloatingMode() ) 872 { 873 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 874 SetFloatingMode( sal_False ); 875 } 876 } 877 878 // ----------------------------------------------------------------------- 879 880 sal_Bool ImplDockingWindowWrapper::ImplStartDocking( const Point& rPos ) 881 { 882 if ( !mbDockable ) 883 return sal_False; 884 885 if( !mbStartDockingEnabled ) 886 return sal_False; 887 888 maMouseOff = rPos; 889 maMouseStart = maMouseOff; 890 mbDocking = sal_True; 891 mbLastFloatMode = IsFloatingMode(); 892 mbStartFloat = mbLastFloatMode; 893 894 // FloatingBorder berechnen 895 FloatingWindow* pWin; 896 if ( mpFloatWin ) 897 pWin = mpFloatWin; 898 else 899 pWin = new ImplDockFloatWin2( mpParent, mnFloatBits, NULL ); 900 pWin->GetBorder( mnDockLeft, mnDockTop, mnDockRight, mnDockBottom ); 901 if ( !mpFloatWin ) 902 delete pWin; 903 904 Point aPos = GetWindow()->ImplOutputToFrame( Point() ); 905 Size aSize = GetWindow()->GetOutputSizePixel(); 906 mnTrackX = aPos.X(); 907 mnTrackY = aPos.Y(); 908 mnTrackWidth = aSize.Width(); 909 mnTrackHeight = aSize.Height(); 910 911 if ( mbLastFloatMode ) 912 { 913 maMouseOff.X() += mnDockLeft; 914 maMouseOff.Y() += mnDockTop; 915 mnTrackX -= mnDockLeft; 916 mnTrackY -= mnDockTop; 917 mnTrackWidth += mnDockLeft+mnDockRight; 918 mnTrackHeight += mnDockTop+mnDockBottom; 919 } 920 921 Window *pDockingArea = GetWindow()->GetParent(); 922 Window::PointerState aState = pDockingArea->GetPointerState(); 923 924 // mouse pos in screen pixels 925 Point aMousePos = pDockingArea->OutputToScreenPixel( aState.maPos ); 926 Point aDockPos = Point( pDockingArea->AbsoluteScreenToOutputPixel( GetWindow()->OutputToAbsoluteScreenPixel( GetWindow()->GetPosPixel() ) ) ); 927 Rectangle aDockRect( aDockPos, GetWindow()->GetSizePixel() ); 928 StartDocking( aMousePos, aDockRect ); 929 930 GetWindow()->ImplUpdateAll(); 931 GetWindow()->ImplGetFrameWindow()->ImplUpdateAll(); 932 933 GetWindow()->StartTracking( STARTTRACK_KEYMOD ); 934 return sal_True; 935 } 936 937 // ======================================================================= 938 939 void ImplDockingWindowWrapper::ImplInitData() 940 { 941 mpDockingWindow = NULL; 942 943 //GetWindow()->mpWindowImpl->mbDockWin = sal_True; // TODO: must be eliminated 944 mpFloatWin = NULL; 945 mbDockCanceled = sal_False; 946 mbFloatPrevented = sal_False; 947 mbDocking = sal_False; 948 mbPined = sal_False; 949 mbRollUp = sal_False; 950 mbDockBtn = sal_False; 951 mbHideBtn = sal_False; 952 maMaxOutSize = Size( SHRT_MAX, SHRT_MAX ); 953 } 954 955 // ----------------------------------------------------------------------- 956 957 void ImplDockingWindowWrapper::Tracking( const TrackingEvent& rTEvt ) 958 { 959 // used during docking of a currently docked window 960 if ( mbDocking ) 961 { 962 if ( rTEvt.IsTrackingEnded() ) 963 { 964 mbDocking = sal_False; 965 GetWindow()->HideTracking(); 966 if ( rTEvt.IsTrackingCanceled() ) 967 { 968 mbDockCanceled = sal_True; 969 EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode ); 970 mbDockCanceled = sal_False; 971 } 972 else 973 EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode ); 974 } 975 // Docking only upon non-synthetic MouseEvents 976 else if ( !rTEvt.GetMouseEvent().IsSynthetic() || rTEvt.GetMouseEvent().IsModifierChanged() ) 977 { 978 Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel(); 979 Point aFrameMousePos = GetWindow()->ImplOutputToFrame( aMousePos ); 980 Size aFrameSize = GetWindow()->ImplGetFrameWindow()->GetOutputSizePixel(); 981 if ( aFrameMousePos.X() < 0 ) 982 aFrameMousePos.X() = 0; 983 if ( aFrameMousePos.Y() < 0 ) 984 aFrameMousePos.Y() = 0; 985 if ( aFrameMousePos.X() > aFrameSize.Width()-1 ) 986 aFrameMousePos.X() = aFrameSize.Width()-1; 987 if ( aFrameMousePos.Y() > aFrameSize.Height()-1 ) 988 aFrameMousePos.Y() = aFrameSize.Height()-1; 989 aMousePos = GetWindow()->ImplFrameToOutput( aFrameMousePos ); 990 aMousePos.X() -= maMouseOff.X(); 991 aMousePos.Y() -= maMouseOff.Y(); 992 Point aPos = GetWindow()->ImplOutputToFrame( aMousePos ); 993 Rectangle aTrackRect( aPos, Size( mnTrackWidth, mnTrackHeight ) ); 994 Rectangle aCompRect = aTrackRect; 995 aPos.X() += maMouseOff.X(); 996 aPos.Y() += maMouseOff.Y(); 997 998 sal_Bool bFloatMode = Docking( aPos, aTrackRect ); 999 1000 mbFloatPrevented = sal_False; 1001 if ( mbLastFloatMode != bFloatMode ) 1002 { 1003 if ( bFloatMode ) 1004 { 1005 aTrackRect.Left() -= mnDockLeft; 1006 aTrackRect.Top() -= mnDockTop; 1007 aTrackRect.Right() += mnDockRight; 1008 aTrackRect.Bottom() += mnDockBottom; 1009 } 1010 else 1011 { 1012 if ( aCompRect == aTrackRect ) 1013 { 1014 aTrackRect.Left() += mnDockLeft; 1015 aTrackRect.Top() += mnDockTop; 1016 aTrackRect.Right() -= mnDockRight; 1017 aTrackRect.Bottom() -= mnDockBottom; 1018 } 1019 } 1020 mbLastFloatMode = bFloatMode; 1021 } 1022 1023 sal_uInt16 nTrackStyle; 1024 if ( bFloatMode ) 1025 nTrackStyle = SHOWTRACK_OBJECT; 1026 else 1027 nTrackStyle = SHOWTRACK_BIG; 1028 Rectangle aShowTrackRect = aTrackRect; 1029 aShowTrackRect.SetPos( GetWindow()->ImplFrameToOutput( aShowTrackRect.TopLeft() ) ); 1030 //if( bFloatMode ) 1031 GetWindow()->ShowTracking( aShowTrackRect, nTrackStyle ); 1032 /*else 1033 { 1034 GetWindow()->HideTracking(); 1035 Point aPt( GetWindow()->GetParent()->ScreenToOutputPixel( aTrackRect.TopLeft() ) ); 1036 GetWindow()->SetPosPixel( aPt ); 1037 }*/ 1038 1039 // Maus-Offset neu berechnen, da Rechteck veraendert werden 1040 // konnte 1041 maMouseOff.X() = aPos.X() - aTrackRect.Left(); 1042 maMouseOff.Y() = aPos.Y() - aTrackRect.Top(); 1043 1044 mnTrackX = aTrackRect.Left(); 1045 mnTrackY = aTrackRect.Top(); 1046 mnTrackWidth = aTrackRect.GetWidth(); 1047 mnTrackHeight = aTrackRect.GetHeight(); 1048 } 1049 } 1050 } 1051 1052 1053 // ----------------------------------------------------------------------- 1054 1055 void ImplDockingWindowWrapper::StartDocking( const Point& rPoint, Rectangle& rRect ) 1056 { 1057 DockingData data( rPoint, rRect, IsFloatingMode() ); 1058 1059 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_STARTDOCKING, &data ); 1060 mbDocking = sal_True; 1061 } 1062 1063 // ----------------------------------------------------------------------- 1064 1065 sal_Bool ImplDockingWindowWrapper::Docking( const Point& rPoint, Rectangle& rRect ) 1066 { 1067 DockingData data( rPoint, rRect, IsFloatingMode() ); 1068 1069 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_DOCKING, &data ); 1070 rRect = data.maTrackRect; 1071 return data.mbFloating; 1072 } 1073 1074 // ----------------------------------------------------------------------- 1075 1076 void ImplDockingWindowWrapper::EndDocking( const Rectangle& rRect, sal_Bool bFloatMode ) 1077 { 1078 Rectangle aRect( rRect ); 1079 1080 if ( !IsDockingCanceled() ) 1081 { 1082 sal_Bool bShow = sal_False; 1083 if ( bFloatMode != IsFloatingMode() ) 1084 { 1085 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 1086 SetFloatingMode( bFloatMode ); 1087 bShow = sal_True; 1088 if ( bFloatMode ) 1089 { 1090 // #i44800# always use outputsize - as in all other places 1091 mpFloatWin->SetOutputSizePixel( aRect.GetSize() ); 1092 mpFloatWin->SetPosPixel( aRect.TopLeft() ); 1093 } 1094 } 1095 if ( !bFloatMode ) 1096 { 1097 Point aPos = aRect.TopLeft(); 1098 aPos = GetWindow()->GetParent()->ScreenToOutputPixel( aPos ); 1099 GetWindow()->SetPosSizePixel( aPos, aRect.GetSize() ); 1100 } 1101 1102 if ( bShow ) 1103 GetWindow()->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); 1104 } 1105 1106 EndDockingData data( aRect, IsFloatingMode(), IsDockingCanceled() ); 1107 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_ENDDOCKING, &data ); 1108 1109 mbDocking = sal_False; 1110 1111 // must be enabled in Window::Notify to prevent permanent docking during mouse move 1112 mbStartDockingEnabled = sal_False; 1113 } 1114 1115 // ----------------------------------------------------------------------- 1116 1117 sal_Bool ImplDockingWindowWrapper::PrepareToggleFloatingMode() 1118 { 1119 sal_Bool bFloating = sal_True; 1120 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_PREPARETOGGLEFLOATING, &bFloating ); 1121 return bFloating; 1122 } 1123 1124 // ----------------------------------------------------------------------- 1125 1126 sal_Bool ImplDockingWindowWrapper::Close() 1127 { 1128 // TODO: send event 1129 /* 1130 ImplDelData aDelData; 1131 ImplAddDel( &aDelData ); 1132 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_CLOSE ); 1133 if ( aDelData.IsDelete() ) 1134 return sal_False; 1135 ImplRemoveDel( &aDelData ); 1136 1137 if ( mpWindowImpl->mxWindowPeer.is() && IsCreatedWithToolkit() ) 1138 return sal_False; 1139 1140 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 1141 */ 1142 return sal_True; 1143 } 1144 1145 // ----------------------------------------------------------------------- 1146 1147 void ImplDockingWindowWrapper::ToggleFloatingMode() 1148 { 1149 // notify dockingwindow/toolbox 1150 // note: this must be done *before* notifying the 1151 // listeners to have the toolbox in the proper state 1152 if( GetWindow()->ImplIsDockingWindow() ) 1153 ((DockingWindow*) GetWindow())->ToggleFloatingMode(); 1154 1155 // now notify listeners 1156 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_TOGGLEFLOATING ); 1157 1158 // must be enabled in Window::Notify to prevent permanent docking during mouse move 1159 mbStartDockingEnabled = sal_False; 1160 } 1161 1162 // ----------------------------------------------------------------------- 1163 1164 void ImplDockingWindowWrapper::TitleButtonClick( sal_uInt16 nType ) 1165 { 1166 if( nType == TITLE_BUTTON_MENU ) 1167 { 1168 ToolBox *pToolBox = dynamic_cast< ToolBox* >( GetWindow() ); 1169 if( pToolBox ) 1170 { 1171 pToolBox->ExecuteCustomMenu(); 1172 } 1173 } 1174 if( nType == TITLE_BUTTON_DOCKING ) 1175 { 1176 SetFloatingMode( !IsFloatingMode() ); 1177 } 1178 } 1179 1180 // ----------------------------------------------------------------------- 1181 1182 void ImplDockingWindowWrapper::Pin() 1183 { 1184 // TODO: send event 1185 } 1186 1187 // ----------------------------------------------------------------------- 1188 1189 void ImplDockingWindowWrapper::Roll() 1190 { 1191 // TODO: send event 1192 } 1193 1194 // ----------------------------------------------------------------------- 1195 1196 void ImplDockingWindowWrapper::PopupModeEnd() 1197 { 1198 // TODO: send event 1199 } 1200 1201 // ----------------------------------------------------------------------- 1202 1203 void ImplDockingWindowWrapper::Resizing( Size& rSize ) 1204 { 1205 // TODO: add virtual Resizing() to class Window, so we can get rid of class DockingWindow 1206 DockingWindow *pDockingWindow = dynamic_cast< DockingWindow* >( GetWindow() ); 1207 if( pDockingWindow ) 1208 pDockingWindow->Resizing( rSize ); 1209 } 1210 1211 // ----------------------------------------------------------------------- 1212 1213 void ImplDockingWindowWrapper::ShowTitleButton( sal_uInt16 nButton, sal_Bool bVisible ) 1214 { 1215 if ( mpFloatWin ) 1216 mpFloatWin->ShowTitleButton( nButton, bVisible ); 1217 else 1218 { 1219 if ( nButton == TITLE_BUTTON_DOCKING ) 1220 mbDockBtn = bVisible; 1221 else // if ( nButton == TITLE_BUTTON_HIDE ) 1222 mbHideBtn = bVisible; 1223 } 1224 } 1225 1226 // ----------------------------------------------------------------------- 1227 1228 sal_Bool ImplDockingWindowWrapper::IsTitleButtonVisible( sal_uInt16 nButton ) const 1229 { 1230 if ( mpFloatWin ) 1231 return mpFloatWin->IsTitleButtonVisible( nButton ); 1232 else 1233 { 1234 if ( nButton == TITLE_BUTTON_DOCKING ) 1235 return mbDockBtn; 1236 else // if ( nButton == TITLE_BUTTON_HIDE ) 1237 return mbHideBtn; 1238 } 1239 } 1240 1241 // ----------------------------------------------------------------------- 1242 1243 void ImplDockingWindowWrapper::StartPopupMode( ToolBox *pParentToolBox, sal_uLong nFlags ) 1244 { 1245 // do nothing if window is floating 1246 if( IsFloatingMode() ) 1247 return; 1248 1249 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 1250 1251 // prepare reparenting 1252 Window* pRealParent = GetWindow()->GetWindow( WINDOW_PARENT ); 1253 mpOldBorderWin = GetWindow()->GetWindow( WINDOW_BORDER ); 1254 if( mpOldBorderWin == GetWindow() ) 1255 mpOldBorderWin = NULL; // no border window found 1256 1257 // the new parent for popup mode 1258 ImplPopupFloatWin* pWin = new ImplPopupFloatWin( mpParent, this, (nFlags & FLOATWIN_POPUPMODE_ALLOWTEAROFF) != 0 ); 1259 1260 pWin->SetPopupModeEndHdl( LINK( this, ImplDockingWindowWrapper, PopupModeEnd ) ); 1261 pWin->SetText( GetWindow()->GetText() ); 1262 1263 pWin->SetOutputSizePixel( GetWindow()->GetSizePixel() ); 1264 1265 GetWindow()->mpWindowImpl->mpBorderWindow = NULL; 1266 GetWindow()->mpWindowImpl->mnLeftBorder = 0; 1267 GetWindow()->mpWindowImpl->mnTopBorder = 0; 1268 GetWindow()->mpWindowImpl->mnRightBorder = 0; 1269 GetWindow()->mpWindowImpl->mnBottomBorder = 0; 1270 1271 // position toolbox below dragrect 1272 GetWindow()->SetPosPixel( pWin->GetToolboxPosition() ); 1273 1274 // reparent borderwindow and window 1275 if ( mpOldBorderWin ) 1276 mpOldBorderWin->SetParent( pWin ); 1277 GetWindow()->SetParent( pWin ); 1278 1279 // correct border window pointers 1280 GetWindow()->mpWindowImpl->mpBorderWindow = pWin; 1281 pWin->mpWindowImpl->mpClientWindow = GetWindow(); 1282 GetWindow()->mpWindowImpl->mpRealParent = pRealParent; 1283 1284 // set mpFloatWin not until all window positioning is done !!! 1285 // (SetPosPixel etc. check for valid mpFloatWin pointer) 1286 mpFloatWin = pWin; 1287 1288 // if the subtoolbar was opened via keyboard make sure that key events 1289 // will go into subtoolbar 1290 if( pParentToolBox->IsKeyEvent() ) 1291 nFlags |= FLOATWIN_POPUPMODE_GRABFOCUS; 1292 1293 mpFloatWin->StartPopupMode( pParentToolBox, nFlags ); 1294 GetWindow()->Show(); 1295 1296 if( pParentToolBox->IsKeyEvent() ) 1297 { 1298 // send HOME key to subtoolbar in order to select first item 1299 KeyEvent aEvent( 0, KeyCode( KEY_HOME ) ); 1300 mpFloatWin->GetPreferredKeyInputWindow()->KeyInput( aEvent ); 1301 } 1302 } 1303 1304 IMPL_LINK( ImplDockingWindowWrapper, PopupModeEnd, void*, EMPTYARG ) 1305 { 1306 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 1307 1308 // set parameter for handler before destroying floating window 1309 ImplPopupFloatWin *pPopupFloatWin = (ImplPopupFloatWin*) mpFloatWin; 1310 EndPopupModeData aData( pPopupFloatWin->GetTearOffPosition(), mpFloatWin->IsPopupModeTearOff() ); 1311 1312 // before deleting change parent back, so we can delete the floating window alone 1313 Window* pRealParent = GetWindow()->GetWindow( WINDOW_PARENT ); 1314 GetWindow()->mpWindowImpl->mpBorderWindow = NULL; 1315 if ( mpOldBorderWin ) 1316 { 1317 GetWindow()->SetParent( mpOldBorderWin ); 1318 ((ImplBorderWindow*)mpOldBorderWin)->GetBorder( 1319 GetWindow()->mpWindowImpl->mnLeftBorder, GetWindow()->mpWindowImpl->mnTopBorder, 1320 GetWindow()->mpWindowImpl->mnRightBorder, GetWindow()->mpWindowImpl->mnBottomBorder ); 1321 mpOldBorderWin->Resize(); 1322 } 1323 GetWindow()->mpWindowImpl->mpBorderWindow = mpOldBorderWin; 1324 GetWindow()->SetParent( pRealParent ); 1325 GetWindow()->mpWindowImpl->mpRealParent = pRealParent; 1326 1327 delete mpFloatWin; 1328 mpFloatWin = NULL; 1329 1330 // call handler - which will destroy the window and thus the wrapper as well ! 1331 GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_ENDPOPUPMODE, &aData ); 1332 1333 return 0; 1334 } 1335 1336 1337 sal_Bool ImplDockingWindowWrapper::IsInPopupMode() const 1338 { 1339 if( GetFloatingWindow() ) 1340 return GetFloatingWindow()->IsInPopupMode(); 1341 else 1342 return sal_False; 1343 } 1344 1345 // ----------------------------------------------------------------------- 1346 1347 void ImplDockingWindowWrapper::SetFloatingMode( sal_Bool bFloatMode ) 1348 { 1349 // do nothing if window is docked and locked 1350 if( !IsFloatingMode() && IsLocked() ) 1351 return; 1352 1353 if ( IsFloatingMode() != bFloatMode ) 1354 { 1355 if ( PrepareToggleFloatingMode() ) 1356 { 1357 sal_Bool bVisible = GetWindow()->IsVisible(); 1358 1359 if ( bFloatMode ) 1360 { 1361 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 1362 1363 maDockPos = GetWindow()->GetPosPixel(); 1364 1365 Window* pRealParent = GetWindow()->GetWindow( WINDOW_PARENT ); 1366 mpOldBorderWin = GetWindow()->GetWindow( WINDOW_BORDER ); 1367 if( mpOldBorderWin == mpDockingWindow ) 1368 mpOldBorderWin = NULL; // no border window found 1369 1370 ImplDockFloatWin2* pWin = 1371 new ImplDockFloatWin2( 1372 mpParent, 1373 mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ? 1374 mnFloatBits | WB_SYSTEMWINDOW 1375 //#ifdef __USE_OWNERDRAWDECORATION__ 1376 | WB_OWNERDRAWDECORATION 1377 //#endif 1378 : mnFloatBits, 1379 this ); 1380 1381 // reduce the border width for seamless NWF painting 1382 // (especially for the toolbar gradient on Windows XP) 1383 /*AllSettings aSettings( pWin->GetSettings() ); 1384 StyleSettings aStyleSettings( aSettings.GetStyleSettings() ); 1385 aStyleSettings.SetBorderSize( 0 ); 1386 aSettings.SetStyleSettings( aStyleSettings ); 1387 pWin->SetSettings( aSettings );*/ 1388 1389 // mpFloatWin = pWin; 1390 1391 1392 GetWindow()->mpWindowImpl->mpBorderWindow = NULL; 1393 GetWindow()->mpWindowImpl->mnLeftBorder = 0; 1394 GetWindow()->mpWindowImpl->mnTopBorder = 0; 1395 GetWindow()->mpWindowImpl->mnRightBorder = 0; 1396 GetWindow()->mpWindowImpl->mnBottomBorder = 0; 1397 1398 // Falls Parent zerstoert wird, muessen wir auch vom 1399 // BorderWindow den Parent umsetzen 1400 if ( mpOldBorderWin ) 1401 mpOldBorderWin->SetParent( pWin ); 1402 GetWindow()->SetParent( pWin ); 1403 pWin->SetPosPixel( Point() ); 1404 1405 GetWindow()->mpWindowImpl->mpBorderWindow = pWin; 1406 pWin->mpWindowImpl->mpClientWindow = mpDockingWindow; 1407 GetWindow()->mpWindowImpl->mpRealParent = pRealParent; 1408 1409 pWin->SetText( GetWindow()->GetText() ); 1410 pWin->SetOutputSizePixel( GetWindow()->GetSizePixel() ); 1411 pWin->SetPosPixel( maFloatPos ); 1412 // DockingDaten ans FloatingWindow weiterreichen 1413 pWin->ShowTitleButton( TITLE_BUTTON_DOCKING, mbDockBtn ); 1414 pWin->ShowTitleButton( TITLE_BUTTON_HIDE, mbHideBtn ); 1415 pWin->SetPin( mbPined ); 1416 if ( mbRollUp ) 1417 pWin->RollUp(); 1418 else 1419 pWin->RollDown(); 1420 pWin->SetRollUpOutputSizePixel( maRollUpOutSize ); 1421 pWin->SetMinOutputSizePixel( maMinOutSize ); 1422 pWin->SetMaxOutputSizePixel( maMaxOutSize ); 1423 1424 mpFloatWin = pWin; 1425 1426 if ( bVisible ) 1427 GetWindow()->Show( sal_True, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE ); 1428 1429 ToggleFloatingMode(); 1430 } 1431 else 1432 { 1433 GetWindow()->Show( sal_False, SHOW_NOFOCUSCHANGE ); 1434 1435 // FloatingDaten wird im FloatingWindow speichern 1436 maFloatPos = mpFloatWin->GetPosPixel(); 1437 mbDockBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_DOCKING ); 1438 mbHideBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_HIDE ); 1439 mbPined = mpFloatWin->IsPined(); 1440 mbRollUp = mpFloatWin->IsRollUp(); 1441 maRollUpOutSize = mpFloatWin->GetRollUpOutputSizePixel(); 1442 maMinOutSize = mpFloatWin->GetMinOutputSizePixel(); 1443 maMaxOutSize = mpFloatWin->GetMaxOutputSizePixel(); 1444 1445 Window* pRealParent = GetWindow()->GetWindow( WINDOW_PARENT ); //mpWindowImpl->mpRealParent; 1446 GetWindow()->mpWindowImpl->mpBorderWindow = NULL; 1447 if ( mpOldBorderWin ) 1448 { 1449 GetWindow()->SetParent( mpOldBorderWin ); 1450 ((ImplBorderWindow*)mpOldBorderWin)->GetBorder( 1451 GetWindow()->mpWindowImpl->mnLeftBorder, GetWindow()->mpWindowImpl->mnTopBorder, 1452 GetWindow()->mpWindowImpl->mnRightBorder, GetWindow()->mpWindowImpl->mnBottomBorder ); 1453 mpOldBorderWin->Resize(); 1454 } 1455 GetWindow()->mpWindowImpl->mpBorderWindow = mpOldBorderWin; 1456 GetWindow()->SetParent( pRealParent ); 1457 GetWindow()->mpWindowImpl->mpRealParent = pRealParent; 1458 1459 delete static_cast<ImplDockFloatWin2*>(mpFloatWin); 1460 mpFloatWin = NULL; 1461 GetWindow()->SetPosPixel( maDockPos ); 1462 1463 if ( bVisible ) 1464 GetWindow()->Show(); 1465 1466 ToggleFloatingMode(); 1467 1468 } 1469 } 1470 } 1471 } 1472 1473 // ----------------------------------------------------------------------- 1474 1475 void ImplDockingWindowWrapper::SetFloatStyle( WinBits nStyle ) 1476 { 1477 mnFloatBits = nStyle; 1478 } 1479 1480 // ----------------------------------------------------------------------- 1481 1482 WinBits ImplDockingWindowWrapper::GetFloatStyle() const 1483 { 1484 return mnFloatBits; 1485 } 1486 1487 // ----------------------------------------------------------------------- 1488 1489 void ImplDockingWindowWrapper::SetTabStop() 1490 { 1491 GetWindow()->SetStyle( GetWindow()->GetStyle() | (WB_GROUP | WB_TABSTOP) ); 1492 } 1493 1494 // ----------------------------------------------------------------------- 1495 1496 void ImplDockingWindowWrapper::SetPosSizePixel( long nX, long nY, 1497 long nWidth, long nHeight, 1498 sal_uInt16 nFlags ) 1499 { 1500 if ( mpFloatWin ) 1501 mpFloatWin->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); 1502 else 1503 GetWindow()->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags ); 1504 } 1505 1506 // ----------------------------------------------------------------------- 1507 1508 Point ImplDockingWindowWrapper::GetPosPixel() const 1509 { 1510 if ( mpFloatWin ) 1511 return mpFloatWin->GetPosPixel(); 1512 else 1513 return mpDockingWindow->GetPosPixel(); 1514 } 1515 1516 // ----------------------------------------------------------------------- 1517 1518 Size ImplDockingWindowWrapper::GetSizePixel() const 1519 { 1520 if ( mpFloatWin ) 1521 return mpFloatWin->GetSizePixel(); 1522 else 1523 return mpDockingWindow->GetSizePixel(); 1524 } 1525 1526 // ----------------------------------------------------------------------- 1527 1528 void ImplDockingWindowWrapper::SetOutputSizePixel( const Size& rNewSize ) 1529 { 1530 if ( mpFloatWin ) 1531 mpFloatWin->SetOutputSizePixel( rNewSize ); 1532 else 1533 GetWindow()->SetOutputSizePixel( rNewSize ); 1534 } 1535 1536 // ----------------------------------------------------------------------- 1537 1538 Size ImplDockingWindowWrapper::GetOutputSizePixel() const 1539 { 1540 if ( mpFloatWin ) 1541 return mpFloatWin->GetOutputSizePixel(); 1542 else 1543 return mpDockingWindow->GetOutputSizePixel(); 1544 } 1545 1546 Point ImplDockingWindowWrapper::GetFloatingPos() const 1547 { 1548 if ( mpFloatWin ) 1549 { 1550 //Rectangle aRect = mpFloatWin->GetWindow( WINDOW_CLIENT)->GetWindowExtentsRelative( mpFloatWin->GetParent() ); 1551 WindowStateData aData; 1552 aData.SetMask( WINDOWSTATE_MASK_POS ); 1553 mpFloatWin->GetWindowStateData( aData ); 1554 Point aPos( aData.GetX(), aData.GetY() ); 1555 aPos = mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos ); 1556 return aPos; 1557 } 1558 else 1559 return maFloatPos; 1560 } 1561 1562 // ----------------------------------------------------------------------- 1563 // old inlines from DockingWindow 1564 // ----------------------------------------------------------------------- 1565 1566 void ImplDockingWindowWrapper::SetPin( sal_Bool bPin ) 1567 { 1568 if ( mpFloatWin ) 1569 mpFloatWin->SetPin( bPin ); 1570 mbPined = bPin; 1571 } 1572 1573 sal_Bool ImplDockingWindowWrapper::IsPined() const 1574 { 1575 if ( mpFloatWin ) 1576 return mpFloatWin->IsPined(); 1577 return mbPined; 1578 } 1579 1580 void ImplDockingWindowWrapper::RollUp() 1581 { 1582 if ( mpFloatWin ) 1583 mpFloatWin->RollUp(); 1584 mbRollUp = sal_True; 1585 } 1586 1587 void ImplDockingWindowWrapper::RollDown() 1588 { 1589 if ( mpFloatWin ) 1590 mpFloatWin->RollDown(); 1591 mbRollUp = sal_False; 1592 } 1593 1594 sal_Bool ImplDockingWindowWrapper::IsRollUp() const 1595 { 1596 if ( mpFloatWin ) 1597 return mpFloatWin->IsRollUp(); 1598 return mbRollUp; 1599 } 1600 1601 void ImplDockingWindowWrapper::SetRollUpOutputSizePixel( const Size& rSize ) 1602 { 1603 if ( mpFloatWin ) 1604 mpFloatWin->SetRollUpOutputSizePixel( rSize ); 1605 maRollUpOutSize = rSize; 1606 } 1607 1608 Size ImplDockingWindowWrapper::GetRollUpOutputSizePixel() const 1609 { 1610 if ( mpFloatWin ) 1611 return mpFloatWin->GetRollUpOutputSizePixel(); 1612 return maRollUpOutSize; 1613 } 1614 1615 void ImplDockingWindowWrapper::SetMinOutputSizePixel( const Size& rSize ) 1616 { 1617 if ( mpFloatWin ) 1618 mpFloatWin->SetMinOutputSizePixel( rSize ); 1619 maMinOutSize = rSize; 1620 } 1621 1622 void ImplDockingWindowWrapper::SetMaxOutputSizePixel( const Size& rSize ) 1623 { 1624 if ( mpFloatWin ) 1625 mpFloatWin->SetMaxOutputSizePixel( rSize ); 1626 maMaxOutSize = rSize; 1627 } 1628 1629 const Size& ImplDockingWindowWrapper::GetMinOutputSizePixel() const 1630 { 1631 if ( mpFloatWin ) 1632 return mpFloatWin->GetMinOutputSizePixel(); 1633 return maMinOutSize; 1634 } 1635 1636 const Size& ImplDockingWindowWrapper::GetMaxOutputSizePixel() const 1637 { 1638 if ( mpFloatWin ) 1639 return mpFloatWin->GetMaxOutputSizePixel(); 1640 return maMaxOutSize; 1641 } 1642 1643 void ImplDockingWindowWrapper::SetFloatingPos( const Point& rNewPos ) 1644 { 1645 if ( mpFloatWin ) 1646 mpFloatWin->SetPosPixel( rNewPos ); 1647 else 1648 maFloatPos = rNewPos; 1649 } 1650 1651 sal_Bool ImplDockingWindowWrapper::IsFloatingMode() const 1652 { 1653 return (mpFloatWin != NULL); 1654 } 1655 1656 1657 void ImplDockingWindowWrapper::SetDragArea( const Rectangle& rRect ) 1658 { 1659 maDragArea = rRect; 1660 } 1661 1662 Rectangle ImplDockingWindowWrapper::GetDragArea() const 1663 { 1664 return maDragArea; 1665 } 1666 1667 void ImplDockingWindowWrapper::Lock() 1668 { 1669 mbLocked = sal_True; 1670 // only toolbars support locking 1671 ToolBox *pToolBox = dynamic_cast< ToolBox * >( GetWindow() ); 1672 if( pToolBox ) 1673 pToolBox->Lock( mbLocked ); 1674 } 1675 1676 void ImplDockingWindowWrapper::Unlock() 1677 { 1678 mbLocked = sal_False; 1679 // only toolbars support locking 1680 ToolBox *pToolBox = dynamic_cast< ToolBox * >( GetWindow() ); 1681 if( pToolBox ) 1682 pToolBox->Lock( mbLocked ); 1683 } 1684 1685 sal_Bool ImplDockingWindowWrapper::IsLocked() const 1686 { 1687 return mbLocked; 1688 } 1689