1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
33 #include <salframe.hxx>
35 #include <vcl/svapp.hxx>
36 #include <vcl/wrkwin.hxx>
37 #include <vcl/event.hxx>
38 #include <vcl/toolbox.hxx>
39 #include <vcl/floatwin.hxx>
42 #include <tools/debug.hxx>
45 // =======================================================================
47 class FloatingWindow::ImplData
54 Rectangle maItemEdgeClipRect
; // used to clip the common edge between a toolbar item and the border of this window
57 FloatingWindow::ImplData::ImplData()
62 FloatingWindow::ImplData::~ImplData()
66 Rectangle
& FloatingWindow::ImplGetItemEdgeClipRect()
68 return mpImplData
->maItemEdgeClipRect
;
71 // =======================================================================
73 void FloatingWindow::ImplInit( Window
* pParent
, WinBits nStyle
)
75 mpImplData
= new ImplData
;
77 mpWindowImpl
->mbFloatWin
= sal_True
;
78 mbInCleanUp
= sal_False
;
79 mbGrabFocus
= sal_False
;
81 DBG_ASSERT( pParent
, "FloatWindow::FloatingWindow(): - pParent == NULL!" );
84 pParent
= ImplGetSVData()->maWinData
.mpAppWin
;
86 DBG_ASSERT( pParent
, "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists" );
88 // no Border, then we dont need a border window
91 mpWindowImpl
->mbOverlapWin
= sal_True
;
92 nStyle
|= WB_DIALOGCONTROL
;
93 SystemWindow::ImplInit( pParent
, nStyle
, NULL
);
97 if ( !(nStyle
& WB_NODIALOGCONTROL
) )
98 nStyle
|= WB_DIALOGCONTROL
;
100 if( nStyle
& (WB_MOVEABLE
| WB_SIZEABLE
| WB_ROLLABLE
| WB_CLOSEABLE
| WB_STANDALONE
)
101 && !(nStyle
& WB_OWNERDRAWDECORATION
) )
103 WinBits nFloatWinStyle
= nStyle
;
104 // #99154# floaters are not closeable by default anymore, eg fullscreen floater
105 // nFloatWinStyle |= WB_CLOSEABLE;
106 mpWindowImpl
->mbFrame
= sal_True
;
107 mpWindowImpl
->mbOverlapWin
= sal_True
;
108 SystemWindow::ImplInit( pParent
, nFloatWinStyle
& ~WB_BORDER
, NULL
);
112 ImplBorderWindow
* pBorderWin
;
113 sal_uInt16 nBorderStyle
= BORDERWINDOW_STYLE_BORDER
| BORDERWINDOW_STYLE_FLOAT
;
115 if( nStyle
& WB_OWNERDRAWDECORATION
) nBorderStyle
|= BORDERWINDOW_STYLE_FRAME
;
116 else nBorderStyle
|= BORDERWINDOW_STYLE_OVERLAP
;
118 if ( (nStyle
& WB_SYSTEMWINDOW
) && !(nStyle
& (WB_MOVEABLE
| WB_SIZEABLE
)) )
120 nBorderStyle
|= BORDERWINDOW_STYLE_FRAME
;
121 nStyle
|= WB_CLOSEABLE
; // make undecorated floaters closeable
123 pBorderWin
= new ImplBorderWindow( pParent
, nStyle
, nBorderStyle
);
124 SystemWindow::ImplInit( pBorderWin
, nStyle
& ~WB_BORDER
, NULL
);
125 pBorderWin
->mpWindowImpl
->mpClientWindow
= this;
126 pBorderWin
->GetBorder( mpWindowImpl
->mnLeftBorder
, mpWindowImpl
->mnTopBorder
, mpWindowImpl
->mnRightBorder
, mpWindowImpl
->mnBottomBorder
);
127 pBorderWin
->SetDisplayActive( sal_True
);
128 mpWindowImpl
->mpBorderWindow
= pBorderWin
;
129 mpWindowImpl
->mpRealParent
= pParent
;
132 SetActivateMode( 0 );
135 mpFirstPopupModeWin
= NULL
;
137 mnTitle
= (nStyle
& (WB_MOVEABLE
| WB_POPUP
)) ? FLOATWIN_TITLE_NORMAL
: FLOATWIN_TITLE_NONE
;
138 mnOldTitle
= mnTitle
;
139 mnPopupModeFlags
= 0;
140 mbInPopupMode
= sal_False
;
141 mbPopupMode
= sal_False
;
142 mbPopupModeCanceled
= sal_False
;
143 mbPopupModeTearOff
= sal_False
;
144 mbMouseDown
= sal_False
;
149 // -----------------------------------------------------------------------
151 void FloatingWindow::ImplInitSettings()
153 const StyleSettings
& rStyleSettings
= GetSettings().GetStyleSettings();
156 if ( IsControlBackground() )
157 aColor
= GetControlBackground();
158 else if ( Window::GetStyle() & WB_3DLOOK
)
159 aColor
= rStyleSettings
.GetFaceColor();
161 aColor
= rStyleSettings
.GetWindowColor();
162 SetBackground( aColor
);
165 // =======================================================================
167 FloatingWindow::FloatingWindow( Window
* pParent
, WinBits nStyle
) :
168 SystemWindow( WINDOW_FLOATINGWINDOW
)
170 ImplInit( pParent
, nStyle
);
173 // -----------------------------------------------------------------------
175 FloatingWindow::FloatingWindow( Window
* pParent
, const ResId
& rResId
) :
176 SystemWindow( WINDOW_FLOATINGWINDOW
)
178 rResId
.SetRT( RSC_FLOATINGWINDOW
);
179 WinBits nStyle
= ImplInitRes( rResId
);
180 ImplInit( pParent
, nStyle
);
181 ImplLoadRes( rResId
);
183 if ( !(nStyle
& WB_HIDE
) )
187 // -----------------------------------------------------------------------
189 void FloatingWindow::ImplLoadRes( const ResId
& rResId
)
191 SystemWindow::ImplLoadRes( rResId
);
193 sal_uLong nObjMask
= ReadLongRes();
195 if ( (RSC_FLOATINGWINDOW_WHMAPMODE
| RSC_FLOATINGWINDOW_WIDTH
|
196 RSC_FLOATINGWINDOW_HEIGHT
) & nObjMask
)
198 // Groessenangabe aus der Resource verwenden
200 MapUnit eSizeMap
= MAP_PIXEL
;
202 if ( RSC_FLOATINGWINDOW_WHMAPMODE
& nObjMask
)
203 eSizeMap
= (MapUnit
) ReadShortRes();
204 if ( RSC_FLOATINGWINDOW_WIDTH
& nObjMask
)
205 aSize
.Width() = ReadShortRes();
206 if ( RSC_FLOATINGWINDOW_HEIGHT
& nObjMask
)
207 aSize
.Height() = ReadShortRes();
209 SetRollUpOutputSizePixel( LogicToPixel( aSize
, eSizeMap
) );
212 if (nObjMask
& RSC_FLOATINGWINDOW_ZOOMIN
)
214 if ( ReadShortRes() )
219 // -----------------------------------------------------------------------
221 FloatingWindow::~FloatingWindow()
223 if( mbPopupModeCanceled
)
224 // indicates that ESC key was pressed
225 // will be handled in Window::ImplGrabFocus()
226 SetDialogControlFlags( GetDialogControlFlags() | WINDOW_DLGCTRL_FLOATWIN_POPUPMODEEND_CANCEL
);
228 if ( IsInPopupMode() )
229 EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
| FLOATWIN_POPUPMODEEND_CLOSEALL
| FLOATWIN_POPUPMODEEND_DONTCALLHDL
);
232 Application::RemoveUserEvent( mnPostId
);
237 // -----------------------------------------------------------------------
239 Point
FloatingWindow::CalcFloatingPosition( Window
* pWindow
, const Rectangle
& rRect
, sal_uLong nFlags
, sal_uInt16
& rArrangeIndex
)
241 return ImplCalcPos( pWindow
, rRect
, nFlags
, rArrangeIndex
);
244 // -----------------------------------------------------------------------
246 Point
FloatingWindow::ImplCalcPos( Window
* pWindow
,
247 const Rectangle
& rRect
, sal_uLong nFlags
,
248 sal_uInt16
& rArrangeIndex
)
250 // Fenster-Position ermitteln
252 Size aSize
= pWindow
->GetSizePixel();
253 Rectangle aScreenRect
= pWindow
->ImplGetFrameWindow()->GetDesktopRectPixel();
254 FloatingWindow
*pFloatingWindow
= dynamic_cast<FloatingWindow
*>( pWindow
);
257 Window
* pW
= pWindow
;
258 if ( pW
->mpWindowImpl
->mpRealParent
)
259 pW
= pW
->mpWindowImpl
->mpRealParent
;
261 Rectangle
normRect( rRect
); // rRect is already relative to top-level window
262 normRect
.SetPos( pW
->ScreenToOutputPixel( normRect
.TopLeft() ) );
264 sal_Bool bRTL
= Application::GetSettings().GetLayoutRTL();
266 Rectangle
devRect( pW
->OutputToAbsoluteScreenPixel( normRect
.TopLeft() ),
267 pW
->OutputToAbsoluteScreenPixel( normRect
.BottomRight() ) );
269 Rectangle
devRectRTL( devRect
);
271 // create a rect that can be compared to desktop coordinates
272 devRectRTL
= pW
->ImplOutputToUnmirroredAbsoluteScreenPixel( normRect
);
273 if( Application::GetScreenCount() > 1 && Application::IsUnifiedDisplay() )
274 aScreenRect
= Application::GetScreenPosSizePixel(
275 Application::GetBestScreen( bRTL
? devRectRTL
: devRect
) );
278 sal_uInt16 nArrangeAry
[5];
279 sal_uInt16 nArrangeIndex
;
281 Point e1
,e2
; // the common edge between the item rect and the floating window
283 if ( nFlags
& FLOATWIN_POPUPMODE_LEFT
)
285 nArrangeAry
[0] = FLOATWIN_POPUPMODE_LEFT
;
286 nArrangeAry
[1] = FLOATWIN_POPUPMODE_RIGHT
;
287 nArrangeAry
[2] = FLOATWIN_POPUPMODE_UP
;
288 nArrangeAry
[3] = FLOATWIN_POPUPMODE_DOWN
;
289 nArrangeAry
[4] = FLOATWIN_POPUPMODE_LEFT
;
291 else if ( nFlags
& FLOATWIN_POPUPMODE_RIGHT
)
293 nArrangeAry
[0] = FLOATWIN_POPUPMODE_RIGHT
;
294 nArrangeAry
[1] = FLOATWIN_POPUPMODE_LEFT
;
295 nArrangeAry
[2] = FLOATWIN_POPUPMODE_UP
;
296 nArrangeAry
[3] = FLOATWIN_POPUPMODE_DOWN
;
297 nArrangeAry
[4] = FLOATWIN_POPUPMODE_RIGHT
;
299 else if ( nFlags
& FLOATWIN_POPUPMODE_UP
)
301 nArrangeAry
[0] = FLOATWIN_POPUPMODE_UP
;
302 nArrangeAry
[1] = FLOATWIN_POPUPMODE_DOWN
;
303 nArrangeAry
[2] = FLOATWIN_POPUPMODE_RIGHT
;
304 nArrangeAry
[3] = FLOATWIN_POPUPMODE_LEFT
;
305 nArrangeAry
[4] = FLOATWIN_POPUPMODE_UP
;
309 nArrangeAry
[0] = FLOATWIN_POPUPMODE_DOWN
;
310 nArrangeAry
[1] = FLOATWIN_POPUPMODE_UP
;
311 nArrangeAry
[2] = FLOATWIN_POPUPMODE_RIGHT
;
312 nArrangeAry
[3] = FLOATWIN_POPUPMODE_LEFT
;
313 nArrangeAry
[4] = FLOATWIN_POPUPMODE_DOWN
;
315 if ( nFlags
& FLOATWIN_POPUPMODE_NOAUTOARRANGE
)
320 for ( ; nArrangeIndex
< 5; nArrangeIndex
++ )
323 switch ( nArrangeAry
[nArrangeIndex
] )
326 case FLOATWIN_POPUPMODE_LEFT
:
327 aPos
.X() = devRect
.Left()-aSize
.Width()+1;
328 aPos
.Y() = devRect
.Top();
329 aPos
.Y() -= pWindow
->mpWindowImpl
->mnTopBorder
;
330 if( bRTL
) // --- RTL --- we're comparing screen coordinates here
332 if( (devRectRTL
.Right()+aSize
.Width()) > aScreenRect
.Right() )
337 if ( aPos
.X() < aScreenRect
.Left() )
342 e1
= devRect
.TopLeft();
343 e2
= devRect
.BottomLeft();
344 // set non-zero width
346 // don't clip corners
351 case FLOATWIN_POPUPMODE_RIGHT
:
352 aPos
= devRect
.TopRight();
353 aPos
.Y() -= pWindow
->mpWindowImpl
->mnTopBorder
;
354 if( bRTL
) // --- RTL --- we're comparing screen coordinates here
356 if( (devRectRTL
.Left() - aSize
.Width()) < aScreenRect
.Left() )
361 if ( aPos
.X()+aSize
.Width() > aScreenRect
.Right() )
366 e1
= devRect
.TopRight();
367 e2
= devRect
.BottomRight();
368 // set non-zero width
370 // don't clip corners
375 case FLOATWIN_POPUPMODE_UP
:
376 aPos
.X() = devRect
.Left();
377 aPos
.Y() = devRect
.Top()-aSize
.Height()+1;
378 if ( aPos
.Y() < aScreenRect
.Top() )
382 e1
= devRect
.TopLeft();
383 e2
= devRect
.TopRight();
384 // set non-zero height
386 // don't clip corners
391 case FLOATWIN_POPUPMODE_DOWN
:
392 aPos
= devRect
.BottomLeft();
393 if ( aPos
.Y()+aSize
.Height() > aScreenRect
.Bottom() )
397 e1
= devRect
.BottomLeft();
398 e2
= devRect
.BottomRight();
399 // set non-zero height
401 // don't clip corners
408 // Evt. noch anpassen
409 if ( bBreak
&& !(nFlags
& FLOATWIN_POPUPMODE_NOAUTOARRANGE
) )
411 if ( (nArrangeAry
[nArrangeIndex
] == FLOATWIN_POPUPMODE_LEFT
) ||
412 (nArrangeAry
[nArrangeIndex
] == FLOATWIN_POPUPMODE_RIGHT
) )
414 if ( aPos
.Y()+aSize
.Height() > aScreenRect
.Bottom() )
416 aPos
.Y() = devRect
.Bottom()-aSize
.Height()+1;
417 if ( aPos
.Y() < aScreenRect
.Top() )
418 aPos
.Y() = aScreenRect
.Top();
423 if( bRTL
) // --- RTL --- we're comparing screen coordinates here
425 if( devRectRTL
.Right()-aSize
.Width()+1 < aScreenRect
.Left() )
426 aPos
.X() -= aScreenRect
.Left() - devRectRTL
.Right() + aSize
.Width() - 1;
428 else if ( aPos
.X()+aSize
.Width() > aScreenRect
.Right() )
430 aPos
.X() = devRect
.Right()-aSize
.Width()+1;
431 if ( aPos
.X() < aScreenRect
.Left() )
432 aPos
.X() = aScreenRect
.Left();
440 if ( nArrangeIndex
> 4 )
443 rArrangeIndex
= nArrangeIndex
;
445 aPos
= pW
->AbsoluteScreenToOutputPixel( aPos
);
447 // store a cliprect that can be used to clip the common edge of the itemrect and the floating window
448 if( pFloatingWindow
)
450 pFloatingWindow
->mpImplData
->maItemEdgeClipRect
=
454 // caller expects cordinates relative to top-level win
455 return pW
->OutputToScreenPixel( aPos
);
458 // -----------------------------------------------------------------------
460 FloatingWindow
* FloatingWindow::ImplFloatHitTest( Window
* pReference
, const Point
& rPos
, sal_uInt16
& rHitTest
)
462 FloatingWindow
* pWin
= this;
464 Point
aAbsolute( rPos
);
466 // compare coordinates in absolute screen coordinates
467 if( pReference
->ImplHasMirroredGraphics() )
469 if(!pReference
->IsRTLEnabled() )
470 // --- RTL --- re-mirror back to get device coordiantes
471 pReference
->ImplReMirror( aAbsolute
);
473 Rectangle
aRect( pReference
->ScreenToOutputPixel(aAbsolute
), Size(1,1) ) ;
474 aRect
= pReference
->ImplOutputToUnmirroredAbsoluteScreenPixel( aRect
);
475 aAbsolute
= aRect
.TopLeft();
478 aAbsolute
= Point( pReference
->OutputToAbsoluteScreenPixel(
479 pReference
->ScreenToOutputPixel(rPos
) ) );
483 // compute the floating window's size in absolute screen coordinates
485 // use the border window to have the exact position
486 Window
*pBorderWin
= pWin
->GetWindow( WINDOW_BORDER
);
488 Point aPt
; // the top-left corner in output coordinates ie (0,0)
489 Rectangle
devRect( pBorderWin
->ImplOutputToUnmirroredAbsoluteScreenPixel( Rectangle( aPt
, pBorderWin
->GetSizePixel()) ) ) ;
490 if ( devRect
.IsInside( aAbsolute
) )
492 rHitTest
= IMPL_FLOATWIN_HITTEST_WINDOW
;
496 // test, if mouse is in rectangle, (this is typically the rect of the active
497 // toolbox item or similar)
498 // note: maFloatRect is set in FloatingWindow::StartPopupMode() and
499 // is already in absolute device coordinates
500 if ( pWin
->maFloatRect
.IsInside( aAbsolute
) )
502 rHitTest
= IMPL_FLOATWIN_HITTEST_RECT
;
506 pWin
= pWin
->mpNextFloat
;
510 rHitTest
= IMPL_FLOATWIN_HITTEST_OUTSIDE
;
514 // -----------------------------------------------------------------------
516 FloatingWindow
* FloatingWindow::ImplFindLastLevelFloat()
518 FloatingWindow
* pWin
= this;
519 FloatingWindow
* pLastFoundWin
= pWin
;
523 if ( pWin
->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NEWLEVEL
)
524 pLastFoundWin
= pWin
;
526 pWin
= pWin
->mpNextFloat
;
530 return pLastFoundWin
;
533 // -----------------------------------------------------------------------
535 sal_Bool
FloatingWindow::ImplIsFloatPopupModeWindow( const Window
* pWindow
)
537 FloatingWindow
* pWin
= this;
541 if ( pWin
->mpFirstPopupModeWin
== pWindow
)
544 pWin
= pWin
->mpNextFloat
;
551 // -----------------------------------------------------------------------
553 IMPL_LINK_NOARG(FloatingWindow
, ImplEndPopupModeHdl
)
556 mnPopupModeFlags
= 0;
557 mbPopupMode
= sal_False
;
562 // -----------------------------------------------------------------------
564 long FloatingWindow::Notify( NotifyEvent
& rNEvt
)
566 // Zuerst Basisklasse rufen wegen TabSteuerung
567 long nRet
= SystemWindow::Notify( rNEvt
);
570 if ( rNEvt
.GetType() == EVENT_KEYINPUT
)
572 const KeyEvent
* pKEvt
= rNEvt
.GetKeyEvent();
573 KeyCode aKeyCode
= pKEvt
->GetKeyCode();
574 sal_uInt16 nKeyCode
= aKeyCode
.GetCode();
576 if ( (nKeyCode
== KEY_ESCAPE
) && (GetStyle() & WB_CLOSEABLE
) )
587 // -----------------------------------------------------------------------
589 void FloatingWindow::StateChanged( StateChangedType nType
)
591 SystemWindow::StateChanged( nType
);
593 if ( nType
== STATE_CHANGE_CONTROLBACKGROUND
)
600 // -----------------------------------------------------------------------
602 void FloatingWindow::DataChanged( const DataChangedEvent
& rDCEvt
)
604 SystemWindow::DataChanged( rDCEvt
);
606 if ( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) &&
607 (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
614 // -----------------------------------------------------------------------
616 void FloatingWindow::ImplCallPopupModeEnd()
618 // PopupMode wurde beendet
619 mbInPopupMode
= sal_False
;
621 // Handler asyncron rufen
623 Application::PostUserEvent( mnPostId
, LINK( this, FloatingWindow
, ImplEndPopupModeHdl
) );
626 // -----------------------------------------------------------------------
628 void FloatingWindow::PopupModeEnd()
630 maPopupModeEndHdl
.Call( this );
633 // -----------------------------------------------------------------------
635 void FloatingWindow::SetTitleType( sal_uInt16 nTitle
)
637 if ( (mnTitle
!= nTitle
) && mpWindowImpl
->mpBorderWindow
)
640 Size aOutSize
= GetOutputSizePixel();
641 sal_uInt16 nTitleStyle
;
642 if ( nTitle
== FLOATWIN_TITLE_NORMAL
)
643 nTitleStyle
= BORDERWINDOW_TITLE_SMALL
;
644 else if ( nTitle
== FLOATWIN_TITLE_TEAROFF
)
645 nTitleStyle
= BORDERWINDOW_TITLE_TEAROFF
;
646 else if ( nTitle
== FLOATWIN_TITLE_POPUP
)
647 nTitleStyle
= BORDERWINDOW_TITLE_POPUP
;
648 else // nTitle == FLOATWIN_TITLE_NONE
649 nTitleStyle
= BORDERWINDOW_TITLE_NONE
;
650 ((ImplBorderWindow
*)mpWindowImpl
->mpBorderWindow
)->SetTitleType( nTitleStyle
, aOutSize
);
651 ((ImplBorderWindow
*)mpWindowImpl
->mpBorderWindow
)->GetBorder( mpWindowImpl
->mnLeftBorder
, mpWindowImpl
->mnTopBorder
, mpWindowImpl
->mnRightBorder
, mpWindowImpl
->mnBottomBorder
);
655 // -----------------------------------------------------------------------
657 void FloatingWindow::StartPopupMode( const Rectangle
& rRect
, sal_uLong nFlags
)
661 Show( sal_False
, SHOW_NOFOCUSCHANGE
);
667 mnOldTitle
= mnTitle
;
668 if ( ( mpWindowImpl
->mnStyle
& WB_POPUP
) && GetText().Len() )
669 SetTitleType( FLOATWIN_TITLE_POPUP
);
670 else if ( nFlags
& FLOATWIN_POPUPMODE_ALLOWTEAROFF
)
671 SetTitleType( FLOATWIN_TITLE_TEAROFF
);
673 SetTitleType( FLOATWIN_TITLE_NONE
);
675 // avoid close on focus change for decorated floating windows only
676 if( mpWindowImpl
->mbFrame
&& (GetStyle() & WB_MOVEABLE
) )
677 nFlags
|= FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE
;
679 // #102010# For debugging Accessibility
680 static const char* pEnv
= getenv("SAL_FLOATWIN_NOAPPFOCUSCLOSE" );
682 nFlags
|= FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE
;
684 // compute window position according to flags and arrangement
685 sal_uInt16 nArrangeIndex
;
686 Point aPos
= ImplCalcPos( this, rRect
, nFlags
, nArrangeIndex
);
689 // set data and display window
690 // convert maFloatRect to absolute device coordinates
691 // so they can be compared across different frames
692 // !!! rRect is expected to be in screen coordinates of the parent frame window !!!
695 Window
*pReference
= GetParent();
697 // compare coordinates in absolute screen coordinates
698 // Keep in sync with FloatingWindow::ImplFloatHitTest, e.g. fdo#33509
699 if( pReference
->ImplHasMirroredGraphics() )
701 if(!pReference
->IsRTLEnabled() )
702 // --- RTL --- re-mirror back to get device coordiantes
703 pReference
->ImplReMirror(maFloatRect
);
705 maFloatRect
.SetPos(pReference
->ScreenToOutputPixel(maFloatRect
.TopLeft()));
706 maFloatRect
= pReference
->ImplOutputToUnmirroredAbsoluteScreenPixel(maFloatRect
);
709 maFloatRect
.SetPos(pReference
->OutputToAbsoluteScreenPixel(pReference
->ScreenToOutputPixel(rRect
.TopLeft())));
711 maFloatRect
.Left() -= 2;
712 maFloatRect
.Top() -= 2;
713 maFloatRect
.Right() += 2;
714 maFloatRect
.Bottom() += 2;
715 mnPopupModeFlags
= nFlags
;
716 mbInPopupMode
= sal_True
;
717 mbPopupMode
= sal_True
;
718 mbPopupModeCanceled
= sal_False
;
719 mbPopupModeTearOff
= sal_False
;
720 mbMouseDown
= sal_False
;
722 mbOldSaveBackMode
= IsSaveBackgroundEnabled();
723 EnableSaveBackground();
725 // add FloatingWindow to list of windows that are in popup mode
726 ImplSVData
* pSVData
= ImplGetSVData();
727 mpNextFloat
= pSVData
->maWinData
.mpFirstFloat
;
728 pSVData
->maWinData
.mpFirstFloat
= this;
729 if( nFlags
& FLOATWIN_POPUPMODE_GRABFOCUS
)
731 // force key input even without focus (useful for menus)
732 mbGrabFocus
= sal_True
;
734 Show( sal_True
, SHOW_NOACTIVATE
);
737 // -----------------------------------------------------------------------
739 void FloatingWindow::StartPopupMode( ToolBox
* pBox
, sal_uLong nFlags
)
741 // get selected button
742 sal_uInt16 nItemId
= pBox
->GetDownItemId();
746 mpImplData
->mpBox
= pBox
;
747 pBox
->ImplFloatControl( sal_True
, this );
749 // retrieve some data from the ToolBox
750 Rectangle aRect
= pBox
->GetItemRect( nItemId
);
752 // convert to parent's screen coordinates
753 aPos
= GetParent()->OutputToScreenPixel( GetParent()->AbsoluteScreenToOutputPixel( pBox
->OutputToAbsoluteScreenPixel( aRect
.TopLeft() ) ) );
754 aRect
.SetPos( aPos
);
757 FLOATWIN_POPUPMODE_NOFOCUSCLOSE
|
758 // FLOATWIN_POPUPMODE_NOMOUSECLOSE |
759 FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE
|
760 // FLOATWIN_POPUPMODE_NOMOUSERECTCLOSE | // #105968# floating toolboxes should close when clicked in (parent's) float rect
761 FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE
;
762 // | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE;
765 * FLOATWIN_POPUPMODE_NOKEYCLOSE |
766 * don't set since it disables closing floaters with escape
769 // Flags fuer Positionierung bestimmen
770 if ( !(nFlags
& (FLOATWIN_POPUPMODE_DOWN
| FLOATWIN_POPUPMODE_UP
|
771 FLOATWIN_POPUPMODE_LEFT
| FLOATWIN_POPUPMODE_RIGHT
|
772 FLOATWIN_POPUPMODE_NOAUTOARRANGE
)) )
774 if ( pBox
->IsHorizontal() )
775 nFlags
|= FLOATWIN_POPUPMODE_DOWN
;
777 nFlags
|= FLOATWIN_POPUPMODE_RIGHT
;
780 // FloatingModus starten
781 StartPopupMode( aRect
, nFlags
);
784 // -----------------------------------------------------------------------
786 void FloatingWindow::ImplEndPopupMode( sal_uInt16 nFlags
, sal_uLong nFocusId
)
788 if ( !mbInPopupMode
)
791 ImplSVData
* pSVData
= ImplGetSVData();
793 mbInCleanUp
= sal_True
; // prevent killing this window due to focus change while working with it
795 // Bei allen nachfolgenden PopupMode-Fenster den Modus auch beenden
796 while ( pSVData
->maWinData
.mpFirstFloat
&& pSVData
->maWinData
.mpFirstFloat
!= this )
797 pSVData
->maWinData
.mpFirstFloat
->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
);
800 // Fenster aus der Liste austragen
801 pSVData
->maWinData
.mpFirstFloat
= mpNextFloat
;
804 sal_uLong nPopupModeFlags
= mnPopupModeFlags
;
806 // Wenn nicht abgerissen wurde, dann Fenster wieder Hiden
807 if ( !(nFlags
& FLOATWIN_POPUPMODEEND_TEAROFF
) ||
808 !(nPopupModeFlags
& FLOATWIN_POPUPMODE_ALLOWTEAROFF
) )
810 Show( sal_False
, SHOW_NOFOCUSCHANGE
);
812 // Focus evt. auf ein entsprechendes FloatingWindow weiterschalten
814 Window::EndSaveFocus( nFocusId
);
815 else if ( pSVData
->maWinData
.mpFocusWin
&& pSVData
->maWinData
.mpFirstFloat
&&
816 ImplIsWindowOrChild( pSVData
->maWinData
.mpFocusWin
) )
817 pSVData
->maWinData
.mpFirstFloat
->GrabFocus();
818 mbPopupModeTearOff
= sal_False
;
822 mbPopupModeTearOff
= sal_True
;
824 Window::EndSaveFocus( nFocusId
, sal_False
);
826 EnableSaveBackground( mbOldSaveBackMode
);
828 mbPopupModeCanceled
= (nFlags
& FLOATWIN_POPUPMODEEND_CANCEL
) != 0;
830 // Gegebenenfalls den Title wieder herstellen
831 SetTitleType( mnOldTitle
);
833 // ToolBox wieder auf normal schalten
834 if ( mpImplData
->mpBox
)
836 mpImplData
->mpBox
->ImplFloatControl( sal_False
, this );
837 mpImplData
->mpBox
= NULL
;
840 // Je nach Parameter den PopupModeEnd-Handler rufen
841 if ( !(nFlags
& FLOATWIN_POPUPMODEEND_DONTCALLHDL
) )
842 ImplCallPopupModeEnd();
844 // Je nach Parameter die restlichen Fenster auch noch schliessen
845 if ( nFlags
& FLOATWIN_POPUPMODEEND_CLOSEALL
)
847 if ( !(nPopupModeFlags
& FLOATWIN_POPUPMODE_NEWLEVEL
) )
849 if ( pSVData
->maWinData
.mpFirstFloat
)
851 FloatingWindow
* pLastLevelFloat
= pSVData
->maWinData
.mpFirstFloat
->ImplFindLastLevelFloat();
852 pLastLevelFloat
->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL
| FLOATWIN_POPUPMODEEND_CLOSEALL
);
857 mbInCleanUp
= sal_False
;
860 // -----------------------------------------------------------------------
862 void FloatingWindow::EndPopupMode( sal_uInt16 nFlags
)
864 ImplEndPopupMode( nFlags
);
867 // -----------------------------------------------------------------------
869 void FloatingWindow::AddPopupModeWindow( Window
* pWindow
)
871 // !!! bisher erst 1 Fenster und noch keine Liste
872 mpFirstPopupModeWin
= pWindow
;
875 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */