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