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