1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
24 #include <salframe.hxx>
26 #include <vcl/svapp.hxx>
27 #include <vcl/wrkwin.hxx>
28 #include <vcl/event.hxx>
29 #include <vcl/toolbox.hxx>
30 #include <vcl/floatwin.hxx>
33 #include <tools/debug.hxx>
36 // =======================================================================
38 class FloatingWindow::ImplData
45 Rectangle maItemEdgeClipRect
; // used to clip the common edge between a toolbar item and the border of this window
48 FloatingWindow::ImplData::ImplData()
53 FloatingWindow::ImplData::~ImplData()
57 Rectangle
& FloatingWindow::ImplGetItemEdgeClipRect()
59 return mpImplData
->maItemEdgeClipRect
;
62 // =======================================================================
64 void FloatingWindow::ImplInit( Window
* pParent
, WinBits nStyle
)
66 mpImplData
= new ImplData
;
68 mpWindowImpl
->mbFloatWin
= sal_True
;
69 mbInCleanUp
= sal_False
;
70 mbGrabFocus
= sal_False
;
72 DBG_ASSERT( pParent
, "FloatWindow::FloatingWindow(): - pParent == NULL!" );
75 pParent
= ImplGetSVData()->maWinData
.mpAppWin
;
77 DBG_ASSERT( pParent
, "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists" );
79 // no Border, then we dont need a border window
82 mpWindowImpl
->mbOverlapWin
= sal_True
;
83 nStyle
|= WB_DIALOGCONTROL
;
84 SystemWindow::ImplInit( pParent
, nStyle
, NULL
);
88 if ( !(nStyle
& WB_NODIALOGCONTROL
) )
89 nStyle
|= WB_DIALOGCONTROL
;
91 if( nStyle
& (WB_MOVEABLE
| WB_SIZEABLE
| WB_ROLLABLE
| WB_CLOSEABLE
| WB_STANDALONE
)
92 && !(nStyle
& WB_OWNERDRAWDECORATION
) )
94 WinBits nFloatWinStyle
= nStyle
;
95 // #99154# floaters are not closeable by default anymore, eg fullscreen floater
96 // nFloatWinStyle |= WB_CLOSEABLE;
97 mpWindowImpl
->mbFrame
= sal_True
;
98 mpWindowImpl
->mbOverlapWin
= sal_True
;
99 SystemWindow::ImplInit( pParent
, nFloatWinStyle
& ~WB_BORDER
, NULL
);
103 ImplBorderWindow
* pBorderWin
;
104 sal_uInt16 nBorderStyle
= BORDERWINDOW_STYLE_BORDER
| BORDERWINDOW_STYLE_FLOAT
;
106 if( nStyle
& WB_OWNERDRAWDECORATION
) nBorderStyle
|= BORDERWINDOW_STYLE_FRAME
;
107 else nBorderStyle
|= BORDERWINDOW_STYLE_OVERLAP
;
109 if ( (nStyle
& WB_SYSTEMWINDOW
) && !(nStyle
& (WB_MOVEABLE
| WB_SIZEABLE
)) )
111 nBorderStyle
|= BORDERWINDOW_STYLE_FRAME
;
112 nStyle
|= WB_CLOSEABLE
; // make undecorated floaters closeable
114 pBorderWin
= new ImplBorderWindow( pParent
, nStyle
, nBorderStyle
);
115 SystemWindow::ImplInit( pBorderWin
, nStyle
& ~WB_BORDER
, NULL
);
116 pBorderWin
->mpWindowImpl
->mpClientWindow
= this;
117 pBorderWin
->GetBorder( mpWindowImpl
->mnLeftBorder
, mpWindowImpl
->mnTopBorder
, mpWindowImpl
->mnRightBorder
, mpWindowImpl
->mnBottomBorder
);
118 pBorderWin
->SetDisplayActive( sal_True
);
119 mpWindowImpl
->mpBorderWindow
= pBorderWin
;
120 mpWindowImpl
->mpRealParent
= pParent
;
123 SetActivateMode( 0 );
126 mpFirstPopupModeWin
= NULL
;
128 mnTitle
= (nStyle
& (WB_MOVEABLE
| WB_POPUP
)) ? FLOATWIN_TITLE_NORMAL
: FLOATWIN_TITLE_NONE
;
129 mnOldTitle
= mnTitle
;
130 mnPopupModeFlags
= 0;
131 mbInPopupMode
= sal_False
;
132 mbPopupMode
= sal_False
;
133 mbPopupModeCanceled
= sal_False
;
134 mbPopupModeTearOff
= sal_False
;
135 mbMouseDown
= sal_False
;
140 // -----------------------------------------------------------------------
142 void FloatingWindow::ImplInitSettings()
144 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
147 if ( IsControlBackground() )
148 aColor
= GetControlBackground();
149 else if ( Window::GetStyle() & WB_3DLOOK
)
150 aColor
= rStyleSettings
.GetFaceColor();
152 aColor
= rStyleSettings
.GetWindowColor();
153 SetBackground( aColor
);
156 // =======================================================================
158 FloatingWindow::FloatingWindow( Window
* pParent
, WinBits nStyle
) :
159 SystemWindow( WINDOW_FLOATINGWINDOW
)
161 ImplInit( pParent
, nStyle
);
164 // -----------------------------------------------------------------------
166 FloatingWindow::FloatingWindow( Window
* pParent
, const ResId
& rResId
) :
167 SystemWindow( WINDOW_FLOATINGWINDOW
)
169 rResId
.SetRT( RSC_FLOATINGWINDOW
);
170 WinBits nStyle
= ImplInitRes( rResId
);
171 ImplInit( pParent
, nStyle
);
172 ImplLoadRes( rResId
);
174 if ( !(nStyle
& WB_HIDE
) )
178 // -----------------------------------------------------------------------
180 void FloatingWindow::ImplLoadRes( const ResId
& rResId
)
182 SystemWindow::ImplLoadRes( rResId
);
184 sal_uLong nObjMask
= ReadLongRes();
186 if ( (RSC_FLOATINGWINDOW_WHMAPMODE
| RSC_FLOATINGWINDOW_WIDTH
|
187 RSC_FLOATINGWINDOW_HEIGHT
) & nObjMask
)
189 // Groessenangabe aus der Resource verwenden
191 MapUnit eSizeMap
= MAP_PIXEL
;
193 if ( RSC_FLOATINGWINDOW_WHMAPMODE
& nObjMask
)
194 eSizeMap
= (MapUnit
) ReadShortRes();
195 if ( RSC_FLOATINGWINDOW_WIDTH
& nObjMask
)
196 aSize
.Width() = ReadShortRes();
197 if ( RSC_FLOATINGWINDOW_HEIGHT
& nObjMask
)
198 aSize
.Height() = ReadShortRes();
200 SetRollUpOutputSizePixel( LogicToPixel( aSize
, eSizeMap
) );
203 if (nObjMask
& RSC_FLOATINGWINDOW_ZOOMIN
)
205 if ( ReadShortRes() )
210 // -----------------------------------------------------------------------
212 FloatingWindow::~FloatingWindow()
214 if( mbPopupModeCanceled
)
215 // indicates that ESC key was pressed
216 // will be handled in Window::ImplGrabFocus()
217 SetDialogControlFlags( GetDialogControlFlags() | WINDOW_DLGCTRL_FLOATWIN_POPUPMODEEND_CANCEL
);
219 if ( IsInPopupMode() )
220 EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
| FLOATWIN_POPUPMODEEND_CLOSEALL
| FLOATWIN_POPUPMODEEND_DONTCALLHDL
);
223 Application::RemoveUserEvent( mnPostId
);
228 // -----------------------------------------------------------------------
230 Point
FloatingWindow::CalcFloatingPosition( Window
* pWindow
, const Rectangle
& rRect
, sal_uLong nFlags
, sal_uInt16
& rArrangeIndex
)
232 return ImplCalcPos( pWindow
, rRect
, nFlags
, rArrangeIndex
);
235 // -----------------------------------------------------------------------
237 Point
FloatingWindow::ImplCalcPos( Window
* pWindow
,
238 const Rectangle
& rRect
, sal_uLong nFlags
,
239 sal_uInt16
& rArrangeIndex
)
241 // Fenster-Position ermitteln
243 Size aSize
= pWindow
->GetSizePixel();
244 Rectangle aScreenRect
= pWindow
->ImplGetFrameWindow()->GetDesktopRectPixel();
245 FloatingWindow
*pFloatingWindow
= dynamic_cast<FloatingWindow
*>( pWindow
);
248 Window
* pW
= pWindow
;
249 if ( pW
->mpWindowImpl
->mpRealParent
)
250 pW
= pW
->mpWindowImpl
->mpRealParent
;
252 Rectangle
normRect( rRect
); // rRect is already relative to top-level window
253 normRect
.SetPos( pW
->ScreenToOutputPixel( normRect
.TopLeft() ) );
255 sal_Bool bRTL
= Application::GetSettings().GetLayoutRTL();
257 Rectangle
devRect( pW
->OutputToAbsoluteScreenPixel( normRect
.TopLeft() ),
258 pW
->OutputToAbsoluteScreenPixel( normRect
.BottomRight() ) );
260 Rectangle
devRectRTL( devRect
);
262 // create a rect that can be compared to desktop coordinates
263 devRectRTL
= pW
->ImplOutputToUnmirroredAbsoluteScreenPixel( normRect
);
264 if( Application::GetScreenCount() > 1 && Application::IsUnifiedDisplay() )
265 aScreenRect
= Application::GetScreenPosSizePixel(
266 Application::GetBestScreen( bRTL
? devRectRTL
: devRect
) );
269 sal_uInt16 nArrangeAry
[5];
270 sal_uInt16 nArrangeIndex
;
272 Point e1
,e2
; // the common edge between the item rect and the floating window
274 if ( nFlags
& FLOATWIN_POPUPMODE_LEFT
)
276 nArrangeAry
[0] = FLOATWIN_POPUPMODE_LEFT
;
277 nArrangeAry
[1] = FLOATWIN_POPUPMODE_RIGHT
;
278 nArrangeAry
[2] = FLOATWIN_POPUPMODE_UP
;
279 nArrangeAry
[3] = FLOATWIN_POPUPMODE_DOWN
;
280 nArrangeAry
[4] = FLOATWIN_POPUPMODE_LEFT
;
282 else if ( nFlags
& FLOATWIN_POPUPMODE_RIGHT
)
284 nArrangeAry
[0] = FLOATWIN_POPUPMODE_RIGHT
;
285 nArrangeAry
[1] = FLOATWIN_POPUPMODE_LEFT
;
286 nArrangeAry
[2] = FLOATWIN_POPUPMODE_UP
;
287 nArrangeAry
[3] = FLOATWIN_POPUPMODE_DOWN
;
288 nArrangeAry
[4] = FLOATWIN_POPUPMODE_RIGHT
;
290 else if ( nFlags
& FLOATWIN_POPUPMODE_UP
)
292 nArrangeAry
[0] = FLOATWIN_POPUPMODE_UP
;
293 nArrangeAry
[1] = FLOATWIN_POPUPMODE_DOWN
;
294 nArrangeAry
[2] = FLOATWIN_POPUPMODE_RIGHT
;
295 nArrangeAry
[3] = FLOATWIN_POPUPMODE_LEFT
;
296 nArrangeAry
[4] = FLOATWIN_POPUPMODE_UP
;
300 nArrangeAry
[0] = FLOATWIN_POPUPMODE_DOWN
;
301 nArrangeAry
[1] = FLOATWIN_POPUPMODE_UP
;
302 nArrangeAry
[2] = FLOATWIN_POPUPMODE_RIGHT
;
303 nArrangeAry
[3] = FLOATWIN_POPUPMODE_LEFT
;
304 nArrangeAry
[4] = FLOATWIN_POPUPMODE_DOWN
;
306 if ( nFlags
& FLOATWIN_POPUPMODE_NOAUTOARRANGE
)
311 for ( ; nArrangeIndex
< 5; nArrangeIndex
++ )
314 switch ( nArrangeAry
[nArrangeIndex
] )
317 case FLOATWIN_POPUPMODE_LEFT
:
318 aPos
.X() = devRect
.Left()-aSize
.Width()+1;
319 aPos
.Y() = devRect
.Top();
320 aPos
.Y() -= pWindow
->mpWindowImpl
->mnTopBorder
;
321 if( bRTL
) // --- RTL --- we're comparing screen coordinates here
323 if( (devRectRTL
.Right()+aSize
.Width()) > aScreenRect
.Right() )
328 if ( aPos
.X() < aScreenRect
.Left() )
333 e1
= devRect
.TopLeft();
334 e2
= devRect
.BottomLeft();
335 // set non-zero width
337 // don't clip corners
342 case FLOATWIN_POPUPMODE_RIGHT
:
343 aPos
= devRect
.TopRight();
344 aPos
.Y() -= pWindow
->mpWindowImpl
->mnTopBorder
;
345 if( bRTL
) // --- RTL --- we're comparing screen coordinates here
347 if( (devRectRTL
.Left() - aSize
.Width()) < aScreenRect
.Left() )
352 if ( aPos
.X()+aSize
.Width() > aScreenRect
.Right() )
357 e1
= devRect
.TopRight();
358 e2
= devRect
.BottomRight();
359 // set non-zero width
361 // don't clip corners
366 case FLOATWIN_POPUPMODE_UP
:
367 aPos
.X() = devRect
.Left();
368 aPos
.Y() = devRect
.Top()-aSize
.Height()+1;
369 if ( aPos
.Y() < aScreenRect
.Top() )
373 e1
= devRect
.TopLeft();
374 e2
= devRect
.TopRight();
375 // set non-zero height
377 // don't clip corners
382 case FLOATWIN_POPUPMODE_DOWN
:
383 aPos
= devRect
.BottomLeft();
384 if ( aPos
.Y()+aSize
.Height() > aScreenRect
.Bottom() )
388 e1
= devRect
.BottomLeft();
389 e2
= devRect
.BottomRight();
390 // set non-zero height
392 // don't clip corners
399 // Evt. noch anpassen
400 if ( bBreak
&& !(nFlags
& FLOATWIN_POPUPMODE_NOAUTOARRANGE
) )
402 if ( (nArrangeAry
[nArrangeIndex
] == FLOATWIN_POPUPMODE_LEFT
) ||
403 (nArrangeAry
[nArrangeIndex
] == FLOATWIN_POPUPMODE_RIGHT
) )
405 if ( aPos
.Y()+aSize
.Height() > aScreenRect
.Bottom() )
407 aPos
.Y() = devRect
.Bottom()-aSize
.Height()+1;
408 if ( aPos
.Y() < aScreenRect
.Top() )
409 aPos
.Y() = aScreenRect
.Top();
414 if( bRTL
) // --- RTL --- we're comparing screen coordinates here
416 if( devRectRTL
.Right()-aSize
.Width()+1 < aScreenRect
.Left() )
417 aPos
.X() -= aScreenRect
.Left() - devRectRTL
.Right() + aSize
.Width() - 1;
419 else if ( aPos
.X()+aSize
.Width() > aScreenRect
.Right() )
421 aPos
.X() = devRect
.Right()-aSize
.Width()+1;
422 if ( aPos
.X() < aScreenRect
.Left() )
423 aPos
.X() = aScreenRect
.Left();
431 if ( nArrangeIndex
> 4 )
434 rArrangeIndex
= nArrangeIndex
;
436 aPos
= pW
->AbsoluteScreenToOutputPixel( aPos
);
438 // store a cliprect that can be used to clip the common edge of the itemrect and the floating window
439 if( pFloatingWindow
)
441 pFloatingWindow
->mpImplData
->maItemEdgeClipRect
=
445 // caller expects cordinates relative to top-level win
446 return pW
->OutputToScreenPixel( aPos
);
449 // -----------------------------------------------------------------------
451 FloatingWindow
* FloatingWindow::ImplFloatHitTest( Window
* pReference
, const Point
& rPos
, sal_uInt16
& rHitTest
)
453 FloatingWindow
* pWin
= this;
455 Point
aAbsolute( rPos
);
457 // compare coordinates in absolute screen coordinates
458 if( pReference
->ImplHasMirroredGraphics() )
460 if(!pReference
->IsRTLEnabled() )
461 // --- RTL --- re-mirror back to get device coordiantes
462 pReference
->ImplReMirror( aAbsolute
);
464 Rectangle
aRect( pReference
->ScreenToOutputPixel(aAbsolute
), Size(1,1) ) ;
465 aRect
= pReference
->ImplOutputToUnmirroredAbsoluteScreenPixel( aRect
);
466 aAbsolute
= aRect
.TopLeft();
469 aAbsolute
= Point( pReference
->OutputToAbsoluteScreenPixel(
470 pReference
->ScreenToOutputPixel(rPos
) ) );
474 // compute the floating window's size in absolute screen coordinates
476 // use the border window to have the exact position
477 Window
*pBorderWin
= pWin
->GetWindow( WINDOW_BORDER
);
479 Point aPt
; // the top-left corner in output coordinates ie (0,0)
480 Rectangle
devRect( pBorderWin
->ImplOutputToUnmirroredAbsoluteScreenPixel( Rectangle( aPt
, pBorderWin
->GetSizePixel()) ) ) ;
481 if ( devRect
.IsInside( aAbsolute
) )
483 rHitTest
= IMPL_FLOATWIN_HITTEST_WINDOW
;
487 // test, if mouse is in rectangle, (this is typically the rect of the active
488 // toolbox item or similar)
489 // note: maFloatRect is set in FloatingWindow::StartPopupMode() and
490 // is already in absolute device coordinates
491 if ( pWin
->maFloatRect
.IsInside( aAbsolute
) )
493 rHitTest
= IMPL_FLOATWIN_HITTEST_RECT
;
497 pWin
= pWin
->mpNextFloat
;
501 rHitTest
= IMPL_FLOATWIN_HITTEST_OUTSIDE
;
505 // -----------------------------------------------------------------------
507 FloatingWindow
* FloatingWindow::ImplFindLastLevelFloat()
509 FloatingWindow
* pWin
= this;
510 FloatingWindow
* pLastFoundWin
= pWin
;
514 if ( pWin
->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NEWLEVEL
)
515 pLastFoundWin
= pWin
;
517 pWin
= pWin
->mpNextFloat
;
521 return pLastFoundWin
;
524 // -----------------------------------------------------------------------
526 sal_Bool
FloatingWindow::ImplIsFloatPopupModeWindow( const Window
* pWindow
)
528 FloatingWindow
* pWin
= this;
532 if ( pWin
->mpFirstPopupModeWin
== pWindow
)
535 pWin
= pWin
->mpNextFloat
;
542 // -----------------------------------------------------------------------
544 IMPL_LINK_NOARG(FloatingWindow
, ImplEndPopupModeHdl
)
547 mnPopupModeFlags
= 0;
548 mbPopupMode
= sal_False
;
553 // -----------------------------------------------------------------------
555 long FloatingWindow::Notify( NotifyEvent
& rNEvt
)
557 // Zuerst Basisklasse rufen wegen TabSteuerung
558 long nRet
= SystemWindow::Notify( rNEvt
);
561 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
563 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
564 KeyCode aKeyCode
= pKEvt
->GetKeyCode();
565 sal_uInt16 nKeyCode
= aKeyCode
.GetCode();
567 if ( (nKeyCode
== KEY_ESCAPE
) && (GetStyle() & WB_CLOSEABLE
) )
578 // -----------------------------------------------------------------------
580 void FloatingWindow::StateChanged( StateChangedType nType
)
582 SystemWindow::StateChanged( nType
);
584 if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
591 // -----------------------------------------------------------------------
593 void FloatingWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
595 SystemWindow::DataChanged( rDCEvt
);
597 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
598 (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
605 // -----------------------------------------------------------------------
607 void FloatingWindow::ImplCallPopupModeEnd()
609 // PopupMode wurde beendet
610 mbInPopupMode
= sal_False
;
612 // Handler asyncron rufen
614 Application::PostUserEvent( mnPostId
, LINK( this, FloatingWindow
, ImplEndPopupModeHdl
) );
617 // -----------------------------------------------------------------------
619 void FloatingWindow::PopupModeEnd()
621 maPopupModeEndHdl
.Call( this );
624 // -----------------------------------------------------------------------
626 void FloatingWindow::SetTitleType( sal_uInt16 nTitle
)
628 if ( (mnTitle
!= nTitle
) && mpWindowImpl
->mpBorderWindow
)
631 Size aOutSize
= GetOutputSizePixel();
632 sal_uInt16 nTitleStyle
;
633 if ( nTitle
== FLOATWIN_TITLE_NORMAL
)
634 nTitleStyle
= BORDERWINDOW_TITLE_SMALL
;
635 else if ( nTitle
== FLOATWIN_TITLE_TEAROFF
)
636 nTitleStyle
= BORDERWINDOW_TITLE_TEAROFF
;
637 else if ( nTitle
== FLOATWIN_TITLE_POPUP
)
638 nTitleStyle
= BORDERWINDOW_TITLE_POPUP
;
639 else // nTitle == FLOATWIN_TITLE_NONE
640 nTitleStyle
= BORDERWINDOW_TITLE_NONE
;
641 ((ImplBorderWindow
*)mpWindowImpl
->mpBorderWindow
)->SetTitleType( nTitleStyle
, aOutSize
);
642 ((ImplBorderWindow
*)mpWindowImpl
->mpBorderWindow
)->GetBorder( mpWindowImpl
->mnLeftBorder
, mpWindowImpl
->mnTopBorder
, mpWindowImpl
->mnRightBorder
, mpWindowImpl
->mnBottomBorder
);
646 // -----------------------------------------------------------------------
648 void FloatingWindow::StartPopupMode( const Rectangle
& rRect
, sal_uLong nFlags
)
652 Show( sal_False
, SHOW_NOFOCUSCHANGE
);
658 mnOldTitle
= mnTitle
;
659 if ( ( mpWindowImpl
->mnStyle
& WB_POPUP
) && !GetText().isEmpty() )
660 SetTitleType( FLOATWIN_TITLE_POPUP
);
661 else if ( nFlags
& FLOATWIN_POPUPMODE_ALLOWTEAROFF
)
662 SetTitleType( FLOATWIN_TITLE_TEAROFF
);
664 SetTitleType( FLOATWIN_TITLE_NONE
);
666 // avoid close on focus change for decorated floating windows only
667 if( mpWindowImpl
->mbFrame
&& (GetStyle() & WB_MOVEABLE
) )
668 nFlags
|= FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE
;
670 // #102010# For debugging Accessibility
671 static const char* pEnv
= getenv("SAL_FLOATWIN_NOAPPFOCUSCLOSE" );
673 nFlags
|= FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE
;
675 // compute window position according to flags and arrangement
676 sal_uInt16 nArrangeIndex
;
677 Point aPos
= ImplCalcPos( this, rRect
, nFlags
, nArrangeIndex
);
680 // set data and display window
681 // convert maFloatRect to absolute device coordinates
682 // so they can be compared across different frames
683 // !!! rRect is expected to be in screen coordinates of the parent frame window !!!
686 Window
*pReference
= GetParent();
688 // compare coordinates in absolute screen coordinates
689 // Keep in sync with FloatingWindow::ImplFloatHitTest, e.g. fdo#33509
690 if( pReference
->ImplHasMirroredGraphics() )
692 if(!pReference
->IsRTLEnabled() )
693 // --- RTL --- re-mirror back to get device coordiantes
694 pReference
->ImplReMirror(maFloatRect
);
696 maFloatRect
.SetPos(pReference
->ScreenToOutputPixel(maFloatRect
.TopLeft()));
697 maFloatRect
= pReference
->ImplOutputToUnmirroredAbsoluteScreenPixel(maFloatRect
);
700 maFloatRect
.SetPos(pReference
->OutputToAbsoluteScreenPixel(pReference
->ScreenToOutputPixel(rRect
.TopLeft())));
702 maFloatRect
.Left() -= 2;
703 maFloatRect
.Top() -= 2;
704 maFloatRect
.Right() += 2;
705 maFloatRect
.Bottom() += 2;
706 mnPopupModeFlags
= nFlags
;
707 mbInPopupMode
= sal_True
;
708 mbPopupMode
= sal_True
;
709 mbPopupModeCanceled
= sal_False
;
710 mbPopupModeTearOff
= sal_False
;
711 mbMouseDown
= sal_False
;
713 mbOldSaveBackMode
= IsSaveBackgroundEnabled();
714 EnableSaveBackground();
716 // add FloatingWindow to list of windows that are in popup mode
717 ImplSVData
* pSVData
= ImplGetSVData();
718 mpNextFloat
= pSVData
->maWinData
.mpFirstFloat
;
719 pSVData
->maWinData
.mpFirstFloat
= this;
720 if( nFlags
& FLOATWIN_POPUPMODE_GRABFOCUS
)
722 // force key input even without focus (useful for menus)
723 mbGrabFocus
= sal_True
;
725 Show( sal_True
, SHOW_NOACTIVATE
);
728 // -----------------------------------------------------------------------
730 void FloatingWindow::StartPopupMode( ToolBox
* pBox
, sal_uLong nFlags
)
732 // get selected button
733 sal_uInt16 nItemId
= pBox
->GetDownItemId();
737 mpImplData
->mpBox
= pBox
;
738 pBox
->ImplFloatControl( sal_True
, this );
740 // retrieve some data from the ToolBox
741 Rectangle aRect
= pBox
->GetItemRect( nItemId
);
743 // convert to parent's screen coordinates
744 aPos
= GetParent()->OutputToScreenPixel( GetParent()->AbsoluteScreenToOutputPixel( pBox
->OutputToAbsoluteScreenPixel( aRect
.TopLeft() ) ) );
745 aRect
.SetPos( aPos
);
748 FLOATWIN_POPUPMODE_NOFOCUSCLOSE
|
749 // FLOATWIN_POPUPMODE_NOMOUSECLOSE |
750 FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE
|
751 // FLOATWIN_POPUPMODE_NOMOUSERECTCLOSE | // #105968# floating toolboxes should close when clicked in (parent's) float rect
752 FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE
;
753 // | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE;
756 * FLOATWIN_POPUPMODE_NOKEYCLOSE |
757 * don't set since it disables closing floaters with escape
760 // Flags fuer Positionierung bestimmen
761 if ( !(nFlags
& (FLOATWIN_POPUPMODE_DOWN
| FLOATWIN_POPUPMODE_UP
|
762 FLOATWIN_POPUPMODE_LEFT
| FLOATWIN_POPUPMODE_RIGHT
|
763 FLOATWIN_POPUPMODE_NOAUTOARRANGE
)) )
765 if ( pBox
->IsHorizontal() )
766 nFlags
|= FLOATWIN_POPUPMODE_DOWN
;
768 nFlags
|= FLOATWIN_POPUPMODE_RIGHT
;
771 // FloatingModus starten
772 StartPopupMode( aRect
, nFlags
);
775 // -----------------------------------------------------------------------
777 void FloatingWindow::ImplEndPopupMode( sal_uInt16 nFlags
, sal_uLong nFocusId
)
779 if ( !mbInPopupMode
)
782 ImplSVData
* pSVData
= ImplGetSVData();
784 mbInCleanUp
= sal_True
; // prevent killing this window due to focus change while working with it
786 // Bei allen nachfolgenden PopupMode-Fenster den Modus auch beenden
787 while ( pSVData
->maWinData
.mpFirstFloat
&& pSVData
->maWinData
.mpFirstFloat
!= this )
788 pSVData
->maWinData
.mpFirstFloat
->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
);
791 // Fenster aus der Liste austragen
792 pSVData
->maWinData
.mpFirstFloat
= mpNextFloat
;
795 sal_uLong nPopupModeFlags
= mnPopupModeFlags
;
797 // Wenn nicht abgerissen wurde, dann Fenster wieder Hiden
798 if ( !(nFlags
& FLOATWIN_POPUPMODEEND_TEAROFF
) ||
799 !(nPopupModeFlags
& FLOATWIN_POPUPMODE_ALLOWTEAROFF
) )
801 Show( sal_False
, SHOW_NOFOCUSCHANGE
);
803 // Focus evt. auf ein entsprechendes FloatingWindow weiterschalten
805 Window::EndSaveFocus( nFocusId
);
806 else if ( pSVData
->maWinData
.mpFocusWin
&& pSVData
->maWinData
.mpFirstFloat
&&
807 ImplIsWindowOrChild( pSVData
->maWinData
.mpFocusWin
) )
808 pSVData
->maWinData
.mpFirstFloat
->GrabFocus();
809 mbPopupModeTearOff
= sal_False
;
813 mbPopupModeTearOff
= sal_True
;
815 Window::EndSaveFocus( nFocusId
, sal_False
);
817 EnableSaveBackground( mbOldSaveBackMode
);
819 mbPopupModeCanceled
= (nFlags
& FLOATWIN_POPUPMODEEND_CANCEL
) != 0;
821 // Gegebenenfalls den Title wieder herstellen
822 SetTitleType( mnOldTitle
);
824 // ToolBox wieder auf normal schalten
825 if ( mpImplData
->mpBox
)
827 mpImplData
->mpBox
->ImplFloatControl( sal_False
, this );
828 mpImplData
->mpBox
= NULL
;
831 // Je nach Parameter den PopupModeEnd-Handler rufen
832 if ( !(nFlags
& FLOATWIN_POPUPMODEEND_DONTCALLHDL
) )
833 ImplCallPopupModeEnd();
835 // Je nach Parameter die restlichen Fenster auch noch schliessen
836 if ( nFlags
& FLOATWIN_POPUPMODEEND_CLOSEALL
)
838 if ( !(nPopupModeFlags
& FLOATWIN_POPUPMODE_NEWLEVEL
) )
840 if ( pSVData
->maWinData
.mpFirstFloat
)
842 FloatingWindow
* pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
843 pLastLevelFloat
->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
| FLOATWIN_POPUPMODEEND_CLOSEALL
);
848 mbInCleanUp
= sal_False
;
851 // -----------------------------------------------------------------------
853 void FloatingWindow::EndPopupMode( sal_uInt16 nFlags
)
855 ImplEndPopupMode( nFlags
);
858 // -----------------------------------------------------------------------
860 void FloatingWindow::AddPopupModeWindow( Window
* pWindow
)
862 // !!! bisher erst 1 Fenster und noch keine Liste
863 mpFirstPopupModeWin
= pWindow
;
866 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */