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