xref: /AOO41X/main/vcl/source/window/floatwin.cxx (revision 9f62ea84a806e17e6f2bbff75724a7257a0eb5d9)
1*9f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9f62ea84SAndrew Rist  * distributed with this work for additional information
6*9f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
9*9f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*9f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*9f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9f62ea84SAndrew Rist  * software distributed under the License is distributed on an
15*9f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
17*9f62ea84SAndrew Rist  * specific language governing permissions and limitations
18*9f62ea84SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*9f62ea84SAndrew Rist  *************************************************************/
21*9f62ea84SAndrew Rist 
22*9f62ea84SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <svdata.hxx>
28cdf0e10cSrcweir #include <brdwin.hxx>
29cdf0e10cSrcweir #include <window.h>
30cdf0e10cSrcweir #include <salframe.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <vcl/svapp.hxx>
33cdf0e10cSrcweir #include <vcl/wrkwin.hxx>
34cdf0e10cSrcweir #include <vcl/event.hxx>
35cdf0e10cSrcweir #include <vcl/toolbox.hxx>
36cdf0e10cSrcweir #include <vcl/floatwin.hxx>
37cdf0e10cSrcweir 
38cdf0e10cSrcweir #include <tools/rc.h>
39cdf0e10cSrcweir #include <tools/debug.hxx>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir 
42cdf0e10cSrcweir // =======================================================================
43cdf0e10cSrcweir 
44cdf0e10cSrcweir class FloatingWindow::ImplData
45cdf0e10cSrcweir {
46cdf0e10cSrcweir public:
47cdf0e10cSrcweir     ImplData();
48cdf0e10cSrcweir     ~ImplData();
49cdf0e10cSrcweir 
50cdf0e10cSrcweir 	ToolBox* 		mpBox;
51cdf0e10cSrcweir 	Rectangle		maItemEdgeClipRect; // used to clip the common edge between a toolbar item and the border of this window
52cdf0e10cSrcweir };
53cdf0e10cSrcweir 
ImplData()54cdf0e10cSrcweir FloatingWindow::ImplData::ImplData()
55cdf0e10cSrcweir {
56cdf0e10cSrcweir     mpBox = NULL;
57cdf0e10cSrcweir }
58cdf0e10cSrcweir 
~ImplData()59cdf0e10cSrcweir FloatingWindow::ImplData::~ImplData()
60cdf0e10cSrcweir {
61cdf0e10cSrcweir }
62cdf0e10cSrcweir 
ImplGetItemEdgeClipRect()63cdf0e10cSrcweir Rectangle& FloatingWindow::ImplGetItemEdgeClipRect()
64cdf0e10cSrcweir {
65cdf0e10cSrcweir     return mpImplData->maItemEdgeClipRect;
66cdf0e10cSrcweir }
67cdf0e10cSrcweir 
68cdf0e10cSrcweir // =======================================================================
69cdf0e10cSrcweir 
ImplInit(Window * pParent,WinBits nStyle)70cdf0e10cSrcweir void FloatingWindow::ImplInit( Window* pParent, WinBits nStyle )
71cdf0e10cSrcweir {
72cdf0e10cSrcweir     mpImplData = new ImplData;
73cdf0e10cSrcweir 
74cdf0e10cSrcweir     mpWindowImpl->mbFloatWin = sal_True;
75cdf0e10cSrcweir     mbInCleanUp = sal_False;
76cdf0e10cSrcweir     mbGrabFocus = sal_False;
77cdf0e10cSrcweir 
78cdf0e10cSrcweir     DBG_ASSERT( pParent, "FloatWindow::FloatingWindow(): - pParent == NULL!" );
79cdf0e10cSrcweir 
80cdf0e10cSrcweir     if ( !pParent )
81cdf0e10cSrcweir         pParent = ImplGetSVData()->maWinData.mpAppWin;
82cdf0e10cSrcweir 
83cdf0e10cSrcweir     DBG_ASSERT( pParent, "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists" );
84cdf0e10cSrcweir 
85cdf0e10cSrcweir     // no Border, then we dont need a border window
86cdf0e10cSrcweir     if ( !nStyle )
87cdf0e10cSrcweir     {
88cdf0e10cSrcweir         mpWindowImpl->mbOverlapWin = sal_True;
89cdf0e10cSrcweir         nStyle |= WB_DIALOGCONTROL;
90cdf0e10cSrcweir         SystemWindow::ImplInit( pParent, nStyle, NULL );
91cdf0e10cSrcweir     }
92cdf0e10cSrcweir     else
93cdf0e10cSrcweir     {
94cdf0e10cSrcweir         if ( !(nStyle & WB_NODIALOGCONTROL) )
95cdf0e10cSrcweir             nStyle |= WB_DIALOGCONTROL;
96cdf0e10cSrcweir 
97cdf0e10cSrcweir         if( nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_CLOSEABLE | WB_STANDALONE)
98cdf0e10cSrcweir             && !(nStyle & WB_OWNERDRAWDECORATION) )
99cdf0e10cSrcweir         {
100cdf0e10cSrcweir             WinBits nFloatWinStyle = nStyle;
101cdf0e10cSrcweir             // #99154# floaters are not closeable by default anymore, eg fullscreen floater
102cdf0e10cSrcweir             // nFloatWinStyle |= WB_CLOSEABLE;
103cdf0e10cSrcweir             mpWindowImpl->mbFrame = sal_True;
104cdf0e10cSrcweir             mpWindowImpl->mbOverlapWin = sal_True;
105cdf0e10cSrcweir             SystemWindow::ImplInit( pParent, nFloatWinStyle & ~WB_BORDER, NULL );
106cdf0e10cSrcweir         }
107cdf0e10cSrcweir         else
108cdf0e10cSrcweir         {
109cdf0e10cSrcweir             ImplBorderWindow*   pBorderWin;
110cdf0e10cSrcweir             sal_uInt16              nBorderStyle = BORDERWINDOW_STYLE_BORDER | BORDERWINDOW_STYLE_FLOAT;
111cdf0e10cSrcweir 
112cdf0e10cSrcweir             if( nStyle & WB_OWNERDRAWDECORATION ) nBorderStyle |= BORDERWINDOW_STYLE_FRAME;
113cdf0e10cSrcweir             else                                  nBorderStyle |= BORDERWINDOW_STYLE_OVERLAP;
114cdf0e10cSrcweir 
115cdf0e10cSrcweir             if ( (nStyle & WB_SYSTEMWINDOW) && !(nStyle & (WB_MOVEABLE | WB_SIZEABLE)) )
116cdf0e10cSrcweir             {
117cdf0e10cSrcweir                 nBorderStyle |= BORDERWINDOW_STYLE_FRAME;
118cdf0e10cSrcweir                 nStyle |= WB_CLOSEABLE; // make undecorated floaters closeable
119cdf0e10cSrcweir             }
120cdf0e10cSrcweir             pBorderWin  = new ImplBorderWindow( pParent, nStyle, nBorderStyle );
121cdf0e10cSrcweir             SystemWindow::ImplInit( pBorderWin, nStyle & ~WB_BORDER, NULL );
122cdf0e10cSrcweir             pBorderWin->mpWindowImpl->mpClientWindow = this;
123cdf0e10cSrcweir             pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
124cdf0e10cSrcweir             pBorderWin->SetDisplayActive( sal_True );
125cdf0e10cSrcweir             mpWindowImpl->mpBorderWindow  = pBorderWin;
126cdf0e10cSrcweir             mpWindowImpl->mpRealParent    = pParent;
127cdf0e10cSrcweir         }
128cdf0e10cSrcweir     }
129cdf0e10cSrcweir     SetActivateMode( 0 );
130cdf0e10cSrcweir 
131cdf0e10cSrcweir     mpNextFloat             = NULL;
132cdf0e10cSrcweir     mpFirstPopupModeWin     = NULL;
133cdf0e10cSrcweir     mnPostId                = 0;
134cdf0e10cSrcweir     mnTitle                 = (nStyle & WB_MOVEABLE) ? FLOATWIN_TITLE_NORMAL : FLOATWIN_TITLE_NONE;
135cdf0e10cSrcweir     mnOldTitle              = mnTitle;
136cdf0e10cSrcweir     mnPopupModeFlags        = 0;
137cdf0e10cSrcweir     mbInPopupMode           = sal_False;
138cdf0e10cSrcweir     mbPopupMode             = sal_False;
139cdf0e10cSrcweir     mbPopupModeCanceled     = sal_False;
140cdf0e10cSrcweir     mbPopupModeTearOff      = sal_False;
141cdf0e10cSrcweir     mbMouseDown             = sal_False;
142cdf0e10cSrcweir 
143cdf0e10cSrcweir     ImplInitSettings();
144cdf0e10cSrcweir }
145cdf0e10cSrcweir 
146cdf0e10cSrcweir // -----------------------------------------------------------------------
147cdf0e10cSrcweir 
ImplInitSettings()148cdf0e10cSrcweir void FloatingWindow::ImplInitSettings()
149cdf0e10cSrcweir {
150cdf0e10cSrcweir     const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
151cdf0e10cSrcweir 
152cdf0e10cSrcweir     Color aColor;
153cdf0e10cSrcweir     if ( IsControlBackground() )
154cdf0e10cSrcweir         aColor = GetControlBackground();
155cdf0e10cSrcweir     else if ( Window::GetStyle() & WB_3DLOOK )
156cdf0e10cSrcweir         aColor = rStyleSettings.GetFaceColor();
157cdf0e10cSrcweir     else
158cdf0e10cSrcweir         aColor = rStyleSettings.GetWindowColor();
159cdf0e10cSrcweir     SetBackground( aColor );
160cdf0e10cSrcweir }
161cdf0e10cSrcweir 
162cdf0e10cSrcweir // =======================================================================
163cdf0e10cSrcweir 
FloatingWindow(Window * pParent,WinBits nStyle)164cdf0e10cSrcweir FloatingWindow::FloatingWindow( Window* pParent, WinBits nStyle ) :
165cdf0e10cSrcweir     SystemWindow( WINDOW_FLOATINGWINDOW )
166cdf0e10cSrcweir {
167cdf0e10cSrcweir     ImplInit( pParent, nStyle );
168cdf0e10cSrcweir }
169cdf0e10cSrcweir 
170cdf0e10cSrcweir // -----------------------------------------------------------------------
171cdf0e10cSrcweir 
FloatingWindow(Window * pParent,const ResId & rResId)172cdf0e10cSrcweir FloatingWindow::FloatingWindow( Window* pParent, const ResId& rResId ) :
173cdf0e10cSrcweir     SystemWindow( WINDOW_FLOATINGWINDOW )
174cdf0e10cSrcweir {
175cdf0e10cSrcweir     rResId.SetRT( RSC_FLOATINGWINDOW );
176cdf0e10cSrcweir     WinBits nStyle = ImplInitRes( rResId );
177cdf0e10cSrcweir     ImplInit( pParent, nStyle );
178cdf0e10cSrcweir     ImplLoadRes( rResId );
179cdf0e10cSrcweir 
180cdf0e10cSrcweir     if ( !(nStyle & WB_HIDE) )
181cdf0e10cSrcweir         Show();
182cdf0e10cSrcweir }
183cdf0e10cSrcweir 
184cdf0e10cSrcweir // -----------------------------------------------------------------------
185cdf0e10cSrcweir 
ImplLoadRes(const ResId & rResId)186cdf0e10cSrcweir void FloatingWindow::ImplLoadRes( const ResId& rResId )
187cdf0e10cSrcweir {
188cdf0e10cSrcweir     SystemWindow::ImplLoadRes( rResId );
189cdf0e10cSrcweir 
190cdf0e10cSrcweir     sal_uLong nObjMask = ReadLongRes();
191cdf0e10cSrcweir 
192cdf0e10cSrcweir     if ( (RSC_FLOATINGWINDOW_WHMAPMODE | RSC_FLOATINGWINDOW_WIDTH |
193cdf0e10cSrcweir           RSC_FLOATINGWINDOW_HEIGHT) & nObjMask )
194cdf0e10cSrcweir     {
195cdf0e10cSrcweir         // Groessenangabe aus der Resource verwenden
196cdf0e10cSrcweir         Size    aSize;
197cdf0e10cSrcweir         MapUnit eSizeMap = MAP_PIXEL;
198cdf0e10cSrcweir 
199cdf0e10cSrcweir         if ( RSC_FLOATINGWINDOW_WHMAPMODE & nObjMask )
200cdf0e10cSrcweir             eSizeMap = (MapUnit) ReadShortRes();
201cdf0e10cSrcweir         if ( RSC_FLOATINGWINDOW_WIDTH & nObjMask )
202cdf0e10cSrcweir             aSize.Width() = ReadShortRes();
203cdf0e10cSrcweir         if ( RSC_FLOATINGWINDOW_HEIGHT & nObjMask )
204cdf0e10cSrcweir             aSize.Height() = ReadShortRes();
205cdf0e10cSrcweir 
206cdf0e10cSrcweir         SetRollUpOutputSizePixel( LogicToPixel( aSize, eSizeMap ) );
207cdf0e10cSrcweir     }
208cdf0e10cSrcweir 
209cdf0e10cSrcweir     if (nObjMask & RSC_FLOATINGWINDOW_ZOOMIN )
210cdf0e10cSrcweir     {
211cdf0e10cSrcweir         if ( ReadShortRes() )
212cdf0e10cSrcweir             RollUp();
213cdf0e10cSrcweir     }
214cdf0e10cSrcweir }
215cdf0e10cSrcweir 
216cdf0e10cSrcweir // -----------------------------------------------------------------------
217cdf0e10cSrcweir 
~FloatingWindow()218cdf0e10cSrcweir FloatingWindow::~FloatingWindow()
219cdf0e10cSrcweir {
220cdf0e10cSrcweir     if( mbPopupModeCanceled )
221cdf0e10cSrcweir         // indicates that ESC key was pressed
222cdf0e10cSrcweir         // will be handled in Window::ImplGrabFocus()
223cdf0e10cSrcweir         SetDialogControlFlags( GetDialogControlFlags() | WINDOW_DLGCTRL_FLOATWIN_POPUPMODEEND_CANCEL );
224cdf0e10cSrcweir 
225cdf0e10cSrcweir     if ( IsInPopupMode() )
226cdf0e10cSrcweir         EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL | FLOATWIN_POPUPMODEEND_DONTCALLHDL );
227cdf0e10cSrcweir 
228cdf0e10cSrcweir     if ( mnPostId )
229cdf0e10cSrcweir         Application::RemoveUserEvent( mnPostId );
230cdf0e10cSrcweir 
231cdf0e10cSrcweir     delete mpImplData;
232cdf0e10cSrcweir }
233cdf0e10cSrcweir 
234cdf0e10cSrcweir // -----------------------------------------------------------------------
235cdf0e10cSrcweir 
CalcFloatingPosition(Window * pWindow,const Rectangle & rRect,sal_uLong nFlags,sal_uInt16 & rArrangeIndex)236cdf0e10cSrcweir Point FloatingWindow::CalcFloatingPosition( Window* pWindow, const Rectangle& rRect, sal_uLong nFlags, sal_uInt16& rArrangeIndex )
237cdf0e10cSrcweir {
238cdf0e10cSrcweir     return ImplCalcPos( pWindow, rRect, nFlags, rArrangeIndex );
239cdf0e10cSrcweir }
240cdf0e10cSrcweir 
241cdf0e10cSrcweir // -----------------------------------------------------------------------
242cdf0e10cSrcweir 
ImplCalcPos(Window * pWindow,const Rectangle & rRect,sal_uLong nFlags,sal_uInt16 & rArrangeIndex)243cdf0e10cSrcweir Point FloatingWindow::ImplCalcPos( Window* pWindow,
244cdf0e10cSrcweir                                    const Rectangle& rRect, sal_uLong nFlags,
245cdf0e10cSrcweir                                    sal_uInt16& rArrangeIndex )
246cdf0e10cSrcweir {
247cdf0e10cSrcweir     // Fenster-Position ermitteln
248cdf0e10cSrcweir     Point       aPos;
249cdf0e10cSrcweir     Size        aSize = pWindow->GetSizePixel();
250cdf0e10cSrcweir     Rectangle   aScreenRect = pWindow->ImplGetFrameWindow()->GetDesktopRectPixel();
251cdf0e10cSrcweir     FloatingWindow *pFloatingWindow = dynamic_cast<FloatingWindow*>( pWindow );
252cdf0e10cSrcweir 
253cdf0e10cSrcweir     // convert....
254cdf0e10cSrcweir     Window* pW = pWindow;
255cdf0e10cSrcweir     if ( pW->mpWindowImpl->mpRealParent )
256cdf0e10cSrcweir         pW = pW->mpWindowImpl->mpRealParent;
257cdf0e10cSrcweir 
258cdf0e10cSrcweir     Rectangle normRect( rRect );  // rRect is already relative to top-level window
259cdf0e10cSrcweir     normRect.SetPos( pW->ScreenToOutputPixel( normRect.TopLeft() ) );
260cdf0e10cSrcweir 
261cdf0e10cSrcweir     sal_Bool bRTL = Application::GetSettings().GetLayoutRTL();
262cdf0e10cSrcweir 
263cdf0e10cSrcweir     Rectangle devRect(  pW->OutputToAbsoluteScreenPixel( normRect.TopLeft() ),
264cdf0e10cSrcweir                         pW->OutputToAbsoluteScreenPixel( normRect.BottomRight() ) );
265cdf0e10cSrcweir 
266cdf0e10cSrcweir     Rectangle devRectRTL( devRect );
267cdf0e10cSrcweir     if( bRTL )
268cdf0e10cSrcweir         // create a rect that can be compared to desktop coordinates
269cdf0e10cSrcweir         devRectRTL = pW->ImplOutputToUnmirroredAbsoluteScreenPixel( normRect );
270cdf0e10cSrcweir     if( Application::GetScreenCount() > 1 && ! Application::IsMultiDisplay() )
271cdf0e10cSrcweir         aScreenRect = Application::GetScreenPosSizePixel(
272cdf0e10cSrcweir             Application::GetBestScreen( bRTL ? devRectRTL : devRect ) );
273cdf0e10cSrcweir 
274cdf0e10cSrcweir 
275cdf0e10cSrcweir     sal_uInt16      nArrangeAry[5];
276cdf0e10cSrcweir     sal_uInt16      nArrangeIndex;
277cdf0e10cSrcweir     sal_Bool        bBreak;
278cdf0e10cSrcweir     Point       e1,e2;  // the common edge between the item rect and the floating window
279cdf0e10cSrcweir 
280cdf0e10cSrcweir     if ( nFlags & FLOATWIN_POPUPMODE_LEFT )
281cdf0e10cSrcweir     {
282cdf0e10cSrcweir         nArrangeAry[0]  = FLOATWIN_POPUPMODE_LEFT;
283cdf0e10cSrcweir         nArrangeAry[1]  = FLOATWIN_POPUPMODE_RIGHT;
284cdf0e10cSrcweir         nArrangeAry[2]  = FLOATWIN_POPUPMODE_UP;
285cdf0e10cSrcweir         nArrangeAry[3]  = FLOATWIN_POPUPMODE_DOWN;
286cdf0e10cSrcweir         nArrangeAry[4]  = FLOATWIN_POPUPMODE_LEFT;
287cdf0e10cSrcweir     }
288cdf0e10cSrcweir     else if ( nFlags & FLOATWIN_POPUPMODE_RIGHT )
289cdf0e10cSrcweir     {
290cdf0e10cSrcweir         nArrangeAry[0]  = FLOATWIN_POPUPMODE_RIGHT;
291cdf0e10cSrcweir         nArrangeAry[1]  = FLOATWIN_POPUPMODE_LEFT;
292cdf0e10cSrcweir         nArrangeAry[2]  = FLOATWIN_POPUPMODE_UP;
293cdf0e10cSrcweir         nArrangeAry[3]  = FLOATWIN_POPUPMODE_DOWN;
294cdf0e10cSrcweir         nArrangeAry[4]  = FLOATWIN_POPUPMODE_RIGHT;
295cdf0e10cSrcweir     }
296cdf0e10cSrcweir     else if ( nFlags & FLOATWIN_POPUPMODE_UP )
297cdf0e10cSrcweir     {
298cdf0e10cSrcweir         nArrangeAry[0]  = FLOATWIN_POPUPMODE_UP;
299cdf0e10cSrcweir         nArrangeAry[1]  = FLOATWIN_POPUPMODE_DOWN;
300cdf0e10cSrcweir         nArrangeAry[2]  = FLOATWIN_POPUPMODE_RIGHT;
301cdf0e10cSrcweir         nArrangeAry[3]  = FLOATWIN_POPUPMODE_LEFT;
302cdf0e10cSrcweir         nArrangeAry[4]  = FLOATWIN_POPUPMODE_UP;
303cdf0e10cSrcweir     }
304cdf0e10cSrcweir     else
305cdf0e10cSrcweir     {
306cdf0e10cSrcweir         nArrangeAry[0]  = FLOATWIN_POPUPMODE_DOWN;
307cdf0e10cSrcweir         nArrangeAry[1]  = FLOATWIN_POPUPMODE_UP;
308cdf0e10cSrcweir         nArrangeAry[2]  = FLOATWIN_POPUPMODE_RIGHT;
309cdf0e10cSrcweir         nArrangeAry[3]  = FLOATWIN_POPUPMODE_LEFT;
310cdf0e10cSrcweir         nArrangeAry[4]  = FLOATWIN_POPUPMODE_DOWN;
311cdf0e10cSrcweir     }
312cdf0e10cSrcweir     if ( nFlags & FLOATWIN_POPUPMODE_NOAUTOARRANGE )
313cdf0e10cSrcweir         nArrangeIndex = 4;
314cdf0e10cSrcweir     else
315cdf0e10cSrcweir         nArrangeIndex = 0;
316cdf0e10cSrcweir 
317cdf0e10cSrcweir     for ( ; nArrangeIndex < 5; nArrangeIndex++ )
318cdf0e10cSrcweir     {
319cdf0e10cSrcweir         bBreak = sal_True;
320cdf0e10cSrcweir         switch ( nArrangeAry[nArrangeIndex] )
321cdf0e10cSrcweir         {
322cdf0e10cSrcweir 
323cdf0e10cSrcweir             case FLOATWIN_POPUPMODE_LEFT:
324cdf0e10cSrcweir                 aPos.X() = devRect.Left()-aSize.Width()+1;
325cdf0e10cSrcweir                 aPos.Y() = devRect.Top();
326cdf0e10cSrcweir                 aPos.Y() -= pWindow->mpWindowImpl->mnTopBorder;
327cdf0e10cSrcweir                 if( bRTL ) // --- RTL --- we're comparing screen coordinates here
328cdf0e10cSrcweir                 {
329cdf0e10cSrcweir                     if( (devRectRTL.Right()+aSize.Width()) > aScreenRect.Right() )
330cdf0e10cSrcweir                         bBreak = sal_False;
331cdf0e10cSrcweir                 }
332cdf0e10cSrcweir                 else
333cdf0e10cSrcweir                 {
334cdf0e10cSrcweir                     if ( aPos.X() < aScreenRect.Left() )
335cdf0e10cSrcweir                         bBreak = sal_False;
336cdf0e10cSrcweir                 }
337cdf0e10cSrcweir                 if( bBreak )
338cdf0e10cSrcweir                 {
339cdf0e10cSrcweir                     e1 = devRect.TopLeft();
340cdf0e10cSrcweir                     e2 = devRect.BottomLeft();
341cdf0e10cSrcweir                     // set non-zero width
342cdf0e10cSrcweir                     e2.X()++;
343cdf0e10cSrcweir                     // don't clip corners
344cdf0e10cSrcweir                     e1.Y()++;
345cdf0e10cSrcweir                     e2.Y()--;
346cdf0e10cSrcweir                 }
347cdf0e10cSrcweir                 break;
348cdf0e10cSrcweir             case FLOATWIN_POPUPMODE_RIGHT:
349cdf0e10cSrcweir                 aPos     = devRect.TopRight();
350cdf0e10cSrcweir                 aPos.Y() -= pWindow->mpWindowImpl->mnTopBorder;
351cdf0e10cSrcweir                 if( bRTL ) // --- RTL --- we're comparing screen coordinates here
352cdf0e10cSrcweir                 {
353cdf0e10cSrcweir                     if( (devRectRTL.Left() - aSize.Width()) < aScreenRect.Left() )
354cdf0e10cSrcweir                         bBreak = sal_False;
355cdf0e10cSrcweir                 }
356cdf0e10cSrcweir                 else
357cdf0e10cSrcweir                 {
358cdf0e10cSrcweir                     if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
359cdf0e10cSrcweir                         bBreak = sal_False;
360cdf0e10cSrcweir                 }
361cdf0e10cSrcweir                 if( bBreak )
362cdf0e10cSrcweir                 {
363cdf0e10cSrcweir                     e1 = devRect.TopRight();
364cdf0e10cSrcweir                     e2 = devRect.BottomRight();
365cdf0e10cSrcweir                     // set non-zero width
366cdf0e10cSrcweir                     e2.X()++;
367cdf0e10cSrcweir                     // don't clip corners
368cdf0e10cSrcweir                     e1.Y()++;
369cdf0e10cSrcweir                     e2.Y()--;
370cdf0e10cSrcweir                 }
371cdf0e10cSrcweir                 break;
372cdf0e10cSrcweir             case FLOATWIN_POPUPMODE_UP:
373cdf0e10cSrcweir                 aPos.X() = devRect.Left();
374cdf0e10cSrcweir                 aPos.Y() = devRect.Top()-aSize.Height()+1;
375cdf0e10cSrcweir                 if ( aPos.Y() < aScreenRect.Top() )
376cdf0e10cSrcweir                     bBreak = sal_False;
377cdf0e10cSrcweir                 if( bBreak )
378cdf0e10cSrcweir                 {
379cdf0e10cSrcweir                     e1 = devRect.TopLeft();
380cdf0e10cSrcweir                     e2 = devRect.TopRight();
381cdf0e10cSrcweir                     // set non-zero height
382cdf0e10cSrcweir                     e2.Y()++;
383cdf0e10cSrcweir                     // don't clip corners
384cdf0e10cSrcweir                     e1.X()++;
385cdf0e10cSrcweir                     e2.X()--;
386cdf0e10cSrcweir                 }
387cdf0e10cSrcweir                 break;
388cdf0e10cSrcweir             case FLOATWIN_POPUPMODE_DOWN:
389cdf0e10cSrcweir                 aPos = devRect.BottomLeft();
390cdf0e10cSrcweir                 if ( aPos.Y()+aSize.Height() > aScreenRect.Bottom() )
391cdf0e10cSrcweir                     bBreak = sal_False;
392cdf0e10cSrcweir                 if( bBreak )
393cdf0e10cSrcweir                 {
394cdf0e10cSrcweir                     e1 = devRect.BottomLeft();
395cdf0e10cSrcweir                     e2 = devRect.BottomRight();
396cdf0e10cSrcweir                     // set non-zero height
397cdf0e10cSrcweir                     e2.Y()++;
398cdf0e10cSrcweir                     // don't clip corners
399cdf0e10cSrcweir                     e1.X()++;
400cdf0e10cSrcweir                     e2.X()--;
401cdf0e10cSrcweir                 }
402cdf0e10cSrcweir                 break;
403cdf0e10cSrcweir         }
404cdf0e10cSrcweir 
405cdf0e10cSrcweir         // Evt. noch anpassen
406cdf0e10cSrcweir         if ( bBreak && !(nFlags & FLOATWIN_POPUPMODE_NOAUTOARRANGE) )
407cdf0e10cSrcweir         {
408cdf0e10cSrcweir             if ( (nArrangeAry[nArrangeIndex] == FLOATWIN_POPUPMODE_LEFT)  ||
409cdf0e10cSrcweir                  (nArrangeAry[nArrangeIndex] == FLOATWIN_POPUPMODE_RIGHT) )
410cdf0e10cSrcweir             {
411cdf0e10cSrcweir                 if ( aPos.Y()+aSize.Height() > aScreenRect.Bottom() )
412cdf0e10cSrcweir                 {
413cdf0e10cSrcweir                     aPos.Y() = devRect.Bottom()-aSize.Height()+1;
414cdf0e10cSrcweir                     if ( aPos.Y() < aScreenRect.Top() )
415cdf0e10cSrcweir                         aPos.Y() = aScreenRect.Top();
416cdf0e10cSrcweir                 }
417cdf0e10cSrcweir             }
418cdf0e10cSrcweir             else
419cdf0e10cSrcweir             {
420cdf0e10cSrcweir                 if( bRTL ) // --- RTL --- we're comparing screen coordinates here
421cdf0e10cSrcweir                 {
422cdf0e10cSrcweir                     if( devRectRTL.Right()-aSize.Width()+1 < aScreenRect.Left() )
423cdf0e10cSrcweir                         aPos.X() -= aScreenRect.Left() - devRectRTL.Right() + aSize.Width() - 1;
424cdf0e10cSrcweir                     else if( aPos.X() + aSize.Width() > aScreenRect.Right() )
425cdf0e10cSrcweir                     {
426cdf0e10cSrcweir                         aPos.X() -= aSize.Width()-2; // popup to left instead
427cdf0e10cSrcweir                         aPos.Y() -= 2;
428cdf0e10cSrcweir                     }
429cdf0e10cSrcweir                 }
430cdf0e10cSrcweir                 else if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
431cdf0e10cSrcweir                 {
432cdf0e10cSrcweir                     aPos.X() = devRect.Right()-aSize.Width()+1;
433cdf0e10cSrcweir                     if ( aPos.X() < aScreenRect.Left() )
434cdf0e10cSrcweir                         aPos.X() = aScreenRect.Left();
435cdf0e10cSrcweir                 }
436cdf0e10cSrcweir             }
437cdf0e10cSrcweir         }
438cdf0e10cSrcweir 
439cdf0e10cSrcweir         if ( bBreak )
440cdf0e10cSrcweir             break;
441cdf0e10cSrcweir     }
442cdf0e10cSrcweir     if ( nArrangeIndex > 4 )
443cdf0e10cSrcweir         nArrangeIndex = 4;
444cdf0e10cSrcweir 
445cdf0e10cSrcweir     rArrangeIndex = nArrangeIndex;
446cdf0e10cSrcweir 
447cdf0e10cSrcweir     aPos = pW->AbsoluteScreenToOutputPixel( aPos );
448cdf0e10cSrcweir 
449cdf0e10cSrcweir     // store a cliprect that can be used to clip the common edge of the itemrect and the floating window
450cdf0e10cSrcweir     if( pFloatingWindow )
451cdf0e10cSrcweir     {
452cdf0e10cSrcweir         pFloatingWindow->mpImplData->maItemEdgeClipRect =
453cdf0e10cSrcweir             Rectangle( e1, e2 );
454cdf0e10cSrcweir     }
455cdf0e10cSrcweir 
456cdf0e10cSrcweir     // caller expects cordinates relative to top-level win
457cdf0e10cSrcweir     return pW->OutputToScreenPixel( aPos );
458cdf0e10cSrcweir }
459cdf0e10cSrcweir 
460cdf0e10cSrcweir // -----------------------------------------------------------------------
461cdf0e10cSrcweir 
ImplFloatHitTest(Window * pReference,const Point & rPos,sal_uInt16 & rHitTest)462cdf0e10cSrcweir FloatingWindow* FloatingWindow::ImplFloatHitTest( Window* pReference, const Point& rPos, sal_uInt16& rHitTest )
463cdf0e10cSrcweir {
464cdf0e10cSrcweir     FloatingWindow* pWin = this;
465cdf0e10cSrcweir 
466cdf0e10cSrcweir     Point aAbsolute( rPos );
467cdf0e10cSrcweir 
468cdf0e10cSrcweir     // compare coordinates in absolute screen coordinates
469cdf0e10cSrcweir     if( pReference->ImplHasMirroredGraphics()  )
470cdf0e10cSrcweir     {
471cdf0e10cSrcweir         if(!pReference->IsRTLEnabled() )
472cdf0e10cSrcweir             // --- RTL --- re-mirror back to get device coordiantes
473cdf0e10cSrcweir             pReference->ImplReMirror( aAbsolute );
474cdf0e10cSrcweir 
475cdf0e10cSrcweir         Rectangle aRect( pReference->ScreenToOutputPixel(aAbsolute), Size(1,1) ) ;
476cdf0e10cSrcweir         aRect = pReference->ImplOutputToUnmirroredAbsoluteScreenPixel( aRect );
477cdf0e10cSrcweir         aAbsolute = aRect.TopLeft();
478cdf0e10cSrcweir     }
479cdf0e10cSrcweir     else
480cdf0e10cSrcweir         aAbsolute = Point( pReference->OutputToAbsoluteScreenPixel(
481cdf0e10cSrcweir             pReference->ScreenToOutputPixel(rPos) ) );
482cdf0e10cSrcweir 
483cdf0e10cSrcweir     do
484cdf0e10cSrcweir     {
485cdf0e10cSrcweir         // compute the floating window's size in absolute screen coordinates
486cdf0e10cSrcweir 
487cdf0e10cSrcweir         // use the border window to have the exact position
488cdf0e10cSrcweir         Window *pBorderWin = pWin->GetWindow( WINDOW_BORDER );
489cdf0e10cSrcweir 
490cdf0e10cSrcweir         Point aPt;  // the top-left corner in output coordinates ie (0,0)
491cdf0e10cSrcweir         Rectangle devRect( pBorderWin->ImplOutputToUnmirroredAbsoluteScreenPixel( Rectangle( aPt, pBorderWin->GetSizePixel()) ) ) ;
492cdf0e10cSrcweir         if ( devRect.IsInside( aAbsolute ) )
493cdf0e10cSrcweir         {
494cdf0e10cSrcweir             rHitTest = IMPL_FLOATWIN_HITTEST_WINDOW;
495cdf0e10cSrcweir             return pWin;
496cdf0e10cSrcweir         }
497cdf0e10cSrcweir 
498cdf0e10cSrcweir         // test, if mouse is in rectangle, (this is typically the rect of the active
499cdf0e10cSrcweir         // toolbox item or similar)
500cdf0e10cSrcweir         // note: maFloatRect is set in FloatingWindow::StartPopupMode() and
501cdf0e10cSrcweir         //       is already in absolute device coordinates
502cdf0e10cSrcweir         if ( pWin->maFloatRect.IsInside( aAbsolute ) )
503cdf0e10cSrcweir         {
504cdf0e10cSrcweir             rHitTest = IMPL_FLOATWIN_HITTEST_RECT;
505cdf0e10cSrcweir             return pWin;
506cdf0e10cSrcweir         }
507cdf0e10cSrcweir 
508cdf0e10cSrcweir         pWin = pWin->mpNextFloat;
509cdf0e10cSrcweir     }
510cdf0e10cSrcweir     while ( pWin );
511cdf0e10cSrcweir 
512cdf0e10cSrcweir     rHitTest = IMPL_FLOATWIN_HITTEST_OUTSIDE;
513cdf0e10cSrcweir     return NULL;
514cdf0e10cSrcweir }
515cdf0e10cSrcweir 
516cdf0e10cSrcweir // -----------------------------------------------------------------------
517cdf0e10cSrcweir 
ImplFindLastLevelFloat()518cdf0e10cSrcweir FloatingWindow* FloatingWindow::ImplFindLastLevelFloat()
519cdf0e10cSrcweir {
520cdf0e10cSrcweir     FloatingWindow* pWin = this;
521cdf0e10cSrcweir     FloatingWindow* pLastFoundWin = pWin;
522cdf0e10cSrcweir 
523cdf0e10cSrcweir     do
524cdf0e10cSrcweir     {
525cdf0e10cSrcweir         if ( pWin->GetPopupModeFlags() & FLOATWIN_POPUPMODE_NEWLEVEL )
526cdf0e10cSrcweir             pLastFoundWin = pWin;
527cdf0e10cSrcweir 
528cdf0e10cSrcweir         pWin = pWin->mpNextFloat;
529cdf0e10cSrcweir     }
530cdf0e10cSrcweir     while ( pWin );
531cdf0e10cSrcweir 
532cdf0e10cSrcweir     return pLastFoundWin;
533cdf0e10cSrcweir }
534cdf0e10cSrcweir 
535cdf0e10cSrcweir // -----------------------------------------------------------------------
536cdf0e10cSrcweir 
ImplIsFloatPopupModeWindow(const Window * pWindow)537cdf0e10cSrcweir sal_Bool FloatingWindow::ImplIsFloatPopupModeWindow( const Window* pWindow )
538cdf0e10cSrcweir {
539cdf0e10cSrcweir     FloatingWindow* pWin = this;
540cdf0e10cSrcweir 
541cdf0e10cSrcweir     do
542cdf0e10cSrcweir     {
543cdf0e10cSrcweir         if ( pWin->mpFirstPopupModeWin == pWindow )
544cdf0e10cSrcweir             return sal_True;
545cdf0e10cSrcweir 
546cdf0e10cSrcweir         pWin = pWin->mpNextFloat;
547cdf0e10cSrcweir     }
548cdf0e10cSrcweir     while ( pWin );
549cdf0e10cSrcweir 
550cdf0e10cSrcweir     return sal_False;
551cdf0e10cSrcweir }
552cdf0e10cSrcweir 
553cdf0e10cSrcweir // -----------------------------------------------------------------------
554cdf0e10cSrcweir 
IMPL_LINK(FloatingWindow,ImplEndPopupModeHdl,void *,EMPTYARG)555cdf0e10cSrcweir IMPL_LINK( FloatingWindow, ImplEndPopupModeHdl, void*, EMPTYARG )
556cdf0e10cSrcweir {
557cdf0e10cSrcweir     mnPostId            = 0;
558cdf0e10cSrcweir     mnPopupModeFlags    = 0;
559cdf0e10cSrcweir     mbPopupMode         = sal_False;
560cdf0e10cSrcweir     PopupModeEnd();
561cdf0e10cSrcweir     return 0;
562cdf0e10cSrcweir }
563cdf0e10cSrcweir 
564cdf0e10cSrcweir // -----------------------------------------------------------------------
565cdf0e10cSrcweir 
Notify(NotifyEvent & rNEvt)566cdf0e10cSrcweir long FloatingWindow::Notify( NotifyEvent& rNEvt )
567cdf0e10cSrcweir {
568cdf0e10cSrcweir     // Zuerst Basisklasse rufen wegen TabSteuerung
569cdf0e10cSrcweir     long nRet = SystemWindow::Notify( rNEvt );
570cdf0e10cSrcweir     if ( !nRet )
571cdf0e10cSrcweir     {
572cdf0e10cSrcweir         if ( rNEvt.GetType() == EVENT_KEYINPUT )
573cdf0e10cSrcweir         {
574cdf0e10cSrcweir             const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
575cdf0e10cSrcweir             KeyCode         aKeyCode = pKEvt->GetKeyCode();
576cdf0e10cSrcweir             sal_uInt16          nKeyCode = aKeyCode.GetCode();
577cdf0e10cSrcweir 
578cdf0e10cSrcweir             if ( (nKeyCode == KEY_ESCAPE) && (GetStyle() & WB_CLOSEABLE) )
579cdf0e10cSrcweir             {
580cdf0e10cSrcweir                 Close();
581cdf0e10cSrcweir                 return sal_True;
582cdf0e10cSrcweir             }
583cdf0e10cSrcweir         }
584cdf0e10cSrcweir     }
585cdf0e10cSrcweir 
586cdf0e10cSrcweir     return nRet;
587cdf0e10cSrcweir }
588cdf0e10cSrcweir 
589cdf0e10cSrcweir // -----------------------------------------------------------------------
590cdf0e10cSrcweir 
StateChanged(StateChangedType nType)591cdf0e10cSrcweir void FloatingWindow::StateChanged( StateChangedType nType )
592cdf0e10cSrcweir {
593cdf0e10cSrcweir     SystemWindow::StateChanged( nType );
594cdf0e10cSrcweir 
595cdf0e10cSrcweir     if ( nType == STATE_CHANGE_CONTROLBACKGROUND )
596cdf0e10cSrcweir     {
597cdf0e10cSrcweir         ImplInitSettings();
598cdf0e10cSrcweir         Invalidate();
599cdf0e10cSrcweir     }
600cdf0e10cSrcweir }
601cdf0e10cSrcweir 
602cdf0e10cSrcweir // -----------------------------------------------------------------------
603cdf0e10cSrcweir 
DataChanged(const DataChangedEvent & rDCEvt)604cdf0e10cSrcweir void FloatingWindow::DataChanged( const DataChangedEvent& rDCEvt )
605cdf0e10cSrcweir {
606cdf0e10cSrcweir     SystemWindow::DataChanged( rDCEvt );
607cdf0e10cSrcweir 
608cdf0e10cSrcweir     if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) &&
609cdf0e10cSrcweir          (rDCEvt.GetFlags() & SETTINGS_STYLE) )
610cdf0e10cSrcweir     {
611cdf0e10cSrcweir         ImplInitSettings();
612cdf0e10cSrcweir         Invalidate();
613cdf0e10cSrcweir     }
614cdf0e10cSrcweir }
615cdf0e10cSrcweir 
616cdf0e10cSrcweir // -----------------------------------------------------------------------
617cdf0e10cSrcweir 
ImplCallPopupModeEnd()618cdf0e10cSrcweir void FloatingWindow::ImplCallPopupModeEnd()
619cdf0e10cSrcweir {
620cdf0e10cSrcweir     // PopupMode wurde beendet
621cdf0e10cSrcweir     mbInPopupMode = sal_False;
622cdf0e10cSrcweir 
623cdf0e10cSrcweir     // Handler asyncron rufen
624cdf0e10cSrcweir     if ( !mnPostId )
625cdf0e10cSrcweir         Application::PostUserEvent( mnPostId, LINK( this, FloatingWindow, ImplEndPopupModeHdl ) );
626cdf0e10cSrcweir }
627cdf0e10cSrcweir 
628cdf0e10cSrcweir // -----------------------------------------------------------------------
629cdf0e10cSrcweir 
PopupModeEnd()630cdf0e10cSrcweir void FloatingWindow::PopupModeEnd()
631cdf0e10cSrcweir {
632cdf0e10cSrcweir     maPopupModeEndHdl.Call( this );
633cdf0e10cSrcweir }
634cdf0e10cSrcweir 
635cdf0e10cSrcweir // -----------------------------------------------------------------------
636cdf0e10cSrcweir 
SetTitleType(sal_uInt16 nTitle)637cdf0e10cSrcweir void FloatingWindow::SetTitleType( sal_uInt16 nTitle )
638cdf0e10cSrcweir {
639cdf0e10cSrcweir     if ( (mnTitle != nTitle) && mpWindowImpl->mpBorderWindow )
640cdf0e10cSrcweir     {
641cdf0e10cSrcweir         mnTitle = nTitle;
642cdf0e10cSrcweir         Size aOutSize = GetOutputSizePixel();
643cdf0e10cSrcweir         sal_uInt16 nTitleStyle;
644cdf0e10cSrcweir         if ( nTitle == FLOATWIN_TITLE_NORMAL )
645cdf0e10cSrcweir             nTitleStyle = BORDERWINDOW_TITLE_SMALL;
646cdf0e10cSrcweir         else if ( nTitle == FLOATWIN_TITLE_TEAROFF )
647cdf0e10cSrcweir             nTitleStyle = BORDERWINDOW_TITLE_TEAROFF;
648cdf0e10cSrcweir         else // nTitle == FLOATWIN_TITLE_NONE
649cdf0e10cSrcweir             nTitleStyle = BORDERWINDOW_TITLE_NONE;
650cdf0e10cSrcweir         ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->SetTitleType( nTitleStyle, aOutSize );
651cdf0e10cSrcweir         ((ImplBorderWindow*)mpWindowImpl->mpBorderWindow)->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
652cdf0e10cSrcweir     }
653cdf0e10cSrcweir }
654cdf0e10cSrcweir 
655cdf0e10cSrcweir // -----------------------------------------------------------------------
656cdf0e10cSrcweir 
StartPopupMode(const Rectangle & rRect,sal_uLong nFlags)657cdf0e10cSrcweir void FloatingWindow::StartPopupMode( const Rectangle& rRect, sal_uLong nFlags )
658cdf0e10cSrcweir {
659cdf0e10cSrcweir     // avoid flickering
660cdf0e10cSrcweir     if ( IsVisible() )
661cdf0e10cSrcweir         Show( sal_False, SHOW_NOFOCUSCHANGE );
662cdf0e10cSrcweir 
663cdf0e10cSrcweir     if ( IsRollUp() )
664cdf0e10cSrcweir         RollDown();
665cdf0e10cSrcweir 
666cdf0e10cSrcweir     // remove title
667cdf0e10cSrcweir     mnOldTitle = mnTitle;
668cdf0e10cSrcweir     if ( nFlags & FLOATWIN_POPUPMODE_ALLOWTEAROFF )
669cdf0e10cSrcweir         SetTitleType( FLOATWIN_TITLE_TEAROFF );
670cdf0e10cSrcweir     else
671cdf0e10cSrcweir         SetTitleType( FLOATWIN_TITLE_NONE );
672cdf0e10cSrcweir 
673cdf0e10cSrcweir     // avoid close on focus change for decorated floating windows only
674cdf0e10cSrcweir     if( mpWindowImpl->mbFrame && (GetStyle() & WB_MOVEABLE) )
675cdf0e10cSrcweir         nFlags |= FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE;
676cdf0e10cSrcweir 
677cdf0e10cSrcweir     // #102010# For debugging Accessibility
678cdf0e10cSrcweir     static const char* pEnv = getenv("SAL_FLOATWIN_NOAPPFOCUSCLOSE" );
679cdf0e10cSrcweir     if( pEnv && *pEnv )
680cdf0e10cSrcweir         nFlags |= FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE;
681cdf0e10cSrcweir 
682cdf0e10cSrcweir     // compute window position according to flags and arrangement
683cdf0e10cSrcweir     sal_uInt16 nArrangeIndex;
684cdf0e10cSrcweir     SetPosPixel( ImplCalcPos( this, rRect, nFlags, nArrangeIndex ) );
685cdf0e10cSrcweir 
686cdf0e10cSrcweir     // set data and display window
687cdf0e10cSrcweir     // convert maFloatRect to absolute device coordinates
688cdf0e10cSrcweir     // so they can be compared across different frames
689cdf0e10cSrcweir     // !!! rRect is expected to be in screen coordinates of the parent frame window !!!
690cdf0e10cSrcweir     maFloatRect             = rRect;
691cdf0e10cSrcweir     if( GetParent()->ImplHasMirroredGraphics() )
692cdf0e10cSrcweir     {
693cdf0e10cSrcweir         maFloatRect.SetPos( GetParent()->ScreenToOutputPixel( rRect.TopLeft() ) );
694cdf0e10cSrcweir         maFloatRect = GetParent()->ImplOutputToUnmirroredAbsoluteScreenPixel( maFloatRect );
695cdf0e10cSrcweir     }
696cdf0e10cSrcweir     else
697cdf0e10cSrcweir         maFloatRect.SetPos( GetParent()->OutputToAbsoluteScreenPixel( GetParent()->ScreenToOutputPixel( rRect.TopLeft() ) ) );
698cdf0e10cSrcweir 
699cdf0e10cSrcweir     maFloatRect.Left()     -= 2;
700cdf0e10cSrcweir     maFloatRect.Top()      -= 2;
701cdf0e10cSrcweir     maFloatRect.Right()    += 2;
702cdf0e10cSrcweir     maFloatRect.Bottom()   += 2;
703cdf0e10cSrcweir     mnPopupModeFlags        = nFlags;
704cdf0e10cSrcweir     mbInPopupMode           = sal_True;
705cdf0e10cSrcweir     mbPopupMode             = sal_True;
706cdf0e10cSrcweir     mbPopupModeCanceled     = sal_False;
707cdf0e10cSrcweir     mbPopupModeTearOff      = sal_False;
708cdf0e10cSrcweir     mbMouseDown             = sal_False;
709cdf0e10cSrcweir 
710cdf0e10cSrcweir     mbOldSaveBackMode       = IsSaveBackgroundEnabled();
711cdf0e10cSrcweir     EnableSaveBackground();
712cdf0e10cSrcweir 
713cdf0e10cSrcweir     // add FloatingWindow to list of windows that are in popup mode
714cdf0e10cSrcweir     ImplSVData* pSVData = ImplGetSVData();
715cdf0e10cSrcweir     mpNextFloat = pSVData->maWinData.mpFirstFloat;
716cdf0e10cSrcweir     pSVData->maWinData.mpFirstFloat = this;
717cdf0e10cSrcweir     if( nFlags & FLOATWIN_POPUPMODE_GRABFOCUS )
718cdf0e10cSrcweir     {
719cdf0e10cSrcweir         // force key input even without focus (useful for menues)
720cdf0e10cSrcweir         mbGrabFocus = sal_True;
721cdf0e10cSrcweir     }
722cdf0e10cSrcweir     Show( sal_True, SHOW_NOACTIVATE );
723cdf0e10cSrcweir }
724cdf0e10cSrcweir 
725cdf0e10cSrcweir // -----------------------------------------------------------------------
726cdf0e10cSrcweir 
StartPopupMode(ToolBox * pBox,sal_uLong nFlags)727cdf0e10cSrcweir void FloatingWindow::StartPopupMode( ToolBox* pBox, sal_uLong nFlags )
728cdf0e10cSrcweir {
729cdf0e10cSrcweir     // get selected button
730cdf0e10cSrcweir     sal_uInt16 nItemId = pBox->GetDownItemId();
731cdf0e10cSrcweir     if ( !nItemId )
732cdf0e10cSrcweir         return;
733cdf0e10cSrcweir 
734cdf0e10cSrcweir     mpImplData->mpBox = pBox;
735cdf0e10cSrcweir     pBox->ImplFloatControl( sal_True, this );
736cdf0e10cSrcweir 
737cdf0e10cSrcweir     // retrieve some data from the ToolBox
738cdf0e10cSrcweir     Rectangle aRect = pBox->GetItemRect( nItemId );
739cdf0e10cSrcweir     Point aPos;
740cdf0e10cSrcweir     // convert to parent's screen coordinates
741cdf0e10cSrcweir     aPos = GetParent()->OutputToScreenPixel( GetParent()->AbsoluteScreenToOutputPixel( pBox->OutputToAbsoluteScreenPixel( aRect.TopLeft() ) ) );
742cdf0e10cSrcweir     aRect.SetPos( aPos );
743cdf0e10cSrcweir 
744cdf0e10cSrcweir     nFlags |=
745cdf0e10cSrcweir         FLOATWIN_POPUPMODE_NOFOCUSCLOSE 	|
746cdf0e10cSrcweir //        FLOATWIN_POPUPMODE_NOMOUSECLOSE		|
747cdf0e10cSrcweir         FLOATWIN_POPUPMODE_ALLMOUSEBUTTONCLOSE |
748cdf0e10cSrcweir //        FLOATWIN_POPUPMODE_NOMOUSERECTCLOSE	|   // #105968# floating toolboxes should close when clicked in (parent's) float rect
749cdf0e10cSrcweir         FLOATWIN_POPUPMODE_NOMOUSEUPCLOSE;
750cdf0e10cSrcweir //        	|      FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE;
751cdf0e10cSrcweir 
752cdf0e10cSrcweir /*
753cdf0e10cSrcweir  *  FLOATWIN_POPUPMODE_NOKEYCLOSE		|
754cdf0e10cSrcweir  *  don't set since it disables closing floaters with escape
755cdf0e10cSrcweir  */
756cdf0e10cSrcweir 
757cdf0e10cSrcweir     // Flags fuer Positionierung bestimmen
758cdf0e10cSrcweir     if ( !(nFlags & (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_UP |
759cdf0e10cSrcweir                      FLOATWIN_POPUPMODE_LEFT | FLOATWIN_POPUPMODE_RIGHT |
760cdf0e10cSrcweir                      FLOATWIN_POPUPMODE_NOAUTOARRANGE)) )
761cdf0e10cSrcweir     {
762cdf0e10cSrcweir          if ( pBox->IsHorizontal() )
763cdf0e10cSrcweir              nFlags |= FLOATWIN_POPUPMODE_DOWN;
764cdf0e10cSrcweir          else
765cdf0e10cSrcweir              nFlags |= FLOATWIN_POPUPMODE_RIGHT;
766cdf0e10cSrcweir     }
767cdf0e10cSrcweir 
768cdf0e10cSrcweir     // FloatingModus starten
769cdf0e10cSrcweir     StartPopupMode( aRect, nFlags );
770cdf0e10cSrcweir }
771cdf0e10cSrcweir 
772cdf0e10cSrcweir // -----------------------------------------------------------------------
773cdf0e10cSrcweir 
ImplEndPopupMode(sal_uInt16 nFlags,sal_uLong nFocusId)774cdf0e10cSrcweir void FloatingWindow::ImplEndPopupMode( sal_uInt16 nFlags, sal_uLong nFocusId )
775cdf0e10cSrcweir {
776cdf0e10cSrcweir     if ( !mbInPopupMode )
777cdf0e10cSrcweir         return;
778cdf0e10cSrcweir 
779cdf0e10cSrcweir     ImplSVData* pSVData = ImplGetSVData();
780cdf0e10cSrcweir 
781cdf0e10cSrcweir     mbInCleanUp = sal_True; // prevent killing this window due to focus change while working with it
782cdf0e10cSrcweir 
783cdf0e10cSrcweir     // Bei allen nachfolgenden PopupMode-Fenster den Modus auch beenden
784cdf0e10cSrcweir     while ( pSVData->maWinData.mpFirstFloat && pSVData->maWinData.mpFirstFloat != this )
785cdf0e10cSrcweir         pSVData->maWinData.mpFirstFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL );
786cdf0e10cSrcweir 
787cdf0e10cSrcweir 
788cdf0e10cSrcweir     // Fenster aus der Liste austragen
789cdf0e10cSrcweir     pSVData->maWinData.mpFirstFloat = mpNextFloat;
790cdf0e10cSrcweir     mpNextFloat = NULL;
791cdf0e10cSrcweir 
792cdf0e10cSrcweir     sal_uLong nPopupModeFlags = mnPopupModeFlags;
793cdf0e10cSrcweir 
794cdf0e10cSrcweir     // Wenn nicht abgerissen wurde, dann Fenster wieder Hiden
795cdf0e10cSrcweir     if ( !(nFlags & FLOATWIN_POPUPMODEEND_TEAROFF) ||
796cdf0e10cSrcweir          !(nPopupModeFlags & FLOATWIN_POPUPMODE_ALLOWTEAROFF) )
797cdf0e10cSrcweir     {
798cdf0e10cSrcweir         Show( sal_False, SHOW_NOFOCUSCHANGE );
799cdf0e10cSrcweir 
800cdf0e10cSrcweir         // Focus evt. auf ein entsprechendes FloatingWindow weiterschalten
801cdf0e10cSrcweir         if ( nFocusId )
802cdf0e10cSrcweir             Window::EndSaveFocus( nFocusId );
803cdf0e10cSrcweir         else if ( pSVData->maWinData.mpFocusWin && pSVData->maWinData.mpFirstFloat &&
804cdf0e10cSrcweir                   ImplIsWindowOrChild( pSVData->maWinData.mpFocusWin ) )
805cdf0e10cSrcweir             pSVData->maWinData.mpFirstFloat->GrabFocus();
806cdf0e10cSrcweir         mbPopupModeTearOff = sal_False;
807cdf0e10cSrcweir     }
808cdf0e10cSrcweir     else
809cdf0e10cSrcweir     {
810cdf0e10cSrcweir         mbPopupModeTearOff = sal_True;
811cdf0e10cSrcweir         if ( nFocusId )
812cdf0e10cSrcweir             Window::EndSaveFocus( nFocusId, sal_False );
813cdf0e10cSrcweir     }
814cdf0e10cSrcweir     EnableSaveBackground( mbOldSaveBackMode );
815cdf0e10cSrcweir 
816cdf0e10cSrcweir     mbPopupModeCanceled = (nFlags & FLOATWIN_POPUPMODEEND_CANCEL) != 0;
817cdf0e10cSrcweir 
818cdf0e10cSrcweir     // Gegebenenfalls den Title wieder herstellen
819cdf0e10cSrcweir     SetTitleType( mnOldTitle );
820cdf0e10cSrcweir 
821cdf0e10cSrcweir     // ToolBox wieder auf normal schalten
822cdf0e10cSrcweir     if ( mpImplData->mpBox )
823cdf0e10cSrcweir     {
824cdf0e10cSrcweir         mpImplData->mpBox->ImplFloatControl( sal_False, this );
825cdf0e10cSrcweir         mpImplData->mpBox = NULL;
826cdf0e10cSrcweir     }
827cdf0e10cSrcweir 
828cdf0e10cSrcweir     // Je nach Parameter den PopupModeEnd-Handler rufen
829cdf0e10cSrcweir     if ( !(nFlags & FLOATWIN_POPUPMODEEND_DONTCALLHDL) )
830cdf0e10cSrcweir         ImplCallPopupModeEnd();
831cdf0e10cSrcweir 
832cdf0e10cSrcweir     // Je nach Parameter die restlichen Fenster auch noch schliessen
833cdf0e10cSrcweir     if ( nFlags & FLOATWIN_POPUPMODEEND_CLOSEALL )
834cdf0e10cSrcweir     {
835cdf0e10cSrcweir         if ( !(nPopupModeFlags & FLOATWIN_POPUPMODE_NEWLEVEL) )
836cdf0e10cSrcweir         {
837cdf0e10cSrcweir             if ( pSVData->maWinData.mpFirstFloat )
838cdf0e10cSrcweir             {
839cdf0e10cSrcweir                 FloatingWindow* pLastLevelFloat = pSVData->maWinData.mpFirstFloat->ImplFindLastLevelFloat();
840cdf0e10cSrcweir                 pLastLevelFloat->EndPopupMode( FLOATWIN_POPUPMODEEND_CANCEL | FLOATWIN_POPUPMODEEND_CLOSEALL );
841cdf0e10cSrcweir             }
842cdf0e10cSrcweir         }
843cdf0e10cSrcweir     }
844cdf0e10cSrcweir 
845cdf0e10cSrcweir     mbInCleanUp = sal_False;
846cdf0e10cSrcweir }
847cdf0e10cSrcweir 
848cdf0e10cSrcweir // -----------------------------------------------------------------------
849cdf0e10cSrcweir 
EndPopupMode(sal_uInt16 nFlags)850cdf0e10cSrcweir void FloatingWindow::EndPopupMode( sal_uInt16 nFlags )
851cdf0e10cSrcweir {
852cdf0e10cSrcweir     ImplEndPopupMode( nFlags );
853cdf0e10cSrcweir }
854cdf0e10cSrcweir 
855cdf0e10cSrcweir // -----------------------------------------------------------------------
856cdf0e10cSrcweir 
AddPopupModeWindow(Window * pWindow)857cdf0e10cSrcweir void FloatingWindow::AddPopupModeWindow( Window* pWindow )
858cdf0e10cSrcweir {
859cdf0e10cSrcweir     // !!! bisher erst 1 Fenster und noch keine Liste
860cdf0e10cSrcweir     mpFirstPopupModeWin = pWindow;
861cdf0e10cSrcweir }
862cdf0e10cSrcweir 
863cdf0e10cSrcweir // -----------------------------------------------------------------------
864cdf0e10cSrcweir 
RemovePopupModeWindow(Window * pWindow)865cdf0e10cSrcweir void FloatingWindow::RemovePopupModeWindow( Window* pWindow )
866cdf0e10cSrcweir {
867cdf0e10cSrcweir     // !!! bisher erst 1 Fenster und noch keine Liste
868cdf0e10cSrcweir     if ( mpFirstPopupModeWin == pWindow )
869cdf0e10cSrcweir         mpFirstPopupModeWin = NULL;
870cdf0e10cSrcweir }
871cdf0e10cSrcweir 
872