xref: /aoo41x/main/vcl/source/window/dockwin.cxx (revision cdf0e10c)
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