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