LibreOffice Module vcl (master) 1
floatwin.cxx
Go to the documentation of this file.
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#include <svdata.hxx>
21#include <brdwin.hxx>
22#include <window.h>
23#include <salframe.hxx>
24#include <helpwin.hxx>
25
26#include <comphelper/lok.hxx>
27#include <sal/log.hxx>
28#include <vcl/layout.hxx>
29#include <vcl/svapp.hxx>
30#include <vcl/wrkwin.hxx>
31#include <vcl/event.hxx>
32#include <vcl/toolbox.hxx>
34#include <vcl/settings.hxx>
36
38{
39public:
40 ImplData();
41
43 tools::Rectangle maItemEdgeClipRect; // used to clip the common edge between a toolbar item and the border of this window
44 Point maPos; // position of the floating window wrt. parent
46};
47
49{
50 mpBox = nullptr;
51}
52
54{
55 return mpImplData->maItemEdgeClipRect;
56}
57
59{
60 mpImplData.reset(new ImplData);
61
62 mpWindowImpl->mbFloatWin = true;
63 mbInCleanUp = false;
64 mbGrabFocus = false;
65
66 SAL_WARN_IF(!pParent, "vcl", "FloatWindow::FloatingWindow(): - pParent == NULL!");
67
68 if (!pParent)
70
71 SAL_WARN_IF(!pParent, "vcl", "FloatWindow::FloatingWindow(): - pParent == NULL and no AppWindow exists");
72
73 // no Border, then we don't need a border window
74 if (!nStyle)
75 {
76 mpWindowImpl->mbOverlapWin = true;
77 nStyle |= WB_DIALOGCONTROL;
78 ImplInit(pParent, nStyle, nullptr);
79 }
80 else
81 {
82 if (!(nStyle & WB_NODIALOGCONTROL))
83 nStyle |= WB_DIALOGCONTROL;
84
86 && !(nStyle & WB_OWNERDRAWDECORATION))
87 {
88 WinBits nFloatWinStyle = nStyle;
89 // #99154# floaters are not closeable by default anymore, eg fullscreen floater
90 // nFloatWinStyle |= WB_CLOSEABLE;
91 mpWindowImpl->mbFrame = true;
92 mpWindowImpl->mbOverlapWin = true;
93 ImplInit(pParent, nFloatWinStyle & ~WB_BORDER, nullptr);
94 }
95 else
96 {
97 VclPtr<ImplBorderWindow> pBorderWin;
99
100 if (nStyle & WB_OWNERDRAWDECORATION)
101 nBorderStyle |= BorderWindowStyle::Frame;
102 else
103 nBorderStyle |= BorderWindowStyle::Overlap;
104
105 if ((nStyle & WB_SYSTEMWINDOW) && !(nStyle & (WB_MOVEABLE | WB_SIZEABLE)))
106 {
107 nBorderStyle |= BorderWindowStyle::Frame;
108 nStyle |= WB_CLOSEABLE; // make undecorated floaters closeable
109 }
110 pBorderWin = VclPtr<ImplBorderWindow>::Create(pParent, nStyle, nBorderStyle);
111 ImplInit(pBorderWin, nStyle & ~WB_BORDER, nullptr);
112 pBorderWin->mpWindowImpl->mpClientWindow = this;
113 pBorderWin->GetBorder(mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder,
114 mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder);
115 pBorderWin->SetDisplayActive(true);
116 mpWindowImpl->mpBorderWindow = pBorderWin;
117 mpWindowImpl->mpRealParent = pParent;
118 }
119 }
121
122 mpNextFloat = nullptr;
123 mpFirstPopupModeWin = nullptr;
124 mnPostId = nullptr;
128 mbInPopupMode = false;
129 mbPopupMode = false;
130 mbPopupModeCanceled = false;
131 mbPopupModeTearOff = false;
132 mbMouseDown = false;
133
135}
136
138{
139 const StyleSettings& rStyleSettings = GetSettings().GetStyleSettings();
140
141 Color aColor;
143 aColor = GetControlBackground();
144 else if (Window::GetStyle() & WB_3DLOOK)
145 aColor = rStyleSettings.GetFaceColor();
146 else
147 aColor = rStyleSettings.GetWindowColor();
148 SetBackground(aColor);
149}
150
152 SystemWindow(WindowType::FLOATINGWINDOW, "vcl::FloatingWindow maLayoutIdle")
153{
154 ImplInitFloating(pParent, nStyle);
155}
156
157FloatingWindow::FloatingWindow(vcl::Window* pParent, const OString& rID, const OUString& rUIXMLDescription, const css::uno::Reference<css::frame::XFrame> &rFrame)
158 : SystemWindow(WindowType::FLOATINGWINDOW, "vcl::FloatingWindow maLayoutIdle")
159 , mpNextFloat(nullptr)
160 , mpFirstPopupModeWin(nullptr)
161 , mnPostId(nullptr)
162 , mnPopupModeFlags(FloatWinPopupFlags::NONE)
163 , mnTitle(FloatWinTitleType::Unknown)
164 , mnOldTitle(FloatWinTitleType::Unknown)
165 , mbInPopupMode(false)
166 , mbPopupMode(false)
167 , mbPopupModeCanceled(false)
168 , mbPopupModeTearOff(false)
169 , mbMouseDown(false)
170 , mbGrabFocus(false)
171 , mbInCleanUp(false)
172{
173 loadUI(pParent, rID, rUIXMLDescription, rFrame);
174}
175
176//Find the real parent stashed in mpDialogParent.
178{
179 vcl::Window *pParent = mpDialogParent;
180 mpDialogParent = nullptr;
181 ImplInitFloating(pParent, nBits);
182 mbIsDeferredInit = false;
183}
184
186{
187 const StyleSettings& rStyleSettings = rRenderContext.GetSettings().GetStyleSettings();
188
189 Color aColor;
190 if (Window::GetStyle() & WB_3DLOOK)
191 aColor = rStyleSettings.GetFaceColor();
192 else
193 aColor = rStyleSettings.GetWindowColor();
194
195 ApplyControlBackground(rRenderContext, aColor);
196}
197
199{
200 disposeOnce();
201 assert (!mnPostId);
202}
203
205{
207
208 if (mpImplData)
209 {
211 // indicates that ESC key was pressed
212 // will be handled in Window::ImplGrabFocus()
214
215 if ( IsInPopupMode() )
217
218 if ( mnPostId )
220 mnPostId = nullptr;
221 }
222
223 mpImplData.reset();
224
229}
230
232 const tools::Rectangle& rRect, FloatWinPopupFlags nFlags,
233 sal_uInt16& rArrangeIndex, Point* pLOKTwipsPos)
234{
235 // get window position
236 Point aPos;
237 Size aSize = ::isLayoutEnabled(pWindow) ? pWindow->get_preferred_size() : pWindow->GetSizePixel();
238 tools::Rectangle aScreenRect = pWindow->ImplGetFrameWindow()->GetDesktopRectPixel();
239 FloatingWindow *pFloatingWindow = dynamic_cast<FloatingWindow*>( pWindow );
240
241 // convert...
242 vcl::Window* pW = pWindow;
243 if ( pW->mpWindowImpl->mpRealParent )
244 pW = pW->mpWindowImpl->mpRealParent;
245
246 tools::Rectangle normRect( rRect ); // rRect is already relative to top-level window
247 normRect.SetPos( pW->ScreenToOutputPixel( normRect.TopLeft() ) );
248
249 bool bRTL = AllSettings::GetLayoutRTL();
250
251 tools::Rectangle devRect( pW->OutputToAbsoluteScreenPixel( normRect.TopLeft() ),
252 pW->OutputToAbsoluteScreenPixel( normRect.BottomRight() ) );
253
254 tools::Rectangle devRectRTL( devRect );
255 if( bRTL )
256 // create a rect that can be compared to desktop coordinates
257 devRectRTL = pW->ImplOutputToUnmirroredAbsoluteScreenPixel( normRect );
260 Application::GetBestScreen( bRTL ? devRectRTL : devRect ) );
261
262 FloatWinPopupFlags nArrangeAry[5];
263 sal_uInt16 nArrangeAttempts = 5;
264 Point e1,e2; // the common edge between the item rect and the floating window
265
266 if ( nFlags & FloatWinPopupFlags::Left )
267 {
268 nArrangeAry[0] = FloatWinPopupFlags::Left;
269 nArrangeAry[1] = FloatWinPopupFlags::Right;
270 nArrangeAry[2] = FloatWinPopupFlags::Up;
271 nArrangeAry[3] = FloatWinPopupFlags::Down;
272 nArrangeAry[4] = FloatWinPopupFlags::Left;
273 }
274 else if ( nFlags & FloatWinPopupFlags::Right )
275 {
276 nArrangeAry[0] = FloatWinPopupFlags::Right;
277 nArrangeAry[1] = FloatWinPopupFlags::Left;
278 nArrangeAry[2] = FloatWinPopupFlags::Up;
279 nArrangeAry[3] = FloatWinPopupFlags::Down;
280 nArrangeAry[4] = FloatWinPopupFlags::Right;
281 }
282 else if ( nFlags & FloatWinPopupFlags::Up )
283 {
284 nArrangeAry[0] = FloatWinPopupFlags::Up;
285 nArrangeAry[1] = FloatWinPopupFlags::Down;
287 {
288 nArrangeAry[2] = FloatWinPopupFlags::Up;
289 nArrangeAttempts = 3;
290 }
291 else
292 {
293 nArrangeAry[2] = FloatWinPopupFlags::Right;
294 nArrangeAry[3] = FloatWinPopupFlags::Left;
295 nArrangeAry[4] = FloatWinPopupFlags::Up;
296 }
297 }
298 else
299 {
300 nArrangeAry[0] = FloatWinPopupFlags::Down;
301 nArrangeAry[1] = FloatWinPopupFlags::Up;
303 {
304 nArrangeAry[2] = FloatWinPopupFlags::Down;
305 nArrangeAttempts = 3;
306 }
307 else
308 {
309 nArrangeAry[2] = FloatWinPopupFlags::Right;
310 nArrangeAry[3] = FloatWinPopupFlags::Left;
311 nArrangeAry[4] = FloatWinPopupFlags::Down;
312 }
313 }
314
315 sal_uInt16 nArrangeIndex = 0;
316 const bool bLOKActive = comphelper::LibreOfficeKit::isActive();
317
318 for ( ; nArrangeIndex < nArrangeAttempts; nArrangeIndex++ )
319 {
320 bool bBreak = true;
321 switch ( nArrangeAry[nArrangeIndex] )
322 {
323
325 aPos.setX( devRect.Left()-aSize.Width()+1 );
326 aPos.setY( devRect.Top() );
327 aPos.AdjustY( -(pWindow->mpWindowImpl->mnTopBorder) );
328 if( bRTL )
329 {
330 if( (devRectRTL.Right()+aSize.Width()) > aScreenRect.Right() )
331 bBreak = false;
332 }
333 else
334 {
335 if ( aPos.X() < aScreenRect.Left() )
336 bBreak = false;
337 }
338 if (bBreak || bLOKActive)
339 {
340 e1 = devRect.TopLeft();
341 e2 = devRect.BottomLeft();
342 // set non-zero width
343 e2.AdjustX( 1 );
344 // don't clip corners
345 e1.AdjustY( 1 );
346 e2.AdjustY( -1 );
347 }
348 break;
350 aPos = devRect.TopRight();
351 aPos.AdjustY( -(pWindow->mpWindowImpl->mnTopBorder) );
352 if( bRTL )
353 {
354 if( (devRectRTL.Left() - aSize.Width()) < aScreenRect.Left() )
355 bBreak = false;
356 }
357 else
358 {
359 if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
360 bBreak = false;
361 }
362 if (bBreak || bLOKActive)
363 {
364 e1 = devRect.TopRight();
365 e2 = devRect.BottomRight();
366 // set non-zero width
367 e2.AdjustX( 1 );
368 // don't clip corners
369 e1.AdjustY( 1 );
370 e2.AdjustY( -1 );
371 }
372 break;
374 aPos.setX( devRect.Left() );
375 aPos.setY( devRect.Top()-aSize.Height()+1 );
376 if ( aPos.Y() < aScreenRect.Top() )
377 bBreak = false;
378 if (bBreak || bLOKActive)
379 {
380 e1 = devRect.TopLeft();
381 e2 = devRect.TopRight();
382 // set non-zero height
383 e2.AdjustY( 1 );
384 // don't clip corners
385 e1.AdjustX( 1 );
386 e2.AdjustX( -1 );
387 }
388 break;
390 aPos = devRect.BottomLeft();
391 if ( aPos.Y()+aSize.Height() > aScreenRect.Bottom() )
392 bBreak = false;
393 if (bBreak || bLOKActive)
394 {
395 e1 = devRect.BottomLeft();
396 e2 = devRect.BottomRight();
397 // set non-zero height
398 e2.AdjustY( 1 );
399 // don't clip corners
400 e1.AdjustX( 1 );
401 e2.AdjustX( -1 );
402 }
403 break;
404 default: break;
405 }
406
407 // no further adjustment for LibreOfficeKit
408 if (bLOKActive)
409 break;
410
411 // adjust if necessary
412 if (bBreak)
413 {
414 if ( (nArrangeAry[nArrangeIndex] == FloatWinPopupFlags::Left) ||
415 (nArrangeAry[nArrangeIndex] == FloatWinPopupFlags::Right) )
416 {
417 if ( aPos.Y()+aSize.Height() > aScreenRect.Bottom() )
418 {
419 aPos.setY( devRect.Bottom()-aSize.Height()+1 );
420 if ( aPos.Y() < aScreenRect.Top() )
421 aPos.setY( aScreenRect.Top() );
422 }
423 }
424 else
425 {
426 if( bRTL )
427 {
428 if( devRectRTL.Right()-aSize.Width()+1 < aScreenRect.Left() )
429 aPos.AdjustX( -(aScreenRect.Left() - devRectRTL.Right() + aSize.Width() - 1) );
430 }
431 else if ( aPos.X()+aSize.Width() > aScreenRect.Right() )
432 {
433 aPos.setX( devRect.Right()-aSize.Width()+1 );
434 if ( aPos.X() < aScreenRect.Left() )
435 aPos.setX( aScreenRect.Left() );
436 }
437 }
438 }
439
440 if ( bBreak )
441 break;
442 }
443 if (nArrangeIndex >= nArrangeAttempts)
444 nArrangeIndex = nArrangeAttempts - 1;
445
446 rArrangeIndex = nArrangeIndex;
447
448 aPos = pW->AbsoluteScreenToOutputPixel( aPos );
449
450 // store a cliprect that can be used to clip the common edge of the itemrect and the floating window
451 if( pFloatingWindow && pFloatingWindow->mpImplData->mpBox )
452 {
453 pFloatingWindow->mpImplData->maItemEdgeClipRect =
454 tools::Rectangle( e1, e2 );
455 }
456
457 if (bLOKActive && pLOKTwipsPos)
458 {
459 if (pW->IsMapModeEnabled() || pW->GetMapMode().GetMapUnit() == MapUnit::MapPixel)
460 {
461 // if we use pW->LogicToLogic(aPos, pW->GetMapMode(), MapMode(MapUnit::MapTwip)),
462 // for pixel conversions when map mode is not enabled, we get
463 // a 20 twips per pixel conversion since LogicToLogic uses
464 // a fixed 72 dpi value, instead of a correctly computed output
465 // device dpi or at least the most commonly used 96 dpi value;
466 // and anyway the following is what we already do in
467 // ScGridWindow::LogicInvalidate when map mode is not enabled.
468
469 *pLOKTwipsPos = pW->PixelToLogic(aPos, MapMode(MapUnit::MapTwip));
470 }
471 else
472 {
473 *pLOKTwipsPos = OutputDevice::LogicToLogic(aPos, pW->GetMapMode(), MapMode(MapUnit::MapTwip));
474 }
475 }
476
477 // caller expects coordinates relative to top-level win
478 return pW->OutputToScreenPixel( aPos );
479}
480
482{
483 Point aAbsolute( rPos );
484
485 const OutputDevice *pWindowOutDev = pReference->GetOutDev();
486
487 // compare coordinates in absolute screen coordinates
488 if( pWindowOutDev->HasMirroredGraphics() )
489 {
490 if(!pReference->IsRTLEnabled() )
491 pWindowOutDev->ReMirror( aAbsolute );
492
493 tools::Rectangle aRect( pReference->ScreenToOutputPixel(aAbsolute), Size(1,1) ) ;
494 aRect = pReference->ImplOutputToUnmirroredAbsoluteScreenPixel( aRect );
495 aAbsolute = aRect.TopLeft();
496 }
497 else
498 aAbsolute = pReference->OutputToAbsoluteScreenPixel(
499 pReference->ScreenToOutputPixel(rPos) );
500
501 return aAbsolute;
502}
503
505{
506 tools::Rectangle aFloatRect = rRect;
507
508 const OutputDevice *pParentWinOutDev = pReference->GetOutDev();
509
510 // compare coordinates in absolute screen coordinates
511 // Keep in sync with FloatingWindow::ImplFloatHitTest, e.g. fdo#33509
512 if( pParentWinOutDev->HasMirroredGraphics() && !comphelper::LibreOfficeKit::isActive() )
513 {
514 if(!pReference->IsRTLEnabled() )
515 pParentWinOutDev->ReMirror(aFloatRect);
516
517 aFloatRect.SetPos(pReference->ScreenToOutputPixel(aFloatRect.TopLeft()));
518 aFloatRect = pReference->ImplOutputToUnmirroredAbsoluteScreenPixel(aFloatRect);
519 }
520 else
521 aFloatRect.SetPos(pReference->OutputToAbsoluteScreenPixel(pReference->ScreenToOutputPixel(rRect.TopLeft())));
522
523 return aFloatRect;
524}
525
527{
528 tools::Rectangle aFloatRect = rRect;
529
530 const OutputDevice *pParentWinOutDev = pReference->GetOutDev();
531
532 // compare coordinates in absolute screen coordinates
533 // Keep in sync with FloatingWindow::ImplFloatHitTest, e.g. fdo#33509
534 if( pParentWinOutDev->HasMirroredGraphics() )
535 {
536 aFloatRect = pReference->ImplUnmirroredAbsoluteScreenToOutputPixel(aFloatRect);
537 aFloatRect.SetPos(pReference->OutputToScreenPixel(aFloatRect.TopLeft()));
538
539 if(!pReference->IsRTLEnabled() )
540 pParentWinOutDev->ReMirror(aFloatRect);
541 }
542 else
543 aFloatRect.SetPos(pReference->OutputToScreenPixel(pReference->AbsoluteScreenToOutputPixel(rRect.TopLeft())));
544
545 return aFloatRect;
546}
547
548FloatingWindow* FloatingWindow::ImplFloatHitTest( vcl::Window* pReference, const Point& rPos, bool& rbHitTestInsideRect )
549{
550 FloatingWindow* pWin = this;
551 rbHitTestInsideRect = false;
552
553 Point aAbsolute(FloatingWindow::ImplConvertToAbsPos(pReference, rPos));
554
555 do
556 {
557 // compute the floating window's size in absolute screen coordinates
558
559 // use the border window to have the exact position
560 vcl::Window *pBorderWin = pWin->GetWindow( GetWindowType::Border );
561 if (!pBorderWin)
562 break;
563
564 // the top-left corner in output coordinates ie (0,0)
566 if ( devRect.Contains( aAbsolute ) )
567 {
568 // inside the window
569 return pWin;
570 }
571
572 // test, if mouse is in rectangle, (this is typically the rect of the active
573 // toolbox item or similar)
574 // note: maFloatRect is set in FloatingWindow::StartPopupMode() and
575 // is already in absolute device coordinates
576 if ( pWin->maFloatRect.Contains( aAbsolute ) )
577 {
578 rbHitTestInsideRect = true;
579 return pWin;
580 }
581
582 pWin = pWin->mpNextFloat;
583 }
584 while ( pWin );
585
586 return nullptr;
587}
588
590{
591 FloatingWindow* pWin = this;
592 FloatingWindow* pLastFoundWin = pWin;
593
594 do
595 {
597 pLastFoundWin = pWin;
598
599 pWin = pWin->mpNextFloat;
600 }
601 while ( pWin );
602
603 return pLastFoundWin;
604}
605
607{
608 FloatingWindow* pWin = this;
609
610 do
611 {
612 if ( pWin->mpFirstPopupModeWin == pWindow )
613 return true;
614
615 pWin = pWin->mpNextFloat;
616 }
617 while ( pWin );
618
619 return false;
620}
621
622IMPL_LINK_NOARG(FloatingWindow, ImplEndPopupModeHdl, void*, void)
623{
624 VclPtr<FloatingWindow> pThis(this);
625 mnPostId = nullptr;
626 mnPopupModeFlags = FloatWinPopupFlags::NONE;
627 mbPopupMode = false;
628 PopupModeEnd();
629}
630
632{
633 // call Base Class first for tab control
634 bool bRet = SystemWindow::EventNotify( rNEvt );
635 if ( !bRet )
636 {
637 if ( rNEvt.GetType() == NotifyEventType::KEYINPUT )
638 {
639 const KeyEvent* pKEvt = rNEvt.GetKeyEvent();
640 vcl::KeyCode aKeyCode = pKEvt->GetKeyCode();
641 sal_uInt16 nKeyCode = aKeyCode.GetCode();
642
643 if ( (nKeyCode == KEY_ESCAPE) && (GetStyle() & WB_CLOSEABLE) )
644 {
645 Close();
646 return true;
647 }
648 }
649 }
650
651 return bRet;
652}
653
655{
657 {
658 const tools::Rectangle aRect(Point(0,0), Size(GetSizePixel().Width()+1, GetSizePixel().Height()+1));
659 std::vector<vcl::LOKPayloadItem> aPayload
660 {
661 std::make_pair(OString("rectangle"), aRect.toString())
662 };
663 const vcl::ILibreOfficeKitNotifier* pNotifier = pParent->GetLOKNotifier();
664 pNotifier->notifyWindow(GetLOKWindowId(), "invalidate", aPayload);
665 }
666}
667
669{
671 {
673 }
674
676
678 if (pParent)
679 {
681 {
682 std::vector<vcl::LOKPayloadItem> aItems;
683 if (pParent == this)
684 {
685 // we are a toplevel window, let's so far pretend to be a
686 // dialog - but maybe we'll need a separate type for this
687 // later
688 if (mbInPopupMode)
689 aItems.emplace_back("type", "dropdown");
690 else
691 aItems.emplace_back("type", "dialog");
692 aItems.emplace_back("position", mpImplData->maLOKTwipsPos.toString()); // twips
693 }
694 else
695 {
696 SetLOKNotifier(pParent->GetLOKNotifier());
697 if (dynamic_cast<HelpTextWindow*>(this))
698 aItems.emplace_back("type", "tooltip");
699 else
700 aItems.emplace_back("type", "child");
701
702 aItems.emplace_back("parentId", OString::number(pParent->GetLOKWindowId()));
703 if (mbInPopupMode)
704 aItems.emplace_back("position", mpImplData->maPos.toString()); // pixels
705 else // mpImplData->maPos is not set
706 aItems.emplace_back("position", GetPosPixel().toString());
707
708 }
709 aItems.emplace_back("size", GetSizePixel().toString());
710 GetLOKNotifier()->notifyWindow(GetLOKWindowId(), "created", aItems);
711 }
712 else if (!IsVisible() && nType == StateChangedType::Visible)
713 {
714 if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier())
715 {
716 pNotifier->notifyWindow(GetLOKWindowId(), "close");
718 }
719 }
720 }
721
723 {
725 Invalidate();
726 }
727}
728
730{
732
733 if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
734 (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
735 {
737 Invalidate();
738 }
739}
740
742{
743 // PopupMode is finished
744 mbInPopupMode = false;
745
746 // call Handler asynchronously.
747 if ( mpImplData && !mnPostId )
748 mnPostId = Application::PostUserEvent(LINK(this, FloatingWindow, ImplEndPopupModeHdl));
749}
750
752{
753 maPopupModeEndHdl.Call( this );
754}
755
757{
758 if ( (mnTitle == nTitle) || !mpWindowImpl->mpBorderWindow )
759 return;
760
761 mnTitle = nTitle;
762 Size aOutSize = GetOutputSizePixel();
763 BorderWindowTitleType nTitleStyle;
764 if ( nTitle == FloatWinTitleType::Normal )
765 nTitleStyle = BorderWindowTitleType::Small;
766 else if ( nTitle == FloatWinTitleType::TearOff )
767 nTitleStyle = BorderWindowTitleType::Tearoff;
768 else if ( nTitle == FloatWinTitleType::Popup )
769 nTitleStyle = BorderWindowTitleType::Popup;
770 else // nTitle == FloatWinTitleType::NONE
771 nTitleStyle = BorderWindowTitleType::NONE;
772 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetTitleType( nTitleStyle, aOutSize );
773 static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
774}
775
777{
778 // remove title
780 if ( ( mpWindowImpl->mnStyle & WB_POPUP ) && !GetText().isEmpty() )
782 else if ( nFlags & FloatWinPopupFlags::AllowTearOff )
784 else
786
787 // avoid close on focus change for decorated floating windows only
788 if( mpWindowImpl->mbFrame && (GetStyle() & WB_MOVEABLE) )
790
791 // compute window position according to flags and arrangement
792 sal_uInt16 nArrangeIndex;
794 mpImplData->maPos = ImplCalcPos(this, rRect, nFlags, nArrangeIndex, &mpImplData->maLOKTwipsPos);
795 SetPosPixel( mpImplData->maPos );
796 ImplGetFrame()->PositionByToolkit(rRect, nFlags);
797
798 // set data and display window
799 // convert maFloatRect to absolute device coordinates
800 // so they can be compared across different frames
801 // !!! rRect is expected to be in screen coordinates of the parent frame window !!!
803
808 mnPopupModeFlags = nFlags;
809 mbInPopupMode = true;
810 mbPopupMode = true;
811 mbPopupModeCanceled = false;
812 mbPopupModeTearOff = false;
813 mbMouseDown = false;
814
815 // add FloatingWindow to list of windows that are in popup mode
816 ImplSVData* pSVData = ImplGetSVData();
818 pSVData->mpWinData->mpFirstFloat = this;
819 bool bGrabFocus(nFlags & FloatWinPopupFlags::GrabFocus);
820 if (bGrabFocus)
821 {
822 // force key input even without focus (useful for menus)
823 mbGrabFocus = true;
824 mxPrevFocusWin = Window::SaveFocus();
825 mpWindowImpl->mpFrameData->mbHasFocus = true;
826 }
828 if (bGrabFocus)
829 GrabFocus();
830}
831
833{
834 mpImplData->mpBox = pBox;
835
836 // get selected button
837 ToolBoxItemId nItemId = pBox->GetDownItemId();
838
839 if ( nItemId )
840 pBox->ImplFloatControl( true, this );
841
842 // retrieve some data from the ToolBox
843 tools::Rectangle aRect = nItemId ? pBox->GetItemRect( nItemId ) : pBox->GetOverflowRect();
844
845 // convert to parent's screen coordinates
847 aRect.SetPos( mpImplData->maPos );
848
849 nFlags |=
852
853 // set Flags for positioning
856 {
857 if ( pBox->IsHorizontal() )
858 nFlags |= FloatWinPopupFlags::Down;
859 else
861 }
862
863 // start FloatingMode
864 StartPopupMode( aRect, nFlags );
865}
866
868{
869 if ( !mbInPopupMode )
870 return;
871
872 ImplSVData* pSVData = ImplGetSVData();
873
874 mbInCleanUp = true; // prevent killing this window due to focus change while working with it
875
877 {
878 // stop the PopupMode also for all PopupMode windows created after us
879 std::vector<VclPtr<FloatingWindow>> aCancelFloats;
880 // stop the PopupMode also for all following PopupMode windows
881 for (auto pFloat = pSVData->mpWinData->mpFirstFloat;
882 pFloat != nullptr && pFloat != this;
883 pFloat = pFloat->mpNextFloat)
884 aCancelFloats.push_back(pFloat);
885 for (auto & it : aCancelFloats)
887 }
888
889 // delete window from the list
891 mpNextFloat = nullptr;
892
893 FloatWinPopupFlags nPopupModeFlags = mnPopupModeFlags;
895 nPopupModeFlags & FloatWinPopupFlags::AllowTearOff;
896
897 // hide window again if it was not deleted
900
901 if (HasChildPathFocus() && xFocusId != nullptr)
902 {
903 // restore focus to previous focus window if we still have the focus
904 Window::EndSaveFocus(xFocusId);
905 }
906 else if ( pSVData->mpWinData->mpFocusWin && pSVData->mpWinData->mpFirstFloat &&
908 {
909 // maybe pass focus on to a suitable FloatingWindow
910 pSVData->mpWinData->mpFirstFloat->GrabFocus();
911 }
912
914
915 // redo title
917
918 // set ToolBox again to normal
919 if (mpImplData && mpImplData->mpBox)
920 {
921 mpImplData->mpBox->ImplFloatControl( false, this );
922 // if the parent ToolBox is in popup mode, it should be closed too.
923 if ( GetDockingManager()->IsInPopupMode( mpImplData->mpBox ) )
925
926 mpImplData->mpBox = nullptr;
927 }
928
929 // call PopupModeEnd-Handler depending on parameter
930 if ( !(nFlags & FloatWinPopupEndFlags::DontCallHdl) )
932
933 // close all other windows depending on parameter
934 if ( nFlags & FloatWinPopupEndFlags::CloseAll )
935 {
936 if ( !(nPopupModeFlags & FloatWinPopupFlags::NewLevel) )
937 {
938 if (pSVData->mpWinData->mpFirstFloat)
939 {
940 FloatingWindow* pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
942 }
943 }
944 }
945
946 mbInCleanUp = false;
947}
948
950{
952}
953
955{
956 // !!! up-to-now only 1 window and not yet a list
957 mpFirstPopupModeWin = pWindow;
958}
959
961{
962 auto pWin = ImplGetParent();
963 if (pWin)
964 {
965 // Simulate Move, so the relative position of the floating window will be recalculated
966 pWin->ImplCallMove();
967 return true;
968 }
969
970 return false;
971}
972
973/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
BorderWindowTitleType
Definition: brdwin.hxx:65
BorderWindowStyle
Definition: brdwin.hxx:33
const StyleSettings & GetStyleSettings() const
static bool GetLayoutRTL()
static SAL_DLLPRIVATE unsigned int GetBestScreen(const tools::Rectangle &)
Get the "best" screen.
Definition: svapp.cxx:1396
static unsigned int GetScreenCount()
Get the number of screens available for the display.
Definition: svapp.cxx:1329
static bool IsUnifiedDisplay()
Determines if the screens that make up a display are separate or form one large display area.
Definition: svapp.cxx:1335
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
Post a user event to the default window.
Definition: svapp.cxx:1122
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
Remove user event based on event ID.
Definition: svapp.cxx:1146
static tools::Rectangle GetScreenPosSizePixel(unsigned int nScreen)
Get a screen's rectangular area.
Definition: svapp.cxx:1370
DataChangedEventType GetType() const
Definition: event.hxx:362
AllSettingsFlags GetFlags() const
Definition: event.hxx:363
VclPtr< ToolBox > mpBox
Definition: floatwin.cxx:42
Point maLOKTwipsPos
absolute position of the floating window in the document - in twips (for toplevel floating windows).
Definition: floatwin.cxx:45
tools::Rectangle maItemEdgeClipRect
Definition: floatwin.cxx:43
void StartPopupMode(const tools::Rectangle &rRect, FloatWinPopupFlags nFlags)
Definition: floatwin.cxx:776
bool mbGrabFocus
Definition: floatwin.hxx:74
SAL_DLLPRIVATE FloatingWindow * ImplFindLastLevelFloat()
Definition: floatwin.cxx:589
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects.
Definition: floatwin.cxx:204
SAL_DLLPRIVATE bool ImplIsFloatPopupModeWindow(const vcl::Window *pWindow)
Definition: floatwin.cxx:606
SAL_DLLPRIVATE FloatingWindow * ImplFloatHitTest(vcl::Window *pReference, const Point &rPos, bool &rbHitTestInsideRect)
Definition: floatwin.cxx:548
void PixelInvalidate(const tools::Rectangle *pRectangle) override
Notification about some rectangle of the output device got invalidated.
Definition: floatwin.cxx:654
virtual void doDeferredInit(WinBits nBits) override
Definition: floatwin.cxx:177
static Point ImplCalcPos(vcl::Window *pWindow, const tools::Rectangle &rRect, FloatWinPopupFlags nFlags, sal_uInt16 &rArrangeIndex, Point *pLOKTwipsPos=nullptr)
Definition: floatwin.cxx:231
bool mbPopupModeCanceled
Definition: floatwin.hxx:71
void EndPopupMode(FloatWinPopupEndFlags nFlags=FloatWinPopupEndFlags::NONE)
Definition: floatwin.cxx:949
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: floatwin.cxx:631
SAL_DLLPRIVATE void ImplInitSettings()
Definition: floatwin.cxx:137
SAL_DLLPRIVATE void ImplInitFloating(vcl::Window *pParent, WinBits nStyle)
Definition: floatwin.cxx:58
bool IsInPopupMode() const
Definition: floatwin.hxx:130
void SetTitleType(FloatWinTitleType nTitle)
Definition: floatwin.cxx:756
bool mbMouseDown
Definition: floatwin.hxx:73
bool mbInPopupMode
Definition: floatwin.hxx:69
static tools::Rectangle ImplConvertToRelPos(vcl::Window *pReference, const tools::Rectangle &rRect)
Definition: floatwin.cxx:526
ImplSVEvent * mnPostId
Definition: floatwin.hxx:65
FloatWinPopupFlags GetPopupModeFlags() const
Definition: floatwin.hxx:128
FloatingWindow(const FloatingWindow &)=delete
tools::Rectangle maFloatRect
Definition: floatwin.hxx:64
virtual void StateChanged(StateChangedType nType) override
Definition: floatwin.cxx:668
virtual void PopupModeEnd()
Definition: floatwin.cxx:751
bool mbPopupMode
Definition: floatwin.hxx:70
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: floatwin.cxx:729
VclPtr< FloatingWindow > mpNextFloat
Definition: floatwin.hxx:60
Link< FloatingWindow *, void > maPopupModeEndHdl
Definition: floatwin.hxx:76
bool mbPopupModeTearOff
Definition: floatwin.hxx:72
VclPtr< vcl::Window > mpFirstPopupModeWin
Definition: floatwin.hxx:61
FloatWinTitleType mnOldTitle
Definition: floatwin.hxx:68
FloatWinPopupFlags mnPopupModeFlags
Definition: floatwin.hxx:66
static Point ImplConvertToAbsPos(vcl::Window *pReference, const Point &rPos)
Definition: floatwin.cxx:481
virtual void ApplySettings(vcl::RenderContext &rRenderContext) override
Definition: floatwin.cxx:185
std::unique_ptr< ImplData > mpImplData
Definition: floatwin.hxx:63
FloatWinTitleType mnTitle
Definition: floatwin.hxx:67
void AddPopupModeWindow(vcl::Window *pWindow)
Definition: floatwin.cxx:954
SAL_DLLPRIVATE void ImplCallPopupModeEnd()
Definition: floatwin.cxx:741
virtual ~FloatingWindow() override
Definition: floatwin.cxx:198
SAL_DLLPRIVATE void ImplEndPopupMode(FloatWinPopupEndFlags nFlags, const VclPtr< vcl::Window > &xFocusId)
Definition: floatwin.cxx:867
SAL_DLLPRIVATE tools::Rectangle & ImplGetItemEdgeClipRect()
Definition: floatwin.cxx:53
VclPtr< vcl::Window > mxPrevFocusWin
Definition: floatwin.hxx:62
bool mbInCleanUp
Definition: floatwin.hxx:75
A tooltip: adds tips to widgets in a floating / popup window.
Definition: helpwin.hxx:31
void SetDisplayActive(bool bActive)
Definition: brdwin.cxx:1868
void GetBorder(sal_Int32 &rLeftBorder, sal_Int32 &rTopBorder, sal_Int32 &rRightBorder, sal_Int32 &rBottomBorder) const
Definition: brdwin.cxx:1963
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:57
MapUnit GetMapUnit() const
Definition: mapmod.cxx:150
const KeyEvent * GetKeyEvent() const
Definition: event.hxx:316
NotifyEventType GetType() const
Definition: event.hxx:308
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:171
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
Definition: map.cxx:1639
SAL_DLLPRIVATE void ReMirror(Point &rPoint) const
Definition: outdev.cxx:672
virtual bool HasMirroredGraphics() const
Definition: outdev.cxx:704
const AllSettings & GetSettings() const
Definition: outdev.hxx:289
virtual void PositionByToolkit(const tools::Rectangle &, FloatWinPopupFlags)
Definition: salframe.hxx:173
constexpr tools::Long Height() const
constexpr tools::Long Width() const
const Color & GetWindowColor() const
const Color & GetFaceColor() const
bool mbIsDeferredInit
Definition: syswin.hxx:114
virtual OUString GetText() const override
Definition: syswin.cxx:1057
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: syswin.cxx:176
SAL_DLLPRIVATE void DoInitialLayout()
Definition: syswin.cxx:1096
bool UpdatePositionData()
Definition: floatwin.cxx:960
bool isLayoutEnabled() const
Definition: syswin.cxx:1004
void loadUI(vcl::Window *pParent, const OString &rID, const OUString &rUIXMLDescription, const css::uno::Reference< css::frame::XFrame > &rFrame=css::uno::Reference< css::frame::XFrame >())
Definition: syswin.cxx:90
virtual bool Close()
Definition: syswin.cxx:262
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects.
Definition: syswin.cxx:103
VclPtr< vcl::Window > mpDialogParent
Definition: syswin.hxx:115
A toolbar: contains all those icons, typically below the menu bar.
Definition: toolbox.hxx:74
ToolBoxItemId GetDownItemId() const
Definition: toolbox.hxx:354
tools::Rectangle GetItemRect(ToolBoxItemId nItemId)
Definition: toolbox2.cxx:838
bool IsHorizontal() const
Definition: toolbox.hxx:333
tools::Rectangle const & GetOverflowRect() const
Definition: toolbox2.cxx:858
SAL_DLLPRIVATE void ImplFloatControl(bool bStart, FloatingWindow *pWindow)
Definition: toolbox.cxx:2814
void clear()
Definition: vclptr.hxx:190
static VclPtr< reference_type > Create(Arg &&... arg)
A construction helper for VclPtr.
Definition: vclptr.hxx:127
bool Contains(const Point &rPOINT) const
constexpr tools::Long Top() const
constexpr Point TopLeft() const
void SetPos(const Point &rPoint)
constexpr tools::Long Right() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
constexpr Point BottomRight() const
constexpr Point TopRight() const
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
rtl::OString toString() const
constexpr Point BottomLeft() const
sal_uInt16 GetCode() const
Definition: keycod.hxx:49
Point AbsoluteScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2867
Point OutputToScreenPixel(const Point &rPos) const
Definition: window.cxx:2808
SAL_DLLPRIVATE bool ImplIsWindowOrChild(const vcl::Window *pWindow, bool bSystemWindow=false) const
Definition: stacking.cxx:699
SAL_DLLPRIVATE tools::Rectangle ImplOutputToUnmirroredAbsoluteScreenPixel(const tools::Rectangle &rRect) const
Definition: window.cxx:2877
void SetActivateMode(ActivateModeFlags nMode)
Definition: window.cxx:2637
vcl::Window * GetParent() const
Definition: window2.cxx:1121
virtual void StateChanged(StateChangedType nStateChange)
Definition: window.cxx:1942
void SetLOKNotifier(const vcl::ILibreOfficeKitNotifier *pNotifier, bool bParent=false)
Interface to register for dialog / window tunneling.
Definition: window.cxx:3183
bool HasChildPathFocus(bool bSystemWindow=false) const
Definition: window.cxx:3009
tools::Rectangle GetDesktopRectPixel() const
Definition: window.cxx:2801
SAL_DLLPRIVATE tools::Rectangle ImplUnmirroredAbsoluteScreenToOutputPixel(const tools::Rectangle &rRect) const
Definition: window.cxx:2896
void ApplyControlBackground(vcl::RenderContext &rRenderContext, const Color &rDefaultColor)
Definition: window2.cxx:553
static DockingManager * GetDockingManager()
Definition: window2.cxx:822
void GetBorder(sal_Int32 &rLeftBorder, sal_Int32 &rTopBorder, sal_Int32 &rRightBorder, sal_Int32 &rBottomBorder) const
Definition: window.cxx:2426
Size get_preferred_size() const
Definition: window2.cxx:1692
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1035
void GrabFocus()
Definition: window.cxx:2981
void ReleaseLOKNotifier()
Indicate that LOK is not going to use this dialog any more.
Definition: window.cxx:3221
virtual Point GetPosPixel() const
Definition: window.cxx:2796
bool IsMapModeEnabled() const
Definition: window3.cxx:106
WinBits GetStyle() const
Definition: window2.cxx:977
const AllSettings & GetSettings() const
Definition: window3.cxx:129
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2189
SAL_DLLPRIVATE vcl::Window * ImplGetParent() const
Definition: window2.cxx:884
const MapMode & GetMapMode() const
Definition: window3.cxx:99
VclPtr< vcl::Window > GetParentWithLOKNotifier()
Find the nearest parent with LOK Notifier; can be itself if this Window has LOK notifier set.
Definition: window.cxx:3263
::OutputDevice const * GetOutDev() const
Definition: window.cxx:567
const vcl::ILibreOfficeKitNotifier * GetLOKNotifier() const
Definition: window.cxx:3253
std::unique_ptr< WindowImpl > mpWindowImpl
Definition: window.hxx:484
vcl::LOKWindowId GetLOKWindowId() const
Definition: window.cxx:3258
SalFrame * ImplGetFrame() const
Definition: window2.cxx:867
bool IsRTLEnabled() const
Definition: window3.cxx:127
Point PixelToLogic(const Point &rDevicePt) const
Definition: window3.cxx:161
virtual Size GetSizePixel() const
Definition: window.cxx:2404
Size GetOutputSizePixel() const
Definition: window3.cxx:89
bool IsControlBackground() const
Definition: window2.cxx:1111
virtual void DataChanged(const DataChangedEvent &rDCEvt)
Definition: event.cxx:36
DialogControlFlags GetDialogControlFlags() const
Definition: window2.cxx:1081
const Color & GetControlBackground() const
Definition: window2.cxx:1106
bool IsVisible() const
Definition: window2.cxx:1126
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1143
virtual void SetPosPixel(const Point &rNewPos)
Definition: window2.cxx:1281
Point OutputToAbsoluteScreenPixel(const Point &rPos) const
Definition: window.cxx:2857
Point ScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2814
void SetDialogControlFlags(DialogControlFlags nFlags)
Definition: window2.cxx:1076
SAL_DLLPRIVATE vcl::Window * ImplGetFrameWindow() const
Definition: window2.cxx:925
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle, SystemParentData *pSystemParentData)
Definition: window.cxx:940
void SetBackground()
Definition: window3.cxx:100
IMPL_LINK_NOARG(FloatingWindow, ImplEndPopupModeHdl, void *, void)
Definition: floatwin.cxx:622
FloatWinPopupEndFlags
Definition: floatwin.hxx:34
FloatWinTitleType
Definition: floatwin.hxx:48
constexpr sal_uInt16 KEY_ESCAPE
Definition: keycodes.hxx:120
#define SAL_WARN_IF(condition, area, stream)
NONE
Unknown
OUString toString(OptionInfo const *info)
QPRO_FUNC_TYPE nType
ImplSVFrameData maFrameData
Definition: svdata.hxx:402
ImplSVWinData * mpWinData
Definition: svdata.hxx:403
VclPtr< WorkWindow > mpAppWin
Definition: svdata.hxx:247
VclPtr< FloatingWindow > mpFirstFloat
Definition: svdata.hxx:258
VclPtr< vcl::Window > mpFocusWin
Definition: svdata.hxx:255
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:76
FloatWinPopupFlags
Definition: vclenum.hxx:330
StateChangedType
Definition: window.hxx:291
sal_Int64 WinBits
Definition: wintypes.hxx:109
WinBits const WB_CLOSEABLE
Definition: wintypes.hxx:123
WinBits const WB_MOVEABLE
Definition: wintypes.hxx:122
WinBits const WB_DIALOGCONTROL
Definition: wintypes.hxx:113
WinBits const WB_OWNERDRAWDECORATION
Definition: wintypes.hxx:173
WindowType
Definition: wintypes.hxx:27
WinBits const WB_POPUP
Definition: wintypes.hxx:175
WinBits const WB_SIZEABLE
Definition: wintypes.hxx:117
WinBits const WB_SYSTEMWINDOW
Definition: wintypes.hxx:126
WinBits const WB_3DLOOK
Definition: wintypes.hxx:118
WinBits const WB_BORDER
Definition: wintypes.hxx:115
WinBits const WB_NODIALOGCONTROL
Definition: wintypes.hxx:114
WinBits const WB_STANDALONE
Definition: wintypes.hxx:124