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