LibreOffice Module vcl (master)  1
layout.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 
10 #include <sal/config.h>
11 
12 #include <string_view>
13 
14 #include <config_features.h>
15 #include <com/sun/star/accessibility/AccessibleRole.hpp>
16 #include <comphelper/base64.hxx>
17 #include <o3tl/enumarray.hxx>
18 #include <o3tl/enumrange.hxx>
19 #include <o3tl/string_view.hxx>
20 #include <tools/stream.hxx>
21 #include <vcl/builder.hxx>
22 #include <vcl/toolkit/button.hxx>
23 #include <vcl/cvtgrf.hxx>
24 #include <vcl/decoview.hxx>
25 #include <vcl/help.hxx>
26 #include <vcl/toolkit/dialog.hxx>
27 #include <vcl/layout.hxx>
28 #include <vcl/scrbar.hxx>
29 #include <vcl/stdtext.hxx>
30 #include <vcl/split.hxx>
31 #include <vcl/svapp.hxx>
32 #include <vcl/settings.hxx>
33 #include <vcl/virdev.hxx>
34 #include <bitmaps.hlst>
35 #include <messagedialog.hxx>
36 #include <svdata.hxx>
37 #include <window.h>
38 #include <boost/multi_array.hpp>
39 #include <vcl/toolkit/vclmedit.hxx>
40 #include <vcl/uitest/uiobject.hxx>
41 #include <sal/log.hxx>
42 #include <tools/json_writer.hxx>
43 
46  , m_bLayoutDirty(true)
47 {
48  ImplInit(pParent, nStyle, nullptr);
50  SetPaintTransparent(true);
51  SetBackground();
52 }
53 
55 {
56  return css::accessibility::AccessibleRole::PANEL;
57 }
58 
60 {
61  return calculateRequisition();
62 }
63 
64 void VclContainer::setLayoutPosSize(vcl::Window &rWindow, const Point &rPos, const Size &rSize)
65 {
66  sal_Int32 nBorderWidth = rWindow.get_border_width();
67  sal_Int32 nLeft = rWindow.get_margin_start() + nBorderWidth;
68  sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
69  sal_Int32 nRight = rWindow.get_margin_end() + nBorderWidth;
70  sal_Int32 nBottom = rWindow.get_margin_bottom() + nBorderWidth;
71  Point aPos(rPos.X() + nLeft, rPos.Y() + nTop);
72  Size aSize(rSize.Width() - nLeft - nRight, rSize.Height() - nTop - nBottom);
73  rWindow.SetPosSizePixel(aPos, aSize);
74 }
75 
76 void VclContainer::setLayoutAllocation(vcl::Window &rChild, const Point &rAllocPos, const Size &rChildAlloc)
77 {
78  VclAlign eHalign = rChild.get_halign();
79  VclAlign eValign = rChild.get_valign();
80 
81  //typical case
82  if (eHalign == VclAlign::Fill && eValign == VclAlign::Fill)
83  {
84  setLayoutPosSize(rChild, rAllocPos, rChildAlloc);
85  return;
86  }
87 
88  Point aChildPos(rAllocPos);
89  Size aChildSize(rChildAlloc);
90  Size aChildPreferredSize(getLayoutRequisition(rChild));
91 
92  switch (eHalign)
93  {
94  case VclAlign::Fill:
95  break;
96  case VclAlign::Start:
97  if (aChildPreferredSize.Width() < rChildAlloc.Width())
98  aChildSize.setWidth( aChildPreferredSize.Width() );
99  break;
100  case VclAlign::End:
101  if (aChildPreferredSize.Width() < rChildAlloc.Width())
102  aChildSize.setWidth( aChildPreferredSize.Width() );
103  aChildPos.AdjustX(rChildAlloc.Width() );
104  aChildPos.AdjustX( -(aChildSize.Width()) );
105  break;
106  case VclAlign::Center:
107  if (aChildPreferredSize.Width() < aChildSize.Width())
108  aChildSize.setWidth( aChildPreferredSize.Width() );
109  aChildPos.AdjustX((rChildAlloc.Width() - aChildSize.Width()) / 2 );
110  break;
111  }
112 
113  switch (eValign)
114  {
115  case VclAlign::Fill:
116  break;
117  case VclAlign::Start:
118  if (aChildPreferredSize.Height() < rChildAlloc.Height())
119  aChildSize.setHeight( aChildPreferredSize.Height() );
120  break;
121  case VclAlign::End:
122  if (aChildPreferredSize.Height() < rChildAlloc.Height())
123  aChildSize.setHeight( aChildPreferredSize.Height() );
124  aChildPos.AdjustY(rChildAlloc.Height() );
125  aChildPos.AdjustY( -(aChildSize.Height()) );
126  break;
127  case VclAlign::Center:
128  if (aChildPreferredSize.Height() < aChildSize.Height())
129  aChildSize.setHeight( aChildPreferredSize.Height() );
130  aChildPos.AdjustY((rChildAlloc.Height() - aChildSize.Height()) / 2 );
131  break;
132  }
133 
134  setLayoutPosSize(rChild, aChildPos, aChildSize);
135 }
136 
137 namespace
138 {
139  Size subtractBorder(const vcl::Window &rWindow, const Size& rSize)
140  {
141  sal_Int32 nBorderWidth = rWindow.get_border_width();
142  sal_Int32 nLeft = rWindow.get_margin_start() + nBorderWidth;
143  sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
144  sal_Int32 nRight = rWindow.get_margin_end() + nBorderWidth;
145  sal_Int32 nBottom = rWindow.get_margin_bottom() + nBorderWidth;
146  Size aSize(rSize);
147  return Size(aSize.Width() + nLeft + nRight, aSize.Height() + nTop + nBottom);
148  }
149 }
150 
152 {
153  return subtractBorder(rWindow, rWindow.get_preferred_size());
154 }
155 
156 void VclContainer::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocation)
157 {
158  bool bSizeChanged = rAllocation != GetOutputSizePixel();
159  Window::SetPosSizePixel(rAllocPos, rAllocation);
160  if (m_bLayoutDirty || bSizeChanged)
161  {
162  m_bLayoutDirty = false;
163  setAllocation(rAllocation);
164  }
165 }
166 
167 void VclContainer::SetPosPixel(const Point& rAllocPos)
168 {
169  Point aAllocPos = rAllocPos;
170  sal_Int32 nBorderWidth = get_border_width();
171  aAllocPos.AdjustX(nBorderWidth + get_margin_start() );
172  aAllocPos.AdjustY(nBorderWidth + get_margin_top() );
173 
174  if (aAllocPos != GetPosPixel())
175  Window::SetPosPixel(aAllocPos);
176 }
177 
178 void VclContainer::SetSizePixel(const Size& rAllocation)
179 {
180  Size aAllocation = rAllocation;
181  sal_Int32 nBorderWidth = get_border_width();
182  aAllocation.AdjustWidth( -(nBorderWidth*2 + get_margin_start() + get_margin_end()) );
183  aAllocation.AdjustHeight( -(nBorderWidth*2 + get_margin_top() + get_margin_bottom()) );
184  bool bSizeChanged = aAllocation != GetSizePixel();
185  if (bSizeChanged)
186  Window::SetSizePixel(aAllocation);
187  if (m_bLayoutDirty || bSizeChanged)
188  {
189  m_bLayoutDirty = false;
190  setAllocation(aAllocation);
191  }
192 }
193 
195 {
196  m_bLayoutDirty = true;
197  Window::queue_resize(eReason);
198 }
199 
200 // support for screenshot context menu
202 {
204  {
205  auto pParent = GetParent();
206  if (pParent)
207  {
208  CommandEvent aCEvt(rCEvt.GetMousePosPixel() + GetPosPixel(), rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetEventData());
209  pParent->Command(aCEvt);
210  return;
211  }
212  }
213 
214  // call parent (do not consume)
215  Window::Command(rCEvt);
216 }
217 
218 void VclBox::accumulateMaxes(const Size &rChildSize, Size &rSize) const
219 {
220  tools::Long nSecondaryChildDimension = getSecondaryDimension(rChildSize);
221  tools::Long nSecondaryBoxDimension = getSecondaryDimension(rSize);
222  setSecondaryDimension(rSize, std::max(nSecondaryChildDimension, nSecondaryBoxDimension));
223 
224  tools::Long nPrimaryChildDimension = getPrimaryDimension(rChildSize);
225  tools::Long nPrimaryBoxDimension = getPrimaryDimension(rSize);
226  if (m_bHomogeneous)
227  setPrimaryDimension(rSize, std::max(nPrimaryBoxDimension, nPrimaryChildDimension));
228  else
229  setPrimaryDimension(rSize, nPrimaryBoxDimension + nPrimaryChildDimension);
230 }
231 
233 {
234  sal_uInt16 nVisibleChildren = 0;
235 
236  Size aSize;
237  for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
238  {
239  if (!pChild->IsVisible())
240  continue;
241  ++nVisibleChildren;
242  Size aChildSize = getLayoutRequisition(*pChild);
243 
244  tools::Long nPrimaryDimension = getPrimaryDimension(aChildSize);
245  nPrimaryDimension += pChild->get_padding() * 2;
246  setPrimaryDimension(aChildSize, nPrimaryDimension);
247 
248  accumulateMaxes(aChildSize, aSize);
249  }
250 
251  return finalizeMaxes(aSize, nVisibleChildren);
252 }
253 
254 void VclBox::setAllocation(const Size &rAllocation)
255 {
256  sal_uInt16 nVisibleChildren = 0, nExpandChildren = 0;
257  for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
258  {
259  if (!pChild->IsVisible())
260  continue;
261  ++nVisibleChildren;
262  bool bExpand = getPrimaryDimensionChildExpand(*pChild);
263  if (bExpand)
264  ++nExpandChildren;
265  }
266 
267  if (!nVisibleChildren)
268  return;
269 
270  tools::Long nAllocPrimaryDimension = getPrimaryDimension(rAllocation);
271 
272  tools::Long nHomogeneousDimension = 0, nExtraSpace = 0;
273  if (m_bHomogeneous)
274  {
275  nHomogeneousDimension = (nAllocPrimaryDimension -
276  (nVisibleChildren - 1) * m_nSpacing) / nVisibleChildren;
277  }
278  else if (nExpandChildren)
279  {
280  Size aRequisition = calculateRequisition();
281  nExtraSpace = (getPrimaryDimension(rAllocation) - getPrimaryDimension(aRequisition)) / nExpandChildren;
282 // In mobile, the screen size is small and extraSpace can become negative
283 // Though the dialogs are rendered in javascript for LOK Android some widgets like weld::DrawingArea
284 // is sent as bitmap but it is rendered from only the visible part
285 // when it gets negative, it shrinks instead of expands and it becomes invisible
286  if (nExtraSpace < 0)
287  {
288  SAL_WARN("vcl.layout", "nExtraSpace went negative, setting to zero for VclBox: " << GetHelpId());
289  nExtraSpace = 0;
290  }
291  }
292 
293  //Split into those we pack from the start onwards, and those we pack from the end backwards
295  for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
296  {
297  if (!pChild->IsVisible())
298  continue;
299 
300  VclPackType ePacking = pChild->get_pack_type();
301  aWindows[ePacking].push_back(pChild);
302  }
303 
304  //See VclBuilder::sortIntoBestTabTraversalOrder for why they are in visual
305  //order under the parent which requires us to reverse them here to
306  //pack from the end back
307  std::reverse(aWindows[VclPackType::End].begin(),aWindows[VclPackType::End].end());
308 
309  for (VclPackType ePackType : o3tl::enumrange<VclPackType>())
310  {
311  Point aPos(0, 0);
312  if (ePackType == VclPackType::End)
313  {
314  tools::Long nPrimaryCoordinate = getPrimaryCoordinate(aPos);
315  setPrimaryCoordinate(aPos, nPrimaryCoordinate + nAllocPrimaryDimension);
316  }
317 
318  for (auto const& window : aWindows[ePackType])
319  {
320  vcl::Window *pChild = window;
321 
322  tools::Long nPadding = pChild->get_padding();
323 
324  Size aBoxSize;
325  if (m_bHomogeneous)
326  setPrimaryDimension(aBoxSize, nHomogeneousDimension);
327  else
328  {
329  aBoxSize = getLayoutRequisition(*pChild);
330  tools::Long nPrimaryDimension = getPrimaryDimension(aBoxSize);
331  nPrimaryDimension += nPadding * 2;
332  if (getPrimaryDimensionChildExpand(*pChild))
333  nPrimaryDimension += nExtraSpace;
334  setPrimaryDimension(aBoxSize, nPrimaryDimension);
335  }
336  setSecondaryDimension(aBoxSize, getSecondaryDimension(rAllocation));
337 
338  Point aChildPos(aPos);
339  Size aChildSize(aBoxSize);
340  tools::Long nPrimaryCoordinate = getPrimaryCoordinate(aPos);
341 
342  bool bFill = pChild->get_fill();
343  if (bFill)
344  {
345  setPrimaryDimension(aChildSize, std::max(static_cast<tools::Long>(1),
346  std::min(getPrimaryDimension(rAllocation), getPrimaryDimension(aBoxSize) - nPadding * 2)));
347 
348  setPrimaryCoordinate(aChildPos, nPrimaryCoordinate + nPadding);
349  }
350  else
351  {
352  setPrimaryDimension(aChildSize,
354 
355  setPrimaryCoordinate(aChildPos, nPrimaryCoordinate +
356  (getPrimaryDimension(aBoxSize) - getPrimaryDimension(aChildSize)) / 2);
357  }
358 
359  tools::Long nDiff = getPrimaryDimension(aBoxSize) + m_nSpacing;
360  if (ePackType == VclPackType::Start)
361  setPrimaryCoordinate(aPos, nPrimaryCoordinate + nDiff);
362  else
363  {
364  setPrimaryCoordinate(aPos, nPrimaryCoordinate - nDiff);
365  setPrimaryCoordinate(aChildPos, getPrimaryCoordinate(aChildPos) -
366  getPrimaryDimension(aBoxSize));
367  }
368 
369  setLayoutAllocation(*pChild, aChildPos, aChildSize);
370  }
371  }
372 }
373 
374 bool VclBox::set_property(const OString &rKey, const OUString &rValue)
375 {
376  if (rKey == "spacing")
377  set_spacing(rValue.toInt32());
378  else if (rKey == "homogeneous")
379  set_homogeneous(toBool(rValue));
380  else
381  return VclContainer::set_property(rKey, rValue);
382  return true;
383 }
384 
386 {
388  rJsonWriter.put("vertical", m_bVerticalContainer);
389 }
390 
392 {
393 #if defined(_WIN32)
394  //fdo#74284 call Boxes Panels, keep then as "Filler" under
395  //at least Linux seeing as that's what Gtk does for GtkBoxes
396  return css::accessibility::AccessibleRole::PANEL;
397 #else
398  return css::accessibility::AccessibleRole::FILLER;
399 #endif
400 }
401 
402 #define DEFAULT_CHILD_MIN_WIDTH 85
403 #define DEFAULT_CHILD_MIN_HEIGHT 27
404 
405 Size VclBox::finalizeMaxes(const Size &rSize, sal_uInt16 nVisibleChildren) const
406 {
407  Size aRet;
408 
409  if (nVisibleChildren)
410  {
411  tools::Long nPrimaryDimension = getPrimaryDimension(rSize);
412  if (m_bHomogeneous)
413  nPrimaryDimension *= nVisibleChildren;
414  setPrimaryDimension(aRet, nPrimaryDimension + m_nSpacing * (nVisibleChildren-1));
416  }
417 
418  return aRet;
419 }
420 
422 {
423  Size aRet;
424 
425  tools::Long nMainGroupDimension = getPrimaryDimension(rReq.m_aMainGroupSize);
426  tools::Long nSubGroupDimension = getPrimaryDimension(rReq.m_aSubGroupSize);
427 
428  setPrimaryDimension(aRet, nMainGroupDimension + nSubGroupDimension);
429 
433 
434  return aRet;
435 }
436 
437 static tools::Long getMaxNonOutlier(const std::vector<tools::Long> &rG, tools::Long nAvgDimension)
438 {
439  tools::Long nMaxDimensionNonOutlier = 0;
440  for (auto const& nPrimaryChildDimension : rG)
441  {
442  if (nPrimaryChildDimension < nAvgDimension * 1.5)
443  {
444  nMaxDimensionNonOutlier = std::max(nPrimaryChildDimension,
445  nMaxDimensionNonOutlier);
446  }
447  }
448  return nMaxDimensionNonOutlier;
449 }
450 
451 static std::vector<tools::Long> setButtonSizes(const std::vector<tools::Long> &rG,
452  const std::vector<bool> &rNonHomogeneous,
453  tools::Long nAvgDimension, tools::Long nMaxNonOutlier, tools::Long nMinWidth)
454 {
455  std::vector<tools::Long> aVec;
456  //set everything < 1.5 times the average to the same width, leave the
457  //outliers un-touched
458  std::vector<bool>::const_iterator aJ = rNonHomogeneous.begin();
459  auto nNonOutlierWidth = std::max(nMaxNonOutlier, nMinWidth);
460  for (auto const& nPrimaryChildDimension : rG)
461  {
462  bool bNonHomogeneous = *aJ;
463  if (!bNonHomogeneous && nPrimaryChildDimension < nAvgDimension * 1.5)
464  {
465  aVec.push_back(nNonOutlierWidth);
466  }
467  else
468  {
469  aVec.push_back(std::max(nPrimaryChildDimension, nMinWidth));
470  }
471  ++aJ;
472  }
473  return aVec;
474 }
475 
477 {
478  Requisition aReq;
479 
480  Size aMainGroupSize(DEFAULT_CHILD_MIN_WIDTH, DEFAULT_CHILD_MIN_HEIGHT); //to-do, pull from theme
481  Size aSubGroupSize(DEFAULT_CHILD_MIN_WIDTH, DEFAULT_CHILD_MIN_HEIGHT); //to-do, pull from theme
482 
483  tools::Long nMinMainGroupPrimary = getPrimaryDimension(aMainGroupSize);
484  tools::Long nMinSubGroupPrimary = getPrimaryDimension(aSubGroupSize);
485  tools::Long nMainGroupSecondary = getSecondaryDimension(aMainGroupSize);
486  tools::Long nSubGroupSecondary = getSecondaryDimension(aSubGroupSize);
487 
488  bool bIgnoreSecondaryPacking = (m_eLayoutStyle == VclButtonBoxStyle::Spread || m_eLayoutStyle == VclButtonBoxStyle::Center);
489 
490  std::vector<tools::Long> aMainGroupSizes;
491  std::vector<bool> aMainGroupNonHomogeneous;
492  std::vector<tools::Long> aSubGroupSizes;
493  std::vector<bool> aSubGroupNonHomogeneous;
494 
495  for (const vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
496  {
497  if (!pChild->IsVisible())
498  continue;
499  Size aChildSize = getLayoutRequisition(*pChild);
500  if (bIgnoreSecondaryPacking || !pChild->get_secondary())
501  {
502  //set the max secondary dimension
503  nMainGroupSecondary = std::max(nMainGroupSecondary, getSecondaryDimension(aChildSize));
504  //collect the primary dimensions
505  aMainGroupSizes.push_back(getPrimaryDimension(aChildSize));
506  aMainGroupNonHomogeneous.push_back(pChild->get_non_homogeneous());
507  }
508  else
509  {
510  nSubGroupSecondary = std::max(nSubGroupSecondary, getSecondaryDimension(aChildSize));
511  aSubGroupSizes.push_back(getPrimaryDimension(aChildSize));
512  aSubGroupNonHomogeneous.push_back(pChild->get_non_homogeneous());
513  }
514  }
515 
516  if (m_bHomogeneous)
517  {
518  tools::Long nMaxMainDimension = aMainGroupSizes.empty() ? 0 :
519  *std::max_element(aMainGroupSizes.begin(), aMainGroupSizes.end());
520  nMaxMainDimension = std::max(nMaxMainDimension, nMinMainGroupPrimary);
521  tools::Long nMaxSubDimension = aSubGroupSizes.empty() ? 0 :
522  *std::max_element(aSubGroupSizes.begin(), aSubGroupSizes.end());
523  nMaxSubDimension = std::max(nMaxSubDimension, nMinSubGroupPrimary);
524  tools::Long nMaxDimension = std::max(nMaxMainDimension, nMaxSubDimension);
525  aReq.m_aMainGroupDimensions.resize(aMainGroupSizes.size(), nMaxDimension);
526  aReq.m_aSubGroupDimensions.resize(aSubGroupSizes.size(), nMaxDimension);
527  }
528  else
529  {
530  //Ideally set everything to the same size, but find outlier widgets
531  //that are way wider than the average and leave them
532  //at their natural size and set the remainder to share the
533  //max size of the remaining members of the buttonbox
534  tools::Long nAccDimension = std::accumulate(aMainGroupSizes.begin(),
535  aMainGroupSizes.end(), 0);
536  nAccDimension = std::accumulate(aSubGroupSizes.begin(),
537  aSubGroupSizes.end(), nAccDimension);
538 
539  size_t nTotalSize = aMainGroupSizes.size() + aSubGroupSizes.size();
540 
541  tools::Long nAvgDimension = nTotalSize ? nAccDimension / nTotalSize : 0;
542 
543  tools::Long nMaxMainNonOutlier = getMaxNonOutlier(aMainGroupSizes,
544  nAvgDimension);
545  tools::Long nMaxSubNonOutlier = getMaxNonOutlier(aSubGroupSizes,
546  nAvgDimension);
547  tools::Long nMaxNonOutlier = std::max(nMaxMainNonOutlier, nMaxSubNonOutlier);
548 
549  aReq.m_aMainGroupDimensions = setButtonSizes(aMainGroupSizes,
550  aMainGroupNonHomogeneous,
551  nAvgDimension, nMaxNonOutlier, nMinMainGroupPrimary);
552  aReq.m_aSubGroupDimensions = setButtonSizes(aSubGroupSizes,
553  aSubGroupNonHomogeneous,
554  nAvgDimension, nMaxNonOutlier, nMinSubGroupPrimary);
555  }
556 
557  if (!aReq.m_aMainGroupDimensions.empty())
558  {
559  setSecondaryDimension(aReq.m_aMainGroupSize, nMainGroupSecondary);
561  std::accumulate(aReq.m_aMainGroupDimensions.begin(),
562  aReq.m_aMainGroupDimensions.end(), 0));
563  }
564  if (!aReq.m_aSubGroupDimensions.empty())
565  {
566  setSecondaryDimension(aReq.m_aSubGroupSize, nSubGroupSecondary);
568  std::accumulate(aReq.m_aSubGroupDimensions.begin(),
569  aReq.m_aSubGroupDimensions.end(), 0));
570  }
571 
572  return aReq;
573 }
574 
575 Size VclButtonBox::addSpacing(const Size &rSize, sal_uInt16 nVisibleChildren) const
576 {
577  Size aRet;
578 
579  if (nVisibleChildren)
580  {
581  tools::Long nPrimaryDimension = getPrimaryDimension(rSize);
582  setPrimaryDimension(aRet,
583  nPrimaryDimension + m_nSpacing * (nVisibleChildren-1));
585  }
586 
587  return aRet;
588 }
589 
591 {
593  sal_uInt16 nVisibleChildren = aReq.m_aMainGroupDimensions.size() +
594  aReq.m_aSubGroupDimensions.size();
595  return addSpacing(addReqGroups(aReq), nVisibleChildren);
596 }
597 
598 bool VclButtonBox::set_property(const OString &rKey, const OUString &rValue)
599 {
600  if (rKey == "layout-style")
601  {
603  if (rValue == "spread")
604  eStyle = VclButtonBoxStyle::Spread;
605  else if (rValue == "edge")
606  eStyle = VclButtonBoxStyle::Edge;
607  else if (rValue == "start")
608  eStyle = VclButtonBoxStyle::Start;
609  else if (rValue == "end")
610  eStyle = VclButtonBoxStyle::End;
611  else if (rValue == "center")
612  eStyle = VclButtonBoxStyle::Center;
613  else
614  {
615  SAL_WARN("vcl.layout", "unknown layout style " << rValue);
616  }
617  m_eLayoutStyle = eStyle;
618  }
619  else
620  return VclBox::set_property(rKey, rValue);
621  return true;
622 }
623 
624 void VclButtonBox::setAllocation(const Size &rAllocation)
625 {
627 
628  if (aReq.m_aMainGroupDimensions.empty() && aReq.m_aSubGroupDimensions.empty())
629  return;
630 
631  tools::Long nAllocPrimaryDimension = getPrimaryDimension(rAllocation);
632 
633  Point aMainGroupPos, aOtherGroupPos;
634  int nSpacing = m_nSpacing;
635 
636  //To-Do, other layout styles
637  switch (m_eLayoutStyle)
638  {
640  if (!aReq.m_aSubGroupDimensions.empty())
641  {
642  tools::Long nOtherPrimaryDimension = getPrimaryDimension(
644  setPrimaryCoordinate(aOtherGroupPos,
645  nAllocPrimaryDimension - nOtherPrimaryDimension);
646  }
647  break;
649  if (!aReq.m_aMainGroupDimensions.empty())
650  {
651  tools::Long nMainPrimaryDimension = getPrimaryDimension(
653  tools::Long nExtraSpace = nAllocPrimaryDimension - nMainPrimaryDimension;
654  nExtraSpace += (aReq.m_aMainGroupDimensions.size()-1) * nSpacing;
655  nSpacing = nExtraSpace/(aReq.m_aMainGroupDimensions.size()+1);
656  setPrimaryCoordinate(aMainGroupPos, nSpacing);
657  }
658  break;
660  if (!aReq.m_aMainGroupDimensions.empty())
661  {
662  tools::Long nMainPrimaryDimension = getPrimaryDimension(
664  tools::Long nExtraSpace = nAllocPrimaryDimension - nMainPrimaryDimension;
665  setPrimaryCoordinate(aMainGroupPos, nExtraSpace/2);
666  }
667  break;
668  default:
669  SAL_WARN("vcl.layout", "todo unimplemented layout style");
670  [[fallthrough]];
673  if (!aReq.m_aMainGroupDimensions.empty())
674  {
675  tools::Long nMainPrimaryDimension = getPrimaryDimension(
677  setPrimaryCoordinate(aMainGroupPos,
678  nAllocPrimaryDimension - nMainPrimaryDimension);
679  }
680  break;
681  }
682 
683  Size aChildSize;
684  setSecondaryDimension(aChildSize, getSecondaryDimension(rAllocation));
685 
686  std::vector<tools::Long>::const_iterator aPrimaryI = aReq.m_aMainGroupDimensions.begin();
687  std::vector<tools::Long>::const_iterator aSecondaryI = aReq.m_aSubGroupDimensions.begin();
688  bool bIgnoreSecondaryPacking = (m_eLayoutStyle == VclButtonBoxStyle::Spread || m_eLayoutStyle == VclButtonBoxStyle::Center);
689  for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
690  {
691  if (!pChild->IsVisible())
692  continue;
693 
694  if (bIgnoreSecondaryPacking || !pChild->get_secondary())
695  {
696  tools::Long nMainGroupPrimaryDimension = *aPrimaryI++;
697  setPrimaryDimension(aChildSize, nMainGroupPrimaryDimension);
698  setLayoutAllocation(*pChild, aMainGroupPos, aChildSize);
699  tools::Long nPrimaryCoordinate = getPrimaryCoordinate(aMainGroupPos);
700  setPrimaryCoordinate(aMainGroupPos, nPrimaryCoordinate + nMainGroupPrimaryDimension + nSpacing);
701  }
702  else
703  {
704  tools::Long nSubGroupPrimaryDimension = *aSecondaryI++;
705  setPrimaryDimension(aChildSize, nSubGroupPrimaryDimension);
706  setLayoutAllocation(*pChild, aOtherGroupPos, aChildSize);
707  tools::Long nPrimaryCoordinate = getPrimaryCoordinate(aOtherGroupPos);
708  setPrimaryCoordinate(aOtherGroupPos, nPrimaryCoordinate + nSubGroupPrimaryDimension + nSpacing);
709  }
710  }
711 }
712 
714 {
715  VclBox::DumpAsPropertyTree(rJsonWriter);
716  rJsonWriter.put("type", "buttonbox");
717 
718  switch(m_eLayoutStyle)
719  {
721  rJsonWriter.put("layoutstyle", "default");
722  break;
723 
725  rJsonWriter.put("layoutstyle", "spread");
726  break;
727 
729  rJsonWriter.put("layoutstyle", "edge");
730  break;
731 
733  rJsonWriter.put("layoutstyle", "center");
734  break;
735 
737  rJsonWriter.put("layoutstyle", "start");
738  break;
739 
741  rJsonWriter.put("layoutstyle", "end");
742  break;
743  }
744 }
745 
746 namespace {
747 
748 struct ButtonOrder
749 {
750  std::u16string_view m_aType;
751  int m_nPriority;
752 };
753 
754 }
755 
756 static int getButtonPriority(std::u16string_view rType)
757 {
758  static const size_t N_TYPES = 6;
759  static const ButtonOrder aDiscardCancelSave[N_TYPES] =
760  {
761  { u"discard", 0 },
762  { u"cancel", 1 },
763  { u"no", 2 },
764  { u"save", 3 },
765  { u"yes", 3 },
766  { u"ok", 3 }
767  };
768 
769  static const ButtonOrder aSaveDiscardCancel[N_TYPES] =
770  {
771  { u"save", 0 },
772  { u"yes", 0 },
773  { u"ok", 0 },
774  { u"discard", 1 },
775  { u"no", 1 },
776  { u"cancel", 2 }
777  };
778 
779  const ButtonOrder* pOrder = &aDiscardCancelSave[0];
780 
781  const OUString &rEnv = Application::GetDesktopEnvironment();
782 
783  if (rEnv.equalsIgnoreAsciiCase("windows") ||
784  rEnv.equalsIgnoreAsciiCase("lxqt") ||
785  rEnv.startsWithIgnoreAsciiCase("plasma"))
786  {
787  pOrder = &aSaveDiscardCancel[0];
788  }
789 
790  for (size_t i = 0; i < N_TYPES; ++i, ++pOrder)
791  {
792  if (rType == pOrder->m_aType)
793  return pOrder->m_nPriority;
794  }
795 
796  return -1;
797 }
798 
799 namespace {
800 
801 class sortButtons
802 {
803  bool m_bVerticalContainer;
804 public:
805  explicit sortButtons(bool bVerticalContainer)
806  : m_bVerticalContainer(bVerticalContainer)
807  {
808  }
809  bool operator()(const vcl::Window *pA, const vcl::Window *pB) const;
810 };
811 
812 }
813 
814 bool sortButtons::operator()(const vcl::Window *pA, const vcl::Window *pB) const
815 {
816  //sort into two groups of pack start and pack end
817  VclPackType ePackA = pA->get_pack_type();
818  VclPackType ePackB = pB->get_pack_type();
819  if (ePackA < ePackB)
820  return true;
821  if (ePackA > ePackB)
822  return false;
823  bool bPackA = pA->get_secondary();
824  bool bPackB = pB->get_secondary();
825  if (!m_bVerticalContainer)
826  {
827  //for horizontal boxes group secondaries before primaries
828  if (bPackA > bPackB)
829  return true;
830  if (bPackA < bPackB)
831  return false;
832  }
833  else
834  {
835  //for vertical boxes group secondaries after primaries
836  if (bPackA < bPackB)
837  return true;
838  if (bPackA > bPackB)
839  return false;
840  }
841 
842  //now order within groups according to platform rules
843  return getButtonPriority(pA->get_id()) < getButtonPriority(pB->get_id());
844 }
845 
846 void sort_native_button_order(const VclBox& rContainer)
847 {
848  std::vector<vcl::Window*> aChilds;
849  for (vcl::Window* pChild = rContainer.GetWindow(GetWindowType::FirstChild); pChild;
850  pChild = pChild->GetWindow(GetWindowType::Next))
851  {
852  aChilds.push_back(pChild);
853  }
854 
855  //sort child order within parent so that we match the platform
856  //button order
857  std::stable_sort(aChilds.begin(), aChilds.end(), sortButtons(rContainer.get_orientation()));
858  BuilderUtils::reorderWithinParent(aChilds, true);
859 }
860 
861 namespace {
862 
863 struct GridEntry
864 {
865  VclPtr<vcl::Window> pChild;
866  sal_Int32 nSpanWidth;
867  sal_Int32 nSpanHeight;
868  int x;
869  int y;
870  GridEntry()
871  : pChild(nullptr)
872  , nSpanWidth(0)
873  , nSpanHeight(0)
874  , x(-1)
875  , y(-1)
876  {
877  }
878 };
879 
880 }
881 
882 typedef boost::multi_array<GridEntry, 2> array_type;
883 
884 static array_type assembleGrid(const VclGrid &rGrid);
885 static bool isNullGrid(const array_type& A);
886 static void calcMaxs(const array_type &A, std::vector<VclGrid::Value> &rWidths, std::vector<VclGrid::Value> &rHeights);
887 
888 array_type assembleGrid(const VclGrid &rGrid)
889 {
890  array_type A;
891 
892  for (vcl::Window* pChild = rGrid.GetWindow(GetWindowType::FirstChild); pChild;
893  pChild = pChild->GetWindow(GetWindowType::Next))
894  {
895  sal_Int32 nLeftAttach = std::max<sal_Int32>(pChild->get_grid_left_attach(), 0);
896  sal_Int32 nWidth = pChild->get_grid_width();
897  sal_Int32 nMaxXPos = nLeftAttach+nWidth-1;
898 
899  sal_Int32 nTopAttach = std::max<sal_Int32>(pChild->get_grid_top_attach(), 0);
900  sal_Int32 nHeight = pChild->get_grid_height();
901  sal_Int32 nMaxYPos = nTopAttach+nHeight-1;
902 
903  sal_Int32 nCurrentMaxXPos = A.shape()[0]-1;
904  sal_Int32 nCurrentMaxYPos = A.shape()[1]-1;
905  if (nMaxXPos > nCurrentMaxXPos || nMaxYPos > nCurrentMaxYPos)
906  {
907  nCurrentMaxXPos = std::max(nMaxXPos, nCurrentMaxXPos);
908  nCurrentMaxYPos = std::max(nMaxYPos, nCurrentMaxYPos);
909  A.resize(boost::extents[nCurrentMaxXPos+1][nCurrentMaxYPos+1]);
910  }
911 
912  GridEntry &rEntry = A[nLeftAttach][nTopAttach];
913  rEntry.pChild = pChild;
914  rEntry.nSpanWidth = nWidth;
915  rEntry.nSpanHeight = nHeight;
916  rEntry.x = nLeftAttach;
917  rEntry.y = nTopAttach;
918 
919  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
920  {
921  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
922  {
923  GridEntry &rSpan = A[nLeftAttach+nSpanX][nTopAttach+nSpanY];
924  rSpan.x = nLeftAttach;
925  rSpan.y = nTopAttach;
926  }
927  }
928  }
929 
930  //see if we have any empty rows/cols
931  sal_Int32 nMaxX = A.shape()[0];
932  sal_Int32 nMaxY = A.shape()[1];
933 
934  std::vector<bool> aNonEmptyCols(nMaxX);
935  std::vector<bool> aNonEmptyRows(nMaxY);
936 
937  for (sal_Int32 x = 0; x < nMaxX; ++x)
938  {
939  for (sal_Int32 y = 0; y < nMaxY; ++y)
940  {
941  const GridEntry &rEntry = A[x][y];
942  const vcl::Window *pChild = rEntry.pChild;
943  if (pChild && pChild->IsVisible())
944  {
945  aNonEmptyCols[x] = true;
946  if (rGrid.get_column_homogeneous())
947  {
948  for (sal_Int32 nSpanX = 1; nSpanX < rEntry.nSpanWidth; ++nSpanX)
949  aNonEmptyCols[x+nSpanX] = true;
950  }
951  aNonEmptyRows[y] = true;
952  if (rGrid.get_row_homogeneous())
953  {
954  for (sal_Int32 nSpanY = 1; nSpanY < rEntry.nSpanHeight; ++nSpanY)
955  aNonEmptyRows[y+nSpanY] = true;
956  }
957  }
958  }
959  }
960 
961  if (!rGrid.get_column_homogeneous())
962  {
963  //reduce the spans of elements that span empty columns
964  for (sal_Int32 x = 0; x < nMaxX; ++x)
965  {
966  std::set<GridEntry*> candidates;
967  for (sal_Int32 y = 0; y < nMaxY; ++y)
968  {
969  if (aNonEmptyCols[x])
970  continue;
971  GridEntry &rSpan = A[x][y];
972  //cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
973  //just points back to itself if there's no cell spanning
974  if ((rSpan.x == -1) || (rSpan.y == -1))
975  {
976  //there is no entry for this cell, i.e. this is a cell
977  //with no widget in it, or spanned by any other widget
978  continue;
979  }
980  GridEntry &rEntry = A[rSpan.x][rSpan.y];
981  candidates.insert(&rEntry);
982  }
983  for (auto const& candidate : candidates)
984  {
985  GridEntry *pEntry = candidate;
986  --pEntry->nSpanWidth;
987  }
988  }
989  }
990 
991  if (!rGrid.get_row_homogeneous())
992  {
993  //reduce the spans of elements that span empty rows
994  for (sal_Int32 y = 0; y < nMaxY; ++y)
995  {
996  std::set<GridEntry*> candidates;
997  for (sal_Int32 x = 0; x < nMaxX; ++x)
998  {
999  if (aNonEmptyRows[y])
1000  continue;
1001  GridEntry &rSpan = A[x][y];
1002  //cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
1003  //just points back to itself if there's no cell spanning
1004  if ((rSpan.x == -1) || (rSpan.y == -1))
1005  {
1006  //there is no entry for this cell, i.e. this is a cell
1007  //with no widget in it, or spanned by any other widget
1008  continue;
1009  }
1010  GridEntry &rEntry = A[rSpan.x][rSpan.y];
1011  candidates.insert(&rEntry);
1012  }
1013  for (auto const& candidate : candidates)
1014  {
1015  GridEntry *pEntry = candidate;
1016  --pEntry->nSpanHeight;
1017  }
1018  }
1019  }
1020 
1021  sal_Int32 nNonEmptyCols = std::count(aNonEmptyCols.begin(), aNonEmptyCols.end(), true);
1022  sal_Int32 nNonEmptyRows = std::count(aNonEmptyRows.begin(), aNonEmptyRows.end(), true);
1023 
1024  //make new grid without empty rows and columns
1025  array_type B(boost::extents[nNonEmptyCols][nNonEmptyRows]);
1026  for (sal_Int32 x = 0, x2 = 0; x < nMaxX; ++x)
1027  {
1028  if (!aNonEmptyCols[x])
1029  continue;
1030  for (sal_Int32 y = 0, y2 = 0; y < nMaxY; ++y)
1031  {
1032  if (!aNonEmptyRows[y])
1033  continue;
1034  GridEntry &rEntry = A[x][y];
1035  B[x2][y2++] = rEntry;
1036  }
1037  ++x2;
1038  }
1039 
1040  return B;
1041 }
1042 
1043 static bool isNullGrid(const array_type &A)
1044 {
1045  sal_Int32 nMaxX = A.shape()[0];
1046  sal_Int32 nMaxY = A.shape()[1];
1047 
1048  return !nMaxX || !nMaxY;
1049 }
1050 
1051 static void calcMaxs(const array_type &A, std::vector<VclGrid::Value> &rWidths, std::vector<VclGrid::Value> &rHeights)
1052 {
1053  sal_Int32 nMaxX = A.shape()[0];
1054  sal_Int32 nMaxY = A.shape()[1];
1055 
1056  rWidths.resize(nMaxX);
1057  rHeights.resize(nMaxY);
1058 
1059  //first use the non spanning entries to set default width/heights
1060  for (sal_Int32 x = 0; x < nMaxX; ++x)
1061  {
1062  for (sal_Int32 y = 0; y < nMaxY; ++y)
1063  {
1064  const GridEntry &rEntry = A[x][y];
1065  const vcl::Window *pChild = rEntry.pChild;
1066  if (!pChild || !pChild->IsVisible())
1067  continue;
1068 
1069  sal_Int32 nWidth = rEntry.nSpanWidth;
1070  sal_Int32 nHeight = rEntry.nSpanHeight;
1071 
1072  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1073  rWidths[x+nSpanX].m_bExpand |= pChild->get_hexpand();
1074 
1075  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1076  rHeights[y+nSpanY].m_bExpand |= pChild->get_vexpand();
1077 
1078  if (nWidth == 1 || nHeight == 1)
1079  {
1080  Size aChildSize = VclContainer::getLayoutRequisition(*pChild);
1081  if (nWidth == 1)
1082  rWidths[x].m_nValue = std::max(rWidths[x].m_nValue, aChildSize.Width());
1083  if (nHeight == 1)
1084  rHeights[y].m_nValue = std::max(rHeights[y].m_nValue, aChildSize.Height());
1085  }
1086  }
1087  }
1088 
1089  //now use the spanning entries and split any extra sizes across expanding rows/cols
1090  //where possible
1091  for (sal_Int32 x = 0; x < nMaxX; ++x)
1092  {
1093  for (sal_Int32 y = 0; y < nMaxY; ++y)
1094  {
1095  const GridEntry &rEntry = A[x][y];
1096  const vcl::Window *pChild = rEntry.pChild;
1097  if (!pChild || !pChild->IsVisible())
1098  continue;
1099 
1100  sal_Int32 nWidth = rEntry.nSpanWidth;
1101  sal_Int32 nHeight = rEntry.nSpanHeight;
1102 
1103  if (nWidth == 1 && nHeight == 1)
1104  continue;
1105 
1106  Size aChildSize = VclContainer::getLayoutRequisition(*pChild);
1107 
1108  if (nWidth > 1)
1109  {
1110  sal_Int32 nExistingWidth = 0;
1111  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1112  nExistingWidth += rWidths[x+nSpanX].m_nValue;
1113 
1114  sal_Int32 nExtraWidth = aChildSize.Width() - nExistingWidth;
1115 
1116  if (nExtraWidth > 0)
1117  {
1118  bool bForceExpandAll = false;
1119  sal_Int32 nExpandables = 0;
1120  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1121  if (rWidths[x+nSpanX].m_bExpand)
1122  ++nExpandables;
1123  if (nExpandables == 0)
1124  {
1125  nExpandables = nWidth;
1126  bForceExpandAll = true;
1127  }
1128 
1129  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1130  {
1131  if (rWidths[x+nSpanX].m_bExpand || bForceExpandAll)
1132  rWidths[x+nSpanX].m_nValue += nExtraWidth/nExpandables;
1133  }
1134  }
1135  }
1136 
1137  if (nHeight > 1)
1138  {
1139  sal_Int32 nExistingHeight = 0;
1140  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1141  nExistingHeight += rHeights[y+nSpanY].m_nValue;
1142 
1143  sal_Int32 nExtraHeight = aChildSize.Height() - nExistingHeight;
1144 
1145  if (nExtraHeight > 0)
1146  {
1147  bool bForceExpandAll = false;
1148  sal_Int32 nExpandables = 0;
1149  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1150  if (rHeights[y+nSpanY].m_bExpand)
1151  ++nExpandables;
1152  if (nExpandables == 0)
1153  {
1154  nExpandables = nHeight;
1155  bForceExpandAll = true;
1156  }
1157 
1158  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1159  {
1160  if (rHeights[y+nSpanY].m_bExpand || bForceExpandAll)
1161  rHeights[y+nSpanY].m_nValue += nExtraHeight/nExpandables;
1162  }
1163  }
1164  }
1165  }
1166  }
1167 }
1168 
1169 static bool compareValues(const VclGrid::Value &i, const VclGrid::Value &j)
1170 {
1171  return i.m_nValue < j.m_nValue;
1172 }
1173 
1175 {
1176  VclGrid::Value aRet;
1177  aRet.m_nValue = i.m_nValue + j.m_nValue;
1178  aRet.m_bExpand = i.m_bExpand || j.m_bExpand;
1179  return aRet;
1180 }
1181 
1183 {
1185 }
1186 
1187 Size VclGrid::calculateRequisitionForSpacings(sal_Int32 nRowSpacing, sal_Int32 nColSpacing) const
1188 {
1189  array_type A = assembleGrid(*this);
1190 
1191  if (isNullGrid(A))
1192  return Size();
1193 
1194  std::vector<Value> aWidths;
1195  std::vector<Value> aHeights;
1196  calcMaxs(A, aWidths, aHeights);
1197 
1198  tools::Long nTotalWidth = 0;
1199  if (get_column_homogeneous())
1200  {
1201  nTotalWidth = std::max_element(aWidths.begin(), aWidths.end(), compareValues)->m_nValue;
1202  nTotalWidth *= aWidths.size();
1203  }
1204  else
1205  {
1206  nTotalWidth = std::accumulate(aWidths.begin(), aWidths.end(), Value(), accumulateValues).m_nValue;
1207  }
1208 
1209  nTotalWidth += nColSpacing * (aWidths.size()-1);
1210 
1211  tools::Long nTotalHeight = 0;
1212  if (get_row_homogeneous())
1213  {
1214  nTotalHeight = std::max_element(aHeights.begin(), aHeights.end(), compareValues)->m_nValue;
1215  nTotalHeight *= aHeights.size();
1216  }
1217  else
1218  {
1219  nTotalHeight = std::accumulate(aHeights.begin(), aHeights.end(), Value(), accumulateValues).m_nValue;
1220  }
1221 
1222  nTotalHeight += nRowSpacing * (aHeights.size()-1);
1223 
1224  return Size(nTotalWidth, nTotalHeight);
1225 }
1226 
1227 void VclGrid::setAllocation(const Size& rAllocation)
1228 {
1229  array_type A = assembleGrid(*this);
1230 
1231  if (isNullGrid(A))
1232  return;
1233 
1234  sal_Int32 nMaxX = A.shape()[0];
1235  sal_Int32 nMaxY = A.shape()[1];
1236 
1237  Size aRequisition;
1238  std::vector<Value> aWidths(nMaxX);
1239  std::vector<Value> aHeights(nMaxY);
1241  {
1242  aRequisition = calculateRequisition();
1243  calcMaxs(A, aWidths, aHeights);
1244  }
1245 
1246  sal_Int32 nColSpacing(get_column_spacing());
1247  sal_Int32 nRowSpacing(get_row_spacing());
1248 
1249  tools::Long nAvailableWidth = rAllocation.Width();
1250  if (nMaxX)
1251  nAvailableWidth -= nColSpacing * (nMaxX - 1);
1252  if (get_column_homogeneous())
1253  {
1254  for (sal_Int32 x = 0; x < nMaxX; ++x)
1255  aWidths[x].m_nValue = nAvailableWidth/nMaxX;
1256  }
1257  else if (rAllocation.Width() != aRequisition.Width())
1258  {
1259  sal_Int32 nExpandables = 0;
1260  for (sal_Int32 x = 0; x < nMaxX; ++x)
1261  if (aWidths[x].m_bExpand)
1262  ++nExpandables;
1263  tools::Long nExtraWidthForExpanders = nExpandables ? (rAllocation.Width() - aRequisition.Width()) / nExpandables : 0;
1264 
1265  //We don't fit and there is no volunteer to be shrunk
1266  if (!nExpandables && rAllocation.Width() < aRequisition.Width())
1267  {
1268  //first reduce spacing
1269  while (nColSpacing)
1270  {
1271  nColSpacing /= 2;
1272  aRequisition = calculateRequisitionForSpacings(nRowSpacing, nColSpacing);
1273  if (aRequisition.Width() <= rAllocation.Width())
1274  break;
1275  }
1276 
1277  //share out the remaining pain to everyone
1278  tools::Long nExtraWidth = (rAllocation.Width() - aRequisition.Width()) / nMaxX;
1279 
1280  for (sal_Int32 x = 0; x < nMaxX; ++x)
1281  aWidths[x].m_nValue += nExtraWidth;
1282  }
1283 
1284  if (nExtraWidthForExpanders)
1285  {
1286  for (sal_Int32 x = 0; x < nMaxX; ++x)
1287  if (aWidths[x].m_bExpand)
1288  aWidths[x].m_nValue += nExtraWidthForExpanders;
1289  }
1290  }
1291 
1292  tools::Long nAvailableHeight = rAllocation.Height();
1293  if (nMaxY)
1294  nAvailableHeight -= nRowSpacing * (nMaxY - 1);
1295  if (get_row_homogeneous())
1296  {
1297  for (sal_Int32 y = 0; y < nMaxY; ++y)
1298  aHeights[y].m_nValue = nAvailableHeight/nMaxY;
1299  }
1300  else if (rAllocation.Height() != aRequisition.Height())
1301  {
1302  sal_Int32 nExpandables = 0;
1303  for (sal_Int32 y = 0; y < nMaxY; ++y)
1304  if (aHeights[y].m_bExpand)
1305  ++nExpandables;
1306  tools::Long nExtraHeightForExpanders = nExpandables ? (rAllocation.Height() - aRequisition.Height()) / nExpandables : 0;
1307 
1308  //We don't fit and there is no volunteer to be shrunk
1309  if (!nExpandables && rAllocation.Height() < aRequisition.Height())
1310  {
1311  //first reduce spacing
1312  while (nRowSpacing)
1313  {
1314  nRowSpacing /= 2;
1315  aRequisition = calculateRequisitionForSpacings(nRowSpacing, nColSpacing);
1316  if (aRequisition.Height() <= rAllocation.Height())
1317  break;
1318  }
1319 
1320  //share out the remaining pain to everyone
1321  tools::Long nExtraHeight = (rAllocation.Height() - aRequisition.Height()) / nMaxY;
1322 
1323  for (sal_Int32 y = 0; y < nMaxY; ++y)
1324  aHeights[y].m_nValue += nExtraHeight;
1325  }
1326 
1327  if (nExtraHeightForExpanders)
1328  {
1329  for (sal_Int32 y = 0; y < nMaxY; ++y)
1330  if (aHeights[y].m_bExpand)
1331  aHeights[y].m_nValue += nExtraHeightForExpanders;
1332  }
1333  }
1334 
1335  Point aAllocPos(0, 0);
1336  for (sal_Int32 x = 0; x < nMaxX; ++x)
1337  {
1338  for (sal_Int32 y = 0; y < nMaxY; ++y)
1339  {
1340  GridEntry &rEntry = A[x][y];
1341  vcl::Window *pChild = rEntry.pChild;
1342  if (pChild)
1343  {
1344  Size aChildAlloc(0, 0);
1345 
1346  sal_Int32 nWidth = rEntry.nSpanWidth;
1347  for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1348  aChildAlloc.AdjustWidth(aWidths[x+nSpanX].m_nValue );
1349  aChildAlloc.AdjustWidth(nColSpacing*(nWidth-1) );
1350 
1351  sal_Int32 nHeight = rEntry.nSpanHeight;
1352  for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1353  aChildAlloc.AdjustHeight(aHeights[y+nSpanY].m_nValue );
1354  aChildAlloc.AdjustHeight(nRowSpacing*(nHeight-1) );
1355 
1356  setLayoutAllocation(*pChild, aAllocPos, aChildAlloc);
1357  }
1358  aAllocPos.AdjustY(aHeights[y].m_nValue + nRowSpacing );
1359  }
1360  aAllocPos.AdjustX(aWidths[x].m_nValue + nColSpacing );
1361  aAllocPos.setY( 0 );
1362  }
1363 }
1364 
1366 {
1367  VclContainer::DumpAsPropertyTree(rJsonWriter);
1368  rJsonWriter.put("type", "grid");
1369 }
1370 
1371 bool toBool(std::u16string_view rValue)
1372 {
1373  return (!rValue.empty() && (rValue[0] == 't' || rValue[0] == 'T' || rValue[0] == '1'));
1374 }
1375 
1376 bool VclGrid::set_property(const OString &rKey, const OUString &rValue)
1377 {
1378  if (rKey == "row-spacing")
1379  set_row_spacing(rValue.toInt32());
1380  else if (rKey == "column-spacing")
1381  set_column_spacing(rValue.toInt32());
1382  else if (rKey == "row-homogeneous")
1383  m_bRowHomogeneous = toBool(rValue);
1384  else if (rKey == "column-homogeneous")
1385  m_bColumnHomogeneous = toBool(rValue);
1386  else if (rKey == "n-rows")
1387  /*nothing to do*/;
1388  else
1389  return VclContainer::set_property(rKey, rValue);
1390  return true;
1391 }
1392 
1393 const vcl::Window *VclBin::get_child() const
1394 {
1395  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1396 
1397  return pWindowImpl->mpFirstChild;
1398 }
1399 
1400 vcl::Window *VclBin::get_child()
1401 {
1402  return const_cast<vcl::Window*>(const_cast<const VclBin*>(this)->get_child());
1403 }
1404 
1405 Size VclBin::calculateRequisition() const
1406 {
1407  const vcl::Window *pChild = get_child();
1408  if (pChild && pChild->IsVisible())
1409  return getLayoutRequisition(*pChild);
1410  return Size(0, 0);
1411 }
1412 
1413 void VclBin::setAllocation(const Size &rAllocation)
1414 {
1415  vcl::Window *pChild = get_child();
1416  if (pChild && pChild->IsVisible())
1417  setLayoutAllocation(*pChild, Point(0, 0), rAllocation);
1418 }
1419 
1421 {
1422  disposeOnce();
1423 }
1424 
1426 {
1427  m_pLabel.clear();
1428  VclBin::dispose();
1429 }
1430 
1431 //To-Do, hook a DecorationView into VclFrame ?
1432 
1434 {
1435  Size aRet(0, 0);
1436 
1437  const vcl::Window *pChild = get_child();
1438  const vcl::Window *pLabel = get_label_widget();
1439 
1440  if (pChild && pChild->IsVisible())
1441  aRet = getLayoutRequisition(*pChild);
1442 
1443  if (pLabel && pLabel->IsVisible())
1444  {
1445  Size aLabelSize = getLayoutRequisition(*pLabel);
1446  aRet.AdjustHeight(aLabelSize.Height() );
1447  aRet.setWidth( std::max(aLabelSize.Width(), aRet.Width()) );
1448  }
1449 
1450  return aRet;
1451 }
1452 
1453 void VclFrame::setAllocation(const Size &rAllocation)
1454 {
1455  //SetBackground( Color(0xFF, 0x00, 0xFF) );
1456 
1457  Size aAllocation(rAllocation);
1458  Point aChildPos;
1459 
1460  vcl::Window *pChild = get_child();
1461  vcl::Window *pLabel = get_label_widget();
1462 
1463  if (pLabel && pLabel->IsVisible())
1464  {
1465  Size aLabelSize = getLayoutRequisition(*pLabel);
1466  aLabelSize.setHeight( std::min(aLabelSize.Height(), aAllocation.Height()) );
1467  aLabelSize.setWidth( std::min(aLabelSize.Width(), aAllocation.Width()) );
1468  setLayoutAllocation(*pLabel, aChildPos, aLabelSize);
1469  aAllocation.AdjustHeight( -(aLabelSize.Height()) );
1470  aChildPos.AdjustY(aLabelSize.Height() );
1471  }
1472 
1473  if (pChild && pChild->IsVisible())
1474  setLayoutAllocation(*pChild, aChildPos, aAllocation);
1475 }
1476 
1477 IMPL_LINK(VclFrame, WindowEventListener, VclWindowEvent&, rEvent, void)
1478 {
1479  if (rEvent.GetId() == VclEventId::ObjectDying)
1480  designate_label(nullptr);
1481 }
1482 
1484 {
1485  assert(!pWindow || pWindow->GetParent() == this);
1486  if (m_pLabel)
1487  m_pLabel->RemoveEventListener(LINK(this, VclFrame, WindowEventListener));
1488  m_pLabel = pWindow;
1489  if (m_pLabel)
1490  m_pLabel->AddEventListener(LINK(this, VclFrame, WindowEventListener));
1491 }
1492 
1494 {
1495  if (m_pLabel)
1496  return m_pLabel;
1497  assert(GetChildCount() == 2);
1498  //The label widget is normally the first (of two) children
1499  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1500  if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //no label exists
1501  return nullptr;
1502  return pWindowImpl->mpFirstChild;
1503 }
1504 
1506 {
1507  return const_cast<vcl::Window*>(const_cast<const VclFrame*>(this)->get_label_widget());
1508 }
1509 
1511 {
1512  //The child widget is the normally the last (of two) children
1513  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1514  assert(GetChildCount() == 2 || pWindowImpl->mbInDispose);
1515  if (!m_pLabel)
1516  return pWindowImpl->mpLastChild;
1517  if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //only label exists
1518  return nullptr;
1519  return pWindowImpl->mpLastChild;
1520 }
1521 
1523 {
1524  return const_cast<vcl::Window*>(const_cast<const VclFrame*>(this)->get_child());
1525 }
1526 
1527 void VclFrame::set_label(const OUString &rLabel)
1528 {
1529  vcl::Window *pLabel = get_label_widget();
1530  assert(pLabel);
1531  pLabel->SetText(rLabel);
1532 }
1533 
1534 OUString VclFrame::get_label() const
1535 {
1536  const vcl::Window *pLabel = get_label_widget();
1537  assert(pLabel);
1538  return pLabel->GetText();
1539 }
1540 
1542 {
1543  const vcl::Window *pLabel = get_label_widget();
1544  if (pLabel)
1545  return pLabel->GetAccessibleName();
1546  return VclBin::getDefaultAccessibleName();
1547 }
1548 
1550 {
1551  VclBin::DumpAsPropertyTree(rJsonWriter);
1552  rJsonWriter.put("type", "frame");
1553 }
1554 
1555 class DisclosureButton final : public CheckBox
1556 {
1557  virtual void ImplDrawCheckBoxState(vcl::RenderContext& rRenderContext) override
1558  {
1559  /* HACK: DisclosureButton is currently assuming, that the disclosure sign
1560  will fit into the rectangle occupied by a normal checkbox on all themes.
1561  If this does not hold true for some theme, ImplGetCheckImageSize
1562  would have to be overridden for DisclosureButton; also GetNativeControlRegion
1563  for ControlType::ListNode would have to be implemented and taken into account
1564  */
1565 
1566  tools::Rectangle aStateRect(GetStateRect());
1567 
1569  tools::Rectangle aCtrlRegion(aStateRect);
1571 
1572  if (HasFocus())
1573  nState |= ControlState::FOCUSED;
1575  nState |= ControlState::DEFAULT;
1576  if (Window::IsEnabled())
1577  nState |= ControlState::ENABLED;
1578  if (IsMouseOver() && GetMouseRect().Contains(GetPointerPosPixel()))
1579  nState |= ControlState::ROLLOVER;
1580 
1581  if (rRenderContext.DrawNativeControl(ControlType::ListNode, ControlPart::Entire, aCtrlRegion,
1582  nState, aControlValue, OUString()))
1583  return;
1584 
1585  ImplSVCtrlData& rCtrlData(ImplGetSVData()->maCtrlData);
1586  if (!rCtrlData.mpDisclosurePlus)
1587  rCtrlData.mpDisclosurePlus.reset(new Image(StockImage::Yes, SV_DISCLOSURE_PLUS));
1588  if (!rCtrlData.mpDisclosureMinus)
1589  rCtrlData.mpDisclosureMinus.reset(new Image(StockImage::Yes, SV_DISCLOSURE_MINUS));
1590 
1591  Image* pImg
1592  = IsChecked() ? rCtrlData.mpDisclosureMinus.get() : rCtrlData.mpDisclosurePlus.get();
1593 
1595  if (!IsEnabled())
1596  nStyle |= DrawImageFlags::Disable;
1597 
1598  Size aSize(aStateRect.GetSize());
1599  Size aImgSize(pImg->GetSizePixel());
1600  Point aOff((aSize.Width() - aImgSize.Width()) / 2,
1601  (aSize.Height() - aImgSize.Height()) / 2);
1602  aOff += aStateRect.TopLeft();
1603  rRenderContext.DrawImage(aOff, *pImg, nStyle);
1604  }
1605 
1606 public:
1607  explicit DisclosureButton(vcl::Window* pParent)
1608  : CheckBox(pParent, 0)
1609  {
1610  }
1611 
1612  virtual void KeyInput( const KeyEvent& rKEvt ) override
1613  {
1614  vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
1615 
1616  if( !aKeyCode.GetModifier() &&
1617  ( ( aKeyCode.GetCode() == KEY_ADD ) ||
1618  ( aKeyCode.GetCode() == KEY_SUBTRACT ) )
1619  )
1620  {
1621  Check( aKeyCode.GetCode() == KEY_ADD );
1622  }
1623  else
1624  CheckBox::KeyInput( rKEvt );
1625  }
1626 };
1627 
1629  : VclBin(pParent)
1630  , m_bResizeTopLevel(false)
1631  , m_pDisclosureButton(VclPtr<DisclosureButton>::Create(this))
1632 {
1633  m_pDisclosureButton->SetToggleHdl(LINK(this, VclExpander, ClickHdl));
1635 }
1636 
1638 {
1639  disposeOnce();
1640 }
1641 
1643 {
1644  return m_pDisclosureButton->IsChecked();
1645 }
1646 
1647 void VclExpander::set_expanded(bool bExpanded)
1648 {
1649  m_pDisclosureButton->Check(bExpanded);
1650 }
1651 
1652 void VclExpander::set_label(const OUString& rLabel)
1653 {
1654  m_pDisclosureButton->SetText(rLabel);
1655 }
1656 
1657 OUString VclExpander::get_label() const
1658 {
1659  return m_pDisclosureButton->GetText();
1660 }
1661 
1663 {
1665  VclBin::dispose();
1666 }
1667 
1669 {
1670  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1671 
1672  assert(pWindowImpl->mpFirstChild == m_pDisclosureButton);
1673 
1674  return pWindowImpl->mpFirstChild->GetWindow(GetWindowType::Next);
1675 }
1676 
1678 {
1679  return const_cast<vcl::Window*>(const_cast<const VclExpander*>(this)->get_child());
1680 }
1681 
1683 {
1684  Size aRet(0, 0);
1685 
1686  WindowImpl* pWindowImpl = ImplGetWindowImpl();
1687 
1688  const vcl::Window *pChild = get_child();
1689  const vcl::Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild.get() : nullptr;
1690 
1691  if (pChild && pChild->IsVisible() && m_pDisclosureButton->IsChecked())
1692  aRet = getLayoutRequisition(*pChild);
1693 
1694  Size aExpanderSize = getLayoutRequisition(*m_pDisclosureButton);
1695 
1696  if (pLabel && pLabel->IsVisible())
1697  {
1698  Size aLabelSize = getLayoutRequisition(*pLabel);
1699  aExpanderSize.setHeight( std::max(aExpanderSize.Height(), aLabelSize.Height()) );
1700  aExpanderSize.AdjustWidth(aLabelSize.Width() );
1701  }
1702 
1703  aRet.AdjustHeight(aExpanderSize.Height() );
1704  aRet.setWidth( std::max(aExpanderSize.Width(), aRet.Width()) );
1705 
1706  return aRet;
1707 }
1708 
1709 void VclExpander::setAllocation(const Size &rAllocation)
1710 {
1711  Size aAllocation(rAllocation);
1712  Point aChildPos;
1713 
1714  WindowImpl* pWindowImpl = ImplGetWindowImpl();
1715 
1716  //The label widget is the last (of two) children
1717  vcl::Window *pChild = get_child();
1718  vcl::Window *pLabel = pChild != pWindowImpl->mpLastChild.get() ? pWindowImpl->mpLastChild.get() : nullptr;
1719 
1720  Size aButtonSize = getLayoutRequisition(*m_pDisclosureButton);
1721  Size aLabelSize;
1722  Size aExpanderSize = aButtonSize;
1723  if (pLabel && pLabel->IsVisible())
1724  {
1725  aLabelSize = getLayoutRequisition(*pLabel);
1726  aExpanderSize.setHeight( std::max(aExpanderSize.Height(), aLabelSize.Height()) );
1727  aExpanderSize.AdjustWidth(aLabelSize.Width() );
1728  }
1729 
1730  aExpanderSize.setHeight( std::min(aExpanderSize.Height(), aAllocation.Height()) );
1731  aExpanderSize.setWidth( std::min(aExpanderSize.Width(), aAllocation.Width()) );
1732 
1733  aButtonSize.setHeight( std::min(aButtonSize.Height(), aExpanderSize.Height()) );
1734  aButtonSize.setWidth( std::min(aButtonSize.Width(), aExpanderSize.Width()) );
1735 
1736  tools::Long nExtraExpanderHeight = aExpanderSize.Height() - aButtonSize.Height();
1737  Point aButtonPos(aChildPos.X(), aChildPos.Y() + nExtraExpanderHeight/2);
1738  setLayoutAllocation(*m_pDisclosureButton, aButtonPos, aButtonSize);
1739 
1740  if (pLabel && pLabel->IsVisible())
1741  {
1742  aLabelSize.setHeight( std::min(aLabelSize.Height(), aExpanderSize.Height()) );
1743  aLabelSize.setWidth( std::min(aLabelSize.Width(),
1744  aExpanderSize.Width() - aButtonSize.Width()) );
1745 
1746  tools::Long nExtraLabelHeight = aExpanderSize.Height() - aLabelSize.Height();
1747  Point aLabelPos(aChildPos.X() + aButtonSize.Width(), aChildPos.Y() + nExtraLabelHeight/2);
1748  setLayoutAllocation(*pLabel, aLabelPos, aLabelSize);
1749  }
1750 
1751  aAllocation.AdjustHeight( -(aExpanderSize.Height()) );
1752  aChildPos.AdjustY(aExpanderSize.Height() );
1753 
1754  if (pChild && pChild->IsVisible())
1755  {
1757  aAllocation = Size();
1758  setLayoutAllocation(*pChild, aChildPos, aAllocation);
1759  }
1760 }
1761 
1762 bool VclExpander::set_property(const OString &rKey, const OUString &rValue)
1763 {
1764  if (rKey == "expanded")
1765  set_expanded(toBool(rValue));
1766  else if (rKey == "resize-toplevel")
1767  m_bResizeTopLevel = toBool(rValue);
1768  else
1769  return VclBin::set_property(rKey, rValue);
1770  return true;
1771 }
1772 
1774 {
1775  VclBin::StateChanged( nType );
1776 
1777  if (nType == StateChangedType::InitShow)
1778  {
1779  vcl::Window *pChild = get_child();
1780  if (pChild)
1781  pChild->Show(m_pDisclosureButton->IsChecked());
1782  }
1783 }
1784 
1786 {
1787  return m_pDisclosureButton;
1788 }
1789 
1791 {
1792  return const_cast<vcl::Window*>(const_cast<const VclExpander*>(this)->get_label_widget());
1793 }
1794 
1796 {
1797  VclContainer::DumpAsPropertyTree(rJsonWriter);
1798  rJsonWriter.put("type", "expander");
1799 }
1800 
1802 {
1803  return ExpanderUIObject::create;
1804 }
1805 
1806 IMPL_LINK( VclExpander, ClickHdl, CheckBox&, rBtn, void )
1807 {
1808  vcl::Window *pChild = get_child();
1809  if (pChild)
1810  {
1811  pChild->Show(rBtn.IsChecked());
1812  queue_resize();
1813  Dialog* pResizeDialog = m_bResizeTopLevel ? GetParentDialog() : nullptr;
1814  if (pResizeDialog)
1815  pResizeDialog->setOptimalLayoutSize(true);
1816  }
1817  maExpandedHdl.Call(*this);
1818 }
1819 
1822  , m_bUserManagedScrolling(false)
1823  , m_eDrawFrameStyle(DrawFrameStyle::NONE)
1824  , m_eDrawFrameFlags(DrawFrameFlags::WindowBorder)
1825  , m_pVScroll(VclPtr<ScrollBar>::Create(this, WB_HIDE | WB_VERT))
1826  , m_pHScroll(VclPtr<ScrollBar>::Create(this, WB_HIDE | WB_HORZ))
1827  , m_aScrollBarBox(VclPtr<ScrollBarBox>::Create(this, WB_HIDE))
1828 {
1829  SetType(WindowType::SCROLLWINDOW);
1830 
1831  AllSettings aAllSettings = GetSettings();
1832  StyleSettings aStyle = aAllSettings.GetStyleSettings();
1833  aStyle.SetMonoColor(aStyle.GetShadowColor());
1834  aAllSettings.SetStyleSettings(aStyle);
1835  GetOutDev()->SetSettings(aAllSettings);
1836 
1837  Link<ScrollBar*,void> aLink( LINK( this, VclScrolledWindow, ScrollBarHdl ) );
1838  m_pVScroll->SetScrollHdl(aLink);
1839  m_pHScroll->SetScrollHdl(aLink);
1840 
1842 }
1843 
1845 {
1847  return 0;
1848  const tools::Rectangle aRect(tools::Rectangle(Point(0, 0), Size(100, 100)));
1849  DecorationView aDecoView(const_cast<OutputDevice*>(GetOutDev()));
1850  // don't actually draw anything, just measure what size it would be and the diff is the desired border size to reserve
1851  const tools::Rectangle aContentRect = aDecoView.DrawFrame(aRect, m_eDrawFrameStyle, m_eDrawFrameFlags | DrawFrameFlags::NoDraw);
1852  const auto nBorderWidth = (aRect.GetWidth() - aContentRect.GetWidth()) / 2;
1853  return std::max<int>(nBorderWidth, 1);
1854 }
1855 
1857 {
1861  VclBin::dispose();
1862 }
1863 
1865 {
1866  vcl::Window *pChild = get_child();
1867  if (!pChild)
1868  return;
1869 
1870  assert(dynamic_cast<VclViewport*>(pChild) && "scrolledwindow child should be a Viewport");
1871 
1872  pChild = pChild->GetWindow(GetWindowType::FirstChild);
1873 
1874  if (!pChild)
1875  return;
1876 
1877  Point aWinPos(-m_pHScroll->GetThumbPos(), -m_pVScroll->GetThumbPos());
1878  pChild->SetPosPixel(aWinPos);
1879 }
1880 
1882 {
1883  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1884  assert(GetChildCount() == 4 || pWindowImpl->mbInDispose);
1885  return pWindowImpl->mpLastChild;
1886 }
1887 
1889 {
1890  return const_cast<vcl::Window*>(const_cast<const VclScrolledWindow*>(this)->get_child());
1891 }
1892 
1894 {
1895  Size aRet(0, 0);
1896 
1897  const vcl::Window *pChild = get_child();
1898  if (pChild && pChild->IsVisible())
1899  aRet = getLayoutRequisition(*pChild);
1900 
1901  if (GetStyle() & WB_VSCROLL)
1902  aRet.AdjustWidth(getLayoutRequisition(*m_pVScroll).Width() );
1903 
1904  if (GetStyle() & WB_HSCROLL)
1905  aRet.AdjustHeight(getLayoutRequisition(*m_pHScroll).Height() );
1906 
1907  aRet.AdjustHeight(2 * m_nBorderWidth);
1908  aRet.AdjustWidth(2 * m_nBorderWidth);
1909 
1910  return aRet;
1911 }
1912 
1914 {
1915  const vcl::Window *pChild = get_child();
1916  if (!pChild || !pChild->IsVisible())
1917  return;
1918 
1919  Size aOutSize(getVisibleChildSize());
1920 
1921  m_pVScroll->SetRangeMax(rRequest.Height());
1922  m_pVScroll->SetVisibleSize(aOutSize.Height());
1923  m_pVScroll->SetPageSize(16);
1924 
1925  m_pHScroll->SetRangeMax(rRequest.Width());
1926  m_pHScroll->SetVisibleSize(aOutSize.Width());
1927  m_pHScroll->SetPageSize(16);
1928 
1929  m_pVScroll->Scroll();
1930  m_pHScroll->Scroll();
1931 }
1932 
1933 void VclScrolledWindow::doSetAllocation(const Size &rAllocation, bool bRetryOnFailure)
1934 {
1935  Size aChildReq;
1936 
1937  vcl::Window *pChild = get_child();
1938  if (pChild && pChild->IsVisible())
1939  aChildReq = getLayoutRequisition(*pChild);
1940 
1941  tools::Long nAvailHeight = rAllocation.Height() - 2 * m_nBorderWidth;
1942  tools::Long nAvailWidth = rAllocation.Width() - 2 * m_nBorderWidth;
1943 
1944  // vert. ScrollBar
1945  bool bShowVScroll;
1946  if (GetStyle() & WB_AUTOVSCROLL)
1947  bShowVScroll = nAvailHeight < aChildReq.Height();
1948  else
1949  bShowVScroll = (GetStyle() & WB_VSCROLL) != 0;
1950 
1951  if (bShowVScroll)
1952  nAvailWidth -= getLayoutRequisition(*m_pVScroll).Width();
1953 
1954  // horz. ScrollBar
1955  bool bShowHScroll;
1956  if (GetStyle() & WB_AUTOHSCROLL)
1957  {
1958  bShowHScroll = nAvailWidth < aChildReq.Width();
1959 
1960  if (bShowHScroll)
1961  nAvailHeight -= getLayoutRequisition(*m_pHScroll).Height();
1962 
1963  if (GetStyle() & WB_AUTOVSCROLL)
1964  bShowVScroll = nAvailHeight < aChildReq.Height();
1965  }
1966  else
1967  bShowHScroll = (GetStyle() & WB_HSCROLL) != 0;
1968 
1969  if (m_pHScroll->IsVisible() != bShowHScroll)
1970  m_pHScroll->Show(bShowHScroll);
1971  if (m_pVScroll->IsVisible() != bShowVScroll)
1972  m_pVScroll->Show(bShowVScroll);
1973 
1974  Size aInnerSize(rAllocation);
1975  aInnerSize.AdjustWidth(-2 * m_nBorderWidth);
1976  aInnerSize.AdjustHeight(-2 * m_nBorderWidth);
1977 
1978  bool bBothVisible = m_pVScroll->IsVisible() && m_pHScroll->IsVisible();
1979  auto nScrollBarWidth = getLayoutRequisition(*m_pVScroll).Width();
1980  auto nScrollBarHeight = getLayoutRequisition(*m_pHScroll).Height();
1981 
1982  if (m_pVScroll->IsVisible())
1983  {
1984  Point aScrollPos(rAllocation.Width() - nScrollBarWidth - m_nBorderWidth, m_nBorderWidth);
1985  Size aScrollSize(nScrollBarWidth, rAllocation.Height() - 2 * m_nBorderWidth);
1986  if (bBothVisible)
1987  aScrollSize.AdjustHeight(-nScrollBarHeight);
1988  setLayoutAllocation(*m_pVScroll, aScrollPos, aScrollSize);
1989  aInnerSize.AdjustWidth( -nScrollBarWidth );
1990  }
1991 
1992  if (m_pHScroll->IsVisible())
1993  {
1994  Point aScrollPos(m_nBorderWidth, rAllocation.Height() - nScrollBarHeight);
1995  Size aScrollSize(rAllocation.Width() - 2 * m_nBorderWidth, nScrollBarHeight);
1996  if (bBothVisible)
1997  aScrollSize.AdjustWidth(-nScrollBarWidth);
1998  setLayoutAllocation(*m_pHScroll, aScrollPos, aScrollSize);
1999  aInnerSize.AdjustHeight( -nScrollBarHeight );
2000  }
2001 
2002  if (bBothVisible)
2003  {
2004  Point aBoxPos(aInnerSize.Width() + m_nBorderWidth, aInnerSize.Height() + m_nBorderWidth);
2005  m_aScrollBarBox->SetPosSizePixel(aBoxPos, Size(nScrollBarWidth, nScrollBarHeight));
2006  m_aScrollBarBox->Show();
2007  }
2008  else
2009  {
2010  m_aScrollBarBox->Hide();
2011  }
2012 
2013  if (pChild && pChild->IsVisible())
2014  {
2015  assert(dynamic_cast<VclViewport*>(pChild) && "scrolledwindow child should be a Viewport");
2016 
2017  WinBits nOldBits = (GetStyle() & (WB_AUTOVSCROLL | WB_VSCROLL | WB_AUTOHSCROLL | WB_HSCROLL));
2018 
2019  setLayoutAllocation(*pChild, Point(m_nBorderWidth, m_nBorderWidth), aInnerSize);
2020 
2021  // tdf#128758 if the layout allocation triggered some callback that
2022  // immediately invalidates the layout by adding scrollbars then
2023  // normally this would simply retrigger layout and another toplevel
2024  // attempt is made later. But the initial layout attempt blocks
2025  // relayouts, so just make another single effort here.
2026  WinBits nNewBits = (GetStyle() & (WB_AUTOVSCROLL | WB_VSCROLL | WB_AUTOHSCROLL | WB_HSCROLL));
2027  if (nOldBits != nNewBits && bRetryOnFailure)
2028  {
2029  doSetAllocation(rAllocation, false);
2030  return;
2031  }
2032  }
2033 
2035  InitScrollBars(aChildReq);
2036 }
2037 
2038 void VclScrolledWindow::setAllocation(const Size &rAllocation)
2039 {
2040  doSetAllocation(rAllocation, true);
2041 }
2042 
2044 {
2045  Size aRet(GetSizePixel());
2046  if (m_pVScroll->IsVisible())
2047  aRet.AdjustWidth( -(m_pVScroll->GetSizePixel().Width()) );
2048  if (m_pHScroll->IsVisible())
2049  aRet.AdjustHeight( -(m_pHScroll->GetSizePixel().Height()) );
2050  aRet.AdjustHeight(-2 * m_nBorderWidth);
2051  aRet.AdjustWidth(-2 * m_nBorderWidth);
2052  return aRet;
2053 }
2054 
2055 bool VclScrolledWindow::set_property(const OString &rKey, const OUString &rValue)
2056 {
2057  if (rKey == "shadow-type" || rKey == "name")
2058  {
2059  if (rKey == "shadow-type")
2060  {
2061  // despite the style names, this looks like the best mapping
2062  if (rValue == "in")
2064  else if (rValue == "out")
2066  else if (rValue == "etched-in")
2068  else if (rValue == "etched-out")
2070  else if (rValue == "none")
2072  }
2073  else if (rKey == "name")
2074  {
2076  if (rValue == "monoborder")
2078  }
2079 
2080  auto nBorderWidth = CalcBorderWidth();
2081  if (m_nBorderWidth != nBorderWidth)
2082  {
2083  m_nBorderWidth = nBorderWidth;
2084  queue_resize();
2085  }
2086 
2087  return true;
2088  }
2089 
2090  bool bRet = VclBin::set_property(rKey, rValue);
2091  m_pVScroll->Show((GetStyle() & WB_VSCROLL) != 0);
2092  m_pHScroll->Show((GetStyle() & WB_HSCROLL) != 0);
2093  return bRet;
2094 }
2095 
2097 {
2098  bool bDone = false;
2099  if ( rNEvt.GetType() == MouseNotifyEvent::COMMAND )
2100  {
2101  const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
2102  if ( rCEvt.GetCommand() == CommandEventId::Wheel )
2103  {
2104  const CommandWheelData* pData = rCEvt.GetWheelData();
2105  if( !pData->GetModifier() && ( pData->GetMode() == CommandWheelMode::SCROLL ) )
2106  {
2107  // tdf#140537 only handle scroll commands in the valid shown scrollbars
2108  bDone = HandleScrollCommand(rCEvt,
2109  m_pHScroll->IsVisible() ? m_pHScroll : nullptr,
2110  m_pVScroll->IsVisible() ? m_pVScroll : nullptr);
2111  }
2112  }
2113  }
2114 
2115  return bDone || VclBin::EventNotify( rNEvt );
2116 }
2117 
2119 {
2120  VclBin::Paint(rRenderContext, rRect);
2122  return;
2123  const tools::Rectangle aRect(tools::Rectangle(Point(0,0), GetSizePixel()));
2124  DecorationView aDecoView(&rRenderContext);
2125  const tools::Rectangle aContentRect = aDecoView.DrawFrame(aRect, m_eDrawFrameStyle, m_eDrawFrameFlags);
2126  const auto nBorderWidth = (aRect.GetWidth() - aContentRect.GetWidth()) / 2;
2127  SAL_WARN_IF(nBorderWidth > m_nBorderWidth, "vcl.layout", "desired border at paint " <<
2128  nBorderWidth << " is larger than expected " << m_nBorderWidth);
2129 }
2130 
2131 void VclViewport::setAllocation(const Size &rAllocation)
2132 {
2133  vcl::Window *pChild = get_child();
2134  if (!(pChild && pChild->IsVisible()))
2135  return;
2136 
2137  Size aReq(getLayoutRequisition(*pChild));
2138  aReq.setWidth( std::max(aReq.Width(), rAllocation.Width()) );
2139  aReq.setHeight( std::max(aReq.Height(), rAllocation.Height()) );
2140  Point aKeepPos(pChild->GetPosPixel());
2142  {
2143  aKeepPos = Point(0, 0);
2144  m_bInitialAllocation = false;
2145  }
2146  setLayoutAllocation(*pChild, aKeepPos, aReq);
2147 }
2148 
2150 {
2151  const WindowImpl* pWindowImpl = ImplGetWindowImpl();
2152 
2153  assert(pWindowImpl->mpFirstChild.get() == m_aEventBoxHelper.get());
2154 
2155  return pWindowImpl->mpFirstChild->GetWindow(GetWindowType::Next);
2156 }
2157 
2159 {
2160  return const_cast<vcl::Window*>(const_cast<const VclEventBox*>(this)->get_child());
2161 }
2162 
2163 void VclEventBox::setAllocation(const Size& rAllocation)
2164 {
2165  Point aChildPos(0, 0);
2166  for (vcl::Window *pChild = GetWindow(GetWindowType::FirstChild); pChild; pChild = pChild->GetWindow(GetWindowType::Next))
2167  {
2168  if (!pChild->IsVisible())
2169  continue;
2170  setLayoutAllocation(*pChild, aChildPos, rAllocation);
2171  }
2172 }
2173 
2175 {
2176  Size aRet(0, 0);
2177 
2178  for (const vcl::Window* pChild = get_child(); pChild;
2179  pChild = pChild->GetWindow(GetWindowType::Next))
2180  {
2181  if (!pChild->IsVisible())
2182  continue;
2183  Size aChildSize = getLayoutRequisition(*pChild);
2184  aRet.setWidth( std::max(aRet.Width(), aChildSize.Width()) );
2185  aRet.setHeight( std::max(aRet.Height(), aChildSize.Height()) );
2186  }
2187 
2188  return aRet;
2189 }
2190 
2192 {
2193  //discard events by default to block them reaching children
2194 }
2195 
2197 {
2198  disposeOnce();
2199 }
2200 
2202 {
2203  m_aEventBoxHelper.disposeAndClear();
2204  VclBin::dispose();
2205 }
2206 
2208 {
2209  //sufficient to trigger one widget to trigger all of them
2210  if (!m_aWindows.empty())
2211  {
2212  (*m_aWindows.begin())->queue_resize();
2213  }
2214 }
2215 
2216 void VclSizeGroup::set_ignore_hidden(bool bIgnoreHidden)
2217 {
2218  if (bIgnoreHidden != m_bIgnoreHidden)
2219  {
2220  m_bIgnoreHidden = bIgnoreHidden;
2222  }
2223 }
2224 
2226 {
2227  if (eMode != m_eMode)
2228  {
2229  m_eMode = eMode;
2231  }
2232 
2233 }
2234 
2235 void VclSizeGroup::set_property(const OString &rKey, const OUString &rValue)
2236 {
2237  if (rKey == "ignore-hidden")
2238  set_ignore_hidden(toBool(rValue));
2239  else if (rKey == "mode")
2240  {
2242  if (rValue == "none")
2243  eMode = VclSizeGroupMode::NONE;
2244  else if (rValue == "horizontal")
2246  else if (rValue == "vertical")
2248  else if (rValue == "both")
2249  eMode = VclSizeGroupMode::Both;
2250  else
2251  {
2252  SAL_WARN("vcl.layout", "unknown size group mode" << rValue);
2253  }
2254  set_mode(eMode);
2255  }
2256  else
2257  {
2258  SAL_INFO("vcl.layout", "unhandled property: " << rKey);
2259  }
2260 }
2261 
2263 {
2265 
2266  if (m_pGrid)
2267  return;
2268 
2269  VclContainer *pContainer = get_content_area();
2270  assert(pContainer);
2271 
2272  m_pGrid.set( VclPtr<VclGrid>::Create(pContainer) );
2279 
2281  switch (m_eMessageType)
2282  {
2283  case VclMessageType::Info:
2285  break;
2288  break;
2291  break;
2292  case VclMessageType::Error:
2294  break;
2295  case VclMessageType::Other:
2296  break;
2297  }
2302 
2304 
2305  bool bHasSecondaryText = !m_sSecondaryString.isEmpty();
2306 
2310 
2314 
2320  m_pSecondaryMessage->Show(bHasSecondaryText);
2321 
2322  MessageDialog::SetMessagesWidths(this, m_pPrimaryMessage, bHasSecondaryText ? m_pSecondaryMessage.get() : nullptr);
2323 
2324  VclButtonBox *pButtonBox = get_action_area();
2325  assert(pButtonBox);
2326 
2327  VclPtr<PushButton> pBtn;
2328  short nDefaultResponse = get_default_response();
2329  switch (m_eButtonsType)
2330  {
2331  case VclButtonsType::NONE:
2332  break;
2333  case VclButtonsType::Ok:
2334  pBtn.set( VclPtr<OKButton>::Create(pButtonBox) );
2335  pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2336  pBtn->Show();
2337  pBtn->set_id("ok");
2338  add_button(pBtn, RET_OK, true);
2339  nDefaultResponse = RET_OK;
2340  break;
2341  case VclButtonsType::Close:
2342  pBtn.set( VclPtr<CloseButton>::Create(pButtonBox) );
2343  pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2344  pBtn->Show();
2345  pBtn->set_id("close");
2346  add_button(pBtn, RET_CLOSE, true);
2347  nDefaultResponse = RET_CLOSE;
2348  break;
2350  pBtn.set( VclPtr<CancelButton>::Create(pButtonBox) );
2351  pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2352  pBtn->Show();
2353  pBtn->set_id("cancel");
2354  add_button(pBtn, RET_CANCEL, true);
2355  nDefaultResponse = RET_CANCEL;
2356  break;
2357  case VclButtonsType::YesNo:
2358  pBtn = VclPtr<PushButton>::Create(pButtonBox);
2359  pBtn->SetText(GetStandardText(StandardButtonType::Yes));
2360  pBtn->Show();
2361  pBtn->set_id("yes");
2362  add_button(pBtn, RET_YES, true);
2363 
2364  pBtn.set( VclPtr<PushButton>::Create(pButtonBox) );
2365  pBtn->SetText(GetStandardText(StandardButtonType::No));
2366  pBtn->Show();
2367  pBtn->set_id("no");
2368  add_button(pBtn, RET_NO, true);
2369  nDefaultResponse = RET_NO;
2370  break;
2372  pBtn.set( VclPtr<OKButton>::Create(pButtonBox) );
2373  pBtn->Show();
2374  pBtn->set_id("ok");
2375  add_button(pBtn, RET_OK, true);
2376 
2377  pBtn.set( VclPtr<CancelButton>::Create(pButtonBox) );
2378  pBtn->Show();
2379  pBtn->set_id("cancel");
2380  add_button(pBtn, RET_CANCEL, true);
2381  nDefaultResponse = RET_CANCEL;
2382  break;
2383  }
2384  set_default_response(nDefaultResponse);
2385  sort_native_button_order(*pButtonBox);
2386  m_pMessageBox->Show();
2387  m_pGrid->Show();
2388 }
2389 
2391 {
2392 #if defined _WIN32
2393  set_border_width(3);
2394 #else
2395  set_border_width(12);
2396 #endif
2403 }
2404 
2406  : Dialog(pParent, nStyle)
2407  , m_eButtonsType(VclButtonsType::NONE)
2408  , m_eMessageType(VclMessageType::Info)
2409  , m_pOwnedContentArea(nullptr)
2410  , m_pOwnedActionArea(nullptr)
2411  , m_pGrid(nullptr)
2412  , m_pMessageBox(nullptr)
2413  , m_pImage(nullptr)
2414  , m_pPrimaryMessage(nullptr)
2415  , m_pSecondaryMessage(nullptr)
2416 {
2417  SetType(WindowType::MESSBOX);
2418 }
2419 
2421  const OUString &rMessage,
2422  VclMessageType eMessageType,
2423  VclButtonsType eButtonsType)
2424  : Dialog(pParent, WB_MOVEABLE | WB_3DLOOK | WB_CLOSEABLE)
2425  , m_eButtonsType(eButtonsType)
2426  , m_eMessageType(eMessageType)
2427  , m_pGrid(nullptr)
2428  , m_pMessageBox(nullptr)
2429  , m_pImage(nullptr)
2430  , m_pPrimaryMessage(nullptr)
2431  , m_pSecondaryMessage(nullptr)
2432  , m_sPrimaryString(rMessage)
2433 {
2434  SetType(WindowType::MESSBOX);
2437 
2438  switch (m_eMessageType)
2439  {
2440  case VclMessageType::Info:
2442  break;
2445  break;
2448  break;
2449  case VclMessageType::Error:
2451  break;
2452  case VclMessageType::Other:
2454  break;
2455  }
2456 }
2457 
2459 {
2468  Dialog::dispose();
2469 }
2470 
2472 {
2473  disposeOnce();
2474 }
2475 
2477  VclMultiLineEdit *pPrimaryMessage, VclMultiLineEdit *pSecondaryMessage)
2478 {
2479  if (pSecondaryMessage)
2480  {
2481  assert(pPrimaryMessage);
2482  vcl::Font aFont = pParent->GetSettings().GetStyleSettings().GetLabelFont();
2483  aFont.SetFontSize(Size(0, aFont.GetFontSize().Height() * 1.2));
2484  aFont.SetWeight(WEIGHT_BOLD);
2485  pPrimaryMessage->SetControlFont(aFont);
2486  pPrimaryMessage->SetMaxTextWidth(pPrimaryMessage->approximate_char_width() * 44);
2487  pSecondaryMessage->SetMaxTextWidth(pSecondaryMessage->approximate_char_width() * 60);
2488  }
2489  else
2490  pPrimaryMessage->SetMaxTextWidth(pPrimaryMessage->approximate_char_width() * 60);
2491 }
2492 
2493 OUString const & MessageDialog::get_primary_text() const
2494 {
2495  const_cast<MessageDialog*>(this)->setDeferredProperties();
2496 
2497  return m_sPrimaryString;
2498 }
2499 
2500 OUString const & MessageDialog::get_secondary_text() const
2501 {
2502  const_cast<MessageDialog*>(this)->setDeferredProperties();
2503 
2504  return m_sSecondaryString;
2505 }
2506 
2507 bool MessageDialog::set_property(const OString &rKey, const OUString &rValue)
2508 {
2509  if (rKey == "text")
2510  set_primary_text(rValue);
2511  else if (rKey == "secondary-text")
2512  set_secondary_text(rValue);
2513  else if (rKey == "message-type")
2514  {
2516  if (rValue == "info")
2517  eMode = VclMessageType::Info;
2518  else if (rValue == "warning")
2519  eMode = VclMessageType::Warning;
2520  else if (rValue == "question")
2521  eMode = VclMessageType::Question;
2522  else if (rValue == "error")
2523  eMode = VclMessageType::Error;
2524  else if (rValue == "other")
2525  eMode = VclMessageType::Other;
2526  else
2527  {
2528  SAL_WARN("vcl.layout", "unknown message type mode" << rValue);
2529  }
2530  m_eMessageType = eMode;
2531  }
2532  else if (rKey == "buttons")
2533  {
2535  if (rValue == "none")
2536  eMode = VclButtonsType::NONE;
2537  else if (rValue == "ok")
2538  eMode = VclButtonsType::Ok;
2539  else if (rValue == "cancel")
2540  eMode = VclButtonsType::Cancel;
2541  else if (rValue == "close")
2542  eMode = VclButtonsType::Close;
2543  else if (rValue == "yes-no")
2544  eMode = VclButtonsType::YesNo;
2545  else if (rValue == "ok-cancel")
2546  eMode = VclButtonsType::OkCancel;
2547  else
2548  {
2549  SAL_WARN("vcl.layout", "unknown buttons type mode" << rValue);
2550  }
2551  m_eButtonsType = eMode;
2552  }
2553  else
2554  return Dialog::set_property(rKey, rValue);
2555  return true;
2556 }
2557 
2558 void MessageDialog::set_primary_text(const OUString &rPrimaryString)
2559 {
2560  m_sPrimaryString = rPrimaryString;
2561  if (m_pPrimaryMessage)
2562  {
2566  }
2567 }
2568 
2569 void MessageDialog::set_secondary_text(const OUString &rSecondaryString)
2570 {
2571  m_sSecondaryString = rSecondaryString;
2572  if (m_pSecondaryMessage)
2573  {
2577  }
2578 }
2579 
2581 {
2582  Dialog::StateChanged(nType);
2583  if (nType == StateChangedType::InitShow)
2584  {
2585  // MessageBox should be at least as wide as to see the title
2586  auto nTitleWidth = CalcTitleWidth();
2587  // Extra-Width for Close button
2588  nTitleWidth += mpWindowImpl->mnTopBorder;
2589  if (get_preferred_size().Width() < nTitleWidth)
2590  {
2591  set_width_request(nTitleWidth);
2592  DoInitialLayout();
2593  }
2594  }
2595 }
2596 
2597 VclPaned::VclPaned(vcl::Window *pParent, bool bVertical)
2598  : VclContainer(pParent, WB_HIDE | WB_CLIPCHILDREN)
2599  , m_pSplitter(VclPtr<Splitter>::Create(this, bVertical ? WB_VSCROLL : WB_HSCROLL))
2600  , m_nPosition(-1)
2601 {
2602  m_pSplitter->SetBackground(Wallpaper(Application::GetSettings().GetStyleSettings().GetFaceColor()));
2603  m_pSplitter->Show();
2604 }
2605 
2607 {
2610 }
2611 
2613  : VclPaned(pParent, true)
2614 {
2615  m_pSplitter->SetSplitHdl(LINK(this, VclVPaned, SplitHdl));
2616 }
2617 
2618 IMPL_LINK(VclVPaned, SplitHdl, Splitter*, pSplitter, void)
2619 {
2620  tools::Long nSize = pSplitter->GetSplitPosPixel();
2621  Size aSplitterSize(m_pSplitter->GetSizePixel());
2622  Size aAllocation(GetSizePixel());
2623  arrange(aAllocation, nSize, aAllocation.Height() - nSize - aSplitterSize.Height());
2624 }
2625 
2626 void VclVPaned::arrange(const Size& rAllocation, tools::Long nFirstHeight, tools::Long nSecondHeight)
2627 {
2628  Size aSplitterSize(rAllocation.Width(), getLayoutRequisition(*m_pSplitter).Height());
2629  Size aFirstChildSize(rAllocation.Width(), nFirstHeight);
2630  Size aSecondChildSize(rAllocation.Width(), nSecondHeight);
2631  int nElement = 0;
2632  for (vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2633  pChild = pChild->GetWindow(GetWindowType::Next))
2634  {
2635  if (!pChild->IsVisible())
2636  continue;
2637  if (nElement == 0)
2638  {
2639  Point aSplitterPos(0, aFirstChildSize.Height());
2640  setLayoutAllocation(*m_pSplitter, aSplitterPos, aSplitterSize);
2641  m_nPosition = aSplitterPos.Y() + aSplitterSize.Height() / 2;
2642  }
2643  else if (nElement == 1)
2644  {
2645  Point aChildPos(0, 0);
2646  setLayoutAllocation(*pChild, aChildPos, aFirstChildSize);
2647  }
2648  else if (nElement == 2)
2649  {
2650  Point aChildPos(0, aFirstChildSize.Height() + aSplitterSize.Height());
2651  setLayoutAllocation(*pChild, aChildPos, aSecondChildSize);
2652  }
2653  ++nElement;
2654  }
2655 }
2656 
2658 {
2659  VclPaned::set_position(nPosition);
2660 
2661  Size aAllocation(GetSizePixel());
2662  Size aSplitterSize(m_pSplitter->GetSizePixel());
2663 
2664  nPosition -= aSplitterSize.Height() / 2;
2665 
2666  arrange(aAllocation, nPosition, aAllocation.Height() - nPosition - aSplitterSize.Height());
2667 }
2668 
2669 void VclVPaned::setAllocation(const Size& rAllocation)
2670 {
2671  //supporting "shrink" could be done by adjusting the allowed drag rectangle
2672  m_pSplitter->SetDragRectPixel(tools::Rectangle(Point(0, 0), rAllocation));
2673  Size aSplitterSize(rAllocation.Width(), getLayoutRequisition(*m_pSplitter).Height());
2674  const tools::Long nHeight = rAllocation.Height() - aSplitterSize.Height();
2675 
2676  tools::Long nFirstHeight = 0;
2677  tools::Long nSecondHeight = 0;
2678  bool bFirstCanResize = true;
2679  bool bSecondCanResize = true;
2680  const bool bInitialAllocation = get_position() < 0;
2681  int nElement = 0;
2682  for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2683  pChild = pChild->GetWindow(GetWindowType::Next))
2684  {
2685  if (!pChild->IsVisible())
2686  continue;
2687  if (nElement == 1)
2688  {
2689  if (bInitialAllocation)
2690  nFirstHeight = getLayoutRequisition(*pChild).Height();
2691  else
2692  nFirstHeight = pChild->GetSizePixel().Height() + pChild->get_margin_top() + pChild->get_margin_bottom();
2693  bFirstCanResize = pChild->get_expand();
2694  }
2695  else if (nElement == 2)
2696  {
2697  if (bInitialAllocation)
2698  nSecondHeight = getLayoutRequisition(*pChild).Height();
2699  else
2700  nSecondHeight = pChild->GetSizePixel().Height() + pChild->get_margin_top() + pChild->get_margin_bottom();
2701  bSecondCanResize = pChild->get_expand();
2702  }
2703  ++nElement;
2704  }
2705  tools::Long nHeightRequest = nFirstHeight + nSecondHeight;
2706  tools::Long nHeightDiff = nHeight - nHeightRequest;
2707  if (bFirstCanResize == bSecondCanResize)
2708  nFirstHeight += nHeightDiff/2;
2709  else if (bFirstCanResize)
2710  nFirstHeight += nHeightDiff;
2711  arrange(rAllocation, nFirstHeight, rAllocation.Height() - nFirstHeight - aSplitterSize.Height());
2712 }
2713 
2715 {
2716  Size aRet(0, 0);
2717 
2718  for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2719  pChild = pChild->GetWindow(GetWindowType::Next))
2720  {
2721  if (!pChild->IsVisible())
2722  continue;
2723  Size aChildSize = getLayoutRequisition(*pChild);
2724  aRet.setWidth( std::max(aRet.Width(), aChildSize.Width()) );
2725  aRet.AdjustHeight(aChildSize.Height() );
2726  }
2727 
2728  return aRet;
2729 }
2730 
2732  : VclPaned(pParent, false)
2733 {
2734  m_pSplitter->SetSplitHdl(LINK(this, VclHPaned, SplitHdl));
2735 }
2736 
2737 IMPL_LINK(VclHPaned, SplitHdl, Splitter*, pSplitter, void)
2738 {
2739  tools::Long nSize = pSplitter->GetSplitPosPixel();
2740  Size aSplitterSize(m_pSplitter->GetSizePixel());
2741  Size aAllocation(GetSizePixel());
2742  arrange(aAllocation, nSize, aAllocation.Width() - nSize - aSplitterSize.Width());
2743 }
2744 
2745 void VclHPaned::arrange(const Size& rAllocation, tools::Long nFirstWidth, tools::Long nSecondWidth)
2746 {
2747  Size aSplitterSize(getLayoutRequisition(*m_pSplitter).Width(), rAllocation.Height());
2748  Size aFirstChildSize(nFirstWidth, rAllocation.Height());
2749  Size aSecondChildSize(nSecondWidth, rAllocation.Height());
2750  int nElement = 0;
2751  for (vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2752  pChild = pChild->GetWindow(GetWindowType::Next))
2753  {
2754  if (!pChild->IsVisible())
2755  continue;
2756  if (nElement == 0)
2757  {
2758  Point aSplitterPos(aFirstChildSize.Width(), 0);
2759  setLayoutAllocation(*m_pSplitter, aSplitterPos, aSplitterSize);
2760  m_nPosition = aSplitterPos.X() + aSplitterSize.Width() / 2;
2761  }
2762  else if (nElement == 1)
2763  {
2764  Point aChildPos(0, 0);
2765  setLayoutAllocation(*pChild, aChildPos, aFirstChildSize);
2766  }
2767  else if (nElement == 2)
2768  {
2769  Point aChildPos(aFirstChildSize.Width() + aSplitterSize.Width(), 0);
2770  setLayoutAllocation(*pChild, aChildPos, aSecondChildSize);
2771  }
2772  ++nElement;
2773  }
2774 }
2775 
2777 {
2778  VclPaned::set_position(nPosition);
2779 
2780  Size aAllocation(GetSizePixel());
2781  Size aSplitterSize(m_pSplitter->GetSizePixel());
2782 
2783  nPosition -= aSplitterSize.Width() / 2;
2784 
2785  arrange(aAllocation, nPosition, aAllocation.Width() - nPosition - aSplitterSize.Width());
2786 }
2787 
2788 void VclHPaned::setAllocation(const Size& rAllocation)
2789 {
2790  //supporting "shrink" could be done by adjusting the allowed drag rectangle
2791  m_pSplitter->SetDragRectPixel(tools::Rectangle(Point(0, 0), rAllocation));
2792  Size aSplitterSize(getLayoutRequisition(*m_pSplitter).Width(), rAllocation.Height());
2793  const tools::Long nWidth = rAllocation.Width() - aSplitterSize.Width();
2794 
2795  tools::Long nFirstWidth = 0;
2796  tools::Long nSecondWidth = 0;
2797  bool bFirstCanResize = true;
2798  bool bSecondCanResize = true;
2799  const bool bInitialAllocation = get_position() < 0;
2800  int nElement = 0;
2801  for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2802  pChild = pChild->GetWindow(GetWindowType::Next))
2803  {
2804  if (!pChild->IsVisible())
2805  continue;
2806  if (nElement == 1)
2807  {
2808  if (bInitialAllocation)
2809  nFirstWidth = getLayoutRequisition(*pChild).Width();
2810  else
2811  nFirstWidth = pChild->GetSizePixel().Width() + pChild->get_margin_start() + pChild->get_margin_end();
2812  bFirstCanResize = pChild->get_expand();
2813  }
2814  else if (nElement == 2)
2815  {
2816  if (bInitialAllocation)
2817  nSecondWidth = getLayoutRequisition(*pChild).Width();
2818  else
2819  nSecondWidth = pChild->GetSizePixel().Width() + pChild->get_margin_start() + pChild->get_margin_end();
2820  bSecondCanResize = pChild->get_expand();
2821  }
2822  ++nElement;
2823  }
2824  tools::Long nWidthRequest = nFirstWidth + nSecondWidth;
2825  tools::Long nWidthDiff = nWidth - nWidthRequest;
2826  if (bFirstCanResize == bSecondCanResize)
2827  nFirstWidth += nWidthDiff/2;
2828  else if (bFirstCanResize)
2829  nFirstWidth += nWidthDiff;
2830  arrange(rAllocation, nFirstWidth, rAllocation.Width() - nFirstWidth - aSplitterSize.Width());
2831 }
2832 
2834 {
2835  Size aRet(0, 0);
2836 
2837  for (const vcl::Window* pChild = GetWindow(GetWindowType::FirstChild); pChild;
2838  pChild = pChild->GetWindow(GetWindowType::Next))
2839  {
2840  if (!pChild->IsVisible())
2841  continue;
2842  Size aChildSize = getLayoutRequisition(*pChild);
2843  aRet.setHeight( std::max(aRet.Height(), aChildSize.Height()) );
2844  aRet.AdjustWidth(aChildSize.Width() );
2845  }
2846 
2847  return aRet;
2848 }
2849 
2851 {
2852  tools::Rectangle aBounds;
2853 
2854  for (const vcl::Window* pChild = rWindow.GetWindow(GetWindowType::FirstChild); pChild;
2855  pChild = pChild->GetWindow(GetWindowType::Next))
2856  {
2857  if (!pChild->IsVisible())
2858  continue;
2859 
2860  tools::Rectangle aChildBounds(pChild->GetPosPixel(), pChild->GetSizePixel());
2861  aBounds.Union(aChildBounds);
2862  }
2863 
2864  if (aBounds.IsEmpty())
2865  return rWindow.GetSizePixel();
2866 
2867  Size aRet(aBounds.GetSize());
2868  Point aTopLeft(aBounds.TopLeft());
2869  aRet.AdjustWidth(aTopLeft.X()*2 );
2870  aRet.AdjustHeight(aTopLeft.Y()*2 );
2871 
2872  return aRet;
2873 }
2874 
2876 {
2877  while (pWindow)
2878  {
2879  pWindow = pWindow->GetParent();
2880  if (!pWindow || !isContainerWindow(*pWindow))
2881  break;
2882  }
2883  return pWindow;
2884 }
2885 
2886 bool isVisibleInLayout(const vcl::Window *pWindow)
2887 {
2888  bool bVisible = true;
2889  while (bVisible)
2890  {
2891  bVisible = pWindow->IsVisible();
2892  pWindow = pWindow->GetParent();
2893  if (!pWindow || !isContainerWindow(*pWindow))
2894  break;
2895  }
2896  return bVisible;
2897 }
2898 
2899 bool isEnabledInLayout(const vcl::Window *pWindow)
2900 {
2901  bool bEnabled = true;
2902  while (bEnabled)
2903  {
2904  bEnabled = pWindow->IsEnabled();
2905  pWindow = pWindow->GetParent();
2906  if (!pWindow || !isContainerWindow(*pWindow))
2907  break;
2908  }
2909  return bEnabled;
2910 }
2911 
2912 bool isLayoutEnabled(const vcl::Window *pWindow)
2913 {
2914  //Child is a container => we're layout enabled
2915  const vcl::Window *pChild = pWindow ? pWindow->GetWindow(GetWindowType::FirstChild) : nullptr;
2916  return pChild && isContainerWindow(*pChild) && !pChild->GetWindow(GetWindowType::Next);
2917 }
2918 
2920 {
2921  if (!(rHelpEvent.GetMode() & (HelpEventMode::QUICK | HelpEventMode::BALLOON)))
2922  return;
2923 
2924  Point aPos(ScreenToOutputPixel(rHelpEvent.GetMousePosPixel()));
2925  tools::Rectangle aHelpArea(aPos.X(), aPos.Y());
2926  OUString sHelpTip = m_aQueryTooltipHdl.Call(aHelpArea);
2927  if (sHelpTip.isEmpty())
2928  return;
2929  Point aPt = OutputToScreenPixel(aHelpArea.TopLeft());
2930  aHelpArea.SetLeft(aPt.X());
2931  aHelpArea.SetTop(aPt.Y());
2932  aPt = OutputToScreenPixel(aHelpArea.BottomRight());
2933  aHelpArea.SetRight(aPt.X());
2934  aHelpArea.SetBottom(aPt.Y());
2935  // tdf#125369 recover newline support of tdf#101779
2936  QuickHelpFlags eHelpWinStyle = sHelpTip.indexOf('\n') != -1 ? QuickHelpFlags::TipStyleBalloon : QuickHelpFlags::NONE;
2937  Help::ShowQuickHelp(this, aHelpArea, sHelpTip, eHelpWinStyle);
2938 }
2939 
2941 {
2942  if (m_aStartDragHdl.Call(this))
2943  return;
2944 
2946  if (!m_xTransferHelper.is())
2947  return;
2948 
2949  xContainer->StartDrag(this, m_nDragAction);
2950 }
2951 
2953 {
2954  if (!m_aGetSurroundingHdl.IsSet())
2955  return Control::GetSurroundingText();
2956  OUString sSurroundingText;
2957  m_aGetSurroundingHdl.Call(sSurroundingText);
2958  return sSurroundingText;
2959 }
2960 
2962 {
2963  if (!m_aGetSurroundingHdl.IsSet())
2965  OUString sSurroundingText;
2966  int nCursor = m_aGetSurroundingHdl.Call(sSurroundingText);
2967  return Selection(nCursor, nCursor);
2968 }
2969 
2971 {
2973  return Control::DeleteSurroundingText(rSelection);
2974  return m_aDeleteSurroundingHdl.Call(rSelection);
2975 }
2976 
2978 {
2979 }
2980 
2982 {
2983 }
2984 
2986 {
2987  disposeOnce();
2988 }
2989 
2991 {
2992  disposeOnce();
2993 }
2994 
2996 {
2997  Control::DumpAsPropertyTree(rJsonWriter);
2998  rJsonWriter.put("type", "drawingarea");
2999 
3001  pDevice->SetOutputSize( GetSizePixel() );
3002  tools::Rectangle aRect(Point(0,0), GetSizePixel());
3003  Paint(*pDevice, aRect);
3004  BitmapEx aImage = pDevice->GetBitmapEx( Point(0,0), GetSizePixel() );
3005  SvMemoryStream aOStm(65535, 65535);
3007  {
3008  css::uno::Sequence<sal_Int8> aSeq( static_cast<sal_Int8 const *>(aOStm.GetData()), aOStm.Tell());
3009  OUStringBuffer aBuffer("data:image/png;base64,");
3011  rJsonWriter.put("image", aBuffer.makeStringAndClear());
3012  }
3013  rJsonWriter.put("text", GetQuickHelpText());
3014 }
3015 
3017 {
3018  if (m_pFactoryFunction)
3019  return m_pFactoryFunction;
3021 }
3022 
3023 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual void set_position(tools::Long nPosition)
Definition: layout.hxx:392
virtual Point GetPosPixel() const
Definition: window.cxx:2796
static OUString GetDisplayName()
Get the default name of the application for message dialogs and printing.
Definition: svapp.cxx:1316
virtual void SetText(const OUString &rStr)
Definition: window.cxx:3031
tools::Long GetTextHeight() const
Height where any character of the current font fits; in logic coordinates.
Definition: window3.cxx:65
virtual Selection GetSurroundingTextSelection() const override
Definition: layout.cxx:2961
Size GetSizePixel() const
Definition: Image.cxx:86
const Color & GetShadowColor() const
virtual sal_uInt16 getDefaultAccessibleRole() const override
Definition: layout.cxx:54
Image const & GetStandardInfoBoxImage()
Definition: stdtext.cxx:49
virtual ~VclExpander() override
Definition: layout.cxx:1637
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:2507
tools::Long m_nPosition
Definition: layout.hxx:385
bool m_bColumnHomogeneous
Definition: layout.hxx:317
virtual void setAllocation(const Size &rAllocation)=0
void SetBackground()
Definition: window3.cxx:100
int get_column_spacing() const
Definition: layout.hxx:361
void SetDragRectPixel(const tools::Rectangle &rDragRect, vcl::Window *pRefWin=nullptr)
Definition: split.cxx:442
Point GetPointerPosPixel()
Definition: mouse.cxx:564
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:1376
sal_Int32 get_padding() const
Definition: window2.cxx:1787
void setDeferredProperties()
Definition: dialog.cxx:1589
static VclGrid::Value accumulateValues(const VclGrid::Value &i, const VclGrid::Value &j)
Definition: layout.cxx:1174
virtual void SetPosPixel(const Point &rAllocPos) override
Definition: layout.cxx:167
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:2055
static void setLayoutAllocation(vcl::Window &rWindow, const Point &rPos, const Size &rSize)
Definition: layout.cxx:76
Image const & GetStandardWarningBoxImage()
Definition: stdtext.cxx:60
virtual void RequestHelp(const HelpEvent &rHelpEvent) override
Definition: layout.cxx:2919
void sort_native_button_order(const VclBox &rContainer)
Definition: layout.cxx:846
DrawFrameFlags m_eDrawFrameFlags
Definition: layout.hxx:511
void SetFontSize(const Size &)
Definition: font/font.cxx:148
bool get_vexpand() const
Definition: window2.cxx:1751
void arrange(const Size &rAllocation, tools::Long nFirstHeight, tools::Long nSecondHeight)
Definition: layout.cxx:2745
bool bVisible
bool isVisibleInLayout(const vcl::Window *pWindow)
Definition: layout.cxx:2886
void InitScrollBars(const Size &rRequest)
Definition: layout.cxx:1913
WinBits const WB_NOLABEL
VclPtr< ScrollBar > m_pHScroll
Definition: layout.hxx:513
virtual void setSecondaryDimension(Size &rSize, tools::Long) const =0
void DrawImage(const Point &rPos, const Image &rImage, DrawImageFlags nStyle=DrawImageFlags::NONE)
This is an overloaded member function, provided for convenience. It differs from the above function o...
void set_border_width(sal_Int32 nBorderWidth)
Definition: window2.cxx:1859
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: layout.cxx:2606
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:1762
OUString const & get_secondary_text() const
Definition: layout.cxx:2500
static void SetMessagesWidths(vcl::Window const *pParent, VclMultiLineEdit *pPrimaryMessage, VclMultiLineEdit *pSecondaryMessage)
Definition: layout.cxx:2476
sal_Int32 get_margin_bottom() const
Definition: window2.cxx:1929
void setWidth(tools::Long nWidth)
void designate_label(vcl::Window *pWindow)
Definition: layout.cxx:1483
VclButtonsType
Definition: vclenum.hxx:243
static array_type assembleGrid(const VclGrid &rGrid)
Definition: layout.cxx:888
VclBox * get_content_area()
Definition: dialog.hxx:119
int CalcBorderWidth() const
Definition: layout.cxx:1844
void create_message_area()
Definition: layout.cxx:2262
virtual Size GetOptimalSize() const override
Definition: layout.cxx:59
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:1453
const CommandEvent * GetCommandEvent() const
Definition: event.hxx:332
VclPtr< vcl::Window > m_pLabel
Definition: layout.hxx:426
void set_grid_left_attach(sal_Int32 nAttach)
Definition: window2.cxx:1829
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:624
OUString GetStandardText(StandardButtonType eButton)
Definition: stdtext.cxx:93
void SetStyleSettings(const StyleSettings &rSet)
signed char sal_Int8
SAL_DLLPRIVATE float approximate_char_width() const
Definition: window3.cxx:61
void SetMonoColor(const Color &rColor)
bool m_bVerticalContainer
Definition: layout.hxx:74
std::unique_ptr< sal_Int32[]> pData
virtual ~VclPaned() override
Definition: layout.cxx:2985
void Create(SwFormatVertOrient &rItem, SvStream &rStrm, sal_uInt16 nVersionAbusedAsSize)
OUString GetStandardErrorBoxText()
Definition: stdtext.cxx:77
VclPtr< DisclosureButton > m_pDisclosureButton
Definition: layout.hxx:478
virtual void StateChanged(StateChangedType nType) override
Definition: layout.cxx:2580
bool get_hexpand() const
Definition: window2.cxx:1739
static Size getLayoutRequisition(const vcl::Window &rWindow)
Definition: layout.cxx:151
long Long
OUString const & get_primary_text() const
Definition: layout.cxx:2493
VclPtr< VclMultiLineEdit > m_pSecondaryMessage
void disposeAndClear()
Definition: vclptr.hxx:200
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
Gets the application's settings.
Definition: svapp.cxx:760
SAL_DLLPRIVATE void disposeOwnedButtons()
Definition: dialog.cxx:380
VclPtr< VclVBox > m_pMessageBox
void DrawFrame(const tools::Rectangle &rRect, const Color &rLeftTopColor, const Color &rRightBottomColor)
Definition: decoview.cxx:804
SAL_DLLPRIVATE const tools::Rectangle & GetStateRect() const
Definition: button.hxx:319
const OUString & GetQuickHelpText() const
Definition: window2.cxx:1255
VclButtonsType m_eButtonsType
std::function< std::unique_ptr< UIObject >vcl::Window *)> FactoryFunction
virtual Size GetSizePixel() const
Definition: window.cxx:2404
virtual void DumpAsPropertyTree(tools::JsonWriter &) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: layout.cxx:2995
void EnableCursor(bool bEnable)
Definition: vclmedit.cxx:1445
void SetWeight(FontWeight)
Definition: font/font.cxx:249
bool m_bRowHomogeneous
Definition: layout.hxx:316
WinBits const WB_AUTOVSCROLL
void set_row_spacing(int nSpacing)
Definition: layout.hxx:349
virtual Size calculateRequisition() const override
Definition: layout.cxx:1433
tools::Long CalcTitleWidth() const
Definition: window.cxx:2050
sal_uInt16 GetCode() const
Definition: keycod.hxx:49
VclPtr< VclBox > m_pOwnedContentArea
void set_spacing(int nSpacing)
Definition: layout.hxx:84
virtual vcl::Window * get_child() override
Definition: layout.cxx:1522
WinBits const WB_VSCROLL
Info
const CommandWheelData * GetWheelData() const
bool m_bExpand
Definition: layout.hxx:325
VclButtonBoxStyle
Definition: layout.hxx:198
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: window.cxx:140
void SetRangeMax(tools::Long nNewRange)
Definition: scrbar.cxx:1332
void SetType(WindowType nType)
Definition: window2.cxx:991
constexpr sal_uInt16 KEY_ADD
Definition: keycodes.hxx:127
virtual void dispose() override
Definition: layout.cxx:1856
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:1709
float x
constexpr int nBorderWidth
TRISTATE_TRUE
tools::Long m_nBorderWidth
Definition: layout.hxx:509
HelpEventMode GetMode() const
Definition: event.hxx:208
VclContainer(vcl::Window *pParent, WinBits nStyle=WB_HIDE|WB_CLIPCHILDREN)
Definition: layout.cxx:44
bool get_fill() const
Definition: window2.cxx:1799
virtual tools::Long getSecondaryDimension(const Size &rSize) const =0
static const OUString & GetDesktopEnvironment()
Get the desktop environment the process is currently running in.
Definition: svapp.cxx:1712
void create_owned_areas()
Definition: layout.cxx:2390
NONE
virtual bool getPrimaryDimensionChildExpand(const vcl::Window &rWindow) const =0
sal_Int32 get_margin_start() const
Definition: window2.cxx:1881
std::vector< tools::Long > m_aMainGroupDimensions
Definition: layout.hxx:226
virtual void set_position(tools::Long nPosition) override
Definition: layout.cxx:2776
static std::vector< tools::Long > setButtonSizes(const std::vector< tools::Long > &rG, const std::vector< bool > &rNonHomogeneous, tools::Long nAvgDimension, tools::Long nMaxNonOutlier, tools::Long nMinWidth)
Definition: layout.cxx:451
OUString GetStandardQueryBoxText()
Definition: stdtext.cxx:88
WEIGHT_BOLD
StateChangedType
Definition: window.hxx:289
const sal_uInt8 A
constexpr tools::Long Width() const
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: button.cxx:3290
rtl::Reference< TransferDataContainer > m_xTransferHelper
Definition: layout.hxx:625
OUString GetAccessibleName() const
sal_Int64 WinBits
virtual void dispose() override
Definition: layout.cxx:2201
Link< OUString &, int > m_aGetSurroundingHdl
Definition: layout.hxx:637
void SetControlFont()
Definition: window2.cxx:432
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: dialog.cxx:620
std::set< VclPtr< vcl::Window > > m_aWindows
Definition: layout.hxx:579
const OUString & get_id() const
Get the ID of the window.
Definition: window.cxx:3934
virtual void dispose() override
Definition: layout.cxx:1425
void SetPageSize(tools::Long nNewSize)
Definition: scrbar.hxx:125
bool m_bLayoutDirty
Definition: layout.hxx:67
void set_ignore_hidden(bool bIgnoreHidden)
Definition: layout.cxx:2216
const vcl::Font & GetLabelFont() const
virtual void DumpAsPropertyTree(tools::JsonWriter &)
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: window.cxx:3363
virtual Size calculateRequisition() const =0
WinBits const WB_DEFBUTTON
OUString get_label() const
Definition: layout.cxx:1657
enumrange< T >::Iterator begin(enumrange< T >)
Size addSpacing(const Size &rSize, sal_uInt16 nVisibleChildren) const
Definition: layout.cxx:575
uno::Type m_aType
WinBits const WB_VERT
VclMessageType m_eMessageType
DrawImageFlags
WinBits const WB_HSCROLL
bool IsMouseEvent() const
boost::multi_array< GridEntry, 2 > array_type
Definition: layout.cxx:882
virtual OUString GetSurroundingText() const override
Definition: layout.cxx:2952
void reorderWithinParent(vcl::Window &rWindow, sal_uInt16 nNewPosition)
Definition: builder.cxx:2269
void Hide()
Definition: window.hxx:884
virtual FactoryFunction GetUITestFactory() const override
Definition: layout.cxx:3016
VclSizeGroupMode
Definition: vclenum.hxx:262
VclPtr< vcl::Window > mpLastChild
Definition: window.h:238
void set_default_response(int nResponse)
Definition: dialog.cxx:1541
constexpr tools::Long GetWidth() const
virtual ~VclHPaned() override
Definition: layout.cxx:2977
Mode eMode
sal_Int8 m_nDragAction
Definition: layout.hxx:626
static bool compareValues(const VclGrid::Value &i, const VclGrid::Value &j)
Definition: layout.cxx:1169
void set_width_request(sal_Int32 nWidthRequest)
Definition: window2.cxx:1648
sal_uInt16 GetModifier() const
Definition: keycod.hxx:52
virtual OUString GetText() const
Definition: window.cxx:3060
void set_mode(VclSizeGroupMode eMode)
Definition: layout.cxx:2225
VclMessageType
Definition: vclenum.hxx:253
virtual void Command(const CommandEvent &rCEvt) override
Definition: layout.cxx:2191
force balloon-style in ShowPopover and ShowQuickHelp
static tools::Long getMaxNonOutlier(const std::vector< tools::Long > &rG, tools::Long nAvgDimension)
Definition: layout.cxx:437
static void encode(OUStringBuffer &aStrBuffer, const css::uno::Sequence< sal_Int8 > &aPass)
void * GetEventData() const
virtual void setPrimaryDimension(Size &rSize, tools::Long) const =0
bool get_secondary() const
Definition: window2.cxx:1947
WinBits const WB_HIDE
TriState GetState() const
Definition: button.hxx:343
virtual Selection GetSurroundingTextSelection() const
Definition: window.cxx:3781
Link< VclDrawingArea *, bool > m_aStartDragHdl
Definition: layout.hxx:639
bool m_bResizeTopLevel
Definition: layout.hxx:477
bool isContainerWindow(const vcl::Window &rWindow)
Definition: layout.hxx:816
constexpr bool IsEmpty() const
float y
const Point & GetMousePosPixel() const
Definition: event.hxx:207
bool mbInDispose
Definition: window.h:317
ImplSVData * ImplGetSVData()
Definition: svdata.cxx:76
Size getLegacyBestSizeForChildren(const vcl::Window &rWindow)
Definition: layout.cxx:2850
const OString & GetHelpId() const
Definition: window2.cxx:846
Size finalizeMaxes(const Size &rSize, sal_uInt16 nVisibleChildren) const
Definition: layout.cxx:405
virtual Size calculateRequisition() const override
Definition: layout.cxx:2714
void clear()
Definition: vclptr.hxx:190
virtual bool DeleteSurroundingText(const Selection &rSelection)
Definition: window.cxx:3810
virtual bool DeleteSurroundingText(const Selection &rSelection) override
Definition: layout.cxx:2970
bool isEnabledInLayout(const vcl::Window *pWindow)
Definition: layout.cxx:2899
virtual void DumpAsPropertyTree(tools::JsonWriter &) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: layout.cxx:713
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: dialog.cxx:1399
virtual ~VclFrame() override
Definition: layout.cxx:1420
VclPackType
Definition: vclenum.hxx:221
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:254
void set_property(const OString &rKey, const OUString &rValue)
Definition: layout.cxx:2235
int i
virtual OUString GetSurroundingText() const
Definition: window.cxx:3776
VclPtr< ScrollBarBox > m_aScrollBarBox
Definition: layout.hxx:514
VclPtr< VclButtonBox > m_pOwnedActionArea
DrawFrameStyle m_eDrawFrameStyle
Definition: layout.hxx:510
VclPtr< ScrollBar > m_pVScroll
Definition: layout.hxx:512
virtual bool EventNotify(NotifyEvent &rNEvt) override
Definition: layout.cxx:2096
bool get_expanded() const
Definition: layout.cxx:1642
void setOptimalLayoutSize(bool bAllowWindowShrink)
Definition: syswin.cxx:1073
virtual void DumpAsPropertyTree(tools::JsonWriter &rJsonWriter) override
Definition: layout.cxx:1795
int get_default_response() const
Definition: dialog.cxx:1501
virtual void DumpAsPropertyTree(tools::JsonWriter &) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: layout.cxx:1365
bool m_bIgnoreHidden
Definition: layout.hxx:580
virtual ~VclScrolledWindow() override
Definition: layout.cxx:2990
std::unique_ptr< Image > mpDisclosureMinus
Definition: svdata.hxx:281
virtual void SetText(const OUString &rStr) override
Definition: ctrl.cxx:95
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2669
void SetVisibleSize(tools::Long nNewSize)
Definition: scrbar.cxx:1375
void SetSplitHdl(const Link< Splitter *, void > &rLink)
Definition: split.hxx:99
OUString get_label() const
Definition: layout.cxx:1534
CommandWheelMode GetMode() const
WinBits const WB_VCENTER
virtual void SetSizePixel(const Size &rAllocation) override
Definition: layout.cxx:178
static int getButtonPriority(std::u16string_view rType)
Definition: layout.cxx:756
sal_Int32 get_margin_top() const
Definition: window2.cxx:1913
QuickHelpFlags
Definition: help.hxx:32
#define DEFAULT_CHILD_MIN_WIDTH
Definition: layout.cxx:402
virtual sal_uInt16 getDefaultAccessibleRole() const override
Definition: layout.cxx:391
void arrange(const Size &rAllocation, tools::Long nFirstHeight, tools::Long nSecondHeight)
Definition: layout.cxx:2626
Size calculateRequisitionForSpacings(sal_Int32 nRowSpacing, sal_Int32 nColSpacing) const
Definition: layout.cxx:1187
Requisition calculatePrimarySecondaryRequisitions() const
Definition: layout.cxx:476
Image const & GetStandardErrorBoxImage()
Definition: stdtext.cxx:71
Some things multiple-inherit from VclAbstractDialog and OutputDevice, so we need to use virtual inher...
Definition: outdev.hxx:175
const AllSettings & GetSettings() const
Definition: window3.cxx:129
CommandEventId GetCommand() const
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:1227
sal_uInt16 GetModifier() const
virtual void Command(const CommandEvent &rCEvt) override
Definition: layout.cxx:201
bool IsChecked() const
Definition: button.hxx:350
float u
void add_button(PushButton *pButton, int nResponse, bool bTransferOwnership)
Definition: dialog.cxx:1431
std::unique_ptr< WindowImpl > mpWindowImpl
Definition: window.hxx:483
const Size & GetFontSize() const
Definition: font/font.cxx:881
Size get_preferred_size() const
Definition: window2.cxx:1684
VclSizeGroupMode m_eMode
Definition: layout.hxx:581
bool isLayoutEnabled(const vcl::Window *pWindow)
Definition: layout.cxx:2912
MouseNotifyEvent GetType() const
Definition: event.hxx:308
VclPtr< FixedImage > m_pImage
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:598
virtual void setPrimaryCoordinate(Point &rPos, tools::Long) const =0
bool DrawNativeControl(ControlType nType, ControlPart nPart, const tools::Rectangle &rControlRegion, ControlState nState, const ImplControlValue &aValue, const OUString &aCaption, const Color &rBackgroundColor=COL_AUTO)
Request rendering of a particular control and/or part.
void SetToggleHdl(const Link< CheckBox &, void > &rLink)
Definition: button.hxx:363
void set_homogeneous(bool bHomogeneous)
Definition: layout.hxx:92
virtual void dispose() override
Definition: layout.cxx:1662
virtual Size calculateRequisition() const override
Definition: layout.cxx:590
void SetPaintTransparent(bool bTransparent)
Definition: paint.cxx:1025
void SetImage(const Image &rImage)
Definition: fixed.cxx:946
VclPtr< Splitter > m_pSplitter
Definition: layout.hxx:384
bool get_row_homogeneous() const
Definition: layout.hxx:341
virtual bool set_property(const OString &rKey, const OUString &rValue)
Definition: window2.cxx:1468
static void setLayoutPosSize(vcl::Window &rWindow, const Point &rPos, const Size &rSize)
Definition: layout.cxx:64
void reorderWithinParent(sal_uInt16 nNewPosition)
Definition: stacking.cxx:162
virtual void KeyInput(const KeyEvent &rKEvt) override
Definition: layout.cxx:1612
FactoryFunction m_pFactoryFunction
Definition: layout.hxx:623
void Check(bool bCheck=true)
Definition: button.hxx:345
VclPackType get_pack_type() const
Definition: window2.cxx:1775
bool get_orientation() const
Definition: layout.hxx:96
Point ScreenToOutputPixel(const Point &rPos) const
Definition: window.cxx:2814
static void ShowQuickHelp(vcl::Window *pParent, const tools::Rectangle &rScreenRect, const OUString &rHelpText, QuickHelpFlags nStyle=QuickHelpFlags::NONE)
Definition: help.cxx:180
vcl::Window * GetParent() const
Definition: window2.cxx:1120
sal_Int32 get_margin_end() const
Definition: window2.cxx:1897
virtual void ImplDrawCheckBoxState(vcl::RenderContext &rRenderContext) override
Definition: layout.cxx:1557
WinBits const WB_LEFT
void SetStyle(WinBits nStyle)
Definition: window.cxx:1964
enumrange< T >::Iterator end(enumrange< T >)
void put(const char *pPropName, const OUString &rPropValue)
void Scroll()
Definition: scrbar.cxx:1292
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize)
Definition: window2.cxx:1291
constexpr Point TopLeft() const
bool get_expand() const
Definition: window2.cxx:1763
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: layout.hxx:641
virtual tools::Long getPrimaryCoordinate(const Point &rPos) const =0
vcl::Window * GetWindow(GetWindowType nType) const
Definition: stacking.cxx:1035
DrawFrameStyle
Definition: vclenum.hxx:335
Size getVisibleChildSize() const
Definition: layout.cxx:2043
const Point & GetMousePosPixel() const
DisclosureButton(vcl::Window *pParent)
Definition: layout.cxx:1607
virtual Size calculateRequisition() const override
Definition: layout.cxx:2833
void set_grid_top_attach(sal_Int32 nAttach)
Definition: window2.cxx:1853
bool m_bInitialAllocation
Definition: layout.hxx:527
SAL_DLLPRIVATE void ImplInit(vcl::Window *pParent, WinBits nStyle, SystemParentData *pSystemParentData)
Definition: window.cxx:940
#define DEFAULT_CHILD_MIN_HEIGHT
Definition: layout.cxx:403
WinBits const WB_3DLOOK
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2163
VclScrolledWindow(vcl::Window *pParent)
Definition: layout.cxx:1820
DrawButtonFlags GetButtonState() const
Definition: button.cxx:519
VclButtonBox * get_action_area()
Definition: dialog.hxx:118
void set_id(const OUString &rID)
Sets an ID.
Definition: window.cxx:3929
static ErrCode Export(SvStream &rOStm, const Graphic &rGraphic, ConvertDataFormat nFormat)
Definition: cvtgrf.cxx:51
VclPtr< VclGrid > m_pGrid
void AddEventListener(const Link< VclWindowEvent &, void > &rEventListener)
Definition: event.cxx:303
void set_valign(VclAlign eAlign)
Definition: window2.cxx:1733
const vcl::KeyCode & GetKeyCode() const
Definition: event.hxx:57
virtual FactoryFunction GetUITestFactory() const override
Definition: layout.cxx:1801
constexpr Size GetSize() const
virtual void StateChanged(StateChangedType nStateChange) override
Definition: dialog.cxx:754
virtual ~VclVPaned() override
Definition: layout.cxx:2981
std::unique_ptr< char[]> aBuffer
OUString GetStandardInfoBoxText()
Definition: stdtext.cxx:55
void SetMaxTextWidth(tools::Long nMaxWidth)
Definition: vclmedit.cxx:1058
virtual ~MessageDialog() override
Definition: layout.cxx:2471
bool IsMouseOver() const
Definition: mouse.cxx:620
virtual vcl::Window * get_child() override
Definition: layout.cxx:1888
virtual vcl::Window * get_child() override
Definition: layout.cxx:2158
constexpr sal_uInt16 KEY_SUBTRACT
Definition: keycodes.hxx:128
VclVPaned(vcl::Window *pParent)
Definition: layout.cxx:2612
sal_Int32 m_nPosition
void set_hexpand(bool bExpand)
Definition: window2.cxx:1745
WindowType
virtual Size calculateRequisition() const override
Definition: layout.cxx:1893
tools::Rectangle & Union(const tools::Rectangle &rRect)
bool get_column_homogeneous() const
Definition: layout.hxx:345
#define SAL_WARN_IF(condition, area, stream)
#define ERRCODE_NONE
Definition: errcode.hxx:196
constexpr tools::Long Height() const
void set_expanded(bool bExpanded)
Definition: layout.cxx:1647
void set_label(const OUString &rLabel)
Definition: layout.cxx:1652
virtual tools::Long getPrimaryDimension(const Size &rSize) const =0
int m_nSpacing
Definition: layout.hxx:75
VclExpander(vcl::Window *pParent)
Definition: layout.cxx:1628
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2131
bool toBool(std::u16string_view rValue)
Definition: layout.cxx:1371
virtual void DumpAsPropertyTree(tools::JsonWriter &) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
Definition: layout.cxx:385
Size addReqGroups(const VclButtonBox::Requisition &rReq) const
Definition: layout.cxx:421
vcl::Window * get_label_widget()
Definition: layout.cxx:1505
bool IsVisible() const
Definition: window2.cxx:1125
virtual vcl::Window * get_child() override
Definition: layout.cxx:1677
#define SAL_INFO(area, stream)
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2038
virtual void StartDrag(sal_Int8 nAction, const Point &rPosPixel) override
Definition: layout.cxx:2940
VclPtr< EventBoxHelper > m_aEventBoxHelper
Definition: layout.hxx:558
void set_column_spacing(int nSpacing)
Definition: layout.hxx:353
virtual Size calculateRequisition() const override
Definition: layout.cxx:2174
void EnableChildTransparentMode(bool bEnable=true)
Definition: window2.cxx:1045
virtual OUString getDefaultAccessibleName() const override
Definition: layout.cxx:1541
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
Definition: layout.cxx:2458
VclPtr< VclMultiLineEdit > m_pPrimaryMessage
virtual void SetText(const OUString &rStr) override
Definition: syswin.cxx:1057
tools::Long AdjustWidth(tools::Long n)
void SetScrollHdl(const Link< ScrollBar *, void > &rLink)
Definition: scrbar.hxx:133
Definition: image.hxx:39
static VclPtr< reference_type > Create(Arg &&...arg)
A construction helper for VclPtr.
Definition: vclptr.hxx:127
virtual Size calculateRequisition() const override
Definition: layout.cxx:1682
void set_content_area(VclBox *pBox)
Definition: dialog.cxx:602
sal_uInt64 Tell() const
void set_action_area(VclButtonBox *pBox)
Definition: dialog.cxx:591
Sequence< sal_Int8 > aSeq
virtual Size calculateRequisition() const override
Definition: layout.cxx:1182
VclAlign get_valign() const
Definition: window2.cxx:1727
static std::unique_ptr< UIObject > create(vcl::Window *pWindow)
MessageDialog(vcl::Window *pParent, WinBits nStyle)
Definition: layout.cxx:2405
Link< tools::Rectangle &, OUString > m_aQueryTooltipHdl
Definition: layout.hxx:636
WinBits const WB_AUTOHSCROLL
void set(reference_type *pBody)
Definition: vclptr.hxx:148
VclPtr< vcl::Window > mpFirstChild
Definition: window.h:237
tools::Long AdjustHeight(tools::Long n)
virtual ~VclEventBox() override
Definition: layout.cxx:2196
SAL_DLLPRIVATE const tools::Rectangle & GetMouseRect() const
Definition: button.hxx:320
Link< const Selection &, bool > m_aDeleteSurroundingHdl
Definition: layout.hxx:638
WinBits const WB_TABSTOP
Size GetOutputSizePixel() const
Definition: window3.cxx:89
IMPL_LINK(VclFrame, WindowEventListener, VclWindowEvent &, rEvent, void)
Definition: layout.cxx:1477
std::unique_ptr< Image > mpDisclosurePlus
Definition: svdata.hxx:280
vcl::Window * getNonLayoutParent(vcl::Window *pWindow)
Definition: layout.cxx:2875
virtual void SetPosSizePixel(const Point &rNewPos, const Size &rNewSize) override
Definition: layout.cxx:156
void setHeight(tools::Long nHeight)
virtual void set_position(tools::Long nPosition) override
Definition: layout.cxx:2657
void doSetAllocation(const Size &rAllocation, bool bRetryOnFailure)
Definition: layout.cxx:1933
VclAlign
Definition: vclenum.hxx:213
WinBits const WB_CENTER
std::vector< tools::Long > m_aSubGroupDimensions
Definition: layout.hxx:227
OUString GetStandardWarningBoxText()
Definition: stdtext.cxx:66
void set_secondary_text(const OUString &rSecondaryString)
Definition: layout.cxx:2569
reference_type * get() const
Get the body.
Definition: vclptr.hxx:143
bool IsEnabled() const
Definition: window2.cxx:1145
#define SAL_WARN(area, stream)
void RemoveEventListener(const Link< VclWindowEvent &, void > &rEventListener)
Definition: event.cxx:308
virtual Size calculateRequisition() const override
Definition: layout.cxx:232
virtual void setAllocation(const Size &rAllocation) override
Definition: layout.cxx:2788
WinBits GetStyle() const
Definition: window2.cxx:976
OUString m_sPrimaryString
void set_primary_text(const OUString &rPrimaryString)
Definition: layout.cxx:2558
Point OutputToScreenPixel(const Point &rPos) const
Definition: window.cxx:2808
WinBits const WB_CLOSEABLE
WinBits const WB_MOVEABLE
virtual void queue_resize(StateChangedType eReason=StateChangedType::Layout) override
Definition: layout.cxx:194
Image const & GetStandardQueryBoxImage()
Definition: stdtext.cxx:82
void accumulateMaxes(const Size &rChildSize, Size &rSize) const
Definition: layout.cxx:218
virtual void DumpAsPropertyTree(tools::JsonWriter &) override
Definition: layout.cxx:1549
virtual void StateChanged(StateChangedType nType) override
Definition: layout.cxx:1773
DrawFrameFlags
Definition: vclenum.hxx:347
static std::unique_ptr< UIObject > create(vcl::Window *pWindow)
int get_row_spacing() const
Definition: layout.hxx:357
WinBits const WB_HORZ
bool HasFocus() const
Definition: window.cxx:2986
bool m_bUserManagedScrolling
Definition: layout.hxx:508
bool m_bHomogeneous
Definition: layout.hxx:73
void set_label(const OUString &rLabel)
Definition: layout.cxx:1527
WinBits const WB_CLIPCHILDREN
sal_Int32 nState
WinBits const WB_NOTABSTOP
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: layout.cxx:2118
virtual void SetPosPixel(const Point &rNewPos)
Definition: window2.cxx:1280
IMPL_LINK_NOARG(VclScrolledWindow, ScrollBarHdl, ScrollBar *, void)
Definition: layout.cxx:1864
VclButtonBoxStyle m_eLayoutStyle
Definition: layout.hxx:223
virtual void SetText(const OUString &rStr) override
Definition: vclmedit.cxx:1103
sal_Int32 get_border_width() const
Definition: window2.cxx:1865
VclPaned(vcl::Window *pParent, bool bVertical)
Definition: layout.cxx:2597
SAL_DLLPRIVATE void DoInitialLayout()
Definition: syswin.cxx:1102
void trigger_queue_resize()
Definition: layout.cxx:2207
VclHPaned(vcl::Window *pParent)
Definition: layout.cxx:2731
const void * GetData()
tools::Long m_nValue
Definition: layout.hxx:324
tools::Long get_position() const
Definition: layout.hxx:391
static bool isNullGrid(const array_type &A)
Definition: layout.cxx:1043
bool m_bDetectedRangeSegmentation false
VclAlign get_halign() const
Definition: window2.cxx:1715
static void calcMaxs(const array_type &A, std::vector< VclGrid::Value > &rWidths, std::vector< VclGrid::Value > &rHeights)
Definition: layout.cxx:1051
OUString m_sSecondaryString
void Show(bool bVisible=true, ShowFlags nFlags=ShowFlags::NONE)
Definition: window.cxx:2189
virtual bool set_property(const OString &rKey, const OUString &rValue) override
Definition: layout.cxx:374
vcl::Window * get_label_widget()
Definition: layout.cxx:1790