xref: /aoo41x/main/vcl/source/window/dockwin.cxx (revision 087aa071)
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     switch(nType)
766     {
767         case STATE_CHANGE_CONTROLBACKGROUND:
768             ImplInitSettings();
769             Invalidate();
770             break;
771 
772         case STATE_CHANGE_STYLE:
773             mbDockable = (GetStyle() & WB_DOCKABLE) != 0;
774             break;
775 
776         default:
777             break;
778     }
779 
780     Window::StateChanged( nType );
781 }
782 
783 // -----------------------------------------------------------------------
784 
785 void DockingWindow::DataChanged( const DataChangedEvent& rDCEvt )
786 {
787     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
788          (rDCEvt.GetFlags() & SETTINGS_STYLE) )
789     {
790         ImplInitSettings();
791         Invalidate();
792     }
793     else
794         Window::DataChanged( rDCEvt );
795 }
796 
797 // -----------------------------------------------------------------------
798 
799 void DockingWindow::ShowTitleButton( sal_uInt16 nButton, sal_Bool bVisible )
800 {
801     if ( mpFloatWin )
802         mpFloatWin->ShowTitleButton( nButton, bVisible );
803     else
804     {
805         if ( nButton == TITLE_BUTTON_DOCKING )
806             mbDockBtn = bVisible;
807         else /* if ( nButton == TITLE_BUTTON_HIDE ) */
808             mbHideBtn = bVisible;
809     }
810 }
811 
812 // -----------------------------------------------------------------------
813 
814 sal_Bool DockingWindow::IsTitleButtonVisible( sal_uInt16 nButton ) const
815 {
816     if ( mpFloatWin )
817         return mpFloatWin->IsTitleButtonVisible( nButton );
818     else
819     {
820         if ( nButton == TITLE_BUTTON_DOCKING )
821             return mbDockBtn;
822         else /* if ( nButton == TITLE_BUTTON_HIDE ) */
823             return mbHideBtn;
824     }
825 }
826 
827 // -----------------------------------------------------------------------
828 
829 void DockingWindow::SetFloatingMode( sal_Bool bFloatMode )
830 {
831     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
832     if( pWrapper )
833     {
834         pWrapper->SetFloatingMode( bFloatMode );
835         return;
836     }
837     if ( IsFloatingMode() != bFloatMode )
838     {
839         if ( PrepareToggleFloatingMode() ) // changes to floating mode can be vetoed
840         {
841             sal_Bool bVisible = IsVisible();
842 
843             if ( bFloatMode )
844             {
845                 Show( sal_False, SHOW_NOFOCUSCHANGE );
846 
847                 maDockPos = Window::GetPosPixel();
848 
849                 Window* pRealParent = mpWindowImpl->mpRealParent;
850                 mpOldBorderWin = mpWindowImpl->mpBorderWindow;
851 
852                 ImplDockFloatWin* pWin =
853                     new ImplDockFloatWin(
854                                          mpImplData->mpParent,
855                                          mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ?  mnFloatBits | WB_SYSTEMWINDOW : mnFloatBits,
856                                          this );
857                 mpFloatWin      = pWin;
858                 mpWindowImpl->mpBorderWindow  = NULL;
859                 mpWindowImpl->mnLeftBorder    = 0;
860                 mpWindowImpl->mnTopBorder     = 0;
861                 mpWindowImpl->mnRightBorder   = 0;
862                 mpWindowImpl->mnBottomBorder  = 0;
863                 // Falls Parent zerstoert wird, muessen wir auch vom
864                 // BorderWindow den Parent umsetzen
865                 if ( mpOldBorderWin )
866                     mpOldBorderWin->SetParent( pWin );
867                 SetParent( pWin );
868                 SetPosPixel( Point() );
869                 mpWindowImpl->mpBorderWindow = pWin;
870                 pWin->mpWindowImpl->mpClientWindow = this;
871                 mpWindowImpl->mpRealParent = pRealParent;
872                 pWin->SetText( Window::GetText() );
873                 pWin->SetOutputSizePixel( Window::GetSizePixel() );
874                 pWin->SetPosPixel( maFloatPos );
875                 // DockingDaten ans FloatingWindow weiterreichen
876                 pWin->ShowTitleButton( TITLE_BUTTON_DOCKING, mbDockBtn );
877                 pWin->ShowTitleButton( TITLE_BUTTON_HIDE, mbHideBtn );
878                 pWin->SetPin( mbPined );
879                 if ( mbRollUp )
880                     pWin->RollUp();
881                 else
882                     pWin->RollDown();
883                 pWin->SetRollUpOutputSizePixel( maRollUpOutSize );
884                 pWin->SetMinOutputSizePixel( maMinOutSize );
885                 pWin->SetMaxOutputSizePixel( mpImplData->maMaxOutSize );
886 
887                 ToggleFloatingMode();
888 
889                 if ( bVisible )
890                     Show();
891             }
892             else
893             {
894                 Show( sal_False, SHOW_NOFOCUSCHANGE );
895 
896                 // FloatingDaten wird im FloatingWindow speichern
897                 maFloatPos      = mpFloatWin->GetPosPixel();
898                 mbDockBtn       = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_DOCKING );
899                 mbHideBtn       = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_HIDE );
900                 mbPined         = mpFloatWin->IsPined();
901                 mbRollUp        = mpFloatWin->IsRollUp();
902                 maRollUpOutSize = mpFloatWin->GetRollUpOutputSizePixel();
903                 maMinOutSize    = mpFloatWin->GetMinOutputSizePixel();
904                 mpImplData->maMaxOutSize = mpFloatWin->GetMaxOutputSizePixel();
905 
906                 Window* pRealParent = mpWindowImpl->mpRealParent;
907                 mpWindowImpl->mpBorderWindow = NULL;
908                 if ( mpOldBorderWin )
909                 {
910                     SetParent( mpOldBorderWin );
911                     ((ImplBorderWindow*)mpOldBorderWin)->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
912                     mpOldBorderWin->Resize();
913                 }
914                 mpWindowImpl->mpBorderWindow = mpOldBorderWin;
915                 SetParent( pRealParent );
916                 mpWindowImpl->mpRealParent = pRealParent;
917                 delete static_cast<ImplDockFloatWin*>(mpFloatWin);
918                 mpFloatWin = NULL;
919                 SetPosPixel( maDockPos );
920 
921                 ToggleFloatingMode();
922 
923                 if ( bVisible )
924                     Show();
925             }
926         }
927     }
928 }
929 
930 // -----------------------------------------------------------------------
931 
932 void DockingWindow::SetFloatStyle( WinBits nStyle )
933 {
934     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
935     if( pWrapper )
936     {
937         pWrapper->SetFloatStyle( nStyle );
938         return;
939     }
940 
941     mnFloatBits = nStyle;
942 }
943 
944 // -----------------------------------------------------------------------
945 
946 WinBits DockingWindow::GetFloatStyle() const
947 {
948     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
949     if( pWrapper )
950     {
951         return pWrapper->GetFloatStyle();
952     }
953 
954     return mnFloatBits;
955 }
956 
957 // -----------------------------------------------------------------------
958 
959 void DockingWindow::SetTabStop()
960 {
961     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
962     if( pWrapper )
963     {
964         pWrapper->SetTabStop();
965         return;
966     }
967 
968     mpWindowImpl->mnStyle |= WB_GROUP | WB_TABSTOP;
969 }
970 
971 // -----------------------------------------------------------------------
972 
973 void DockingWindow::SetPosSizePixel( long nX, long nY,
974                                      long nWidth, long nHeight,
975                                      sal_uInt16 nFlags )
976 {
977     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
978     if( pWrapper )
979     {
980         if ( pWrapper->mpFloatWin )
981             pWrapper->mpFloatWin->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
982         else
983             Window::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
984         return;
985     }
986 
987     if ( mpFloatWin )
988         mpFloatWin->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
989     else
990         Window::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
991 }
992 
993 // -----------------------------------------------------------------------
994 
995 Point DockingWindow::GetPosPixel() const
996 {
997     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
998     if( pWrapper )
999     {
1000         if ( pWrapper->mpFloatWin )
1001             return pWrapper->mpFloatWin->GetPosPixel();
1002         else
1003             return Window::GetPosPixel();
1004     }
1005 
1006     if ( mpFloatWin )
1007         return mpFloatWin->GetPosPixel();
1008     else
1009         return Window::GetPosPixel();
1010 }
1011 
1012 // -----------------------------------------------------------------------
1013 
1014 Size DockingWindow::GetSizePixel() const
1015 {
1016     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1017     if( pWrapper )
1018     {
1019         if ( pWrapper->mpFloatWin )
1020             return pWrapper->mpFloatWin->GetSizePixel();
1021         else
1022             return Window::GetSizePixel();
1023     }
1024 
1025     if ( mpFloatWin )
1026         return mpFloatWin->GetSizePixel();
1027     else
1028         return Window::GetSizePixel();
1029 }
1030 
1031 // -----------------------------------------------------------------------
1032 
1033 void DockingWindow::SetOutputSizePixel( const Size& rNewSize )
1034 {
1035     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1036     if( pWrapper )
1037     {
1038         if ( pWrapper->mpFloatWin )
1039             pWrapper->mpFloatWin->SetOutputSizePixel( rNewSize );
1040         else
1041             Window::SetOutputSizePixel( rNewSize );
1042         return;
1043     }
1044 
1045     if ( mpFloatWin )
1046         mpFloatWin->SetOutputSizePixel( rNewSize );
1047     else
1048         Window::SetOutputSizePixel( rNewSize );
1049 }
1050 
1051 // -----------------------------------------------------------------------
1052 
1053 Size DockingWindow::GetOutputSizePixel() const
1054 {
1055     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1056     if( pWrapper )
1057     {
1058         if ( pWrapper->mpFloatWin )
1059             return pWrapper->mpFloatWin->GetOutputSizePixel();
1060         else
1061             return Window::GetOutputSizePixel();
1062     }
1063 
1064     if ( mpFloatWin )
1065         return mpFloatWin->GetOutputSizePixel();
1066     else
1067         return Window::GetOutputSizePixel();
1068 }
1069 
1070 Point DockingWindow::GetFloatingPos() const
1071 {
1072     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1073     if( pWrapper )
1074     {
1075 	    if ( pWrapper->mpFloatWin )
1076         {
1077             WindowStateData aData;
1078             aData.SetMask( WINDOWSTATE_MASK_POS );
1079             pWrapper->mpFloatWin->GetWindowStateData( aData );
1080             Point aPos( aData.GetX(), aData.GetY() );
1081             aPos = pWrapper->mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos );
1082             return aPos;
1083         }
1084 	    else
1085 		    return maFloatPos;
1086     }
1087 
1088 	if ( mpFloatWin )
1089     {
1090         WindowStateData aData;
1091         aData.SetMask( WINDOWSTATE_MASK_POS );
1092         mpFloatWin->GetWindowStateData( aData );
1093         Point aPos( aData.GetX(), aData.GetY() );
1094         aPos = mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos );
1095         return aPos;
1096     }
1097 	else
1098 		return maFloatPos;
1099 }
1100 
1101 sal_Bool DockingWindow::IsFloatingMode() const
1102 {
1103     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1104     if( pWrapper )
1105         return pWrapper->IsFloatingMode();
1106     else
1107 	    return (mpFloatWin != NULL);
1108 }
1109 
1110 void DockingWindow::SetMaxOutputSizePixel( const Size& rSize )
1111 {
1112 	if ( mpFloatWin )
1113 		mpFloatWin->SetMaxOutputSizePixel( rSize );
1114 	mpImplData->maMaxOutSize = rSize;
1115 }
1116 
1117 const Size& DockingWindow::GetMaxOutputSizePixel() const
1118 {
1119 	if ( mpFloatWin )
1120 		return mpFloatWin->GetMaxOutputSizePixel();
1121 	return mpImplData->maMaxOutSize;
1122 }
1123