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