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