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 : ImplSVEvent * mnLastUserEvent;
51 :
52 : DECL_LINK(DockingHdl, void *);
53 : DECL_LINK(DockTimerHdl, void *);
54 : DECL_LINK(EndDockTimerHdl, void *);
55 : public:
56 : ImplDockFloatWin2( vcl::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( vcl::Window* pParent, WinBits nWinBits,
74 : ImplDockingWindowWrapper* pDockingWin ) :
75 : FloatingWindow( pParent, nWinBits ),
76 : mpDockWin( pDockingWin ),
77 0 : mnLastTicks( tools::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 : vcl::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 : vcl::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 : (tools::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 314 : DockingManager::DockingManager()
302 : {
303 314 : }
304 :
305 620 : DockingManager::~DockingManager()
306 : {
307 310 : ::std::vector< ImplDockingWindowWrapper* >::iterator p;
308 310 : p = mDockingWindows.begin();
309 314 : for(; p != mDockingWindows.end(); ++p )
310 : {
311 4 : delete (*p);
312 : }
313 310 : mDockingWindows.clear();
314 310 : }
315 :
316 6732498 : ImplDockingWindowWrapper* DockingManager::GetDockingWindowWrapper( const vcl::Window *pWindow )
317 : {
318 6732498 : ::std::vector< ImplDockingWindowWrapper* >::iterator p;
319 6732498 : p = mDockingWindows.begin();
320 27540671 : while( p != mDockingWindows.end() )
321 : {
322 16505200 : if( (*p)->mpDockingWindow == pWindow )
323 2429525 : return (*p);
324 : else
325 14075675 : ++p;
326 : }
327 4302973 : return NULL;
328 : }
329 :
330 771824 : bool DockingManager::IsDockable( const vcl::Window *pWindow )
331 : {
332 771824 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
333 :
334 : /*
335 : if( pWindow->HasDockingHandler() )
336 : return true;
337 : */
338 771824 : return (pWrapper != NULL);
339 : }
340 :
341 30102 : bool DockingManager::IsFloating( const vcl::Window *pWindow )
342 : {
343 30102 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
344 30102 : if( pWrapper )
345 30102 : return pWrapper->IsFloatingMode();
346 : else
347 0 : return false;
348 : }
349 :
350 0 : bool DockingManager::IsLocked( const vcl::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 vcl::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 vcl::Window *pWindow )
367 : {
368 0 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
369 0 : if( pWrapper )
370 0 : pWrapper->Unlock();
371 0 : }
372 :
373 16268 : void DockingManager::SetFloatingMode( const vcl::Window *pWindow, bool bFloating )
374 : {
375 16268 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
376 16268 : if( pWrapper )
377 16268 : pWrapper->SetFloatingMode( bFloating );
378 16268 : }
379 :
380 0 : void DockingManager::StartPopupMode( ToolBox *pParentToolBox, const vcl::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 vcl::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 vcl::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 vcl::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 18907 : void DockingManager::AddWindow( const vcl::Window *pWindow )
412 : {
413 18907 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
414 18907 : if( pWrapper )
415 18907 : return;
416 : else
417 18907 : pWrapper = new ImplDockingWindowWrapper( pWindow );
418 :
419 18907 : mDockingWindows.push_back( pWrapper );
420 : }
421 :
422 445465 : void DockingManager::RemoveWindow( const vcl::Window *pWindow )
423 : {
424 445465 : ::std::vector< ImplDockingWindowWrapper* >::iterator p;
425 445465 : p = mDockingWindows.begin();
426 2127510 : while( p != mDockingWindows.end() )
427 : {
428 1255481 : if( (*p)->mpDockingWindow == pWindow )
429 : {
430 18901 : delete (*p);
431 18901 : mDockingWindows.erase( p );
432 18901 : break;
433 : }
434 : else
435 1236580 : ++p;
436 : }
437 445465 : }
438 :
439 16268 : void DockingManager::SetPosSizePixel( vcl::Window *pWindow, long nX, long nY,
440 : long nWidth, long nHeight,
441 : sal_uInt16 nFlags )
442 : {
443 16268 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
444 16268 : if( pWrapper )
445 16268 : pWrapper->setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
446 16268 : }
447 :
448 36742 : Rectangle DockingManager::GetPosSizePixel( const vcl::Window *pWindow )
449 : {
450 36742 : Rectangle aRect;
451 36742 : ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
452 36742 : if( pWrapper )
453 36742 : aRect = Rectangle( pWrapper->GetPosPixel(), pWrapper->GetSizePixel() );
454 :
455 36742 : 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( vcl::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 vcl::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( vcl::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 : vcl::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 : vcl::Region oldClipRgn( GetClipRegion( ) );
608 0 : vcl::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( vcl::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 18907 : ImplDockingWindowWrapper::ImplDockingWindowWrapper( const vcl::Window *pWindow )
798 : : mpDockingWindow(const_cast<vcl::Window*>(pWindow))
799 : , mpFloatWin(NULL)
800 : , mpOldBorderWin(NULL)
801 18907 : , mpParent(pWindow->GetParent())
802 : , maMaxOutSize( SHRT_MAX, SHRT_MAX )
803 : , mnTrackX(0)
804 : , mnTrackY(0)
805 : , mnTrackWidth(0)
806 : , mnTrackHeight(0)
807 : , mnDockLeft(0)
808 : , mnDockTop(0)
809 : , mnDockRight(0)
810 : , mnDockBottom(0)
811 18907 : , mnFloatBits(WB_BORDER | WB_CLOSEABLE | WB_SIZEABLE | (pWindow->GetStyle() & DOCKWIN_FLOATSTYLES))
812 : , mbDockCanceled(false)
813 : , mbFloatPrevented(false)
814 : , mbDockable(true)
815 : , mbDocking(false)
816 : , mbDragFull(false)
817 : , mbLastFloatMode(false)
818 : , mbStartFloat(false)
819 : , mbTrackDock(false)
820 : , mbPinned(false)
821 : , mbRollUp(false)
822 : , mbDockBtn(false)
823 : , mbHideBtn(false)
824 : // must be enabled in Window::Notify to prevent permanent docking during mouse move
825 : , mbStartDockingEnabled(false)
826 56721 : , mbLocked(false)
827 : {
828 18907 : DockingWindow *pDockWin = dynamic_cast< DockingWindow* > ( mpDockingWindow );
829 18907 : if( pDockWin )
830 18907 : mnFloatBits = pDockWin->GetFloatStyle();
831 18907 : }
832 :
833 37810 : ImplDockingWindowWrapper::~ImplDockingWindowWrapper()
834 : {
835 18905 : if ( IsFloatingMode() )
836 : {
837 0 : GetWindow()->Show( false, SHOW_NOFOCUSCHANGE );
838 0 : SetFloatingMode( false );
839 : }
840 37810 : }
841 :
842 0 : bool ImplDockingWindowWrapper::ImplStartDocking( const Point& rPos )
843 : {
844 0 : if ( !mbDockable )
845 0 : return false;
846 :
847 0 : if( !mbStartDockingEnabled )
848 0 : return false;
849 :
850 0 : maMouseOff = rPos;
851 0 : maMouseStart = maMouseOff;
852 0 : mbDocking = true;
853 0 : mbLastFloatMode = IsFloatingMode();
854 0 : mbStartFloat = mbLastFloatMode;
855 :
856 : // calculate FloatingBorder
857 : FloatingWindow* pWin;
858 0 : if ( mpFloatWin )
859 0 : pWin = mpFloatWin;
860 : else
861 0 : pWin = new ImplDockFloatWin2( mpParent, mnFloatBits, NULL );
862 0 : pWin->GetBorder( mnDockLeft, mnDockTop, mnDockRight, mnDockBottom );
863 0 : if ( !mpFloatWin )
864 0 : delete pWin;
865 :
866 0 : Point aPos = GetWindow()->ImplOutputToFrame( Point() );
867 0 : Size aSize = GetWindow()->GetOutputSizePixel();
868 0 : mnTrackX = aPos.X();
869 0 : mnTrackY = aPos.Y();
870 0 : mnTrackWidth = aSize.Width();
871 0 : mnTrackHeight = aSize.Height();
872 :
873 0 : if ( mbLastFloatMode )
874 : {
875 0 : maMouseOff.X() += mnDockLeft;
876 0 : maMouseOff.Y() += mnDockTop;
877 0 : mnTrackX -= mnDockLeft;
878 0 : mnTrackY -= mnDockTop;
879 0 : mnTrackWidth += mnDockLeft+mnDockRight;
880 0 : mnTrackHeight += mnDockTop+mnDockBottom;
881 : }
882 :
883 0 : vcl::Window *pDockingArea = GetWindow()->GetParent();
884 0 : vcl::Window::PointerState aState = pDockingArea->GetPointerState();
885 :
886 : // mouse pos in screen pixels
887 0 : Point aMousePos = pDockingArea->OutputToScreenPixel( aState.maPos );
888 0 : Point aDockPos = Point( pDockingArea->AbsoluteScreenToOutputPixel( GetWindow()->OutputToAbsoluteScreenPixel( GetWindow()->GetPosPixel() ) ) );
889 0 : Rectangle aDockRect( aDockPos, GetWindow()->GetSizePixel() );
890 0 : StartDocking( aMousePos, aDockRect );
891 :
892 0 : GetWindow()->ImplUpdateAll();
893 0 : GetWindow()->ImplGetFrameWindow()->ImplUpdateAll();
894 :
895 0 : GetWindow()->StartTracking( STARTTRACK_KEYMOD );
896 0 : return true;
897 : }
898 :
899 0 : void ImplDockingWindowWrapper::Tracking( const TrackingEvent& rTEvt )
900 : {
901 : // used during docking of a currently docked window
902 0 : if ( mbDocking )
903 : {
904 0 : if ( rTEvt.IsTrackingEnded() )
905 : {
906 0 : mbDocking = false;
907 0 : GetWindow()->HideTracking();
908 0 : if ( rTEvt.IsTrackingCanceled() )
909 : {
910 0 : mbDockCanceled = true;
911 0 : EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
912 0 : mbDockCanceled = false;
913 : }
914 : else
915 0 : EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
916 : }
917 : // Docking only upon non-synthetic MouseEvents
918 0 : else if ( !rTEvt.GetMouseEvent().IsSynthetic() || rTEvt.GetMouseEvent().IsModifierChanged() )
919 : {
920 0 : Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
921 0 : Point aFrameMousePos = GetWindow()->ImplOutputToFrame( aMousePos );
922 0 : Size aFrameSize = GetWindow()->ImplGetFrameWindow()->GetOutputSizePixel();
923 0 : if ( aFrameMousePos.X() < 0 )
924 0 : aFrameMousePos.X() = 0;
925 0 : if ( aFrameMousePos.Y() < 0 )
926 0 : aFrameMousePos.Y() = 0;
927 0 : if ( aFrameMousePos.X() > aFrameSize.Width()-1 )
928 0 : aFrameMousePos.X() = aFrameSize.Width()-1;
929 0 : if ( aFrameMousePos.Y() > aFrameSize.Height()-1 )
930 0 : aFrameMousePos.Y() = aFrameSize.Height()-1;
931 0 : aMousePos = GetWindow()->ImplFrameToOutput( aFrameMousePos );
932 0 : aMousePos.X() -= maMouseOff.X();
933 0 : aMousePos.Y() -= maMouseOff.Y();
934 0 : Point aPos = GetWindow()->ImplOutputToFrame( aMousePos );
935 0 : Rectangle aTrackRect( aPos, Size( mnTrackWidth, mnTrackHeight ) );
936 0 : Rectangle aCompRect = aTrackRect;
937 0 : aPos.X() += maMouseOff.X();
938 0 : aPos.Y() += maMouseOff.Y();
939 :
940 0 : bool bFloatMode = Docking( aPos, aTrackRect );
941 :
942 0 : mbFloatPrevented = false;
943 0 : if ( mbLastFloatMode != bFloatMode )
944 : {
945 0 : if ( bFloatMode )
946 : {
947 0 : aTrackRect.Left() -= mnDockLeft;
948 0 : aTrackRect.Top() -= mnDockTop;
949 0 : aTrackRect.Right() += mnDockRight;
950 0 : aTrackRect.Bottom() += mnDockBottom;
951 : }
952 : else
953 : {
954 0 : if ( aCompRect == aTrackRect )
955 : {
956 0 : aTrackRect.Left() += mnDockLeft;
957 0 : aTrackRect.Top() += mnDockTop;
958 0 : aTrackRect.Right() -= mnDockRight;
959 0 : aTrackRect.Bottom() -= mnDockBottom;
960 : }
961 : }
962 0 : mbLastFloatMode = bFloatMode;
963 : }
964 :
965 : sal_uInt16 nTrackStyle;
966 0 : if ( bFloatMode )
967 0 : nTrackStyle = SHOWTRACK_OBJECT;
968 : else
969 0 : nTrackStyle = SHOWTRACK_BIG;
970 0 : Rectangle aShowTrackRect = aTrackRect;
971 0 : aShowTrackRect.SetPos( GetWindow()->ImplFrameToOutput( aShowTrackRect.TopLeft() ) );
972 :
973 0 : GetWindow()->ShowTracking( aShowTrackRect, nTrackStyle );
974 :
975 : // calculate mouse offset again, as the rectangle was changed
976 0 : maMouseOff.X() = aPos.X() - aTrackRect.Left();
977 0 : maMouseOff.Y() = aPos.Y() - aTrackRect.Top();
978 :
979 0 : mnTrackX = aTrackRect.Left();
980 0 : mnTrackY = aTrackRect.Top();
981 0 : mnTrackWidth = aTrackRect.GetWidth();
982 0 : mnTrackHeight = aTrackRect.GetHeight();
983 : }
984 : }
985 0 : }
986 :
987 0 : void ImplDockingWindowWrapper::StartDocking( const Point& rPoint, Rectangle& rRect )
988 : {
989 0 : DockingData data( rPoint, rRect, IsFloatingMode() );
990 :
991 0 : GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_STARTDOCKING, &data );
992 0 : mbDocking = true;
993 0 : }
994 :
995 0 : bool ImplDockingWindowWrapper::Docking( const Point& rPoint, Rectangle& rRect )
996 : {
997 0 : DockingData data( rPoint, rRect, IsFloatingMode() );
998 :
999 0 : GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_DOCKING, &data );
1000 0 : rRect = data.maTrackRect;
1001 0 : return data.mbFloating;
1002 : }
1003 :
1004 0 : void ImplDockingWindowWrapper::EndDocking( const Rectangle& rRect, bool bFloatMode )
1005 : {
1006 0 : Rectangle aRect( rRect );
1007 :
1008 0 : if ( !IsDockingCanceled() )
1009 : {
1010 0 : bool bShow = false;
1011 0 : if ( bFloatMode != IsFloatingMode() )
1012 : {
1013 0 : GetWindow()->Show( false, SHOW_NOFOCUSCHANGE );
1014 0 : SetFloatingMode( bFloatMode );
1015 0 : bShow = true;
1016 0 : if ( bFloatMode )
1017 : {
1018 : // #i44800# always use outputsize - as in all other places
1019 0 : mpFloatWin->SetOutputSizePixel( aRect.GetSize() );
1020 0 : mpFloatWin->SetPosPixel( aRect.TopLeft() );
1021 : }
1022 : }
1023 0 : if ( !bFloatMode )
1024 : {
1025 0 : Point aPos = aRect.TopLeft();
1026 0 : aPos = GetWindow()->GetParent()->ScreenToOutputPixel( aPos );
1027 0 : GetWindow()->SetPosSizePixel( aPos, aRect.GetSize() );
1028 : }
1029 :
1030 0 : if ( bShow )
1031 0 : GetWindow()->Show( true, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
1032 : }
1033 :
1034 0 : EndDockingData data( aRect, IsFloatingMode(), IsDockingCanceled() );
1035 0 : GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_ENDDOCKING, &data );
1036 :
1037 0 : mbDocking = false;
1038 :
1039 : // must be enabled in Window::Notify to prevent permanent docking during mouse move
1040 0 : mbStartDockingEnabled = false;
1041 0 : }
1042 :
1043 0 : bool ImplDockingWindowWrapper::PrepareToggleFloatingMode()
1044 : {
1045 0 : bool bFloating = true;
1046 0 : GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_PREPARETOGGLEFLOATING, &bFloating );
1047 0 : return bFloating;
1048 : }
1049 :
1050 0 : bool ImplDockingWindowWrapper::Close()
1051 : {
1052 : // TODO: send event
1053 0 : return true;
1054 : }
1055 :
1056 0 : void ImplDockingWindowWrapper::ToggleFloatingMode()
1057 : {
1058 : // notify dockingwindow/toolbox
1059 : // note: this must be done *before* notifying the
1060 : // listeners to have the toolbox in the proper state
1061 0 : if( GetWindow()->ImplIsDockingWindow() )
1062 0 : static_cast<DockingWindow*>(GetWindow())->ToggleFloatingMode();
1063 :
1064 : // now notify listeners
1065 0 : GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_TOGGLEFLOATING );
1066 :
1067 : // must be enabled in Window::Notify to prevent permanent docking during mouse move
1068 0 : mbStartDockingEnabled = false;
1069 0 : }
1070 :
1071 0 : void ImplDockingWindowWrapper::TitleButtonClick( sal_uInt16 nType )
1072 : {
1073 0 : if( nType == TITLE_BUTTON_MENU )
1074 : {
1075 0 : ToolBox *pToolBox = dynamic_cast< ToolBox* >( GetWindow() );
1076 0 : if( pToolBox )
1077 : {
1078 0 : pToolBox->ExecuteCustomMenu();
1079 : }
1080 : }
1081 0 : if( nType == TITLE_BUTTON_DOCKING )
1082 : {
1083 0 : SetFloatingMode( !IsFloatingMode() );
1084 : }
1085 0 : }
1086 :
1087 0 : void ImplDockingWindowWrapper::Pin()
1088 : {
1089 : // TODO: send event
1090 0 : }
1091 :
1092 0 : void ImplDockingWindowWrapper::Roll()
1093 : {
1094 : // TODO: send event
1095 0 : }
1096 :
1097 0 : void ImplDockingWindowWrapper::PopupModeEnd()
1098 : {
1099 : // TODO: send event
1100 0 : }
1101 :
1102 0 : void ImplDockingWindowWrapper::Resizing( Size& rSize )
1103 : {
1104 : // TODO: add virtual Resizing() to class Window, so we can get rid of class DockingWindow
1105 0 : DockingWindow *pDockingWindow = dynamic_cast< DockingWindow* >( GetWindow() );
1106 0 : if( pDockingWindow )
1107 0 : pDockingWindow->Resizing( rSize );
1108 0 : }
1109 :
1110 0 : void ImplDockingWindowWrapper::ShowTitleButton( sal_uInt16 nButton, bool bVisible )
1111 : {
1112 0 : if ( mpFloatWin )
1113 0 : mpFloatWin->ShowTitleButton( nButton, bVisible );
1114 : else
1115 : {
1116 0 : if ( nButton == TITLE_BUTTON_DOCKING )
1117 0 : mbDockBtn = bVisible;
1118 : else // if ( nButton == TITLE_BUTTON_HIDE )
1119 0 : mbHideBtn = bVisible;
1120 : }
1121 0 : }
1122 :
1123 0 : void ImplDockingWindowWrapper::StartPopupMode( ToolBox *pParentToolBox, sal_uLong nFlags )
1124 : {
1125 : // do nothing if window is floating
1126 0 : if( IsFloatingMode() )
1127 0 : return;
1128 :
1129 0 : GetWindow()->Show( false, SHOW_NOFOCUSCHANGE );
1130 :
1131 : // prepare reparenting
1132 0 : vcl::Window* pRealParent = GetWindow()->GetWindow( WINDOW_PARENT );
1133 0 : mpOldBorderWin = GetWindow()->GetWindow( WINDOW_BORDER );
1134 0 : if( mpOldBorderWin == GetWindow() )
1135 0 : mpOldBorderWin = NULL; // no border window found
1136 :
1137 : // the new parent for popup mode
1138 0 : ImplPopupFloatWin* pWin = new ImplPopupFloatWin( mpParent, this, (nFlags & FLOATWIN_POPUPMODE_ALLOWTEAROFF) != 0 );
1139 :
1140 0 : pWin->SetPopupModeEndHdl( LINK( this, ImplDockingWindowWrapper, PopupModeEnd ) );
1141 0 : pWin->SetText( GetWindow()->GetText() );
1142 :
1143 0 : pWin->SetOutputSizePixel( GetWindow()->GetSizePixel() );
1144 :
1145 0 : GetWindow()->mpWindowImpl->mpBorderWindow = NULL;
1146 0 : GetWindow()->mpWindowImpl->mnLeftBorder = 0;
1147 0 : GetWindow()->mpWindowImpl->mnTopBorder = 0;
1148 0 : GetWindow()->mpWindowImpl->mnRightBorder = 0;
1149 0 : GetWindow()->mpWindowImpl->mnBottomBorder = 0;
1150 :
1151 : // position toolbox below dragrect
1152 0 : GetWindow()->SetPosPixel( pWin->GetToolboxPosition() );
1153 :
1154 : // reparent borderwindow and window
1155 0 : if ( mpOldBorderWin )
1156 0 : mpOldBorderWin->SetParent( pWin );
1157 0 : GetWindow()->SetParent( pWin );
1158 :
1159 : // correct border window pointers
1160 0 : GetWindow()->mpWindowImpl->mpBorderWindow = pWin;
1161 0 : pWin->mpWindowImpl->mpClientWindow = GetWindow();
1162 0 : GetWindow()->mpWindowImpl->mpRealParent = pRealParent;
1163 :
1164 : // set mpFloatWin not until all window positioning is done !!!
1165 : // (SetPosPixel etc. check for valid mpFloatWin pointer)
1166 0 : mpFloatWin = pWin;
1167 :
1168 : // if the subtoolbar was opened via keyboard make sure that key events
1169 : // will go into subtoolbar
1170 0 : if( pParentToolBox->IsKeyEvent() )
1171 0 : nFlags |= FLOATWIN_POPUPMODE_GRABFOCUS;
1172 :
1173 0 : mpFloatWin->StartPopupMode( pParentToolBox, nFlags );
1174 0 : GetWindow()->Show();
1175 :
1176 0 : if( pParentToolBox->IsKeyEvent() )
1177 : {
1178 : // send HOME key to subtoolbar in order to select first item
1179 0 : KeyEvent aEvent( 0, vcl::KeyCode( KEY_HOME ) );
1180 0 : mpFloatWin->GetPreferredKeyInputWindow()->KeyInput( aEvent );
1181 : }
1182 : }
1183 :
1184 0 : IMPL_LINK_NOARG(ImplDockingWindowWrapper, PopupModeEnd)
1185 : {
1186 0 : GetWindow()->Show( false, SHOW_NOFOCUSCHANGE );
1187 :
1188 : // set parameter for handler before destroying floating window
1189 0 : ImplPopupFloatWin *pPopupFloatWin = static_cast<ImplPopupFloatWin*>(mpFloatWin);
1190 0 : EndPopupModeData aData( pPopupFloatWin->GetTearOffPosition(), mpFloatWin->IsPopupModeTearOff() );
1191 :
1192 : // before deleting change parent back, so we can delete the floating window alone
1193 0 : vcl::Window* pRealParent = GetWindow()->GetWindow( WINDOW_PARENT );
1194 0 : GetWindow()->mpWindowImpl->mpBorderWindow = NULL;
1195 0 : if ( mpOldBorderWin )
1196 : {
1197 0 : GetWindow()->SetParent( mpOldBorderWin );
1198 : static_cast<ImplBorderWindow*>(mpOldBorderWin)->GetBorder(
1199 0 : GetWindow()->mpWindowImpl->mnLeftBorder, GetWindow()->mpWindowImpl->mnTopBorder,
1200 0 : GetWindow()->mpWindowImpl->mnRightBorder, GetWindow()->mpWindowImpl->mnBottomBorder );
1201 0 : mpOldBorderWin->Resize();
1202 : }
1203 0 : GetWindow()->mpWindowImpl->mpBorderWindow = mpOldBorderWin;
1204 0 : GetWindow()->SetParent( pRealParent );
1205 0 : GetWindow()->mpWindowImpl->mpRealParent = pRealParent;
1206 :
1207 0 : delete mpFloatWin;
1208 0 : mpFloatWin = NULL;
1209 :
1210 : // call handler - which will destroy the window and thus the wrapper as well !
1211 0 : GetWindow()->ImplCallEventListeners( VCLEVENT_WINDOW_ENDPOPUPMODE, &aData );
1212 :
1213 0 : return 0;
1214 : }
1215 :
1216 0 : bool ImplDockingWindowWrapper::IsInPopupMode() const
1217 : {
1218 0 : if( GetFloatingWindow() )
1219 0 : return GetFloatingWindow()->IsInPopupMode();
1220 : else
1221 0 : return false;
1222 : }
1223 :
1224 16268 : void ImplDockingWindowWrapper::SetFloatingMode( bool bFloatMode )
1225 : {
1226 : // do nothing if window is docked and locked
1227 16268 : if( !IsFloatingMode() && IsLocked() )
1228 16268 : return;
1229 :
1230 16268 : if ( IsFloatingMode() != bFloatMode )
1231 : {
1232 0 : if ( PrepareToggleFloatingMode() )
1233 : {
1234 0 : bool bVisible = GetWindow()->IsVisible();
1235 :
1236 0 : if ( bFloatMode )
1237 : {
1238 0 : GetWindow()->Show( false, SHOW_NOFOCUSCHANGE );
1239 :
1240 0 : maDockPos = GetWindow()->GetPosPixel();
1241 :
1242 0 : vcl::Window* pRealParent = GetWindow()->GetWindow( WINDOW_PARENT );
1243 0 : mpOldBorderWin = GetWindow()->GetWindow( WINDOW_BORDER );
1244 0 : if( mpOldBorderWin == mpDockingWindow )
1245 0 : mpOldBorderWin = NULL; // no border window found
1246 :
1247 : ImplDockFloatWin2* pWin =
1248 : new ImplDockFloatWin2(
1249 : mpParent,
1250 0 : mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ?
1251 : mnFloatBits | WB_SYSTEMWINDOW
1252 0 : | WB_OWNERDRAWDECORATION
1253 : : mnFloatBits,
1254 0 : this );
1255 :
1256 0 : GetWindow()->mpWindowImpl->mpBorderWindow = NULL;
1257 0 : GetWindow()->mpWindowImpl->mnLeftBorder = 0;
1258 0 : GetWindow()->mpWindowImpl->mnTopBorder = 0;
1259 0 : GetWindow()->mpWindowImpl->mnRightBorder = 0;
1260 0 : GetWindow()->mpWindowImpl->mnBottomBorder = 0;
1261 :
1262 : // if the parent gets destroyed, we also have to reset the parent of the BorderWindow
1263 0 : if ( mpOldBorderWin )
1264 0 : mpOldBorderWin->SetParent( pWin );
1265 0 : GetWindow()->SetParent( pWin );
1266 0 : pWin->SetPosPixel( Point() );
1267 :
1268 0 : GetWindow()->mpWindowImpl->mpBorderWindow = pWin;
1269 0 : pWin->mpWindowImpl->mpClientWindow = mpDockingWindow;
1270 0 : GetWindow()->mpWindowImpl->mpRealParent = pRealParent;
1271 :
1272 0 : pWin->SetText( GetWindow()->GetText() );
1273 0 : pWin->SetOutputSizePixel( GetWindow()->GetSizePixel() );
1274 0 : pWin->SetPosPixel( maFloatPos );
1275 : // pass on DockingData to FloatingWindow
1276 0 : pWin->ShowTitleButton( TITLE_BUTTON_DOCKING, mbDockBtn );
1277 0 : pWin->ShowTitleButton( TITLE_BUTTON_HIDE, mbHideBtn );
1278 0 : pWin->SetPin( mbPinned );
1279 0 : if ( mbRollUp )
1280 0 : pWin->RollUp();
1281 : else
1282 0 : pWin->RollDown();
1283 0 : pWin->SetRollUpOutputSizePixel( maRollUpOutSize );
1284 0 : pWin->SetMinOutputSizePixel( maMinOutSize );
1285 0 : pWin->SetMaxOutputSizePixel( maMaxOutSize );
1286 :
1287 0 : mpFloatWin = pWin;
1288 :
1289 0 : if ( bVisible )
1290 0 : GetWindow()->Show( true, SHOW_NOFOCUSCHANGE | SHOW_NOACTIVATE );
1291 :
1292 0 : ToggleFloatingMode();
1293 : }
1294 : else
1295 : {
1296 0 : GetWindow()->Show( false, SHOW_NOFOCUSCHANGE );
1297 :
1298 : // store FloatingData in FloatingWindow
1299 0 : maFloatPos = mpFloatWin->GetPosPixel();
1300 0 : mbDockBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_DOCKING );
1301 0 : mbHideBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_HIDE );
1302 0 : mbPinned = mpFloatWin->IsPinned();
1303 0 : mbRollUp = mpFloatWin->IsRollUp();
1304 0 : maRollUpOutSize = mpFloatWin->GetRollUpOutputSizePixel();
1305 0 : maMinOutSize = mpFloatWin->GetMinOutputSizePixel();
1306 0 : maMaxOutSize = mpFloatWin->GetMaxOutputSizePixel();
1307 :
1308 0 : vcl::Window* pRealParent = GetWindow()->GetWindow( WINDOW_PARENT ); //mpWindowImpl->mpRealParent;
1309 0 : GetWindow()->mpWindowImpl->mpBorderWindow = NULL;
1310 0 : if ( mpOldBorderWin )
1311 : {
1312 0 : GetWindow()->SetParent( mpOldBorderWin );
1313 : static_cast<ImplBorderWindow*>(mpOldBorderWin)->GetBorder(
1314 0 : GetWindow()->mpWindowImpl->mnLeftBorder, GetWindow()->mpWindowImpl->mnTopBorder,
1315 0 : GetWindow()->mpWindowImpl->mnRightBorder, GetWindow()->mpWindowImpl->mnBottomBorder );
1316 0 : mpOldBorderWin->Resize();
1317 : }
1318 0 : GetWindow()->mpWindowImpl->mpBorderWindow = mpOldBorderWin;
1319 0 : GetWindow()->SetParent( pRealParent );
1320 0 : GetWindow()->mpWindowImpl->mpRealParent = pRealParent;
1321 :
1322 0 : delete static_cast<ImplDockFloatWin2*>(mpFloatWin);
1323 0 : mpFloatWin = NULL;
1324 0 : GetWindow()->SetPosPixel( maDockPos );
1325 :
1326 0 : if ( bVisible )
1327 0 : GetWindow()->Show();
1328 :
1329 0 : ToggleFloatingMode();
1330 :
1331 : }
1332 : }
1333 : }
1334 : }
1335 :
1336 18 : void ImplDockingWindowWrapper::SetFloatStyle( WinBits nStyle )
1337 : {
1338 18 : mnFloatBits = nStyle;
1339 18 : }
1340 :
1341 :
1342 16268 : void ImplDockingWindowWrapper::setPosSizePixel( long nX, long nY,
1343 : long nWidth, long nHeight,
1344 : sal_uInt16 nFlags )
1345 : {
1346 16268 : if ( mpFloatWin )
1347 0 : mpFloatWin->setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
1348 : else
1349 16268 : GetWindow()->setPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
1350 16268 : }
1351 :
1352 36742 : Point ImplDockingWindowWrapper::GetPosPixel() const
1353 : {
1354 36742 : if ( mpFloatWin )
1355 0 : return mpFloatWin->GetPosPixel();
1356 : else
1357 36742 : return mpDockingWindow->GetPosPixel();
1358 : }
1359 :
1360 36742 : Size ImplDockingWindowWrapper::GetSizePixel() const
1361 : {
1362 36742 : if ( mpFloatWin )
1363 0 : return mpFloatWin->GetSizePixel();
1364 : else
1365 36742 : return mpDockingWindow->GetSizePixel();
1366 : }
1367 :
1368 : // old inlines from DockingWindow
1369 :
1370 0 : void ImplDockingWindowWrapper::SetMinOutputSizePixel( const Size& rSize )
1371 : {
1372 0 : if ( mpFloatWin )
1373 0 : mpFloatWin->SetMinOutputSizePixel( rSize );
1374 0 : maMinOutSize = rSize;
1375 0 : }
1376 :
1377 0 : void ImplDockingWindowWrapper::SetMaxOutputSizePixel( const Size& rSize )
1378 : {
1379 0 : if ( mpFloatWin )
1380 0 : mpFloatWin->SetMaxOutputSizePixel( rSize );
1381 0 : maMaxOutSize = rSize;
1382 0 : }
1383 :
1384 1393967 : bool ImplDockingWindowWrapper::IsFloatingMode() const
1385 : {
1386 1393967 : return (mpFloatWin != NULL);
1387 : }
1388 :
1389 12869 : void ImplDockingWindowWrapper::SetDragArea( const Rectangle& rRect )
1390 : {
1391 12869 : maDragArea = rRect;
1392 12869 : }
1393 :
1394 :
1395 0 : void ImplDockingWindowWrapper::Lock()
1396 : {
1397 0 : mbLocked = true;
1398 : // only toolbars support locking
1399 0 : ToolBox *pToolBox = dynamic_cast< ToolBox * >( GetWindow() );
1400 0 : if( pToolBox )
1401 0 : pToolBox->Lock( mbLocked );
1402 0 : }
1403 :
1404 0 : void ImplDockingWindowWrapper::Unlock()
1405 : {
1406 0 : mbLocked = false;
1407 : // only toolbars support locking
1408 0 : ToolBox *pToolBox = dynamic_cast< ToolBox * >( GetWindow() );
1409 0 : if( pToolBox )
1410 0 : pToolBox->Lock( mbLocked );
1411 1233 : }
1412 :
1413 :
1414 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|