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