xref: /trunk/main/vcl/source/window/dockwin.cxx (revision 526a327c)
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 
ImplData()62 DockingWindow::ImplData::ImplData()
63 {
64     mpParent = NULL;
65     maMaxOutSize = Size( SHRT_MAX, SHRT_MAX );
66 }
67 
~ImplData()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 
GetLastTicks() const101     sal_uLong GetLastTicks() const { return mnLastTicks; }
102 };
103 
104 
ImplDockFloatWin(Window * pParent,WinBits nWinBits,DockingWindow * pDockingWin)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 
~ImplDockFloatWin()132 ImplDockFloatWin::~ImplDockFloatWin()
133 {
134     if( mnLastUserEvent )
135         Application::RemoveUserEvent( mnLastUserEvent );
136 }
137 
138 // -----------------------------------------------------------------------
139 
IMPL_LINK(ImplDockFloatWin,DockTimerHdl,ImplDockFloatWin *,EMPTYARG)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 
IMPL_LINK(ImplDockFloatWin,DockingHdl,ImplDockFloatWin *,EMPTYARG)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 
Move()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 
Resize()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 
TitleButtonClick(sal_uInt16 nButton)240 void ImplDockFloatWin::TitleButtonClick( sal_uInt16 nButton )
241 {
242     FloatingWindow::TitleButtonClick( nButton );
243     mpDockWin->TitleButtonClick( nButton );
244 }
245 
246 // -----------------------------------------------------------------------
247 
Pin()248 void ImplDockFloatWin::Pin()
249 {
250     FloatingWindow::Pin();
251     mpDockWin->Pin();
252 }
253 
254 // -----------------------------------------------------------------------
255 
Roll()256 void ImplDockFloatWin::Roll()
257 {
258     FloatingWindow::Roll();
259     mpDockWin->Roll();
260 }
261 
262 // -----------------------------------------------------------------------
263 
PopupModeEnd()264 void ImplDockFloatWin::PopupModeEnd()
265 {
266     FloatingWindow::PopupModeEnd();
267     mpDockWin->PopupModeEnd();
268 }
269 
270 // -----------------------------------------------------------------------
271 
Resizing(Size & rSize)272 void ImplDockFloatWin::Resizing( Size& rSize )
273 {
274     FloatingWindow::Resizing( rSize );
275     mpDockWin->Resizing( rSize );
276 }
277 
278 // -----------------------------------------------------------------------
279 
Close()280 sal_Bool ImplDockFloatWin::Close()
281 {
282     return mpDockWin->Close();
283 }
284 
285 // =======================================================================
286 
ImplStartDocking(const Point & rPos)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 
ImplInitDockingWindowData()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 
ImplInit(Window * pParent,WinBits nStyle)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 
ImplInitSettings()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 
ImplLoadRes(const ResId & rResId)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 
DockingWindow(WindowType nType)440 DockingWindow::DockingWindow( WindowType nType ) :
441     Window( nType )
442 {
443     ImplInitDockingWindowData();
444 }
445 
446 // -----------------------------------------------------------------------
447 
DockingWindow(Window * pParent,WinBits nStyle)448 DockingWindow::DockingWindow( Window* pParent, WinBits nStyle ) :
449     Window( WINDOW_DOCKINGWINDOW )
450 {
451     ImplInitDockingWindowData();
452     ImplInit( pParent, nStyle );
453 }
454 
455 // -----------------------------------------------------------------------
456 
DockingWindow(Window * pParent,const ResId & rResId)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 
~DockingWindow()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 
Tracking(const TrackingEvent & rTEvt)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 
Notify(NotifyEvent & rNEvt)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 
StartDocking()660 void DockingWindow::StartDocking()
661 {
662     mbDocking = sal_True;
663 }
664 
665 // -----------------------------------------------------------------------
666 
Docking(const Point &,Rectangle &)667 sal_Bool DockingWindow::Docking( const Point&, Rectangle& )
668 {
669     return IsFloatingMode();
670 }
671 
672 // -----------------------------------------------------------------------
673 
EndDocking(const Rectangle & rRect,sal_Bool bFloatMode)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 
PrepareToggleFloatingMode()702 sal_Bool DockingWindow::PrepareToggleFloatingMode()
703 {
704     return sal_True;
705 }
706 
707 // -----------------------------------------------------------------------
708 
Close()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 
ToggleFloatingMode()727 void DockingWindow::ToggleFloatingMode()
728 {
729 }
730 
731 // -----------------------------------------------------------------------
732 
TitleButtonClick(sal_uInt16)733 void DockingWindow::TitleButtonClick( sal_uInt16 )
734 {
735 }
736 
737 // -----------------------------------------------------------------------
738 
Pin()739 void DockingWindow::Pin()
740 {
741 }
742 
743 // -----------------------------------------------------------------------
744 
Roll()745 void DockingWindow::Roll()
746 {
747 }
748 
749 // -----------------------------------------------------------------------
750 
PopupModeEnd()751 void DockingWindow::PopupModeEnd()
752 {
753 }
754 
755 // -----------------------------------------------------------------------
756 
Resizing(Size &)757 void DockingWindow::Resizing( Size& )
758 {
759 }
760 
761 // -----------------------------------------------------------------------
762 
StateChanged(StateChangedType nType)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 
DataChanged(const DataChangedEvent & rDCEvt)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 
ShowTitleButton(sal_uInt16 nButton,sal_Bool bVisible)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 
IsTitleButtonVisible(sal_uInt16 nButton) const814 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 
SetFloatingMode(sal_Bool bFloatMode)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 
868                 // #123765# reset the buffered DropTargets when undocking, else it may not
869                 // be correctly initialized
870                 mpWindowImpl->mxDNDListenerContainer.clear();
871 
872                 SetParent( pWin );
873                 SetPosPixel( Point() );
874                 mpWindowImpl->mpBorderWindow = pWin;
875                 pWin->mpWindowImpl->mpClientWindow = this;
876                 mpWindowImpl->mpRealParent = pRealParent;
877                 pWin->SetText( Window::GetText() );
878                 pWin->SetOutputSizePixel( Window::GetSizePixel() );
879                 pWin->SetPosPixel( maFloatPos );
880                 // DockingDaten ans FloatingWindow weiterreichen
881                 pWin->ShowTitleButton( TITLE_BUTTON_DOCKING, mbDockBtn );
882                 pWin->ShowTitleButton( TITLE_BUTTON_HIDE, mbHideBtn );
883                 pWin->SetPin( mbPined );
884                 if ( mbRollUp )
885                     pWin->RollUp();
886                 else
887                     pWin->RollDown();
888                 pWin->SetRollUpOutputSizePixel( maRollUpOutSize );
889                 pWin->SetMinOutputSizePixel( maMinOutSize );
890                 pWin->SetMaxOutputSizePixel( mpImplData->maMaxOutSize );
891 
892                 ToggleFloatingMode();
893 
894                 if ( bVisible )
895                     Show();
896             }
897             else
898             {
899                 Show( sal_False, SHOW_NOFOCUSCHANGE );
900 
901                 // FloatingDaten wird im FloatingWindow speichern
902                 maFloatPos      = mpFloatWin->GetPosPixel();
903                 mbDockBtn       = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_DOCKING );
904                 mbHideBtn       = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_HIDE );
905                 mbPined         = mpFloatWin->IsPined();
906                 mbRollUp        = mpFloatWin->IsRollUp();
907                 maRollUpOutSize = mpFloatWin->GetRollUpOutputSizePixel();
908                 maMinOutSize    = mpFloatWin->GetMinOutputSizePixel();
909                 mpImplData->maMaxOutSize = mpFloatWin->GetMaxOutputSizePixel();
910 
911                 Window* pRealParent = mpWindowImpl->mpRealParent;
912                 mpWindowImpl->mpBorderWindow = NULL;
913                 if ( mpOldBorderWin )
914                 {
915                     SetParent( mpOldBorderWin );
916                     ((ImplBorderWindow*)mpOldBorderWin)->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
917                     mpOldBorderWin->Resize();
918                 }
919                 mpWindowImpl->mpBorderWindow = mpOldBorderWin;
920                 SetParent( pRealParent );
921                 mpWindowImpl->mpRealParent = pRealParent;
922                 delete static_cast<ImplDockFloatWin*>(mpFloatWin);
923                 mpFloatWin = NULL;
924                 SetPosPixel( maDockPos );
925 
926                 ToggleFloatingMode();
927 
928                 if ( bVisible )
929                     Show();
930             }
931         }
932     }
933 }
934 
935 // -----------------------------------------------------------------------
936 
SetFloatStyle(WinBits nStyle)937 void DockingWindow::SetFloatStyle( WinBits nStyle )
938 {
939     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
940     if( pWrapper )
941     {
942         pWrapper->SetFloatStyle( nStyle );
943         return;
944     }
945 
946     mnFloatBits = nStyle;
947 }
948 
949 // -----------------------------------------------------------------------
950 
GetFloatStyle() const951 WinBits DockingWindow::GetFloatStyle() const
952 {
953     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
954     if( pWrapper )
955     {
956         return pWrapper->GetFloatStyle();
957     }
958 
959     return mnFloatBits;
960 }
961 
962 // -----------------------------------------------------------------------
963 
SetTabStop()964 void DockingWindow::SetTabStop()
965 {
966     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
967     if( pWrapper )
968     {
969         pWrapper->SetTabStop();
970         return;
971     }
972 
973     mpWindowImpl->mnStyle |= WB_GROUP | WB_TABSTOP;
974 }
975 
976 // -----------------------------------------------------------------------
977 
SetPosSizePixel(long nX,long nY,long nWidth,long nHeight,sal_uInt16 nFlags)978 void DockingWindow::SetPosSizePixel( long nX, long nY,
979                                      long nWidth, long nHeight,
980                                      sal_uInt16 nFlags )
981 {
982     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
983     if( pWrapper )
984     {
985         if ( pWrapper->mpFloatWin )
986             pWrapper->mpFloatWin->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
987         else
988             Window::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
989         return;
990     }
991 
992     if ( mpFloatWin )
993         mpFloatWin->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
994     else
995         Window::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
996 }
997 
998 // -----------------------------------------------------------------------
999 
GetPosPixel() const1000 Point DockingWindow::GetPosPixel() const
1001 {
1002     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1003     if( pWrapper )
1004     {
1005         if ( pWrapper->mpFloatWin )
1006             return pWrapper->mpFloatWin->GetPosPixel();
1007         else
1008             return Window::GetPosPixel();
1009     }
1010 
1011     if ( mpFloatWin )
1012         return mpFloatWin->GetPosPixel();
1013     else
1014         return Window::GetPosPixel();
1015 }
1016 
1017 // -----------------------------------------------------------------------
1018 
GetSizePixel() const1019 Size DockingWindow::GetSizePixel() const
1020 {
1021     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1022     if( pWrapper )
1023     {
1024         if ( pWrapper->mpFloatWin )
1025             return pWrapper->mpFloatWin->GetSizePixel();
1026         else
1027             return Window::GetSizePixel();
1028     }
1029 
1030     if ( mpFloatWin )
1031         return mpFloatWin->GetSizePixel();
1032     else
1033         return Window::GetSizePixel();
1034 }
1035 
1036 // -----------------------------------------------------------------------
1037 
SetOutputSizePixel(const Size & rNewSize)1038 void DockingWindow::SetOutputSizePixel( const Size& rNewSize )
1039 {
1040     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1041     if( pWrapper )
1042     {
1043         if ( pWrapper->mpFloatWin )
1044             pWrapper->mpFloatWin->SetOutputSizePixel( rNewSize );
1045         else
1046             Window::SetOutputSizePixel( rNewSize );
1047         return;
1048     }
1049 
1050     if ( mpFloatWin )
1051         mpFloatWin->SetOutputSizePixel( rNewSize );
1052     else
1053         Window::SetOutputSizePixel( rNewSize );
1054 }
1055 
1056 // -----------------------------------------------------------------------
1057 
GetOutputSizePixel() const1058 Size DockingWindow::GetOutputSizePixel() const
1059 {
1060     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1061     if( pWrapper )
1062     {
1063         if ( pWrapper->mpFloatWin )
1064             return pWrapper->mpFloatWin->GetOutputSizePixel();
1065         else
1066             return Window::GetOutputSizePixel();
1067     }
1068 
1069     if ( mpFloatWin )
1070         return mpFloatWin->GetOutputSizePixel();
1071     else
1072         return Window::GetOutputSizePixel();
1073 }
1074 
GetFloatingPos() const1075 Point DockingWindow::GetFloatingPos() const
1076 {
1077     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1078     if( pWrapper )
1079     {
1080 	    if ( pWrapper->mpFloatWin )
1081         {
1082             WindowStateData aData;
1083             aData.SetMask( WINDOWSTATE_MASK_POS );
1084             pWrapper->mpFloatWin->GetWindowStateData( aData );
1085             Point aPos( aData.GetX(), aData.GetY() );
1086             aPos = pWrapper->mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos );
1087             return aPos;
1088         }
1089 	    else
1090 		    return maFloatPos;
1091     }
1092 
1093 	if ( mpFloatWin )
1094     {
1095         WindowStateData aData;
1096         aData.SetMask( WINDOWSTATE_MASK_POS );
1097         mpFloatWin->GetWindowStateData( aData );
1098         Point aPos( aData.GetX(), aData.GetY() );
1099         aPos = mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos );
1100         return aPos;
1101     }
1102 	else
1103 		return maFloatPos;
1104 }
1105 
IsFloatingMode() const1106 sal_Bool DockingWindow::IsFloatingMode() const
1107 {
1108     ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1109     if( pWrapper )
1110         return pWrapper->IsFloatingMode();
1111     else
1112 	    return (mpFloatWin != NULL);
1113 }
1114 
SetMaxOutputSizePixel(const Size & rSize)1115 void DockingWindow::SetMaxOutputSizePixel( const Size& rSize )
1116 {
1117 	if ( mpFloatWin )
1118 		mpFloatWin->SetMaxOutputSizePixel( rSize );
1119 	mpImplData->maMaxOutSize = rSize;
1120 }
1121 
GetMaxOutputSizePixel() const1122 const Size& DockingWindow::GetMaxOutputSizePixel() const
1123 {
1124 	if ( mpFloatWin )
1125 		return mpFloatWin->GetMaxOutputSizePixel();
1126 	return mpImplData->maMaxOutSize;
1127 }
1128