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