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