1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26
27 #include <tools/time.hxx>
28 #include <tools/rc.h>
29
30 #include <vcl/event.hxx>
31 #include <vcl/floatwin.hxx>
32 #include <vcl/dockwin.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/timer.hxx>
35 #include <vcl/unowrap.hxx>
36
37 #include <svdata.hxx>
38 #include <window.h>
39 #include <brdwin.hxx>
40 #include <salframe.hxx>
41
42
43
44 // =======================================================================
45
46 #define DOCKWIN_FLOATSTYLES (WB_SIZEABLE | WB_MOVEABLE | WB_CLOSEABLE | WB_STANDALONE | WB_PINABLE | WB_ROLLABLE )
47
48 // =======================================================================
49
50 // -----------------------------------------------------------------------
51
52 class DockingWindow::ImplData
53 {
54 public:
55 ImplData();
56 ~ImplData();
57
58 Window* mpParent;
59 Size maMaxOutSize;
60 };
61
ImplData()62 DockingWindow::ImplData::ImplData()
63 {
64 mpParent = NULL;
65 maMaxOutSize = Size( SHRT_MAX, SHRT_MAX );
66 }
67
~ImplData()68 DockingWindow::ImplData::~ImplData()
69 {
70 }
71
72 // -----------------------------------------------------------------------
73
74 class ImplDockFloatWin : public FloatingWindow
75 {
76 private:
77 DockingWindow* mpDockWin;
78 sal_uLong mnLastTicks;
79 Timer maDockTimer;
80 Point maDockPos;
81 Rectangle maDockRect;
82 sal_Bool mbInMove;
83 sal_uLong mnLastUserEvent;
84
85 DECL_LINK( DockingHdl, ImplDockFloatWin* );
86 DECL_LINK( DockTimerHdl, ImplDockFloatWin* );
87 public:
88 ImplDockFloatWin( Window* pParent, WinBits nWinBits,
89 DockingWindow* pDockingWin );
90 ~ImplDockFloatWin();
91
92 virtual void Move();
93 virtual void Resize();
94 virtual void TitleButtonClick( sal_uInt16 nButton );
95 virtual void Pin();
96 virtual void Roll();
97 virtual void PopupModeEnd();
98 virtual void Resizing( Size& rSize );
99 virtual sal_Bool Close();
100
GetLastTicks() const101 sal_uLong GetLastTicks() const { return mnLastTicks; }
102 };
103
104
ImplDockFloatWin(Window * pParent,WinBits nWinBits,DockingWindow * pDockingWin)105 ImplDockFloatWin::ImplDockFloatWin( Window* pParent, WinBits nWinBits,
106 DockingWindow* pDockingWin ) :
107 FloatingWindow( pParent, nWinBits ),
108 mpDockWin( pDockingWin ),
109 mnLastTicks( Time::GetSystemTicks() ),
110 mbInMove( sal_False ),
111 mnLastUserEvent( 0 )
112 {
113 // Daten vom DockingWindow uebernehmen
114 if ( pDockingWin )
115 {
116 SetSettings( pDockingWin->GetSettings() );
117 Enable( pDockingWin->IsEnabled(), sal_False );
118 EnableInput( pDockingWin->IsInputEnabled(), sal_False );
119 AlwaysEnableInput( pDockingWin->IsAlwaysEnableInput(), sal_False );
120 EnableAlwaysOnTop( pDockingWin->IsAlwaysOnTopEnabled() );
121 SetActivateMode( pDockingWin->GetActivateMode() );
122 }
123
124 SetBackground();
125
126 maDockTimer.SetTimeoutHdl( LINK( this, ImplDockFloatWin, DockTimerHdl ) );
127 maDockTimer.SetTimeout( 50 );
128 }
129
130 // -----------------------------------------------------------------------
131
~ImplDockFloatWin()132 ImplDockFloatWin::~ImplDockFloatWin()
133 {
134 if( mnLastUserEvent )
135 Application::RemoveUserEvent( mnLastUserEvent );
136 }
137
138 // -----------------------------------------------------------------------
139
IMPL_LINK(ImplDockFloatWin,DockTimerHdl,ImplDockFloatWin *,EMPTYARG)140 IMPL_LINK( ImplDockFloatWin, DockTimerHdl, ImplDockFloatWin*, EMPTYARG )
141 {
142 DBG_ASSERT( mpDockWin->IsFloatingMode(), "docktimer called but not floating" );
143
144 maDockTimer.Stop();
145 PointerState aState = GetPointerState();
146
147 if( aState.mnState & KEY_MOD1 )
148 {
149 // i43499 CTRL disables docking now
150 mpDockWin->GetParent()->ImplGetFrameWindow()->HideTracking();
151 mpDockWin->EndDocking( maDockRect, sal_True );
152 if( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) )
153 maDockTimer.Start();
154 }
155 else if( ! ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) )
156 {
157 mpDockWin->GetParent()->ImplGetFrameWindow()->HideTracking();
158 mpDockWin->EndDocking( maDockRect, sal_False );
159 }
160 else
161 {
162 mpDockWin->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_BIG | SHOWTRACK_WINDOW );
163 maDockTimer.Start();
164 }
165
166 return 0;
167 }
168
IMPL_LINK(ImplDockFloatWin,DockingHdl,ImplDockFloatWin *,EMPTYARG)169 IMPL_LINK( ImplDockFloatWin, DockingHdl, ImplDockFloatWin*, EMPTYARG )
170 {
171 PointerState aState = mpDockWin->GetParent()->GetPointerState();
172
173 mnLastUserEvent = 0;
174 if( mpDockWin->IsDockable() &&
175 (Time::GetSystemTicks() - mnLastTicks > 500) &&
176 ( aState.mnState & ( MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT ) ) &&
177 !(aState.mnState & KEY_MOD1) ) // i43499 CTRL disables docking now
178 {
179 maDockPos = Point( mpDockWin->GetParent()->AbsoluteScreenToOutputPixel( OutputToAbsoluteScreenPixel( Point() ) ) );
180 maDockPos = mpDockWin->GetParent()->OutputToScreenPixel( maDockPos ); // sfx expects screen coordinates
181
182 if( ! mpDockWin->IsDocking() )
183 mpDockWin->StartDocking();
184 maDockRect = Rectangle( maDockPos, mpDockWin->GetSizePixel() );
185
186 // mouse pos also in screen pixels
187 Point aMousePos = mpDockWin->GetParent()->OutputToScreenPixel( aState.maPos );
188
189 sal_Bool bFloatMode = mpDockWin->Docking( aMousePos, maDockRect );
190 if( ! bFloatMode )
191 {
192 mpDockWin->GetParent()->ImplGetFrameWindow()->ShowTracking( maDockRect, SHOWTRACK_OBJECT | SHOWTRACK_WINDOW );
193 DockTimerHdl( this );
194 }
195 else
196 {
197 mpDockWin->GetParent()->ImplGetFrameWindow()->HideTracking();
198 maDockTimer.Stop();
199 mpDockWin->EndDocking( maDockRect, sal_True );
200 }
201 }
202 mbInMove = sal_False;
203 return 0;
204 }
205 // -----------------------------------------------------------------------
206
Move()207 void ImplDockFloatWin::Move()
208 {
209 if( mbInMove )
210 return;
211
212 mbInMove = sal_True;
213 FloatingWindow::Move();
214 mpDockWin->Move();
215
216 /*
217 * note: the window should only dock if
218 * the user releases all mouse buttons. The real problem here
219 * is that we don't get mouse events (at least not on X)
220 * if the mouse is on the decoration. So we have to start an
221 * awkward timer based process that polls the modifier/buttons
222 * to see whether they are in the right condition shortly after the
223 * last Move message.
224 */
225 if( ! mnLastUserEvent )
226 mnLastUserEvent = Application::PostUserEvent( LINK( this, ImplDockFloatWin, DockingHdl ) );
227 }
228
229 // -----------------------------------------------------------------------
230
Resize()231 void ImplDockFloatWin::Resize()
232 {
233 FloatingWindow::Resize();
234 Size aSize( GetSizePixel() );
235 mpDockWin->ImplPosSizeWindow( 0, 0, aSize.Width(), aSize.Height(), WINDOW_POSSIZE_POSSIZE );
236 }
237
238 // -----------------------------------------------------------------------
239
TitleButtonClick(sal_uInt16 nButton)240 void ImplDockFloatWin::TitleButtonClick( sal_uInt16 nButton )
241 {
242 FloatingWindow::TitleButtonClick( nButton );
243 mpDockWin->TitleButtonClick( nButton );
244 }
245
246 // -----------------------------------------------------------------------
247
Pin()248 void ImplDockFloatWin::Pin()
249 {
250 FloatingWindow::Pin();
251 mpDockWin->Pin();
252 }
253
254 // -----------------------------------------------------------------------
255
Roll()256 void ImplDockFloatWin::Roll()
257 {
258 FloatingWindow::Roll();
259 mpDockWin->Roll();
260 }
261
262 // -----------------------------------------------------------------------
263
PopupModeEnd()264 void ImplDockFloatWin::PopupModeEnd()
265 {
266 FloatingWindow::PopupModeEnd();
267 mpDockWin->PopupModeEnd();
268 }
269
270 // -----------------------------------------------------------------------
271
Resizing(Size & rSize)272 void ImplDockFloatWin::Resizing( Size& rSize )
273 {
274 FloatingWindow::Resizing( rSize );
275 mpDockWin->Resizing( rSize );
276 }
277
278 // -----------------------------------------------------------------------
279
Close()280 sal_Bool ImplDockFloatWin::Close()
281 {
282 return mpDockWin->Close();
283 }
284
285 // =======================================================================
286
ImplStartDocking(const Point & rPos)287 sal_Bool DockingWindow::ImplStartDocking( const Point& rPos )
288 {
289 if ( !mbDockable )
290 return sal_False;
291
292 maMouseOff = rPos;
293 maMouseStart = maMouseOff;
294 mbDocking = sal_True;
295 mbLastFloatMode = IsFloatingMode();
296 mbStartFloat = mbLastFloatMode;
297
298 // FloatingBorder berechnen
299 FloatingWindow* pWin;
300 if ( mpFloatWin )
301 pWin = mpFloatWin;
302 else
303 pWin = new ImplDockFloatWin( mpImplData->mpParent, mnFloatBits, NULL );
304 pWin->GetBorder( mnDockLeft, mnDockTop, mnDockRight, mnDockBottom );
305 if ( !mpFloatWin )
306 delete pWin;
307
308 Point aPos = ImplOutputToFrame( Point() );
309 Size aSize = Window::GetOutputSizePixel();
310 mnTrackX = aPos.X();
311 mnTrackY = aPos.Y();
312 mnTrackWidth = aSize.Width();
313 mnTrackHeight = aSize.Height();
314
315 if ( mbLastFloatMode )
316 {
317 maMouseOff.X() += mnDockLeft;
318 maMouseOff.Y() += mnDockTop;
319 mnTrackX -= mnDockLeft;
320 mnTrackY -= mnDockTop;
321 mnTrackWidth += mnDockLeft+mnDockRight;
322 mnTrackHeight += mnDockTop+mnDockBottom;
323 }
324
325 if ( GetSettings().GetStyleSettings().GetDragFullOptions() & DRAGFULL_OPTION_DOCKING &&
326 !( mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ) ) // no full drag when migrating to system window
327 mbDragFull = sal_True;
328 else
329 {
330 StartDocking();
331 mbDragFull = sal_False;
332 ImplUpdateAll();
333 ImplGetFrameWindow()->ImplUpdateAll();
334 }
335
336 StartTracking( STARTTRACK_KEYMOD );
337 return sal_True;
338 }
339
340 // =======================================================================
341
ImplInitDockingWindowData()342 void DockingWindow::ImplInitDockingWindowData()
343 {
344 mpImplData = new ImplData;
345 mpWindowImpl->mbDockWin = sal_True;
346
347 mpFloatWin = NULL;
348 mbDockCanceled = sal_False;
349 mbDockPrevented = sal_False;
350 mbFloatPrevented = sal_False;
351 mbDocking = sal_False;
352 mbPined = sal_False;
353 mbRollUp = sal_False;
354 mbDockBtn = sal_False;
355 mbHideBtn = sal_False;
356 }
357
358 // -----------------------------------------------------------------------
359
ImplInit(Window * pParent,WinBits nStyle)360 void DockingWindow::ImplInit( Window* pParent, WinBits nStyle )
361 {
362 if ( !(nStyle & WB_NODIALOGCONTROL) )
363 nStyle |= WB_DIALOGCONTROL;
364
365 mpImplData->mpParent = pParent;
366 mbDockable = (nStyle & WB_DOCKABLE) != 0;
367 mnFloatBits = WB_BORDER | (nStyle & DOCKWIN_FLOATSTYLES);
368 nStyle &= ~(DOCKWIN_FLOATSTYLES | WB_BORDER);
369 if ( nStyle & WB_DOCKBORDER )
370 nStyle |= WB_BORDER;
371
372 Window::ImplInit( pParent, nStyle, NULL );
373
374 ImplInitSettings();
375 }
376
377 // -----------------------------------------------------------------------
378
ImplInitSettings()379 void DockingWindow::ImplInitSettings()
380 {
381 // Hack, damit man auch DockingWindows ohne Hintergrund bauen kann
382 // und noch nicht alles umgestellt ist
383 if ( IsBackground() )
384 {
385 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
386
387 Color aColor;
388 if ( IsControlBackground() )
389 aColor = GetControlBackground();
390 else if ( Window::GetStyle() & WB_3DLOOK )
391 aColor = rStyleSettings.GetFaceColor();
392 else
393 aColor = rStyleSettings.GetWindowColor();
394 SetBackground( aColor );
395 }
396 }
397
398 // -----------------------------------------------------------------------
399
ImplLoadRes(const ResId & rResId)400 void DockingWindow::ImplLoadRes( const ResId& rResId )
401 {
402 Window::ImplLoadRes( rResId );
403
404 sal_uLong nMask = ReadLongRes();
405
406 if ( (RSC_DOCKINGWINDOW_XYMAPMODE | RSC_DOCKINGWINDOW_X |
407 RSC_DOCKINGWINDOW_Y) & nMask )
408 {
409 // Groessenangabe aus der Resource verwenden
410 Point aPos;
411 MapUnit ePosMap = MAP_PIXEL;
412
413 if ( RSC_DOCKINGWINDOW_XYMAPMODE & nMask )
414 ePosMap = (MapUnit)ReadLongRes();
415
416 if ( RSC_DOCKINGWINDOW_X & nMask )
417 {
418 aPos.X() = ReadShortRes();
419 aPos.X() = ImplLogicUnitToPixelX( aPos.X(), ePosMap );
420 }
421
422 if ( RSC_DOCKINGWINDOW_Y & nMask )
423 {
424 aPos.Y() = ReadShortRes();
425 aPos.Y() = ImplLogicUnitToPixelY( aPos.Y(), ePosMap );
426 }
427
428 SetFloatingPos( aPos );
429 }
430
431 if ( nMask & RSC_DOCKINGWINDOW_FLOATING )
432 {
433 if ( (sal_Bool)ReadShortRes() )
434 SetFloatingMode( sal_True );
435 }
436 }
437
438 // -----------------------------------------------------------------------
439
DockingWindow(WindowType nType)440 DockingWindow::DockingWindow( WindowType nType ) :
441 Window( nType )
442 {
443 ImplInitDockingWindowData();
444 }
445
446 // -----------------------------------------------------------------------
447
DockingWindow(Window * pParent,WinBits nStyle)448 DockingWindow::DockingWindow( Window* pParent, WinBits nStyle ) :
449 Window( WINDOW_DOCKINGWINDOW )
450 {
451 ImplInitDockingWindowData();
452 ImplInit( pParent, nStyle );
453 }
454
455 // -----------------------------------------------------------------------
456
DockingWindow(Window * pParent,const ResId & rResId)457 DockingWindow::DockingWindow( Window* pParent, const ResId& rResId ) :
458 Window( WINDOW_DOCKINGWINDOW )
459 {
460 ImplInitDockingWindowData();
461 rResId.SetRT( RSC_DOCKINGWINDOW );
462 WinBits nStyle = ImplInitRes( rResId );
463 ImplInit( pParent, nStyle );
464 ImplLoadRes( rResId );
465
466 if ( !(nStyle & WB_HIDE) )
467 Show();
468 }
469
470 // -----------------------------------------------------------------------
471
~DockingWindow()472 DockingWindow::~DockingWindow()
473 {
474 if ( IsFloatingMode() )
475 {
476 Show( sal_False, SHOW_NOFOCUSCHANGE );
477 SetFloatingMode( sal_False );
478 }
479 delete mpImplData;
480 }
481
482 // -----------------------------------------------------------------------
483
Tracking(const TrackingEvent & rTEvt)484 void DockingWindow::Tracking( const TrackingEvent& rTEvt )
485 {
486 if( GetDockingManager()->IsDockable( this ) ) // new docking interface
487 return Window::Tracking( rTEvt );
488
489 if ( mbDocking )
490 {
491 if ( rTEvt.IsTrackingEnded() )
492 {
493 mbDocking = sal_False;
494 if ( mbDragFull )
495 {
496 // Bei Abbruch alten Zustand wieder herstellen
497 if ( rTEvt.IsTrackingCanceled() )
498 {
499 StartDocking();
500 Rectangle aRect( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) );
501 EndDocking( aRect, mbStartFloat );
502 }
503 }
504 else
505 {
506 HideTracking();
507 if ( rTEvt.IsTrackingCanceled() )
508 {
509 mbDockCanceled = sal_True;
510 EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
511 mbDockCanceled = sal_False;
512 }
513 else
514 EndDocking( Rectangle( Point( mnTrackX, mnTrackY ), Size( mnTrackWidth, mnTrackHeight ) ), mbLastFloatMode );
515 }
516 }
517 // Docking nur bei nicht synthetischen MouseEvents
518 else if ( !rTEvt.GetMouseEvent().IsSynthetic() || rTEvt.GetMouseEvent().IsModifierChanged() )
519 {
520 Point aMousePos = rTEvt.GetMouseEvent().GetPosPixel();
521 Point aFrameMousePos = ImplOutputToFrame( aMousePos );
522 Size aFrameSize = mpWindowImpl->mpFrameWindow->GetOutputSizePixel();
523 if ( aFrameMousePos.X() < 0 )
524 aFrameMousePos.X() = 0;
525 if ( aFrameMousePos.Y() < 0 )
526 aFrameMousePos.Y() = 0;
527 if ( aFrameMousePos.X() > aFrameSize.Width()-1 )
528 aFrameMousePos.X() = aFrameSize.Width()-1;
529 if ( aFrameMousePos.Y() > aFrameSize.Height()-1 )
530 aFrameMousePos.Y() = aFrameSize.Height()-1;
531 aMousePos = ImplFrameToOutput( aFrameMousePos );
532 aMousePos.X() -= maMouseOff.X();
533 aMousePos.Y() -= maMouseOff.Y();
534 Point aFramePos = ImplOutputToFrame( aMousePos );
535 Rectangle aTrackRect( aFramePos, Size( mnTrackWidth, mnTrackHeight ) );
536 Rectangle aCompRect = aTrackRect;
537 aFramePos.X() += maMouseOff.X();
538 aFramePos.Y() += maMouseOff.Y();
539 if ( mbDragFull )
540 StartDocking();
541 sal_Bool bFloatMode = Docking( aFramePos, aTrackRect );
542 mbDockPrevented = sal_False;
543 mbFloatPrevented = sal_False;
544 if ( mbLastFloatMode != bFloatMode )
545 {
546 if ( bFloatMode )
547 {
548 aTrackRect.Left() -= mnDockLeft;
549 aTrackRect.Top() -= mnDockTop;
550 aTrackRect.Right() += mnDockRight;
551 aTrackRect.Bottom() += mnDockBottom;
552 }
553 else
554 {
555 if ( aCompRect == aTrackRect )
556 {
557 aTrackRect.Left() += mnDockLeft;
558 aTrackRect.Top() += mnDockTop;
559 aTrackRect.Right() -= mnDockRight;
560 aTrackRect.Bottom() -= mnDockBottom;
561 }
562 }
563 mbLastFloatMode = bFloatMode;
564 }
565 if ( mbDragFull )
566 {
567 Point aPos;
568 Point aOldPos = OutputToScreenPixel( aPos );
569 EndDocking( aTrackRect, mbLastFloatMode );
570 // Wenn der Status bzw. die Position sich
571 // geaendert hat, dann neu ausgeben
572 if ( aOldPos != OutputToScreenPixel( aPos ) )
573 {
574 ImplUpdateAll();
575 ImplGetFrameWindow()->ImplUpdateAll();
576 }
577 // EndDocking( aTrackRect, mbLastFloatMode );
578 }
579 else
580 {
581 sal_uInt16 nTrackStyle;
582 if ( bFloatMode )
583 nTrackStyle = SHOWTRACK_BIG;
584 else
585 nTrackStyle = SHOWTRACK_OBJECT;
586 Rectangle aShowTrackRect = aTrackRect;
587 aShowTrackRect.SetPos( ImplFrameToOutput( aShowTrackRect.TopLeft() ) );
588 ShowTracking( aShowTrackRect, nTrackStyle );
589
590 // Maus-Offset neu berechnen, da Rechteck veraendert werden
591 // konnte
592 maMouseOff.X() = aFramePos.X() - aTrackRect.Left();
593 maMouseOff.Y() = aFramePos.Y() - aTrackRect.Top();
594 }
595
596 mnTrackX = aTrackRect.Left();
597 mnTrackY = aTrackRect.Top();
598 mnTrackWidth = aTrackRect.GetWidth();
599 mnTrackHeight = aTrackRect.GetHeight();
600 }
601 }
602 }
603
604 // -----------------------------------------------------------------------
605
Notify(NotifyEvent & rNEvt)606 long DockingWindow::Notify( NotifyEvent& rNEvt )
607 {
608 if( GetDockingManager()->IsDockable( this ) ) // new docking interface
609 return Window::Notify( rNEvt );
610
611 if ( mbDockable )
612 {
613 if ( rNEvt.GetType() == EVENT_MOUSEBUTTONDOWN )
614 {
615 const MouseEvent* pMEvt = rNEvt.GetMouseEvent();
616 if ( pMEvt->IsLeft() )
617 {
618 if ( pMEvt->IsMod1() && (pMEvt->GetClicks() == 2) )
619 {
620 SetFloatingMode( !IsFloatingMode() );
621 return sal_True;
622 }
623 else if ( pMEvt->GetClicks() == 1 )
624 {
625 // check if window is floating standalone (IsFloating())
626 // or only partially floating and still docked with one border
627 // ( !mpWindowImpl->mbFrame)
628 if( ! IsFloatingMode() || ! mpFloatWin->mpWindowImpl->mbFrame )
629 {
630 Point aPos = pMEvt->GetPosPixel();
631 Window* pWindow = rNEvt.GetWindow();
632 if ( pWindow != this )
633 {
634 aPos = pWindow->OutputToScreenPixel( aPos );
635 aPos = ScreenToOutputPixel( aPos );
636 }
637 ImplStartDocking( aPos );
638 }
639 return sal_True;
640 }
641 }
642 }
643 else if( rNEvt.GetType() == EVENT_KEYINPUT )
644 {
645 const KeyCode& rKey = rNEvt.GetKeyEvent()->GetKeyCode();
646 if( rKey.GetCode() == KEY_F10 && rKey.GetModifier() &&
647 rKey.IsShift() && rKey.IsMod1() )
648 {
649 SetFloatingMode( !IsFloatingMode() );
650 return sal_True;
651 }
652 }
653 }
654
655 return Window::Notify( rNEvt );
656 }
657
658 // -----------------------------------------------------------------------
659
StartDocking()660 void DockingWindow::StartDocking()
661 {
662 mbDocking = sal_True;
663 }
664
665 // -----------------------------------------------------------------------
666
Docking(const Point &,Rectangle &)667 sal_Bool DockingWindow::Docking( const Point&, Rectangle& )
668 {
669 return IsFloatingMode();
670 }
671
672 // -----------------------------------------------------------------------
673
EndDocking(const Rectangle & rRect,sal_Bool bFloatMode)674 void DockingWindow::EndDocking( const Rectangle& rRect, sal_Bool bFloatMode )
675 {
676 if ( !IsDockingCanceled() )
677 {
678 sal_Bool bShow = sal_False;
679 if ( bFloatMode != IsFloatingMode() )
680 {
681 Show( sal_False, SHOW_NOFOCUSCHANGE );
682 SetFloatingMode( bFloatMode );
683 bShow = sal_True;
684 if ( bFloatMode && mpFloatWin )
685 mpFloatWin->SetPosSizePixel( rRect.TopLeft(), rRect.GetSize() );
686 }
687 if ( !bFloatMode )
688 {
689 Point aPos = rRect.TopLeft();
690 aPos = GetParent()->ScreenToOutputPixel( aPos );
691 Window::SetPosSizePixel( aPos, rRect.GetSize() );
692 }
693
694 if ( bShow )
695 Show();
696 }
697 mbDocking = sal_False;
698 }
699
700 // -----------------------------------------------------------------------
701
PrepareToggleFloatingMode()702 sal_Bool DockingWindow::PrepareToggleFloatingMode()
703 {
704 return sal_True;
705 }
706
707 // -----------------------------------------------------------------------
708
Close()709 sal_Bool DockingWindow::Close()
710 {
711 ImplDelData aDelData;
712 ImplAddDel( &aDelData );
713 ImplCallEventListeners( VCLEVENT_WINDOW_CLOSE );
714 if ( aDelData.IsDelete() )
715 return sal_False;
716 ImplRemoveDel( &aDelData );
717
718 if ( mpWindowImpl->mxWindowPeer.is() && IsCreatedWithToolkit() )
719 return sal_False;
720
721 Show( sal_False, SHOW_NOFOCUSCHANGE );
722 return sal_True;
723 }
724
725 // -----------------------------------------------------------------------
726
ToggleFloatingMode()727 void DockingWindow::ToggleFloatingMode()
728 {
729 }
730
731 // -----------------------------------------------------------------------
732
TitleButtonClick(sal_uInt16)733 void DockingWindow::TitleButtonClick( sal_uInt16 )
734 {
735 }
736
737 // -----------------------------------------------------------------------
738
Pin()739 void DockingWindow::Pin()
740 {
741 }
742
743 // -----------------------------------------------------------------------
744
Roll()745 void DockingWindow::Roll()
746 {
747 }
748
749 // -----------------------------------------------------------------------
750
PopupModeEnd()751 void DockingWindow::PopupModeEnd()
752 {
753 }
754
755 // -----------------------------------------------------------------------
756
Resizing(Size &)757 void DockingWindow::Resizing( Size& )
758 {
759 }
760
761 // -----------------------------------------------------------------------
762
StateChanged(StateChangedType nType)763 void DockingWindow::StateChanged( StateChangedType nType )
764 {
765 switch(nType)
766 {
767 case STATE_CHANGE_CONTROLBACKGROUND:
768 ImplInitSettings();
769 Invalidate();
770 break;
771
772 case STATE_CHANGE_STYLE:
773 mbDockable = (GetStyle() & WB_DOCKABLE) != 0;
774 break;
775
776 default:
777 break;
778 }
779
780 Window::StateChanged( nType );
781 }
782
783 // -----------------------------------------------------------------------
784
DataChanged(const DataChangedEvent & rDCEvt)785 void DockingWindow::DataChanged( const DataChangedEvent& rDCEvt )
786 {
787 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
788 (rDCEvt.GetFlags() & SETTINGS_STYLE) )
789 {
790 ImplInitSettings();
791 Invalidate();
792 }
793 else
794 Window::DataChanged( rDCEvt );
795 }
796
797 // -----------------------------------------------------------------------
798
ShowTitleButton(sal_uInt16 nButton,sal_Bool bVisible)799 void DockingWindow::ShowTitleButton( sal_uInt16 nButton, sal_Bool bVisible )
800 {
801 if ( mpFloatWin )
802 mpFloatWin->ShowTitleButton( nButton, bVisible );
803 else
804 {
805 if ( nButton == TITLE_BUTTON_DOCKING )
806 mbDockBtn = bVisible;
807 else /* if ( nButton == TITLE_BUTTON_HIDE ) */
808 mbHideBtn = bVisible;
809 }
810 }
811
812 // -----------------------------------------------------------------------
813
IsTitleButtonVisible(sal_uInt16 nButton) const814 sal_Bool DockingWindow::IsTitleButtonVisible( sal_uInt16 nButton ) const
815 {
816 if ( mpFloatWin )
817 return mpFloatWin->IsTitleButtonVisible( nButton );
818 else
819 {
820 if ( nButton == TITLE_BUTTON_DOCKING )
821 return mbDockBtn;
822 else /* if ( nButton == TITLE_BUTTON_HIDE ) */
823 return mbHideBtn;
824 }
825 }
826
827 // -----------------------------------------------------------------------
828
SetFloatingMode(sal_Bool bFloatMode)829 void DockingWindow::SetFloatingMode( sal_Bool bFloatMode )
830 {
831 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
832 if( pWrapper )
833 {
834 pWrapper->SetFloatingMode( bFloatMode );
835 return;
836 }
837 if ( IsFloatingMode() != bFloatMode )
838 {
839 if ( PrepareToggleFloatingMode() ) // changes to floating mode can be vetoed
840 {
841 sal_Bool bVisible = IsVisible();
842
843 if ( bFloatMode )
844 {
845 Show( sal_False, SHOW_NOFOCUSCHANGE );
846
847 maDockPos = Window::GetPosPixel();
848
849 Window* pRealParent = mpWindowImpl->mpRealParent;
850 mpOldBorderWin = mpWindowImpl->mpBorderWindow;
851
852 ImplDockFloatWin* pWin =
853 new ImplDockFloatWin(
854 mpImplData->mpParent,
855 mnFloatBits & ( WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE ) ? mnFloatBits | WB_SYSTEMWINDOW : mnFloatBits,
856 this );
857 mpFloatWin = pWin;
858 mpWindowImpl->mpBorderWindow = NULL;
859 mpWindowImpl->mnLeftBorder = 0;
860 mpWindowImpl->mnTopBorder = 0;
861 mpWindowImpl->mnRightBorder = 0;
862 mpWindowImpl->mnBottomBorder = 0;
863 // Falls Parent zerstoert wird, muessen wir auch vom
864 // BorderWindow den Parent umsetzen
865 if ( mpOldBorderWin )
866 mpOldBorderWin->SetParent( pWin );
867
868 // #123765# reset the buffered DropTargets when undocking, else it may not
869 // be correctly initialized
870 mpWindowImpl->mxDNDListenerContainer.clear();
871
872 SetParent( pWin );
873 SetPosPixel( Point() );
874 mpWindowImpl->mpBorderWindow = pWin;
875 pWin->mpWindowImpl->mpClientWindow = this;
876 mpWindowImpl->mpRealParent = pRealParent;
877 pWin->SetText( Window::GetText() );
878 pWin->SetOutputSizePixel( Window::GetSizePixel() );
879 pWin->SetPosPixel( maFloatPos );
880 // DockingDaten ans FloatingWindow weiterreichen
881 pWin->ShowTitleButton( TITLE_BUTTON_DOCKING, mbDockBtn );
882 pWin->ShowTitleButton( TITLE_BUTTON_HIDE, mbHideBtn );
883 pWin->SetPin( mbPined );
884 if ( mbRollUp )
885 pWin->RollUp();
886 else
887 pWin->RollDown();
888 pWin->SetRollUpOutputSizePixel( maRollUpOutSize );
889 pWin->SetMinOutputSizePixel( maMinOutSize );
890 pWin->SetMaxOutputSizePixel( mpImplData->maMaxOutSize );
891
892 ToggleFloatingMode();
893
894 if ( bVisible )
895 Show();
896 }
897 else
898 {
899 Show( sal_False, SHOW_NOFOCUSCHANGE );
900
901 // FloatingDaten wird im FloatingWindow speichern
902 maFloatPos = mpFloatWin->GetPosPixel();
903 mbDockBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_DOCKING );
904 mbHideBtn = mpFloatWin->IsTitleButtonVisible( TITLE_BUTTON_HIDE );
905 mbPined = mpFloatWin->IsPined();
906 mbRollUp = mpFloatWin->IsRollUp();
907 maRollUpOutSize = mpFloatWin->GetRollUpOutputSizePixel();
908 maMinOutSize = mpFloatWin->GetMinOutputSizePixel();
909 mpImplData->maMaxOutSize = mpFloatWin->GetMaxOutputSizePixel();
910
911 Window* pRealParent = mpWindowImpl->mpRealParent;
912 mpWindowImpl->mpBorderWindow = NULL;
913 if ( mpOldBorderWin )
914 {
915 SetParent( mpOldBorderWin );
916 ((ImplBorderWindow*)mpOldBorderWin)->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
917 mpOldBorderWin->Resize();
918 }
919 mpWindowImpl->mpBorderWindow = mpOldBorderWin;
920 SetParent( pRealParent );
921 mpWindowImpl->mpRealParent = pRealParent;
922 delete static_cast<ImplDockFloatWin*>(mpFloatWin);
923 mpFloatWin = NULL;
924 SetPosPixel( maDockPos );
925
926 ToggleFloatingMode();
927
928 if ( bVisible )
929 Show();
930 }
931 }
932 }
933 }
934
935 // -----------------------------------------------------------------------
936
SetFloatStyle(WinBits nStyle)937 void DockingWindow::SetFloatStyle( WinBits nStyle )
938 {
939 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
940 if( pWrapper )
941 {
942 pWrapper->SetFloatStyle( nStyle );
943 return;
944 }
945
946 mnFloatBits = nStyle;
947 }
948
949 // -----------------------------------------------------------------------
950
GetFloatStyle() const951 WinBits DockingWindow::GetFloatStyle() const
952 {
953 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
954 if( pWrapper )
955 {
956 return pWrapper->GetFloatStyle();
957 }
958
959 return mnFloatBits;
960 }
961
962 // -----------------------------------------------------------------------
963
SetTabStop()964 void DockingWindow::SetTabStop()
965 {
966 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
967 if( pWrapper )
968 {
969 pWrapper->SetTabStop();
970 return;
971 }
972
973 mpWindowImpl->mnStyle |= WB_GROUP | WB_TABSTOP;
974 }
975
976 // -----------------------------------------------------------------------
977
SetPosSizePixel(long nX,long nY,long nWidth,long nHeight,sal_uInt16 nFlags)978 void DockingWindow::SetPosSizePixel( long nX, long nY,
979 long nWidth, long nHeight,
980 sal_uInt16 nFlags )
981 {
982 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
983 if( pWrapper )
984 {
985 if ( pWrapper->mpFloatWin )
986 pWrapper->mpFloatWin->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
987 else
988 Window::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
989 return;
990 }
991
992 if ( mpFloatWin )
993 mpFloatWin->SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
994 else
995 Window::SetPosSizePixel( nX, nY, nWidth, nHeight, nFlags );
996 }
997
998 // -----------------------------------------------------------------------
999
GetPosPixel() const1000 Point DockingWindow::GetPosPixel() const
1001 {
1002 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1003 if( pWrapper )
1004 {
1005 if ( pWrapper->mpFloatWin )
1006 return pWrapper->mpFloatWin->GetPosPixel();
1007 else
1008 return Window::GetPosPixel();
1009 }
1010
1011 if ( mpFloatWin )
1012 return mpFloatWin->GetPosPixel();
1013 else
1014 return Window::GetPosPixel();
1015 }
1016
1017 // -----------------------------------------------------------------------
1018
GetSizePixel() const1019 Size DockingWindow::GetSizePixel() const
1020 {
1021 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1022 if( pWrapper )
1023 {
1024 if ( pWrapper->mpFloatWin )
1025 return pWrapper->mpFloatWin->GetSizePixel();
1026 else
1027 return Window::GetSizePixel();
1028 }
1029
1030 if ( mpFloatWin )
1031 return mpFloatWin->GetSizePixel();
1032 else
1033 return Window::GetSizePixel();
1034 }
1035
1036 // -----------------------------------------------------------------------
1037
SetOutputSizePixel(const Size & rNewSize)1038 void DockingWindow::SetOutputSizePixel( const Size& rNewSize )
1039 {
1040 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1041 if( pWrapper )
1042 {
1043 if ( pWrapper->mpFloatWin )
1044 pWrapper->mpFloatWin->SetOutputSizePixel( rNewSize );
1045 else
1046 Window::SetOutputSizePixel( rNewSize );
1047 return;
1048 }
1049
1050 if ( mpFloatWin )
1051 mpFloatWin->SetOutputSizePixel( rNewSize );
1052 else
1053 Window::SetOutputSizePixel( rNewSize );
1054 }
1055
1056 // -----------------------------------------------------------------------
1057
GetOutputSizePixel() const1058 Size DockingWindow::GetOutputSizePixel() const
1059 {
1060 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1061 if( pWrapper )
1062 {
1063 if ( pWrapper->mpFloatWin )
1064 return pWrapper->mpFloatWin->GetOutputSizePixel();
1065 else
1066 return Window::GetOutputSizePixel();
1067 }
1068
1069 if ( mpFloatWin )
1070 return mpFloatWin->GetOutputSizePixel();
1071 else
1072 return Window::GetOutputSizePixel();
1073 }
1074
GetFloatingPos() const1075 Point DockingWindow::GetFloatingPos() const
1076 {
1077 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1078 if( pWrapper )
1079 {
1080 if ( pWrapper->mpFloatWin )
1081 {
1082 WindowStateData aData;
1083 aData.SetMask( WINDOWSTATE_MASK_POS );
1084 pWrapper->mpFloatWin->GetWindowStateData( aData );
1085 Point aPos( aData.GetX(), aData.GetY() );
1086 aPos = pWrapper->mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos );
1087 return aPos;
1088 }
1089 else
1090 return maFloatPos;
1091 }
1092
1093 if ( mpFloatWin )
1094 {
1095 WindowStateData aData;
1096 aData.SetMask( WINDOWSTATE_MASK_POS );
1097 mpFloatWin->GetWindowStateData( aData );
1098 Point aPos( aData.GetX(), aData.GetY() );
1099 aPos = mpFloatWin->GetParent()->ImplGetFrameWindow()->AbsoluteScreenToOutputPixel( aPos );
1100 return aPos;
1101 }
1102 else
1103 return maFloatPos;
1104 }
1105
IsFloatingMode() const1106 sal_Bool DockingWindow::IsFloatingMode() const
1107 {
1108 ImplDockingWindowWrapper *pWrapper = ImplGetDockingManager()->GetDockingWindowWrapper( this );
1109 if( pWrapper )
1110 return pWrapper->IsFloatingMode();
1111 else
1112 return (mpFloatWin != NULL);
1113 }
1114
SetMaxOutputSizePixel(const Size & rSize)1115 void DockingWindow::SetMaxOutputSizePixel( const Size& rSize )
1116 {
1117 if ( mpFloatWin )
1118 mpFloatWin->SetMaxOutputSizePixel( rSize );
1119 mpImplData->maMaxOutSize = rSize;
1120 }
1121
GetMaxOutputSizePixel() const1122 const Size& DockingWindow::GetMaxOutputSizePixel() const
1123 {
1124 if ( mpFloatWin )
1125 return mpFloatWin->GetMaxOutputSizePixel();
1126 return mpImplData->maMaxOutSize;
1127 }
1128