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>
33 #include <vcl/toolkit/floatwin.hxx>
34 #include <vcl/settings.hxx>
36 
38 {
39 public:
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)
69  pParent = ImplGetSVData()->maFrameData.mpAppWin;
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;
142  if (IsControlBackground())
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 
153 {
154  ImplInitFloating(pParent, nStyle);
155 }
156 
157 FloatingWindow::FloatingWindow(vcl::Window* pParent, const OString& rID, const OUString& rUIXMLDescription, const css::uno::Reference<css::frame::XFrame> &rFrame)
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  {
210  if( mbPopupModeCanceled )
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 
225  mpNextFloat.clear();
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 
324  case FloatWinPopupFlags::Left:
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;
349  case FloatWinPopupFlags::Right:
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;
373  case FloatWinPopupFlags::Up:
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() )
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 
548 FloatingWindow* 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.IsInside( 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.IsInside( 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 
622 IMPL_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() == MouseNotifyEvent::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  std::vector<vcl::LOKPayloadItem> aPayload;
659  const tools::Rectangle aRect(Point(0,0), Size(GetSizePixel().Width()+1, GetSizePixel().Height()+1));
660  aPayload.push_back(std::make_pair(OString("rectangle"), aRect.toString()));
661  const vcl::ILibreOfficeKitNotifier* pNotifier = pParent->GetLOKNotifier();
662  pNotifier->notifyWindow(GetLOKWindowId(), "invalidate", aPayload);
663  }
664 }
665 
667 {
668  if (nType == StateChangedType::InitShow)
669  {
670  DoInitialLayout();
671  }
672 
674 
676  if (pParent)
677  {
678  if (nType == StateChangedType::InitShow)
679  {
680  std::vector<vcl::LOKPayloadItem> aItems;
681  if (pParent == this)
682  {
683  // we are a toplevel window, let's so far pretend to be a
684  // dialog - but maybe we'll need a separate type for this
685  // later
686  aItems.emplace_back("type", "dialog");
687  aItems.emplace_back("position", mpImplData->maLOKTwipsPos.toString()); // twips
688  }
689  else
690  {
691  SetLOKNotifier(pParent->GetLOKNotifier());
692  if (dynamic_cast<HelpTextWindow*>(this))
693  aItems.emplace_back("type", "tooltip");
694  else
695  aItems.emplace_back("type", "child");
696 
697  aItems.emplace_back("parentId", OString::number(pParent->GetLOKWindowId()));
698  if (mbInPopupMode)
699  aItems.emplace_back("position", mpImplData->maPos.toString()); // pixels
700  else // mpImplData->maPos is not set
701  aItems.emplace_back("position", GetPosPixel().toString());
702 
703  }
704  aItems.emplace_back("size", GetSizePixel().toString());
705  GetLOKNotifier()->notifyWindow(GetLOKWindowId(), "created", aItems);
706  }
707  else if (!IsVisible() && nType == StateChangedType::Visible)
708  {
709  if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier())
710  {
711  pNotifier->notifyWindow(GetLOKWindowId(), "close");
713  }
714  }
715  }
716 
718  {
720  Invalidate();
721  }
722 }
723 
725 {
726  SystemWindow::DataChanged( rDCEvt );
727 
728  if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) &&
729  (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) )
730  {
732  Invalidate();
733  }
734 }
735 
737 {
738  // PopupMode is finished
739  mbInPopupMode = false;
740 
741  // call Handler asynchronously.
742  if ( mpImplData && !mnPostId )
743  mnPostId = Application::PostUserEvent(LINK(this, FloatingWindow, ImplEndPopupModeHdl));
744 }
745 
747 {
748  maPopupModeEndHdl.Call( this );
749 }
750 
752 {
753  if ( (mnTitle == nTitle) || !mpWindowImpl->mpBorderWindow )
754  return;
755 
756  mnTitle = nTitle;
757  Size aOutSize = GetOutputSizePixel();
758  BorderWindowTitleType nTitleStyle;
759  if ( nTitle == FloatWinTitleType::Normal )
760  nTitleStyle = BorderWindowTitleType::Small;
761  else if ( nTitle == FloatWinTitleType::TearOff )
762  nTitleStyle = BorderWindowTitleType::Tearoff;
763  else if ( nTitle == FloatWinTitleType::Popup )
764  nTitleStyle = BorderWindowTitleType::Popup;
765  else // nTitle == FloatWinTitleType::NONE
766  nTitleStyle = BorderWindowTitleType::NONE;
767  static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->SetTitleType( nTitleStyle, aOutSize );
768  static_cast<ImplBorderWindow*>(mpWindowImpl->mpBorderWindow.get())->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder );
769 }
770 
772 {
773  // remove title
775  if ( ( mpWindowImpl->mnStyle & WB_POPUP ) && !GetText().isEmpty() )
777  else if ( nFlags & FloatWinPopupFlags::AllowTearOff )
779  else
781 
782  // avoid close on focus change for decorated floating windows only
783  if( mpWindowImpl->mbFrame && (GetStyle() & WB_MOVEABLE) )
785 
786  // compute window position according to flags and arrangement
787  sal_uInt16 nArrangeIndex;
788  DoInitialLayout();
789  mpImplData->maPos = ImplCalcPos(this, rRect, nFlags, nArrangeIndex, &mpImplData->maLOKTwipsPos);
790  SetPosPixel( mpImplData->maPos );
791  ImplGetFrame()->PositionByToolkit(rRect, nFlags);
792 
793  // set data and display window
794  // convert maFloatRect to absolute device coordinates
795  // so they can be compared across different frames
796  // !!! rRect is expected to be in screen coordinates of the parent frame window !!!
798 
799  maFloatRect.AdjustLeft( -2 );
800  maFloatRect.AdjustTop( -2 );
803  mnPopupModeFlags = nFlags;
804  mbInPopupMode = true;
805  mbPopupMode = true;
806  mbPopupModeCanceled = false;
807  mbPopupModeTearOff = false;
808  mbMouseDown = false;
809 
810  // add FloatingWindow to list of windows that are in popup mode
811  ImplSVData* pSVData = ImplGetSVData();
812  mpNextFloat = pSVData->mpWinData->mpFirstFloat;
813  pSVData->mpWinData->mpFirstFloat = this;
814  bool bGrabFocus(nFlags & FloatWinPopupFlags::GrabFocus);
815  if (bGrabFocus)
816  {
817  // force key input even without focus (useful for menus)
818  mbGrabFocus = true;
819  mxPrevFocusWin = Window::SaveFocus();
820  mpWindowImpl->mpFrameData->mbHasFocus = true;
821  }
822  Show( true, ShowFlags::NoActivate );
823  if (bGrabFocus)
824  GrabFocus();
825 }
826 
828 {
829  mpImplData->mpBox = pBox;
830 
831  // get selected button
832  ToolBoxItemId nItemId = pBox->GetDownItemId();
833 
834  if ( nItemId )
835  pBox->ImplFloatControl( true, this );
836 
837  // retrieve some data from the ToolBox
838  tools::Rectangle aRect = nItemId ? pBox->GetItemRect( nItemId ) : pBox->GetOverflowRect();
839 
840  // convert to parent's screen coordinates
842  aRect.SetPos( mpImplData->maPos );
843 
844  nFlags |=
847 
848  // set Flags for positioning
851  {
852  if ( pBox->IsHorizontal() )
853  nFlags |= FloatWinPopupFlags::Down;
854  else
855  nFlags |= FloatWinPopupFlags::Right;
856  }
857 
858  // start FloatingMode
859  StartPopupMode( aRect, nFlags );
860 }
861 
863 {
864  if ( !mbInPopupMode )
865  return;
866 
867  ImplSVData* pSVData = ImplGetSVData();
868 
869  mbInCleanUp = true; // prevent killing this window due to focus change while working with it
870 
872  {
873  // stop the PopupMode also for all PopupMode windows created after us
874  std::vector<VclPtr<FloatingWindow>> aCancelFloats;
875  // stop the PopupMode also for all following PopupMode windows
876  for (auto pFloat = pSVData->mpWinData->mpFirstFloat;
877  pFloat != nullptr && pFloat != this;
878  pFloat = pFloat->mpNextFloat)
879  aCancelFloats.push_back(pFloat);
880  for (auto & it : aCancelFloats)
881  it->EndPopupMode(FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::NoCloseChildren);
882  }
883 
884  // delete window from the list
885  pSVData->mpWinData->mpFirstFloat = mpNextFloat;
886  mpNextFloat = nullptr;
887 
888  FloatWinPopupFlags nPopupModeFlags = mnPopupModeFlags;
890  nPopupModeFlags & FloatWinPopupFlags::AllowTearOff;
891 
892  // hide window again if it was not deleted
893  if (!mbPopupModeTearOff)
894  Show( false, ShowFlags::NoFocusChange );
895 
896  if (HasChildPathFocus() && xFocusId != nullptr)
897  {
898  // restore focus to previous focus window if we still have the focus
899  Window::EndSaveFocus(xFocusId);
900  }
901  else if ( pSVData->mpWinData->mpFocusWin && pSVData->mpWinData->mpFirstFloat &&
903  {
904  // maybe pass focus on to a suitable FloatingWindow
905  pSVData->mpWinData->mpFirstFloat->GrabFocus();
906  }
907 
909 
910  // redo title
912 
913  // set ToolBox again to normal
914  if (mpImplData && mpImplData->mpBox)
915  {
916  mpImplData->mpBox->ImplFloatControl( false, this );
917  // if the parent ToolBox is in popup mode, it should be closed too.
918  if ( GetDockingManager()->IsInPopupMode( mpImplData->mpBox ) )
920 
921  mpImplData->mpBox = nullptr;
922  }
923 
924  // call PopupModeEnd-Handler depending on parameter
925  if ( !(nFlags & FloatWinPopupEndFlags::DontCallHdl) )
927 
928  // close all other windows depending on parameter
929  if ( nFlags & FloatWinPopupEndFlags::CloseAll )
930  {
931  if ( !(nPopupModeFlags & FloatWinPopupFlags::NewLevel) )
932  {
933  if (pSVData->mpWinData->mpFirstFloat)
934  {
935  FloatingWindow* pLastLevelFloat = pSVData->mpWinData->mpFirstFloat->ImplFindLastLevelFloat();
936  pLastLevelFloat->EndPopupMode( FloatWinPopupEndFlags::Cancel | FloatWinPopupEndFlags::CloseAll );
937  }
938  }
939  }
940 
941  mbInCleanUp = false;
942 }
943 
945 {
947 }
948 
950 {
951  // !!! up-to-now only 1 window and not yet a list
952  mpFirstPopupModeWin = pWindow;
953 }
954 
956 {
957  auto pWin = ImplGetParent();
958  if (pWin)
959  {
960  // Simulate Move, so the relative position of the floating window will be recalculated
961  pWin->ImplCallMove();
962  return true;
963  }
964 
965  return false;
966 }
967 
968 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual Point GetPosPixel() const
Definition: window.cxx:2781
void SetPos(const Point &rPoint)
FloatWinTitleType mnOldTitle
Definition: floatwin.hxx:68
bool IsControlBackground() const
Definition: window2.cxx:1081
bool IsInPopupMode() const
Definition: floatwin.hxx:130
void SetBackground()
Definition: window3.cxx:100
vcl::LOKWindowId GetLOKWindowId() const
Definition: window.cxx:3243
void StartPopupMode(const tools::Rectangle &rRect, FloatWinPopupFlags nFlags)
Definition: floatwin.cxx:771
bool mbPopupMode
Definition: floatwin.hxx:70
WinBits const WB_SYSTEMWINDOW
VclPtr< vcl::Window > mpFocusWin
Definition: svdata.hxx:250
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:88
tools::Long AdjustRight(tools::Long nHorzMoveDelta)
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: syswin.cxx:174
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
Definition: map.cxx:1562
virtual void StateChanged(StateChangedType nType) override
Definition: floatwin.cxx:666
WinBits const WB_NODIALOGCONTROL
constexpr tools::Long Left() const
void PixelInvalidate(const tools::Rectangle *pRectangle) override
Notification about some rectangle of the output device got invalidated.
Definition: floatwin.cxx:654
SAL_DLLPRIVATE void ImplFloatControl(bool bStart, FloatingWindow *pWindow)
Definition: toolbox.cxx:2823
FloatingWindow(const FloatingWindow &)=delete
Point AbsoluteScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2852
SAL_DLLPRIVATE void ImplInitFloating(vcl::Window *pParent, WinBits nStyle)
Definition: floatwin.cxx:58
void SetDisplayActive(bool bActive)
Definition: brdwin.cxx:1859
const StyleSettings & GetStyleSettings() const
const Color & GetFaceColor() const
Link< FloatingWindow *, void > maPopupModeEndHdl
Definition: floatwin.hxx:76
virtual Size GetSizePixel() const
Definition: window.cxx:2392
SAL_DLLPRIVATE vcl::Window * ImplGetFrameWindow() const
Definition: window2.cxx:895
virtual ~FloatingWindow() override
Definition: floatwin.cxx:198
void SetLOKNotifier(const vcl::ILibreOfficeKitNotifier *pNotifier, bool bParent=false)
Interface to register for dialog / window tunneling.
Definition: window.cxx:3168
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:1025
sal_uInt16 GetCode() const
Definition: keycod.hxx:49
static bool IsUnifiedDisplay()
Determines if the screens that make up a display are separate or form one large display area...
Definition: svapp.cxx:1232
bool mbGrabFocus
Definition: floatwin.hxx:74
SAL_DLLPRIVATE tools::Rectangle ImplOutputToUnmirroredAbsoluteScreenPixel(const tools::Rectangle &rRect) const
Definition: window.cxx:2862
DataChangedEventType GetType() const
Definition: event.hxx:362
const KeyEvent * GetKeyEvent() const
Definition: event.hxx:316
tools::Rectangle GetDesktopRectPixel() const
Definition: window.cxx:2786
SAL_DLLPRIVATE void ImplInitSettings()
Definition: floatwin.cxx:137
const Color & GetControlBackground() const
Definition: window2.cxx:1076
bool mbInCleanUp
Definition: floatwin.hxx:75
FloatWinPopupFlags
Definition: vclenum.hxx:367
bool IsRTLEnabled() const
Definition: window3.cxx:127
static Point ImplCalcPos(vcl::Window *pWindow, const tools::Rectangle &rRect, FloatWinPopupFlags nFlags, sal_uInt16 &rArrangeIndex, Point *pLOKTwipsPos=nullptr)
Definition: floatwin.cxx:231
bool HasChildPathFocus(bool bSystemWindow=false) const
Definition: window.cxx:2994
tools::Rectangle GetItemRect(ToolBoxItemId nItemId)
Definition: toolbox2.cxx:835
Unknown
BorderWindowTitleType
Definition: brdwin.hxx:65
DialogControlFlags GetDialogControlFlags() const
Definition: window2.cxx:1051
NONE
tools::Rectangle const & GetOverflowRect() const
Definition: toolbox2.cxx:855
tools::Rectangle maFloatRect
Definition: floatwin.hxx:64
StateChangedType
Definition: window.hxx:289
constexpr tools::Long Width() const
FloatWinPopupEndFlags
Definition: floatwin.hxx:33
WinBits const WB_OWNERDRAWDECORATION
sal_Int64 WinBits
bool mbPopupModeTearOff
Definition: floatwin.hxx:72
static tools::Rectangle ImplConvertToRelPos(vcl::Window *pReference, const tools::Rectangle &rRect)
Definition: floatwin.cxx:526
SAL_DLLPRIVATE void ReMirror(Point &rPoint) const
Definition: outdev.cxx:667
VclPtr< vcl::Window > GetParentWithLOKNotifier()
Find the nearest parent with LOK Notifier; can be itself if this Window has LOK notifier set...
Definition: window.cxx:3248
AllSettingsFlags GetFlags() const
Definition: event.hxx:363
bool IsHorizontal() const
Definition: toolbox.hxx:345
VclPtr< ToolBox > mpBox
Definition: floatwin.cxx:42
FloatWinPopupFlags GetPopupModeFlags() const
Definition: floatwin.hxx:128
SAL_DLLPRIVATE tools::Rectangle & ImplGetItemEdgeClipRect()
Definition: floatwin.cxx:53
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
tools::Rectangle maItemEdgeClipRect
Definition: floatwin.cxx:43
IMPL_LINK_NOARG(FloatingWindow, ImplEndPopupModeHdl, void *, void)
Definition: floatwin.cxx:622
std::unique_ptr< ImplData > mpImplData
Definition: floatwin.hxx:63
virtual bool Close()
Definition: syswin.cxx:260
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
Remove user event based on event ID.
Definition: svapp.cxx:1049
WinBits const WB_DIALOGCONTROL
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:75
void clear()
Definition: vclptr.hxx:190
static tools::Rectangle GetScreenPosSizePixel(unsigned int nScreen)
Get a screen's rectangular area.
Definition: svapp.cxx:1267
VclPtr< vcl::Window > mxPrevFocusWin
Definition: floatwin.hxx:62
void SetActivateMode(ActivateModeFlags nMode)
Definition: window.cxx:2625
Point maLOKTwipsPos
absolute position of the floating window in the document - in twips (for toplevel floating windows)...
Definition: floatwin.cxx:45
const MapMode & GetMapMode() const
Definition: window3.cxx:99
virtual void doDeferredInit(WinBits nBits) override
Definition: floatwin.cxx:177
VclPtr< WorkWindow > mpAppWin
Definition: svdata.hxx:242
virtual void Invalidate(InvalidateFlags nFlags=InvalidateFlags::NONE)
Definition: paint.cxx:1164
static Point ImplConvertToAbsPos(vcl::Window *pReference, const Point &rPos)
Definition: floatwin.cxx:481
virtual bool HasMirroredGraphics() const
Definition: outdev.cxx:699
constexpr tools::Long Right() const
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:168
const AllSettings & GetSettings() const
Definition: window3.cxx:129
void AddPopupModeWindow(vcl::Window *pWindow)
Definition: floatwin.cxx:949
static bool GetLayoutRTL()
std::unique_ptr< WindowImpl > mpWindowImpl
Definition: window.hxx:483
SAL_DLLPRIVATE vcl::Window * ImplGetParent() const
Definition: window2.cxx:854
Size get_preferred_size() const
Definition: window2.cxx:1655
bool mbIsDeferredInit
Definition: syswin.hxx:113
constexpr tools::Long Top() const
MouseNotifyEvent GetType() const
Definition: event.hxx:308
VclPtr< FloatingWindow > mpNextFloat
Definition: floatwin.hxx:60
bool IsInside(const Point &rPOINT) const
SAL_DLLPRIVATE FloatingWindow * ImplFindLastLevelFloat()
Definition: floatwin.cxx:589
const AllSettings & GetSettings() const
Definition: outdev.hxx:288
FloatWinPopupFlags mnPopupModeFlags
Definition: floatwin.hxx:66
MapUnit GetMapUnit() const
Definition: mapmod.cxx:138
static unsigned int GetScreenCount()
Get the number of screens available for the display.
Definition: svapp.cxx:1226
static SAL_DLLPRIVATE unsigned int GetBestScreen(const tools::Rectangle &)
Get the "best" screen.
Definition: svapp.cxx:1293
Point PixelToLogic(const Point &rDevicePt) const
Definition: window3.cxx:161
SAL_DLLPRIVATE bool ImplIsFloatPopupModeWindow(const vcl::Window *pWindow)
Definition: floatwin.cxx:606
virtual void PopupModeEnd()
Definition: floatwin.cxx:746
Point ScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2799
void GrabFocus()
Definition: window.cxx:2966
virtual void DataChanged(const DataChangedEvent &rDCEvt) override
Definition: floatwin.cxx:724
FloatWinTitleType
Definition: floatwin.hxx:47
vcl::Window * GetParent() const
Definition: window2.cxx:1091
Point OutputToAbsoluteScreenPixel(const Point &rPos) const
Definition: window.cxx:2842
constexpr Point TopLeft() const
tools::Long AdjustTop(tools::Long nVertMoveDelta)
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1035
SAL_DLLPRIVATE void ImplEndPopupMode(FloatWinPopupEndFlags nFlags, const VclPtr< vcl::Window > &xFocusId)
Definition: floatwin.cxx:862
constexpr tools::Long Bottom() const
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle, SystemParentData *pSystemParentData)
Definition: window.cxx:935
SAL_DLLPRIVATE void ImplCallPopupModeEnd()
Definition: floatwin.cxx:736
WinBits const WB_3DLOOK
WinBits const WB_SIZEABLE
WinBits const WB_STANDALONE
void GetBorder(sal_Int32 &rLeftBorder, sal_Int32 &rTopBorder, sal_Int32 &rRightBorder, sal_Int32 &rBottomBorder) const
Definition: window.cxx:2414
bool IsMapModeEnabled() const
Definition: window3.cxx:106
SalFrame * ImplGetFrame() const
Definition: window2.cxx:837
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:57
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: syswin.cxx:101
ImplSVEvent * mnPostId
Definition: floatwin.hxx:65
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: floatwin.cxx:631
WindowType
#define SAL_WARN_IF(condition, area, stream)
constexpr tools::Long Height() const
bool mbPopupModeCanceled
Definition: floatwin.hxx:71
WinBits const WB_BORDER
constexpr sal_uInt16 KEY_ESCAPE
Definition: keycodes.hxx:120
void GetBorder(sal_Int32 &rLeftBorder, sal_Int32 &rTopBorder, sal_Int32 &rRightBorder, sal_Int32 &rBottomBorder) const
Definition: brdwin.cxx:1954
ImplSVFrameData maFrameData
Definition: svdata.hxx:395
bool IsVisible() const
Definition: window2.cxx:1096
virtual OUString GetText() const override
Definition: syswin.cxx:1057
::OutputDevice const * GetOutDev() const
Definition: window.cxx:565
SAL_DLLPRIVATE tools::Rectangle ImplUnmirroredAbsoluteScreenToOutputPixel(const tools::Rectangle &rRect) const
Definition: window.cxx:2881
static VclPtr< reference_type > Create(Arg &&...arg)
A construction helper for VclPtr.
Definition: vclptr.hxx:127
virtual void PositionByToolkit(const tools::Rectangle &, FloatWinPopupFlags)
Definition: salframe.hxx:173
FloatWinTitleType mnTitle
Definition: floatwin.hxx:67
bool UpdatePositionData()
Definition: floatwin.cxx:955
const Color & GetWindowColor() const
BorderWindowStyle
Definition: brdwin.hxx:33
SAL_DLLPRIVATE bool ImplIsWindowOrChild(const vcl::Window *pWindow, bool bSystemWindow=false) const
Definition: stacking.cxx:699
VclPtr< FloatingWindow > mpFirstFloat
Definition: svdata.hxx:253
void ApplyControlBackground(vcl::RenderContext &rRenderContext, const Color &rDefaultColor)
Definition: window2.cxx:523
virtual void ApplySettings(vcl::RenderContext &rRenderContext) override
Definition: floatwin.cxx:185
Size GetOutputSizePixel() const
Definition: window3.cxx:89
VclPtr< vcl::Window > mpFirstPopupModeWin
Definition: floatwin.hxx:61
VclPtr< vcl::Window > mpDialogParent
Definition: syswin.hxx:114
constexpr Point BottomRight() const
SAL_DLLPRIVATE FloatingWindow * ImplFloatHitTest(vcl::Window *pReference, const Point &rPos, bool &rbHitTestInsideRect)
Definition: floatwin.cxx:548
virtual void StateChanged(StateChangedType nStateChange)
Definition: window.cxx:1930
const vcl::ILibreOfficeKitNotifier * GetLOKNotifier() const
Definition: window.cxx:3238
tools::Long AdjustLeft(tools::Long nHorzMoveDelta)
void SetDialogControlFlags(DialogControlFlags nFlags)
Definition: window2.cxx:1046
WinBits GetStyle() const
Definition: window2.cxx:947
Point OutputToScreenPixel(const Point &rPos) const
Definition: window.cxx:2793
void ReleaseLOKNotifier()
Indicate that LOK is not going to use this dialog any more.
Definition: window.cxx:3206
WinBits const WB_CLOSEABLE
WinBits const WB_MOVEABLE
rtl::OString toString() const
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
WinBits const WB_POPUP
void SetTitleType(FloatWinTitleType nTitle)
Definition: floatwin.cxx:751
void EndPopupMode(FloatWinPopupEndFlags nFlags=FloatWinPopupEndFlags::NONE)
Definition: floatwin.cxx:944
bool mbInPopupMode
Definition: floatwin.hxx:69
virtual void SetPosPixel(const Point &rNewPos)
Definition: window2.cxx:1251
bool isLayoutEnabled() const
Definition: syswin.cxx:1004
SAL_DLLPRIVATE void DoInitialLayout()
Definition: syswin.cxx:1088
ToolBoxItemId GetDownItemId() const
Definition: toolbox.hxx:366
static DockingManager * GetDockingManager()
Definition: window2.cxx:792
virtual void DataChanged(const DataChangedEvent &rDCEvt)
Definition: event.cxx:36
OUString toString(OptionInfo const *info)
ImplSVWinData * mpWinData
Definition: svdata.hxx:396
bool mbMouseDown
Definition: floatwin.hxx:73
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2177