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