Line data Source code
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 <vcl/dialog.hxx>
12 : #include <vcl/layout.hxx>
13 : #include <vcl/msgbox.hxx>
14 : #include <vcl/svapp.hxx>
15 : #include <vcl/settings.hxx>
16 : #include "window.h"
17 :
18 0 : VclContainer::VclContainer(Window *pParent, WinBits nStyle)
19 : : Window(WINDOW_CONTAINER)
20 0 : , m_bLayoutDirty(true)
21 : {
22 0 : ImplInit(pParent, nStyle, NULL);
23 0 : EnableChildTransparentMode();
24 0 : SetPaintTransparent(true);
25 0 : SetBackground();
26 0 : }
27 :
28 0 : sal_uInt16 VclContainer::getDefaultAccessibleRole() const
29 : {
30 0 : return com::sun::star::accessibility::AccessibleRole::PANEL;
31 : }
32 :
33 0 : Size VclContainer::GetOptimalSize() const
34 : {
35 0 : return calculateRequisition();
36 : }
37 :
38 0 : void VclContainer::setLayoutPosSize(Window &rWindow, const Point &rPos, const Size &rSize)
39 : {
40 0 : sal_Int32 nBorderWidth = rWindow.get_border_width();
41 0 : sal_Int32 nLeft = rWindow.get_margin_left() + nBorderWidth;
42 0 : sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
43 0 : sal_Int32 nRight = rWindow.get_margin_right() + nBorderWidth;
44 0 : sal_Int32 nBottom = rWindow.get_margin_bottom() + nBorderWidth;
45 0 : Point aPos(rPos.X() + nLeft, rPos.Y() + nTop);
46 0 : Size aSize(rSize.Width() - nLeft - nRight, rSize.Height() - nTop - nBottom);
47 0 : rWindow.SetPosSizePixel(aPos, aSize);
48 0 : }
49 :
50 0 : void VclContainer::setLayoutAllocation(Window &rChild, const Point &rAllocPos, const Size &rChildAlloc)
51 : {
52 0 : VclAlign eHalign = rChild.get_halign();
53 0 : VclAlign eValign = rChild.get_valign();
54 :
55 : //typical case
56 0 : if (eHalign == VCL_ALIGN_FILL && eValign == VCL_ALIGN_FILL)
57 : {
58 0 : setLayoutPosSize(rChild, rAllocPos, rChildAlloc);
59 0 : return;
60 : }
61 :
62 0 : Point aChildPos(rAllocPos);
63 0 : Size aChildSize(rChildAlloc);
64 0 : Size aChildPreferredSize(getLayoutRequisition(rChild));
65 :
66 0 : switch (eHalign)
67 : {
68 : case VCL_ALIGN_FILL:
69 0 : break;
70 : case VCL_ALIGN_START:
71 0 : if (aChildPreferredSize.Width() < rChildAlloc.Width())
72 0 : aChildSize.Width() = aChildPreferredSize.Width();
73 0 : break;
74 : case VCL_ALIGN_END:
75 0 : if (aChildPreferredSize.Width() < rChildAlloc.Width())
76 0 : aChildSize.Width() = aChildPreferredSize.Width();
77 0 : aChildPos.X() += rChildAlloc.Width();
78 0 : aChildPos.X() -= aChildSize.Width();
79 0 : break;
80 : case VCL_ALIGN_CENTER:
81 0 : if (aChildPreferredSize.Width() < aChildSize.Width())
82 0 : aChildSize.Width() = aChildPreferredSize.Width();
83 0 : aChildPos.X() += (rChildAlloc.Width() - aChildSize.Width()) / 2;
84 0 : break;
85 : }
86 :
87 0 : switch (eValign)
88 : {
89 : case VCL_ALIGN_FILL:
90 0 : break;
91 : case VCL_ALIGN_START:
92 0 : if (aChildPreferredSize.Height() < rChildAlloc.Height())
93 0 : aChildSize.Height() = aChildPreferredSize.Height();
94 0 : break;
95 : case VCL_ALIGN_END:
96 0 : if (aChildPreferredSize.Height() < rChildAlloc.Height())
97 0 : aChildSize.Height() = aChildPreferredSize.Height();
98 0 : aChildPos.Y() += rChildAlloc.Height();
99 0 : aChildPos.Y() -= aChildSize.Height();
100 0 : break;
101 : case VCL_ALIGN_CENTER:
102 0 : if (aChildPreferredSize.Height() < aChildSize.Height())
103 0 : aChildSize.Height() = aChildPreferredSize.Height();
104 0 : aChildPos.Y() += (rChildAlloc.Height() - aChildSize.Height()) / 2;
105 0 : break;
106 : }
107 :
108 0 : setLayoutPosSize(rChild, aChildPos, aChildSize);
109 : }
110 :
111 0 : Size VclContainer::getLayoutRequisition(const Window &rWindow)
112 : {
113 0 : sal_Int32 nBorderWidth = rWindow.get_border_width();
114 0 : sal_Int32 nLeft = rWindow.get_margin_left() + nBorderWidth;
115 0 : sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
116 0 : sal_Int32 nRight = rWindow.get_margin_right() + nBorderWidth;
117 0 : sal_Int32 nBottom = rWindow.get_margin_bottom() + nBorderWidth;
118 0 : Size aSize(rWindow.get_preferred_size());
119 0 : return Size(aSize.Width() + nLeft + nRight, aSize.Height() + nTop + nBottom);
120 : }
121 :
122 0 : void VclContainer::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocation)
123 : {
124 0 : bool bSizeChanged = rAllocation != GetOutputSizePixel();
125 0 : Window::SetPosSizePixel(rAllocPos, rAllocation);
126 0 : if (m_bLayoutDirty || bSizeChanged)
127 : {
128 0 : m_bLayoutDirty = false;
129 0 : setAllocation(rAllocation);
130 : }
131 0 : }
132 :
133 0 : void VclContainer::SetPosPixel(const Point& rAllocPos)
134 : {
135 0 : Point aAllocPos = rAllocPos;
136 0 : sal_Int32 nBorderWidth = get_border_width();
137 0 : aAllocPos.X() += nBorderWidth + get_margin_left();
138 0 : aAllocPos.Y() += nBorderWidth + get_margin_top();
139 :
140 0 : if (aAllocPos != GetPosPixel())
141 0 : Window::SetPosPixel(aAllocPos);
142 0 : }
143 :
144 0 : void VclContainer::SetSizePixel(const Size& rAllocation)
145 : {
146 0 : Size aAllocation = rAllocation;
147 0 : sal_Int32 nBorderWidth = get_border_width();
148 0 : aAllocation.Width() -= nBorderWidth*2 + get_margin_left() + get_margin_right();
149 0 : aAllocation.Height() -= nBorderWidth*2 + get_margin_top() + get_margin_bottom();
150 0 : bool bSizeChanged = aAllocation != GetSizePixel();
151 0 : if (bSizeChanged)
152 0 : Window::SetSizePixel(aAllocation);
153 0 : if (m_bLayoutDirty || bSizeChanged)
154 : {
155 0 : m_bLayoutDirty = false;
156 0 : setAllocation(aAllocation);
157 : }
158 0 : }
159 :
160 0 : void VclContainer::queue_resize()
161 : {
162 0 : markLayoutDirty();
163 0 : Window::queue_resize();
164 0 : }
165 :
166 0 : void VclBox::accumulateMaxes(const Size &rChildSize, Size &rSize) const
167 : {
168 0 : long nSecondaryChildDimension = getSecondaryDimension(rChildSize);
169 0 : long nSecondaryBoxDimension = getSecondaryDimension(rSize);
170 0 : setSecondaryDimension(rSize, std::max(nSecondaryChildDimension, nSecondaryBoxDimension));
171 :
172 0 : long nPrimaryChildDimension = getPrimaryDimension(rChildSize);
173 0 : long nPrimaryBoxDimension = getPrimaryDimension(rSize);
174 0 : if (m_bHomogeneous)
175 0 : setPrimaryDimension(rSize, std::max(nPrimaryBoxDimension, nPrimaryChildDimension));
176 : else
177 0 : setPrimaryDimension(rSize, nPrimaryBoxDimension + nPrimaryChildDimension);
178 0 : }
179 :
180 0 : Size VclBox::calculateRequisition() const
181 : {
182 0 : sal_uInt16 nVisibleChildren = 0;
183 :
184 0 : Size aSize;
185 0 : for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
186 : {
187 0 : if (!pChild->IsVisible())
188 0 : continue;
189 0 : ++nVisibleChildren;
190 0 : Size aChildSize = getLayoutRequisition(*pChild);
191 :
192 0 : long nPrimaryDimension = getPrimaryDimension(aChildSize);
193 0 : nPrimaryDimension += pChild->get_padding() * 2;
194 0 : setPrimaryDimension(aChildSize, nPrimaryDimension);
195 :
196 0 : accumulateMaxes(aChildSize, aSize);
197 : }
198 :
199 0 : return finalizeMaxes(aSize, nVisibleChildren);
200 : }
201 :
202 0 : void VclBox::setAllocation(const Size &rAllocation)
203 : {
204 0 : sal_uInt16 nVisibleChildren = 0, nExpandChildren = 0;
205 0 : for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
206 : {
207 0 : if (!pChild->IsVisible())
208 0 : continue;
209 0 : ++nVisibleChildren;
210 0 : bool bExpand = getPrimaryDimensionChildExpand(*pChild);
211 0 : if (bExpand)
212 0 : ++nExpandChildren;
213 : }
214 :
215 0 : if (!nVisibleChildren)
216 0 : return;
217 :
218 0 : long nAllocPrimaryDimension = getPrimaryDimension(rAllocation);
219 :
220 0 : long nHomogeneousDimension = 0, nExtraSpace = 0;
221 0 : if (m_bHomogeneous)
222 : {
223 0 : nHomogeneousDimension = ((nAllocPrimaryDimension -
224 0 : (nVisibleChildren - 1) * m_nSpacing)) / nVisibleChildren;
225 : }
226 0 : else if (nExpandChildren)
227 : {
228 0 : Size aRequisition = calculateRequisition();
229 0 : nExtraSpace = (getPrimaryDimension(rAllocation) - getPrimaryDimension(aRequisition)) / nExpandChildren;
230 : }
231 :
232 : //Split into those we pack from the start onwards, and those we pack from the end backwards
233 0 : std::vector<Window*> aWindows[2];
234 0 : for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
235 : {
236 0 : if (!pChild->IsVisible())
237 0 : continue;
238 :
239 0 : sal_Int32 ePacking = pChild->get_pack_type();
240 0 : aWindows[ePacking].push_back(pChild);
241 : }
242 :
243 : //See VclBuilder::sortIntoBestTabTraversalOrder for why they are in visual
244 : //order under the parent which requires us to reverse them here to
245 : //pack from the end back
246 0 : std::reverse(aWindows[VCL_PACK_END].begin(),aWindows[VCL_PACK_END].end());
247 :
248 0 : for (sal_Int32 ePackType = VCL_PACK_START; ePackType <= VCL_PACK_END; ++ePackType)
249 : {
250 0 : Point aPos(0, 0);
251 0 : if (ePackType == VCL_PACK_END)
252 : {
253 0 : long nPrimaryCoordinate = getPrimaryCoordinate(aPos);
254 0 : setPrimaryCoordinate(aPos, nPrimaryCoordinate + nAllocPrimaryDimension);
255 : }
256 :
257 0 : for (std::vector<Window*>::iterator aI = aWindows[ePackType].begin(), aEnd = aWindows[ePackType].end(); aI != aEnd; ++aI)
258 : {
259 0 : Window *pChild = *aI;
260 :
261 0 : long nPadding = pChild->get_padding();
262 :
263 0 : Size aBoxSize;
264 0 : if (m_bHomogeneous)
265 0 : setPrimaryDimension(aBoxSize, nHomogeneousDimension);
266 : else
267 : {
268 0 : aBoxSize = getLayoutRequisition(*pChild);
269 0 : long nPrimaryDimension = getPrimaryDimension(aBoxSize);
270 0 : nPrimaryDimension += nPadding * 2;
271 0 : if (getPrimaryDimensionChildExpand(*pChild))
272 0 : nPrimaryDimension += nExtraSpace;
273 0 : setPrimaryDimension(aBoxSize, nPrimaryDimension);
274 : }
275 0 : setSecondaryDimension(aBoxSize, getSecondaryDimension(rAllocation));
276 :
277 0 : Point aChildPos(aPos);
278 0 : Size aChildSize(aBoxSize);
279 0 : long nPrimaryCoordinate = getPrimaryCoordinate(aPos);
280 :
281 0 : bool bFill = pChild->get_fill();
282 0 : if (bFill)
283 : {
284 : setPrimaryDimension(aChildSize, std::max(static_cast<long>(1),
285 0 : getPrimaryDimension(aBoxSize) - nPadding * 2));
286 :
287 0 : setPrimaryCoordinate(aChildPos, nPrimaryCoordinate + nPadding);
288 : }
289 : else
290 : {
291 : setPrimaryDimension(aChildSize,
292 0 : getPrimaryDimension(getLayoutRequisition(*pChild)));
293 :
294 : setPrimaryCoordinate(aChildPos, nPrimaryCoordinate +
295 0 : (getPrimaryDimension(aBoxSize) - getPrimaryDimension(aChildSize)) / 2);
296 : }
297 :
298 0 : long nDiff = getPrimaryDimension(aBoxSize) + m_nSpacing;
299 0 : if (ePackType == VCL_PACK_START)
300 0 : setPrimaryCoordinate(aPos, nPrimaryCoordinate + nDiff);
301 : else
302 : {
303 0 : setPrimaryCoordinate(aPos, nPrimaryCoordinate - nDiff);
304 0 : setPrimaryCoordinate(aChildPos, getPrimaryCoordinate(aChildPos) -
305 0 : getPrimaryDimension(aBoxSize));
306 : }
307 :
308 0 : setLayoutAllocation(*pChild, aChildPos, aChildSize);
309 : }
310 0 : }
311 : }
312 :
313 0 : bool VclBox::set_property(const OString &rKey, const OString &rValue)
314 : {
315 0 : if (rKey == "spacing")
316 0 : set_spacing(rValue.toInt32());
317 0 : else if (rKey == "homogeneous")
318 0 : set_homogeneous(toBool(rValue));
319 : else
320 0 : return VclContainer::set_property(rKey, rValue);
321 0 : return true;
322 : }
323 :
324 0 : sal_uInt16 VclBox::getDefaultAccessibleRole() const
325 : {
326 : #if defined(WNT)
327 : //fdo#74284 call Boxes Panels, keep then as "Filler" under
328 : //at least Linux seeing as that's what Gtk does for GtkBoxes
329 : return com::sun::star::accessibility::AccessibleRole::PANEL;
330 : #else
331 0 : return com::sun::star::accessibility::AccessibleRole::FILLER;
332 : #endif
333 : }
334 :
335 : #define DEFAULT_CHILD_MIN_WIDTH 85
336 : #define DEFAULT_CHILD_MIN_HEIGHT 27
337 :
338 0 : Size VclBox::finalizeMaxes(const Size &rSize, sal_uInt16 nVisibleChildren) const
339 : {
340 0 : Size aRet;
341 :
342 0 : if (nVisibleChildren)
343 : {
344 0 : long nPrimaryDimension = getPrimaryDimension(rSize);
345 0 : if (m_bHomogeneous)
346 0 : nPrimaryDimension *= nVisibleChildren;
347 0 : setPrimaryDimension(aRet, nPrimaryDimension + m_nSpacing * (nVisibleChildren-1));
348 0 : setSecondaryDimension(aRet, getSecondaryDimension(rSize));
349 : }
350 :
351 0 : return aRet;
352 : }
353 :
354 0 : Size VclButtonBox::addReqGroups(const VclButtonBox::Requisition &rReq) const
355 : {
356 0 : Size aRet;
357 :
358 0 : long nMainGroupDimension = getPrimaryDimension(rReq.m_aMainGroupSize);
359 0 : long nSubGroupDimension = getPrimaryDimension(rReq.m_aSubGroupSize);
360 :
361 0 : setPrimaryDimension(aRet, nMainGroupDimension + nSubGroupDimension);
362 :
363 : setSecondaryDimension(aRet,
364 0 : std::max(getSecondaryDimension(rReq.m_aMainGroupSize),
365 0 : getSecondaryDimension(rReq.m_aSubGroupSize)));
366 :
367 0 : return aRet;
368 : }
369 :
370 0 : static long getMaxNonOutlier(const std::vector<long> &rG, long nAvgDimension)
371 : {
372 0 : long nMaxDimensionNonOutlier = 0;
373 0 : for (std::vector<long>::const_iterator aI = rG.begin(),
374 0 : aEnd = rG.end(); aI != aEnd; ++aI)
375 : {
376 0 : long nPrimaryChildDimension = *aI;
377 0 : if (nPrimaryChildDimension < nAvgDimension * 1.5)
378 : {
379 : nMaxDimensionNonOutlier = std::max(nPrimaryChildDimension,
380 0 : nMaxDimensionNonOutlier);
381 : }
382 : }
383 0 : return nMaxDimensionNonOutlier;
384 : }
385 :
386 0 : static std::vector<long> setButtonSizes(const std::vector<long> &rG,
387 : const std::vector<bool> &rNonHomogeneous,
388 : long nAvgDimension, long nMaxNonOutlier, long nMinWidth)
389 : {
390 0 : std::vector<long> aVec;
391 : //set everything < 1.5 times the average to the same width, leave the
392 : //outliers un-touched
393 0 : std::vector<bool>::const_iterator aJ = rNonHomogeneous.begin();
394 0 : for (std::vector<long>::const_iterator aI = rG.begin(), aEnd = rG.end();
395 : aI != aEnd; ++aI, ++aJ)
396 : {
397 0 : long nPrimaryChildDimension = *aI;
398 0 : bool bNonHomogeneous = *aJ;
399 0 : if (!bNonHomogeneous && nPrimaryChildDimension < nAvgDimension * 1.5)
400 : {
401 0 : aVec.push_back(std::max(nMaxNonOutlier, nMinWidth));
402 : }
403 : else
404 : {
405 0 : aVec.push_back(std::max(nPrimaryChildDimension, nMinWidth));
406 : }
407 : }
408 0 : return aVec;
409 : }
410 :
411 0 : VclButtonBox::Requisition VclButtonBox::calculatePrimarySecondaryRequisitions() const
412 : {
413 0 : Requisition aReq;
414 :
415 0 : Size aMainGroupSize(DEFAULT_CHILD_MIN_WIDTH, DEFAULT_CHILD_MIN_HEIGHT); //to-do, pull from theme
416 0 : Size aSubGroupSize(DEFAULT_CHILD_MIN_WIDTH, DEFAULT_CHILD_MIN_HEIGHT); //to-do, pull from theme
417 :
418 0 : long nMinMainGroupPrimary = getPrimaryDimension(aMainGroupSize);
419 0 : long nMinSubGroupPrimary = getPrimaryDimension(aSubGroupSize);
420 0 : long nMainGroupSecondary = getSecondaryDimension(aMainGroupSize);
421 0 : long nSubGroupSecondary = getSecondaryDimension(aSubGroupSize);
422 :
423 0 : bool bIgnoreSecondaryPacking = (m_eLayoutStyle == VCL_BUTTONBOX_SPREAD || m_eLayoutStyle == VCL_BUTTONBOX_CENTER);
424 :
425 0 : std::vector<long> aMainGroupSizes;
426 0 : std::vector<bool> aMainGroupNonHomogeneous;
427 0 : std::vector<long> aSubGroupSizes;
428 0 : std::vector<bool> aSubGroupNonHomogeneous;
429 :
430 0 : for (const Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
431 : {
432 0 : if (!pChild->IsVisible())
433 0 : continue;
434 0 : Size aChildSize = getLayoutRequisition(*pChild);
435 0 : if (bIgnoreSecondaryPacking || !pChild->get_secondary())
436 : {
437 : //set the max secondary dimension
438 0 : nMainGroupSecondary = std::max(nMainGroupSecondary, getSecondaryDimension(aChildSize));
439 : //collect the primary dimensions
440 0 : aMainGroupSizes.push_back(getPrimaryDimension(aChildSize));
441 0 : aMainGroupNonHomogeneous.push_back(pChild->get_non_homogeneous());
442 : }
443 : else
444 : {
445 0 : nSubGroupSecondary = std::max(nSubGroupSecondary, getSecondaryDimension(aChildSize));
446 0 : aSubGroupSizes.push_back(getPrimaryDimension(aChildSize));
447 0 : aSubGroupNonHomogeneous.push_back(pChild->get_non_homogeneous());
448 : }
449 : }
450 :
451 0 : if (m_bHomogeneous)
452 : {
453 0 : long nMaxMainDimension = aMainGroupSizes.empty() ? 0 :
454 0 : *std::max_element(aMainGroupSizes.begin(), aMainGroupSizes.end());
455 0 : nMaxMainDimension = std::max(nMaxMainDimension, nMinMainGroupPrimary);
456 0 : long nMaxSubDimension = aSubGroupSizes.empty() ? 0 :
457 0 : *std::max_element(aSubGroupSizes.begin(), aSubGroupSizes.end());
458 0 : nMaxSubDimension = std::max(nMaxSubDimension, nMinSubGroupPrimary);
459 0 : long nMaxDimension = std::max(nMaxMainDimension, nMaxSubDimension);
460 0 : aReq.m_aMainGroupDimensions.resize(aMainGroupSizes.size(), nMaxDimension);
461 0 : aReq.m_aSubGroupDimensions.resize(aSubGroupSizes.size(), nMaxDimension);
462 : }
463 : else
464 : {
465 : //Ideally set everything to the same size, but find outlier widgets
466 : //that are way wider than the average and leave them
467 : //at their natural size and set the remainder to share the
468 : //max size of the remaining members of the buttonbox
469 : long nAccDimension = std::accumulate(aMainGroupSizes.begin(),
470 0 : aMainGroupSizes.end(), 0);
471 : nAccDimension = std::accumulate(aSubGroupSizes.begin(),
472 0 : aSubGroupSizes.end(), nAccDimension);
473 :
474 0 : size_t nTotalSize = aMainGroupSizes.size() + aSubGroupSizes.size();
475 :
476 0 : long nAvgDimension = nTotalSize ? nAccDimension / nTotalSize : 0;
477 :
478 : long nMaxMainNonOutlier = getMaxNonOutlier(aMainGroupSizes,
479 0 : nAvgDimension);
480 : long nMaxSubNonOutlier = getMaxNonOutlier(aSubGroupSizes,
481 0 : nAvgDimension);
482 0 : long nMaxNonOutlier = std::max(nMaxMainNonOutlier, nMaxSubNonOutlier);
483 :
484 0 : aReq.m_aMainGroupDimensions = setButtonSizes(aMainGroupSizes,
485 : aMainGroupNonHomogeneous,
486 0 : nAvgDimension, nMaxNonOutlier, nMinMainGroupPrimary);
487 0 : aReq.m_aSubGroupDimensions = setButtonSizes(aSubGroupSizes,
488 : aSubGroupNonHomogeneous,
489 0 : nAvgDimension, nMaxNonOutlier, nMinSubGroupPrimary);
490 : }
491 :
492 0 : if (!aReq.m_aMainGroupDimensions.empty())
493 : {
494 0 : setSecondaryDimension(aReq.m_aMainGroupSize, nMainGroupSecondary);
495 : setPrimaryDimension(aReq.m_aMainGroupSize,
496 : std::accumulate(aReq.m_aMainGroupDimensions.begin(),
497 0 : aReq.m_aMainGroupDimensions.end(), 0));
498 : }
499 0 : if (!aReq.m_aSubGroupDimensions.empty())
500 : {
501 0 : setSecondaryDimension(aReq.m_aSubGroupSize, nSubGroupSecondary);
502 : setPrimaryDimension(aReq.m_aSubGroupSize,
503 : std::accumulate(aReq.m_aSubGroupDimensions.begin(),
504 0 : aReq.m_aSubGroupDimensions.end(), 0));
505 : }
506 :
507 0 : return aReq;
508 : }
509 :
510 0 : Size VclButtonBox::addSpacing(const Size &rSize, sal_uInt16 nVisibleChildren) const
511 : {
512 0 : Size aRet;
513 :
514 0 : if (nVisibleChildren)
515 : {
516 0 : long nPrimaryDimension = getPrimaryDimension(rSize);
517 : setPrimaryDimension(aRet,
518 0 : nPrimaryDimension + m_nSpacing * (nVisibleChildren-1));
519 0 : setSecondaryDimension(aRet, getSecondaryDimension(rSize));
520 : }
521 :
522 0 : return aRet;
523 : }
524 :
525 0 : Size VclButtonBox::calculateRequisition() const
526 : {
527 0 : Requisition aReq(calculatePrimarySecondaryRequisitions());
528 0 : sal_uInt16 nVisibleChildren = aReq.m_aMainGroupDimensions.size() +
529 0 : aReq.m_aSubGroupDimensions.size();
530 0 : return addSpacing(addReqGroups(aReq), nVisibleChildren);
531 : }
532 :
533 0 : bool VclButtonBox::set_property(const OString &rKey, const OString &rValue)
534 : {
535 0 : if (rKey == "layout-style")
536 : {
537 0 : VclButtonBoxStyle eStyle = VCL_BUTTONBOX_DEFAULT_STYLE;
538 0 : if (rValue == "spread")
539 0 : eStyle = VCL_BUTTONBOX_SPREAD;
540 0 : else if (rValue == "edge")
541 0 : eStyle = VCL_BUTTONBOX_EDGE;
542 0 : else if (rValue == "start")
543 0 : eStyle = VCL_BUTTONBOX_START;
544 0 : else if (rValue == "end")
545 0 : eStyle = VCL_BUTTONBOX_END;
546 0 : else if (rValue == "center")
547 0 : eStyle = VCL_BUTTONBOX_CENTER;
548 : else
549 : {
550 : SAL_WARN("vcl.layout", "unknown layout style " << rValue.getStr());
551 : }
552 0 : set_layout(eStyle);
553 : }
554 : else
555 0 : return VclBox::set_property(rKey, rValue);
556 0 : return true;
557 : }
558 :
559 0 : void VclButtonBox::setAllocation(const Size &rAllocation)
560 : {
561 0 : Requisition aReq(calculatePrimarySecondaryRequisitions());
562 :
563 0 : if (aReq.m_aMainGroupDimensions.empty() && aReq.m_aSubGroupDimensions.empty())
564 0 : return;
565 :
566 0 : long nAllocPrimaryDimension = getPrimaryDimension(rAllocation);
567 :
568 0 : Point aMainGroupPos, aOtherGroupPos;
569 0 : int nSpacing = m_nSpacing;
570 :
571 : //To-Do, other layout styles
572 0 : switch (m_eLayoutStyle)
573 : {
574 : case VCL_BUTTONBOX_START:
575 0 : if (!aReq.m_aSubGroupDimensions.empty())
576 : {
577 : long nOtherPrimaryDimension = getPrimaryDimension(
578 0 : addSpacing(aReq.m_aSubGroupSize, aReq.m_aSubGroupDimensions.size()));
579 : setPrimaryCoordinate(aOtherGroupPos,
580 0 : nAllocPrimaryDimension - nOtherPrimaryDimension);
581 : }
582 0 : break;
583 : case VCL_BUTTONBOX_SPREAD:
584 0 : if (!aReq.m_aMainGroupDimensions.empty())
585 : {
586 : long nMainPrimaryDimension = getPrimaryDimension(
587 0 : addSpacing(aReq.m_aMainGroupSize, aReq.m_aMainGroupDimensions.size()));
588 0 : long nExtraSpace = nAllocPrimaryDimension - nMainPrimaryDimension;
589 0 : nExtraSpace += (aReq.m_aMainGroupDimensions.size()-1) * nSpacing;
590 0 : nSpacing = nExtraSpace/(aReq.m_aMainGroupDimensions.size()+1);
591 0 : setPrimaryCoordinate(aMainGroupPos, nSpacing);
592 : }
593 0 : break;
594 : case VCL_BUTTONBOX_CENTER:
595 0 : if (!aReq.m_aMainGroupDimensions.empty())
596 : {
597 : long nMainPrimaryDimension = getPrimaryDimension(
598 0 : addSpacing(aReq.m_aMainGroupSize, aReq.m_aMainGroupDimensions.size()));
599 0 : long nExtraSpace = nAllocPrimaryDimension - nMainPrimaryDimension;
600 0 : setPrimaryCoordinate(aMainGroupPos, nExtraSpace/2);
601 : }
602 0 : break;
603 : default:
604 : SAL_WARN("vcl.layout", "todo unimplemented layout style");
605 : //fall-through
606 : case VCL_BUTTONBOX_DEFAULT_STYLE:
607 : case VCL_BUTTONBOX_END:
608 0 : if (!aReq.m_aMainGroupDimensions.empty())
609 : {
610 : long nMainPrimaryDimension = getPrimaryDimension(
611 0 : addSpacing(aReq.m_aMainGroupSize, aReq.m_aMainGroupDimensions.size()));
612 : setPrimaryCoordinate(aMainGroupPos,
613 0 : nAllocPrimaryDimension - nMainPrimaryDimension);
614 : }
615 0 : break;
616 : }
617 :
618 0 : Size aChildSize;
619 0 : setSecondaryDimension(aChildSize, getSecondaryDimension(rAllocation));
620 :
621 0 : std::vector<long>::const_iterator aPrimaryI = aReq.m_aMainGroupDimensions.begin();
622 0 : std::vector<long>::const_iterator aSecondaryI = aReq.m_aSubGroupDimensions.begin();
623 0 : bool bIgnoreSecondaryPacking = (m_eLayoutStyle == VCL_BUTTONBOX_SPREAD || m_eLayoutStyle == VCL_BUTTONBOX_CENTER);
624 0 : for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
625 : {
626 0 : if (!pChild->IsVisible())
627 0 : continue;
628 :
629 0 : if (bIgnoreSecondaryPacking || !pChild->get_secondary())
630 : {
631 0 : long nMainGroupPrimaryDimension = *aPrimaryI++;
632 0 : setPrimaryDimension(aChildSize, nMainGroupPrimaryDimension);
633 0 : setLayoutAllocation(*pChild, aMainGroupPos, aChildSize);
634 0 : long nPrimaryCoordinate = getPrimaryCoordinate(aMainGroupPos);
635 0 : setPrimaryCoordinate(aMainGroupPos, nPrimaryCoordinate + nMainGroupPrimaryDimension + nSpacing);
636 : }
637 : else
638 : {
639 0 : long nSubGroupPrimaryDimension = *aSecondaryI++;
640 0 : setPrimaryDimension(aChildSize, nSubGroupPrimaryDimension);
641 0 : setLayoutAllocation(*pChild, aOtherGroupPos, aChildSize);
642 0 : long nPrimaryCoordinate = getPrimaryCoordinate(aOtherGroupPos);
643 0 : setPrimaryCoordinate(aOtherGroupPos, nPrimaryCoordinate + nSubGroupPrimaryDimension + nSpacing);
644 : }
645 0 : }
646 : }
647 :
648 0 : struct ButtonOrder
649 : {
650 : OString m_aType;
651 : int m_nPriority;
652 : };
653 :
654 0 : static int getButtonPriority(const OString &rType)
655 : {
656 : static const size_t N_TYPES = 3;
657 : static const ButtonOrder aDiscardCancelSave[N_TYPES] =
658 : {
659 : { "/discard", 0 },
660 : { "/cancel", 1 },
661 : { "/save", 2 }
662 0 : };
663 :
664 : static const ButtonOrder aSaveDiscardCancel[N_TYPES] =
665 : {
666 : { "/save", 0 },
667 : { "/discard", 1 },
668 : { "/cancel", 2 }
669 0 : };
670 :
671 0 : const ButtonOrder* pOrder = &aDiscardCancelSave[0];
672 :
673 0 : const OUString &rEnv = Application::GetDesktopEnvironment();
674 :
675 0 : if (rEnv.equalsIgnoreAsciiCase("windows") ||
676 0 : rEnv.equalsIgnoreAsciiCase("kde4") ||
677 0 : rEnv.equalsIgnoreAsciiCase("tde") ||
678 0 : rEnv.equalsIgnoreAsciiCase("kde"))
679 : {
680 0 : pOrder = &aSaveDiscardCancel[0];
681 : }
682 :
683 0 : for (size_t i = 0; i < N_TYPES; ++i, ++pOrder)
684 : {
685 0 : if (rType.endsWith(pOrder->m_aType))
686 0 : return pOrder->m_nPriority;
687 : }
688 :
689 0 : return -1;
690 : }
691 :
692 : class sortButtons
693 : : public std::binary_function<const Window*, const Window*, bool>
694 : {
695 : bool m_bVerticalContainer;
696 : public:
697 0 : sortButtons(bool bVerticalContainer)
698 0 : : m_bVerticalContainer(bVerticalContainer)
699 : {
700 0 : }
701 : bool operator()(const Window *pA, const Window *pB) const;
702 : };
703 :
704 0 : bool sortButtons::operator()(const Window *pA, const Window *pB) const
705 : {
706 : //sort into two groups of pack start and pack end
707 0 : VclPackType ePackA = pA->get_pack_type();
708 0 : VclPackType ePackB = pB->get_pack_type();
709 0 : if (ePackA < ePackB)
710 0 : return true;
711 0 : if (ePackA > ePackB)
712 0 : return false;
713 0 : bool bPackA = pA->get_secondary();
714 0 : bool bPackB = pB->get_secondary();
715 0 : if (!m_bVerticalContainer)
716 : {
717 : //for horizontal boxes group secondaries before primaries
718 0 : if (bPackA > bPackB)
719 0 : return true;
720 0 : if (bPackA < bPackB)
721 0 : return false;
722 : }
723 : else
724 : {
725 : //for vertical boxes group secondaries after primaries
726 0 : if (bPackA < bPackB)
727 0 : return true;
728 0 : if (bPackA > bPackB)
729 0 : return false;
730 : }
731 :
732 : //now order within groups according to platform rules
733 0 : return getButtonPriority(pA->GetHelpId()) < getButtonPriority(pB->GetHelpId());
734 : }
735 :
736 0 : void VclButtonBox::sort_native_button_order()
737 : {
738 0 : std::vector<Window*> aChilds;
739 0 : for (Window* pChild = GetWindow(WINDOW_FIRSTCHILD); pChild;
740 0 : pChild = pChild->GetWindow(WINDOW_NEXT))
741 : {
742 0 : aChilds.push_back(pChild);
743 : }
744 :
745 : //sort child order within parent so that we match the platform
746 : //button order
747 0 : std::stable_sort(aChilds.begin(), aChilds.end(), sortButtons(m_bVerticalContainer));
748 0 : VclBuilder::reorderWithinParent(aChilds, true);
749 0 : }
750 :
751 0 : VclGrid::array_type VclGrid::assembleGrid() const
752 : {
753 0 : ext_array_type A;
754 :
755 0 : for (Window* pChild = GetWindow(WINDOW_FIRSTCHILD); pChild;
756 : pChild = pChild->GetWindow(WINDOW_NEXT))
757 : {
758 0 : sal_Int32 nLeftAttach = pChild->get_grid_left_attach();
759 0 : sal_Int32 nWidth = pChild->get_grid_width();
760 0 : sal_Int32 nMaxXPos = nLeftAttach+nWidth-1;
761 :
762 0 : sal_Int32 nTopAttach = pChild->get_grid_top_attach();
763 0 : sal_Int32 nHeight = pChild->get_grid_height();
764 0 : sal_Int32 nMaxYPos = nTopAttach+nHeight-1;
765 :
766 0 : sal_Int32 nCurrentMaxXPos = A.shape()[0]-1;
767 0 : sal_Int32 nCurrentMaxYPos = A.shape()[1]-1;
768 0 : if (nMaxXPos > nCurrentMaxXPos || nMaxYPos > nCurrentMaxYPos)
769 : {
770 0 : nCurrentMaxXPos = std::max(nMaxXPos, nCurrentMaxXPos);
771 0 : nCurrentMaxYPos = std::max(nMaxYPos, nCurrentMaxYPos);
772 0 : A.resize(boost::extents[nCurrentMaxXPos+1][nCurrentMaxYPos+1]);
773 : }
774 :
775 0 : ExtendedGridEntry &rEntry = A[nLeftAttach][nTopAttach];
776 0 : rEntry.pChild = pChild;
777 0 : rEntry.nSpanWidth = nWidth;
778 0 : rEntry.nSpanHeight = nHeight;
779 0 : rEntry.x = nLeftAttach;
780 0 : rEntry.y = nTopAttach;
781 :
782 0 : for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
783 : {
784 0 : for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
785 : {
786 0 : ExtendedGridEntry &rSpan = A[nLeftAttach+nSpanX][nTopAttach+nSpanY];
787 0 : rSpan.x = nLeftAttach;
788 0 : rSpan.y = nTopAttach;
789 : }
790 : }
791 : }
792 :
793 : //see if we have any empty rows/cols
794 0 : sal_Int32 nMaxX = A.shape()[0];
795 0 : sal_Int32 nMaxY = A.shape()[1];
796 :
797 0 : std::vector<bool> aNonEmptyCols(nMaxX);
798 0 : std::vector<bool> aNonEmptyRows(nMaxY);
799 :
800 0 : for (sal_Int32 x = 0; x < nMaxX; ++x)
801 : {
802 0 : for (sal_Int32 y = 0; y < nMaxY; ++y)
803 : {
804 0 : const GridEntry &rEntry = A[x][y];
805 0 : const Window *pChild = rEntry.pChild;
806 0 : if (pChild && pChild->IsVisible())
807 : {
808 0 : aNonEmptyCols[x] = true;
809 0 : if (get_column_homogeneous())
810 : {
811 0 : for (sal_Int32 nSpanX = 1; nSpanX < rEntry.nSpanWidth; ++nSpanX)
812 0 : aNonEmptyCols[x+nSpanX] = true;
813 : }
814 0 : aNonEmptyRows[y] = true;
815 0 : if (get_row_homogeneous())
816 : {
817 0 : for (sal_Int32 nSpanY = 1; nSpanY < rEntry.nSpanHeight; ++nSpanY)
818 0 : aNonEmptyRows[y+nSpanY] = true;
819 : }
820 : }
821 : }
822 : }
823 :
824 0 : if (!get_column_homogeneous())
825 : {
826 : //reduce the spans of elements that span empty columns
827 0 : for (sal_Int32 x = 0; x < nMaxX; ++x)
828 : {
829 0 : std::set<ExtendedGridEntry*> candidates;
830 0 : for (sal_Int32 y = 0; y < nMaxY; ++y)
831 : {
832 0 : if (aNonEmptyCols[x])
833 0 : continue;
834 0 : ExtendedGridEntry &rSpan = A[x][y];
835 : //cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
836 : //just points back to itself if there's no cell spanning
837 0 : if ((rSpan.x == -1) || (rSpan.y == -1))
838 : {
839 : //there is no entry for this cell, i.e. this is a cell
840 : //with no widget in it, or spanned by any other widget
841 0 : continue;
842 : }
843 0 : ExtendedGridEntry &rEntry = A[rSpan.x][rSpan.y];
844 0 : candidates.insert(&rEntry);
845 : }
846 0 : for (std::set<ExtendedGridEntry*>::iterator aI = candidates.begin(), aEnd = candidates.end();
847 : aI != aEnd; ++aI)
848 : {
849 0 : ExtendedGridEntry *pEntry = *aI;
850 0 : --pEntry->nSpanWidth;
851 : }
852 0 : }
853 : }
854 :
855 0 : if (!get_row_homogeneous())
856 : {
857 : //reduce the spans of elements that span empty rows
858 0 : for (sal_Int32 y = 0; y < nMaxY; ++y)
859 : {
860 0 : std::set<ExtendedGridEntry*> candidates;
861 0 : for (sal_Int32 x = 0; x < nMaxX; ++x)
862 : {
863 0 : if (aNonEmptyRows[y])
864 0 : continue;
865 0 : ExtendedGridEntry &rSpan = A[x][y];
866 : //cell x/y is spanned by the widget at cell rSpan.x/rSpan.y,
867 : //just points back to itself if there's no cell spanning
868 0 : if ((rSpan.x == -1) || (rSpan.y == -1))
869 : {
870 : //there is no entry for this cell, i.e. this is a cell
871 : //with no widget in it, or spanned by any other widget
872 0 : continue;
873 : }
874 0 : ExtendedGridEntry &rEntry = A[rSpan.x][rSpan.y];
875 0 : candidates.insert(&rEntry);
876 : }
877 0 : for (std::set<ExtendedGridEntry*>::iterator aI = candidates.begin(), aEnd = candidates.end();
878 : aI != aEnd; ++aI)
879 : {
880 0 : ExtendedGridEntry *pEntry = *aI;
881 0 : --pEntry->nSpanHeight;
882 : }
883 0 : }
884 : }
885 :
886 0 : sal_Int32 nNonEmptyCols = std::count(aNonEmptyCols.begin(), aNonEmptyCols.end(), true);
887 0 : sal_Int32 nNonEmptyRows = std::count(aNonEmptyRows.begin(), aNonEmptyRows.end(), true);
888 :
889 : //make new grid without empty rows and columns
890 0 : array_type B(boost::extents[nNonEmptyCols][nNonEmptyRows]);
891 0 : for (sal_Int32 x = 0, x2 = 0; x < nMaxX; ++x)
892 : {
893 0 : if (aNonEmptyCols[x] == false)
894 0 : continue;
895 0 : for (sal_Int32 y = 0, y2 = 0; y < nMaxY; ++y)
896 : {
897 0 : if (aNonEmptyRows[y] == false)
898 0 : continue;
899 0 : GridEntry &rEntry = A[x][y];
900 0 : B[x2][y2++] = rEntry;
901 : }
902 0 : ++x2;
903 : }
904 :
905 0 : return B;
906 : }
907 :
908 0 : bool VclGrid::isNullGrid(const array_type &A) const
909 : {
910 0 : sal_Int32 nMaxX = A.shape()[0];
911 0 : sal_Int32 nMaxY = A.shape()[1];
912 :
913 0 : if (!nMaxX || !nMaxY)
914 0 : return true;
915 0 : return false;
916 : }
917 :
918 0 : void VclGrid::calcMaxs(const array_type &A, std::vector<Value> &rWidths, std::vector<Value> &rHeights) const
919 : {
920 0 : sal_Int32 nMaxX = A.shape()[0];
921 0 : sal_Int32 nMaxY = A.shape()[1];
922 :
923 0 : rWidths.resize(nMaxX);
924 0 : rHeights.resize(nMaxY);
925 :
926 : //first use the non spanning entries to set default width/heights
927 0 : for (sal_Int32 x = 0; x < nMaxX; ++x)
928 : {
929 0 : for (sal_Int32 y = 0; y < nMaxY; ++y)
930 : {
931 0 : const GridEntry &rEntry = A[x][y];
932 0 : const Window *pChild = rEntry.pChild;
933 0 : if (!pChild || !pChild->IsVisible())
934 0 : continue;
935 :
936 0 : sal_Int32 nWidth = rEntry.nSpanWidth;
937 0 : sal_Int32 nHeight = rEntry.nSpanHeight;
938 :
939 0 : for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
940 0 : rWidths[x+nSpanX].m_bExpand |= pChild->get_hexpand();
941 :
942 0 : for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
943 0 : rHeights[y+nSpanY].m_bExpand |= pChild->get_vexpand();
944 :
945 0 : if (nWidth == 1 || nHeight == 1)
946 : {
947 0 : Size aChildSize = getLayoutRequisition(*pChild);
948 0 : if (nWidth == 1)
949 0 : rWidths[x].m_nValue = std::max(rWidths[x].m_nValue, aChildSize.Width());
950 0 : if (nHeight == 1)
951 0 : rHeights[y].m_nValue = std::max(rHeights[y].m_nValue, aChildSize.Height());
952 : }
953 : }
954 : }
955 :
956 : //now use the spanning entries and split any extra sizes across expanding rows/cols
957 : //where possible
958 0 : for (sal_Int32 x = 0; x < nMaxX; ++x)
959 : {
960 0 : for (sal_Int32 y = 0; y < nMaxY; ++y)
961 : {
962 0 : const GridEntry &rEntry = A[x][y];
963 0 : const Window *pChild = rEntry.pChild;
964 0 : if (!pChild || !pChild->IsVisible())
965 0 : continue;
966 :
967 0 : sal_Int32 nWidth = rEntry.nSpanWidth;
968 0 : sal_Int32 nHeight = rEntry.nSpanHeight;
969 :
970 0 : if (nWidth == 1 && nHeight == 1)
971 0 : continue;
972 :
973 0 : Size aChildSize = getLayoutRequisition(*pChild);
974 :
975 0 : if (nWidth > 1)
976 : {
977 0 : sal_Int32 nExistingWidth = 0;
978 0 : for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
979 0 : nExistingWidth += rWidths[x+nSpanX].m_nValue;
980 :
981 0 : sal_Int32 nExtraWidth = aChildSize.Width() - nExistingWidth;
982 :
983 0 : if (nExtraWidth > 0)
984 : {
985 0 : bool bForceExpandAll = false;
986 0 : sal_Int32 nExpandables = 0;
987 0 : for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
988 0 : if (rWidths[x+nSpanX].m_bExpand)
989 0 : ++nExpandables;
990 0 : if (nExpandables == 0)
991 : {
992 0 : nExpandables = nWidth;
993 0 : bForceExpandAll = true;
994 : }
995 :
996 0 : for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
997 : {
998 0 : if (rWidths[x+nSpanX].m_bExpand || bForceExpandAll)
999 0 : rWidths[x+nSpanX].m_nValue += nExtraWidth/nExpandables;
1000 : }
1001 : }
1002 : }
1003 :
1004 0 : if (nHeight > 1)
1005 : {
1006 0 : sal_Int32 nExistingHeight = 0;
1007 0 : for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1008 0 : nExistingHeight += rHeights[y+nSpanY].m_nValue;
1009 :
1010 0 : sal_Int32 nExtraHeight = aChildSize.Height() - nExistingHeight;
1011 :
1012 0 : if (nExtraHeight > 0)
1013 : {
1014 0 : bool bForceExpandAll = false;
1015 0 : sal_Int32 nExpandables = 0;
1016 0 : for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1017 0 : if (rHeights[y+nSpanY].m_bExpand)
1018 0 : ++nExpandables;
1019 0 : if (nExpandables == 0)
1020 : {
1021 0 : nExpandables = nHeight;
1022 0 : bForceExpandAll = true;
1023 : }
1024 :
1025 0 : for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1026 : {
1027 0 : if (rHeights[y+nSpanY].m_bExpand || bForceExpandAll)
1028 0 : rHeights[y+nSpanY].m_nValue += nExtraHeight/nExpandables;
1029 : }
1030 : }
1031 : }
1032 : }
1033 : }
1034 0 : }
1035 :
1036 0 : bool compareValues(const VclGrid::Value &i, const VclGrid::Value &j)
1037 : {
1038 0 : return i.m_nValue < j.m_nValue;
1039 : }
1040 :
1041 0 : VclGrid::Value accumulateValues(const VclGrid::Value &i, const VclGrid::Value &j)
1042 : {
1043 0 : VclGrid::Value aRet;
1044 0 : aRet.m_nValue = i.m_nValue + j.m_nValue;
1045 0 : aRet.m_bExpand = i.m_bExpand || j.m_bExpand;
1046 0 : return aRet;
1047 : }
1048 :
1049 0 : Size VclGrid::calculateRequisition() const
1050 : {
1051 0 : return calculateRequisitionForSpacings(get_row_spacing(), get_column_spacing());
1052 : }
1053 :
1054 0 : Size VclGrid::calculateRequisitionForSpacings(sal_Int32 nRowSpacing, sal_Int32 nColSpacing) const
1055 : {
1056 0 : array_type A = assembleGrid();
1057 :
1058 0 : if (isNullGrid(A))
1059 0 : return Size();
1060 :
1061 0 : std::vector<Value> aWidths;
1062 0 : std::vector<Value> aHeights;
1063 0 : calcMaxs(A, aWidths, aHeights);
1064 :
1065 0 : long nTotalWidth = 0;
1066 0 : if (get_column_homogeneous())
1067 : {
1068 0 : nTotalWidth = std::max_element(aWidths.begin(), aWidths.end(), compareValues)->m_nValue;
1069 0 : nTotalWidth *= aWidths.size();
1070 : }
1071 : else
1072 : {
1073 0 : nTotalWidth = std::accumulate(aWidths.begin(), aWidths.end(), Value(), accumulateValues).m_nValue;
1074 : }
1075 :
1076 0 : nTotalWidth += nColSpacing * (aWidths.size()-1);
1077 :
1078 0 : long nTotalHeight = 0;
1079 0 : if (get_row_homogeneous())
1080 : {
1081 0 : nTotalHeight = std::max_element(aHeights.begin(), aHeights.end(), compareValues)->m_nValue;
1082 0 : nTotalHeight *= aHeights.size();
1083 : }
1084 : else
1085 : {
1086 0 : nTotalHeight = std::accumulate(aHeights.begin(), aHeights.end(), Value(), accumulateValues).m_nValue;
1087 : }
1088 :
1089 0 : nTotalHeight += nRowSpacing * (aHeights.size()-1);
1090 :
1091 0 : return Size(nTotalWidth, nTotalHeight);
1092 : }
1093 :
1094 0 : void VclGrid::setAllocation(const Size& rAllocation)
1095 : {
1096 0 : array_type A = assembleGrid();
1097 :
1098 0 : if (isNullGrid(A))
1099 0 : return;
1100 :
1101 0 : sal_Int32 nMaxX = A.shape()[0];
1102 0 : sal_Int32 nMaxY = A.shape()[1];
1103 :
1104 0 : Size aRequisition;
1105 0 : std::vector<Value> aWidths(nMaxX);
1106 0 : std::vector<Value> aHeights(nMaxY);
1107 0 : if (!get_column_homogeneous() || !get_row_homogeneous())
1108 : {
1109 0 : aRequisition = calculateRequisition();
1110 0 : calcMaxs(A, aWidths, aHeights);
1111 : }
1112 :
1113 0 : sal_Int32 nColSpacing(get_column_spacing());
1114 0 : sal_Int32 nRowSpacing(get_row_spacing());
1115 :
1116 0 : long nAvailableWidth = rAllocation.Width();
1117 0 : if (nMaxX)
1118 0 : nAvailableWidth -= nColSpacing * (nMaxX - 1);
1119 0 : if (get_column_homogeneous())
1120 : {
1121 0 : for (sal_Int32 x = 0; x < nMaxX; ++x)
1122 0 : aWidths[x].m_nValue = nAvailableWidth/nMaxX;
1123 : }
1124 0 : else if (rAllocation.Width() != aRequisition.Width())
1125 : {
1126 0 : sal_Int32 nExpandables = 0;
1127 0 : for (sal_Int32 x = 0; x < nMaxX; ++x)
1128 0 : if (aWidths[x].m_bExpand)
1129 0 : ++nExpandables;
1130 0 : long nExtraWidthForExpanders = nExpandables ? (rAllocation.Width() - aRequisition.Width()) / nExpandables : 0;
1131 :
1132 : //We don't fit and there is no volunteer to be shrunk
1133 0 : if (!nExpandables && rAllocation.Width() < aRequisition.Width())
1134 : {
1135 : //first reduce spacing
1136 0 : while (nColSpacing)
1137 : {
1138 0 : nColSpacing /= 2;
1139 0 : aRequisition = calculateRequisitionForSpacings(nRowSpacing, nColSpacing);
1140 0 : if (aRequisition.Width() <= rAllocation.Width())
1141 0 : break;
1142 : }
1143 :
1144 : //share out the remaining pain to everyone
1145 0 : long nExtraWidth = (rAllocation.Width() - aRequisition.Width()) / nMaxX;
1146 :
1147 0 : for (sal_Int32 x = 0; x < nMaxX; ++x)
1148 0 : aWidths[x].m_nValue += nExtraWidth;
1149 : }
1150 :
1151 0 : if (nExtraWidthForExpanders)
1152 : {
1153 0 : for (sal_Int32 x = 0; x < nMaxX; ++x)
1154 0 : if (aWidths[x].m_bExpand)
1155 0 : aWidths[x].m_nValue += nExtraWidthForExpanders;
1156 : }
1157 : }
1158 :
1159 0 : long nAvailableHeight = rAllocation.Height();
1160 0 : if (nMaxY)
1161 0 : nAvailableHeight -= nRowSpacing * (nMaxY - 1);
1162 0 : if (get_row_homogeneous())
1163 : {
1164 0 : for (sal_Int32 y = 0; y < nMaxY; ++y)
1165 0 : aHeights[y].m_nValue = nAvailableHeight/nMaxY;
1166 : }
1167 0 : else if (rAllocation.Height() != aRequisition.Height())
1168 : {
1169 0 : sal_Int32 nExpandables = 0;
1170 0 : for (sal_Int32 y = 0; y < nMaxY; ++y)
1171 0 : if (aHeights[y].m_bExpand)
1172 0 : ++nExpandables;
1173 0 : long nExtraHeightForExpanders = nExpandables ? (rAllocation.Height() - aRequisition.Height()) / nExpandables : 0;
1174 :
1175 : //We don't fit and there is no volunteer to be shrunk
1176 0 : if (!nExpandables && rAllocation.Height() < aRequisition.Height())
1177 : {
1178 : //first reduce spacing
1179 0 : while (nRowSpacing)
1180 : {
1181 0 : nRowSpacing /= 2;
1182 0 : aRequisition = calculateRequisitionForSpacings(nRowSpacing, nColSpacing);
1183 0 : if (aRequisition.Height() <= rAllocation.Height())
1184 0 : break;
1185 : }
1186 :
1187 : //share out the remaining pain to everyone
1188 0 : long nExtraHeight = (rAllocation.Height() - aRequisition.Height()) / nMaxY;
1189 :
1190 0 : for (sal_Int32 y = 0; y < nMaxY; ++y)
1191 0 : aHeights[y].m_nValue += nExtraHeight;
1192 : }
1193 :
1194 0 : if (nExtraHeightForExpanders)
1195 : {
1196 0 : for (sal_Int32 y = 0; y < nMaxY; ++y)
1197 0 : if (aHeights[y].m_bExpand)
1198 0 : aHeights[y].m_nValue += nExtraHeightForExpanders;
1199 : }
1200 : }
1201 :
1202 0 : Point aAllocPos(0, 0);
1203 0 : for (sal_Int32 x = 0; x < nMaxX; ++x)
1204 : {
1205 0 : for (sal_Int32 y = 0; y < nMaxY; ++y)
1206 : {
1207 0 : GridEntry &rEntry = A[x][y];
1208 0 : Window *pChild = rEntry.pChild;
1209 0 : if (pChild)
1210 : {
1211 0 : Size aChildAlloc(0, 0);
1212 :
1213 0 : sal_Int32 nWidth = rEntry.nSpanWidth;
1214 0 : for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
1215 0 : aChildAlloc.Width() += aWidths[x+nSpanX].m_nValue;
1216 0 : aChildAlloc.Width() += nColSpacing*(nWidth-1);
1217 :
1218 0 : sal_Int32 nHeight = rEntry.nSpanHeight;
1219 0 : for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
1220 0 : aChildAlloc.Height() += aHeights[y+nSpanY].m_nValue;
1221 0 : aChildAlloc.Height() += nRowSpacing*(nHeight-1);
1222 :
1223 0 : setLayoutAllocation(*pChild, aAllocPos, aChildAlloc);
1224 : }
1225 0 : aAllocPos.Y() += aHeights[y].m_nValue + nRowSpacing;
1226 : }
1227 0 : aAllocPos.X() += aWidths[x].m_nValue + nColSpacing;
1228 0 : aAllocPos.Y() = 0;
1229 0 : }
1230 : }
1231 :
1232 0 : bool toBool(const OString &rValue)
1233 : {
1234 0 : return (rValue[0] == 't' || rValue[0] == 'T' || rValue[0] == '1');
1235 : }
1236 :
1237 0 : bool VclGrid::set_property(const OString &rKey, const OString &rValue)
1238 : {
1239 0 : if (rKey == "row-spacing")
1240 0 : set_row_spacing(rValue.toInt32());
1241 0 : else if (rKey == "column-spacing")
1242 0 : set_column_spacing(rValue.toInt32());
1243 0 : else if (rKey == "row-homogeneous")
1244 0 : set_row_homogeneous(toBool(rValue));
1245 0 : else if (rKey == "column-homogeneous")
1246 0 : set_column_homogeneous(toBool(rValue));
1247 0 : else if (rKey == "n-rows")
1248 : /*nothing to do*/;
1249 : else
1250 0 : return VclContainer::set_property(rKey, rValue);
1251 0 : return true;
1252 : }
1253 :
1254 0 : void setGridAttach(Window &rWidget, sal_Int32 nLeft, sal_Int32 nTop, sal_Int32 nWidth, sal_Int32 nHeight)
1255 : {
1256 0 : rWidget.set_grid_left_attach(nLeft);
1257 0 : rWidget.set_grid_top_attach(nTop);
1258 0 : rWidget.set_grid_width(nWidth);
1259 0 : rWidget.set_grid_height(nHeight);
1260 0 : }
1261 :
1262 0 : const Window *VclBin::get_child() const
1263 : {
1264 0 : const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1265 :
1266 0 : return pWindowImpl->mpFirstChild;
1267 : }
1268 :
1269 0 : Window *VclBin::get_child()
1270 : {
1271 0 : return const_cast<Window*>(const_cast<const VclBin*>(this)->get_child());
1272 : }
1273 :
1274 0 : Size VclBin::calculateRequisition() const
1275 : {
1276 0 : const Window *pChild = get_child();
1277 0 : if (pChild && pChild->IsVisible())
1278 0 : return getLayoutRequisition(*pChild);
1279 0 : return Size(0, 0);
1280 : }
1281 :
1282 0 : void VclBin::setAllocation(const Size &rAllocation)
1283 : {
1284 0 : Window *pChild = get_child();
1285 0 : if (pChild && pChild->IsVisible())
1286 0 : setLayoutAllocation(*pChild, Point(0, 0), rAllocation);
1287 0 : }
1288 :
1289 : //To-Do, hook a DecorationView into VclFrame ?
1290 :
1291 0 : Size VclFrame::calculateRequisition() const
1292 : {
1293 0 : Size aRet(0, 0);
1294 :
1295 0 : const Window *pChild = get_child();
1296 0 : const Window *pLabel = get_label_widget();
1297 :
1298 0 : if (pChild && pChild->IsVisible())
1299 0 : aRet = getLayoutRequisition(*pChild);
1300 :
1301 0 : if (pLabel && pLabel->IsVisible())
1302 : {
1303 0 : Size aLabelSize = getLayoutRequisition(*pLabel);
1304 0 : aRet.Height() += aLabelSize.Height();
1305 0 : aRet.Width() = std::max(aLabelSize.Width(), aRet.Width());
1306 : }
1307 :
1308 : const FrameStyle &rFrameStyle =
1309 0 : GetSettings().GetStyleSettings().GetFrameStyle();
1310 0 : aRet.Width() += rFrameStyle.left + rFrameStyle.right;
1311 0 : aRet.Height() += rFrameStyle.top + rFrameStyle.bottom;
1312 :
1313 0 : return aRet;
1314 : }
1315 :
1316 0 : void VclFrame::setAllocation(const Size &rAllocation)
1317 : {
1318 : //SetBackground( Color(0xFF, 0x00, 0xFF) );
1319 :
1320 : const FrameStyle &rFrameStyle =
1321 0 : GetSettings().GetStyleSettings().GetFrameStyle();
1322 0 : Size aAllocation(rAllocation.Width() - rFrameStyle.left - rFrameStyle.right,
1323 0 : rAllocation.Height() - rFrameStyle.top - rFrameStyle.bottom);
1324 0 : Point aChildPos(rFrameStyle.left, rFrameStyle.top);
1325 :
1326 0 : Window *pChild = get_child();
1327 0 : Window *pLabel = get_label_widget();
1328 :
1329 0 : if (pLabel && pLabel->IsVisible())
1330 : {
1331 0 : Size aLabelSize = getLayoutRequisition(*pLabel);
1332 0 : aLabelSize.Height() = std::min(aLabelSize.Height(), aAllocation.Height());
1333 0 : aLabelSize.Width() = std::min(aLabelSize.Width(), aAllocation.Width());
1334 0 : setLayoutAllocation(*pLabel, aChildPos, aLabelSize);
1335 0 : aAllocation.Height() -= aLabelSize.Height();
1336 0 : aChildPos.Y() += aLabelSize.Height();
1337 : }
1338 :
1339 0 : if (pChild && pChild->IsVisible())
1340 0 : setLayoutAllocation(*pChild, aChildPos, aAllocation);
1341 0 : }
1342 :
1343 0 : void VclFrame::designate_label(Window *pWindow)
1344 : {
1345 : assert(pWindow->GetParent() == this);
1346 0 : m_pLabel = pWindow;
1347 0 : }
1348 :
1349 0 : const Window *VclFrame::get_label_widget() const
1350 : {
1351 : assert(GetChildCount() == 2);
1352 0 : if (m_pLabel)
1353 0 : return m_pLabel;
1354 : //The label widget is normally the first (of two) children
1355 0 : const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1356 0 : if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //no label exists
1357 0 : return NULL;
1358 0 : return pWindowImpl->mpFirstChild;
1359 : }
1360 :
1361 0 : Window *VclFrame::get_label_widget()
1362 : {
1363 0 : return const_cast<Window*>(const_cast<const VclFrame*>(this)->get_label_widget());
1364 : }
1365 :
1366 0 : const Window *VclFrame::get_child() const
1367 : {
1368 : assert(GetChildCount() == 2);
1369 : //The child widget is the normally the last (of two) children
1370 0 : const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1371 0 : if (!m_pLabel)
1372 0 : return pWindowImpl->mpLastChild;
1373 0 : if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //only label exists
1374 0 : return NULL;
1375 0 : return pWindowImpl->mpLastChild;
1376 : }
1377 :
1378 0 : Window *VclFrame::get_child()
1379 : {
1380 0 : return const_cast<Window*>(const_cast<const VclFrame*>(this)->get_child());
1381 : }
1382 :
1383 0 : void VclFrame::set_label(const OUString &rLabel)
1384 : {
1385 0 : Window *pLabel = get_label_widget();
1386 : assert(pLabel);
1387 0 : pLabel->SetText(rLabel);
1388 0 : }
1389 :
1390 0 : OUString VclFrame::get_label() const
1391 : {
1392 0 : const Window *pLabel = get_label_widget();
1393 : assert(pLabel);
1394 0 : return pLabel->GetText();
1395 : }
1396 :
1397 0 : OUString VclFrame::getDefaultAccessibleName() const
1398 : {
1399 0 : const Window *pLabel = get_label_widget();
1400 0 : if (pLabel)
1401 0 : return pLabel->GetAccessibleName();
1402 0 : return VclBin::getDefaultAccessibleName();
1403 : }
1404 :
1405 0 : Size VclAlignment::calculateRequisition() const
1406 : {
1407 : Size aRet(m_nLeftPadding + m_nRightPadding,
1408 0 : m_nTopPadding + m_nBottomPadding);
1409 :
1410 0 : const Window *pChild = get_child();
1411 0 : if (pChild && pChild->IsVisible())
1412 : {
1413 0 : Size aChildSize = getLayoutRequisition(*pChild);
1414 0 : aRet.Width() += aChildSize.Width();
1415 0 : aRet.Height() += aChildSize.Height();
1416 : }
1417 :
1418 0 : return aRet;
1419 : }
1420 :
1421 0 : void VclAlignment::setAllocation(const Size &rAllocation)
1422 : {
1423 0 : Window *pChild = get_child();
1424 0 : if (!pChild || !pChild->IsVisible())
1425 0 : return;
1426 :
1427 0 : Point aChildPos(m_nLeftPadding, m_nTopPadding);
1428 :
1429 0 : Size aAllocation;
1430 0 : aAllocation.Width() = rAllocation.Width() - (m_nLeftPadding + m_nRightPadding);
1431 0 : aAllocation.Height() = rAllocation.Height() - (m_nTopPadding + m_nBottomPadding);
1432 :
1433 0 : setLayoutAllocation(*pChild, aChildPos, aAllocation);
1434 : }
1435 :
1436 0 : bool VclAlignment::set_property(const OString &rKey, const OString &rValue)
1437 : {
1438 0 : if (rKey == "bottom-padding")
1439 0 : m_nBottomPadding = rValue.toInt32();
1440 0 : else if (rKey == "left-padding")
1441 0 : m_nLeftPadding = rValue.toInt32();
1442 0 : else if (rKey == "right-padding")
1443 0 : m_nRightPadding = rValue.toInt32();
1444 0 : else if (rKey == "top-padding")
1445 0 : m_nTopPadding = rValue.toInt32();
1446 0 : else if (rKey == "xalign")
1447 0 : m_fXAlign = rValue.toFloat();
1448 0 : else if (rKey == "xscale")
1449 0 : m_fXScale = rValue.toFloat();
1450 0 : else if (rKey == "yalign")
1451 0 : m_fYAlign = rValue.toFloat();
1452 0 : else if (rKey == "yscale")
1453 0 : m_fYScale = rValue.toFloat();
1454 : else
1455 0 : return VclBin::set_property(rKey, rValue);
1456 0 : return true;
1457 : }
1458 :
1459 0 : const Window *VclExpander::get_child() const
1460 : {
1461 0 : const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1462 :
1463 : assert(pWindowImpl->mpFirstChild == &m_aDisclosureButton);
1464 :
1465 0 : return pWindowImpl->mpFirstChild->GetWindow(WINDOW_NEXT);
1466 : }
1467 :
1468 0 : Window *VclExpander::get_child()
1469 : {
1470 0 : return const_cast<Window*>(const_cast<const VclExpander*>(this)->get_child());
1471 : }
1472 :
1473 0 : Size VclExpander::calculateRequisition() const
1474 : {
1475 0 : Size aRet(0, 0);
1476 :
1477 0 : WindowImpl* pWindowImpl = ImplGetWindowImpl();
1478 :
1479 0 : const Window *pChild = get_child();
1480 0 : const Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
1481 :
1482 0 : if (pChild && pChild->IsVisible() && m_aDisclosureButton.IsChecked())
1483 0 : aRet = getLayoutRequisition(*pChild);
1484 :
1485 0 : Size aExpanderSize = getLayoutRequisition(m_aDisclosureButton);
1486 :
1487 0 : if (pLabel && pLabel->IsVisible())
1488 : {
1489 0 : Size aLabelSize = getLayoutRequisition(*pLabel);
1490 0 : aExpanderSize.Height() = std::max(aExpanderSize.Height(), aLabelSize.Height());
1491 0 : aExpanderSize.Width() += aLabelSize.Width();
1492 : }
1493 :
1494 0 : aRet.Height() += aExpanderSize.Height();
1495 0 : aRet.Width() = std::max(aExpanderSize.Width(), aRet.Width());
1496 :
1497 : const FrameStyle &rFrameStyle =
1498 0 : GetSettings().GetStyleSettings().GetFrameStyle();
1499 0 : aRet.Width() += rFrameStyle.left + rFrameStyle.right;
1500 0 : aRet.Height() += rFrameStyle.top + rFrameStyle.bottom;
1501 :
1502 0 : return aRet;
1503 : }
1504 :
1505 0 : void VclExpander::setAllocation(const Size &rAllocation)
1506 : {
1507 : const FrameStyle &rFrameStyle =
1508 0 : GetSettings().GetStyleSettings().GetFrameStyle();
1509 0 : Size aAllocation(rAllocation.Width() - rFrameStyle.left - rFrameStyle.right,
1510 0 : rAllocation.Height() - rFrameStyle.top - rFrameStyle.bottom);
1511 0 : Point aChildPos(rFrameStyle.left, rFrameStyle.top);
1512 :
1513 0 : WindowImpl* pWindowImpl = ImplGetWindowImpl();
1514 :
1515 : //The label widget is the last (of two) children
1516 0 : Window *pChild = get_child();
1517 0 : Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
1518 :
1519 0 : Size aButtonSize = getLayoutRequisition(m_aDisclosureButton);
1520 0 : Size aLabelSize;
1521 0 : Size aExpanderSize = aButtonSize;
1522 0 : if (pLabel && pLabel->IsVisible())
1523 : {
1524 0 : aLabelSize = getLayoutRequisition(*pLabel);
1525 0 : aExpanderSize.Height() = std::max(aExpanderSize.Height(), aLabelSize.Height());
1526 0 : aExpanderSize.Width() += aLabelSize.Width();
1527 : }
1528 :
1529 0 : aExpanderSize.Height() = std::min(aExpanderSize.Height(), aAllocation.Height());
1530 0 : aExpanderSize.Width() = std::min(aExpanderSize.Width(), aAllocation.Width());
1531 :
1532 0 : aButtonSize.Height() = std::min(aButtonSize.Height(), aExpanderSize.Height());
1533 0 : aButtonSize.Width() = std::min(aButtonSize.Width(), aExpanderSize.Width());
1534 :
1535 0 : long nExtraExpanderHeight = aExpanderSize.Height() - aButtonSize.Height();
1536 0 : Point aButtonPos(aChildPos.X(), aChildPos.Y() + nExtraExpanderHeight/2);
1537 0 : setLayoutAllocation(m_aDisclosureButton, aButtonPos, aButtonSize);
1538 :
1539 0 : if (pLabel && pLabel->IsVisible())
1540 : {
1541 0 : aLabelSize.Height() = std::min(aLabelSize.Height(), aExpanderSize.Height());
1542 0 : aLabelSize.Width() = std::min(aLabelSize.Width(),
1543 0 : aExpanderSize.Width() - aButtonSize.Width());
1544 :
1545 0 : long nExtraLabelHeight = aExpanderSize.Height() - aLabelSize.Height();
1546 0 : Point aLabelPos(aChildPos.X() + aButtonSize.Width(), aChildPos.Y() + nExtraLabelHeight/2);
1547 0 : setLayoutAllocation(*pLabel, aLabelPos, aLabelSize);
1548 : }
1549 :
1550 0 : aAllocation.Height() -= aExpanderSize.Height();
1551 0 : aChildPos.Y() += aExpanderSize.Height();
1552 :
1553 0 : if (pChild && pChild->IsVisible())
1554 : {
1555 0 : if (!m_aDisclosureButton.IsChecked())
1556 0 : aAllocation = Size();
1557 0 : setLayoutAllocation(*pChild, aChildPos, aAllocation);
1558 : }
1559 0 : }
1560 :
1561 0 : bool VclExpander::set_property(const OString &rKey, const OString &rValue)
1562 : {
1563 0 : if (rKey == "expanded")
1564 0 : set_expanded(toBool(rValue));
1565 0 : else if (rKey == "resize-toplevel")
1566 0 : m_bResizeTopLevel = toBool(rValue);
1567 : else
1568 0 : return VclBin::set_property(rKey, rValue);
1569 0 : return true;
1570 : }
1571 :
1572 0 : void VclExpander::StateChanged(StateChangedType nType)
1573 : {
1574 0 : VclBin::StateChanged( nType );
1575 :
1576 0 : if (nType == STATE_CHANGE_INITSHOW)
1577 : {
1578 0 : Window *pChild = get_child();
1579 0 : if (pChild)
1580 0 : pChild->Show(m_aDisclosureButton.IsChecked());
1581 : }
1582 0 : }
1583 :
1584 0 : IMPL_LINK( VclExpander, ClickHdl, DisclosureButton*, pBtn )
1585 : {
1586 0 : Window *pChild = get_child();
1587 0 : if (pChild)
1588 : {
1589 0 : pChild->Show(pBtn->IsChecked());
1590 0 : queue_resize();
1591 0 : Dialog* pResizeDialog = m_bResizeTopLevel ? GetParentDialog() : NULL;
1592 0 : if (pResizeDialog)
1593 0 : pResizeDialog->setOptimalLayoutSize();
1594 : }
1595 0 : maExpandedHdl.Call(this);
1596 0 : return 0;
1597 : }
1598 :
1599 0 : VclScrolledWindow::VclScrolledWindow(Window *pParent, WinBits nStyle)
1600 : : VclBin(pParent, nStyle)
1601 : , m_bUserManagedScrolling(false)
1602 : , m_aVScroll(this, WB_HIDE | WB_VERT)
1603 : , m_aHScroll(this, WB_HIDE | WB_HORZ)
1604 0 : , m_aScrollBarBox(this, WB_HIDE)
1605 : {
1606 0 : SetType(WINDOW_SCROLLWINDOW);
1607 :
1608 0 : Link aLink( LINK( this, VclScrolledWindow, ScrollBarHdl ) );
1609 0 : m_aVScroll.SetScrollHdl(aLink);
1610 0 : m_aHScroll.SetScrollHdl(aLink);
1611 0 : }
1612 :
1613 0 : IMPL_LINK_NOARG(VclScrolledWindow, ScrollBarHdl)
1614 : {
1615 0 : Window *pChild = get_child();
1616 0 : if (!pChild)
1617 0 : return 1;
1618 :
1619 0 : Point aWinPos;
1620 :
1621 0 : if (m_aHScroll.IsVisible())
1622 : {
1623 0 : aWinPos.X() = -m_aHScroll.GetThumbPos();
1624 : }
1625 :
1626 0 : if (m_aVScroll.IsVisible())
1627 : {
1628 0 : aWinPos.Y() = -m_aVScroll.GetThumbPos();
1629 : }
1630 :
1631 0 : pChild->SetPosPixel(aWinPos);
1632 :
1633 0 : return 1;
1634 : }
1635 :
1636 0 : const Window *VclScrolledWindow::get_child() const
1637 : {
1638 : assert(GetChildCount() == 4);
1639 0 : const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1640 0 : return pWindowImpl->mpLastChild;
1641 : }
1642 :
1643 0 : Window *VclScrolledWindow::get_child()
1644 : {
1645 0 : return const_cast<Window*>(const_cast<const VclScrolledWindow*>(this)->get_child());
1646 : }
1647 :
1648 0 : Size VclScrolledWindow::calculateRequisition() const
1649 : {
1650 0 : Size aRet(0, 0);
1651 :
1652 0 : const Window *pChild = get_child();
1653 0 : if (pChild && pChild->IsVisible())
1654 0 : aRet = getLayoutRequisition(*pChild);
1655 :
1656 0 : if (GetStyle() & WB_VSCROLL)
1657 0 : aRet.Width() += getLayoutRequisition(m_aVScroll).Width();
1658 :
1659 0 : if (GetStyle() & WB_HSCROLL)
1660 0 : aRet.Height() += getLayoutRequisition(m_aHScroll).Height();
1661 :
1662 0 : return aRet;
1663 : }
1664 :
1665 0 : void VclScrolledWindow::InitScrollBars(const Size &rRequest)
1666 : {
1667 0 : const Window *pChild = get_child();
1668 0 : if (!pChild || !pChild->IsVisible())
1669 0 : return;
1670 :
1671 0 : Size aOutSize(getVisibleChildSize());
1672 :
1673 0 : if (m_aVScroll.IsVisible())
1674 : {
1675 0 : m_aVScroll.SetRangeMax(rRequest.Height());
1676 0 : m_aVScroll.SetVisibleSize(aOutSize.Height());
1677 0 : m_aVScroll.SetPageSize(16);
1678 : }
1679 :
1680 0 : if (m_aHScroll.IsVisible())
1681 : {
1682 0 : m_aHScroll.SetRangeMax(rRequest.Width());
1683 0 : m_aHScroll.SetVisibleSize(aOutSize.Width());
1684 0 : m_aHScroll.SetPageSize(16);
1685 : }
1686 : }
1687 :
1688 0 : void VclScrolledWindow::setAllocation(const Size &rAllocation)
1689 : {
1690 0 : Size aChildAllocation(rAllocation);
1691 0 : Size aChildReq;
1692 :
1693 0 : Window *pChild = get_child();
1694 0 : if (pChild && pChild->IsVisible())
1695 0 : aChildReq = getLayoutRequisition(*pChild);
1696 :
1697 0 : long nAvailHeight = rAllocation.Width();
1698 0 : long nAvailWidth = rAllocation.Width();
1699 : // vert. ScrollBar
1700 0 : if (GetStyle() & WB_AUTOVSCROLL)
1701 0 : m_aVScroll.Show(nAvailHeight < aChildReq.Height());
1702 :
1703 0 : if (m_aVScroll.IsVisible())
1704 0 : nAvailWidth -= getLayoutRequisition(m_aVScroll).Width();
1705 :
1706 : // horz. ScrollBar
1707 0 : if (GetStyle() & WB_AUTOHSCROLL)
1708 : {
1709 0 : m_aHScroll.Show(nAvailWidth < aChildReq.Width());
1710 0 : nAvailHeight -= getLayoutRequisition(m_aHScroll).Height();
1711 :
1712 0 : if (GetStyle() & WB_AUTOVSCROLL)
1713 0 : m_aVScroll.Show(nAvailHeight < aChildReq.Height());
1714 : }
1715 :
1716 0 : Size aInnerSize(aChildAllocation);
1717 0 : long nScrollBarWidth = 0, nScrollBarHeight = 0;
1718 :
1719 0 : if (m_aVScroll.IsVisible())
1720 : {
1721 0 : nScrollBarWidth = getLayoutRequisition(m_aVScroll).Width();
1722 0 : Point aScrollPos(rAllocation.Width() - nScrollBarWidth, 0);
1723 0 : Size aScrollSize(nScrollBarWidth, rAllocation.Height());
1724 0 : setLayoutAllocation(m_aVScroll, aScrollPos, aScrollSize);
1725 0 : aChildAllocation.Width() -= nScrollBarWidth;
1726 0 : aInnerSize.Width() -= nScrollBarWidth;
1727 0 : aChildAllocation.Height() = aChildReq.Height();
1728 : }
1729 :
1730 0 : if (m_aHScroll.IsVisible())
1731 : {
1732 0 : nScrollBarHeight = getLayoutRequisition(m_aHScroll).Height();
1733 0 : Point aScrollPos(0, rAllocation.Height() - nScrollBarHeight);
1734 0 : Size aScrollSize(rAllocation.Width(), nScrollBarHeight);
1735 0 : setLayoutAllocation(m_aHScroll, aScrollPos, aScrollSize);
1736 0 : aChildAllocation.Height() -= nScrollBarHeight;
1737 0 : aInnerSize.Height() -= nScrollBarHeight;
1738 0 : aChildAllocation.Width() = aChildReq.Width();
1739 : }
1740 :
1741 0 : if (m_aVScroll.IsVisible() && m_aHScroll.IsVisible())
1742 : {
1743 0 : Point aBoxPos(aInnerSize.Width(), aInnerSize.Height());
1744 0 : m_aScrollBarBox.SetPosSizePixel(aBoxPos, Size(nScrollBarWidth, nScrollBarHeight));
1745 0 : m_aScrollBarBox.Show();
1746 : }
1747 : else
1748 : {
1749 0 : m_aScrollBarBox.Hide();
1750 : }
1751 :
1752 0 : if (pChild && pChild->IsVisible())
1753 : {
1754 0 : Point aChildPos(pChild->GetPosPixel());
1755 0 : if (!m_aHScroll.IsVisible())
1756 0 : aChildPos.X() = 0;
1757 0 : if (!m_aVScroll.IsVisible())
1758 0 : aChildPos.Y() = 0;
1759 0 : setLayoutAllocation(*pChild, aChildPos, aChildAllocation);
1760 : }
1761 :
1762 0 : if (!m_bUserManagedScrolling)
1763 0 : InitScrollBars(aChildReq);
1764 0 : }
1765 :
1766 0 : Size VclScrolledWindow::getVisibleChildSize() const
1767 : {
1768 0 : Size aRet(GetSizePixel());
1769 0 : if (m_aVScroll.IsVisible())
1770 0 : aRet.Width() -= m_aVScroll.GetSizePixel().Width();
1771 0 : if (m_aHScroll.IsVisible())
1772 0 : aRet.Height() -= m_aHScroll.GetSizePixel().Height();
1773 0 : return aRet;
1774 : }
1775 :
1776 0 : bool VclScrolledWindow::set_property(const OString &rKey, const OString &rValue)
1777 : {
1778 0 : bool bRet = VclBin::set_property(rKey, rValue);
1779 0 : m_aVScroll.Show((GetStyle() & WB_VSCROLL) != 0);
1780 0 : m_aHScroll.Show((GetStyle() & WB_HSCROLL) != 0);
1781 0 : return bRet;
1782 : }
1783 :
1784 0 : bool VclScrolledWindow::Notify(NotifyEvent& rNEvt)
1785 : {
1786 0 : bool nDone = false;
1787 0 : if ( rNEvt.GetType() == EVENT_COMMAND )
1788 : {
1789 0 : const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
1790 0 : if ( rCEvt.GetCommand() == COMMAND_WHEEL )
1791 : {
1792 0 : const CommandWheelData* pData = rCEvt.GetWheelData();
1793 0 : if( !pData->GetModifier() && ( pData->GetMode() == COMMAND_WHEEL_SCROLL ) )
1794 : {
1795 0 : nDone = HandleScrollCommand(rCEvt, &m_aHScroll, &m_aVScroll);
1796 : }
1797 : }
1798 : }
1799 :
1800 0 : return nDone || VclBin::Notify( rNEvt );
1801 : }
1802 :
1803 0 : const Window *VclEventBox::get_child() const
1804 : {
1805 0 : const WindowImpl* pWindowImpl = ImplGetWindowImpl();
1806 :
1807 : assert(pWindowImpl->mpFirstChild == &m_aEventBoxHelper);
1808 :
1809 0 : return pWindowImpl->mpFirstChild->GetWindow(WINDOW_NEXT);
1810 : }
1811 :
1812 0 : Window *VclEventBox::get_child()
1813 : {
1814 0 : return const_cast<Window*>(const_cast<const VclEventBox*>(this)->get_child());
1815 : }
1816 :
1817 0 : void VclEventBox::setAllocation(const Size& rAllocation)
1818 : {
1819 0 : Point aChildPos(0, 0);
1820 0 : for (Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
1821 : {
1822 0 : if (!pChild->IsVisible())
1823 0 : continue;
1824 0 : setLayoutAllocation(*pChild, aChildPos, rAllocation);
1825 : }
1826 0 : }
1827 :
1828 0 : Size VclEventBox::calculateRequisition() const
1829 : {
1830 0 : Size aRet(0, 0);
1831 :
1832 0 : for (const Window* pChild = get_child(); pChild;
1833 : pChild = pChild->GetWindow(WINDOW_NEXT))
1834 : {
1835 0 : if (!pChild->IsVisible())
1836 0 : continue;
1837 0 : Size aChildSize = getLayoutRequisition(*pChild);
1838 0 : aRet.Width() = std::max(aRet.Width(), aChildSize.Width());
1839 0 : aRet.Height() = std::max(aRet.Height(), aChildSize.Height());
1840 : }
1841 :
1842 0 : return aRet;
1843 : }
1844 :
1845 0 : void VclEventBox::Command(const CommandEvent&)
1846 : {
1847 : //discard events by default to block them reaching children
1848 0 : }
1849 :
1850 0 : void VclSizeGroup::trigger_queue_resize()
1851 : {
1852 : //sufficient to trigger one widget to trigger all of them
1853 0 : if (!m_aWindows.empty())
1854 : {
1855 0 : Window *pWindow = *m_aWindows.begin();
1856 0 : pWindow->queue_resize();
1857 : }
1858 0 : }
1859 :
1860 0 : void VclSizeGroup::set_ignore_hidden(bool bIgnoreHidden)
1861 : {
1862 0 : if (bIgnoreHidden != m_bIgnoreHidden)
1863 : {
1864 0 : m_bIgnoreHidden = bIgnoreHidden;
1865 0 : trigger_queue_resize();
1866 : }
1867 0 : }
1868 :
1869 0 : void VclSizeGroup::set_mode(VclSizeGroupMode eMode)
1870 : {
1871 0 : if (eMode != m_eMode)
1872 : {
1873 0 : m_eMode = eMode;
1874 0 : trigger_queue_resize();
1875 : }
1876 :
1877 0 : }
1878 :
1879 0 : bool VclSizeGroup::set_property(const OString &rKey, const OString &rValue)
1880 : {
1881 0 : if (rKey == "ignore-hidden")
1882 0 : set_ignore_hidden(toBool(rValue));
1883 0 : else if (rKey == "mode")
1884 : {
1885 0 : VclSizeGroupMode eMode = VCL_SIZE_GROUP_HORIZONTAL;
1886 0 : if (rValue.equals("none"))
1887 0 : eMode = VCL_SIZE_GROUP_NONE;
1888 0 : else if (rValue.equals("horizontal"))
1889 0 : eMode = VCL_SIZE_GROUP_HORIZONTAL;
1890 0 : else if (rValue.equals("vertical"))
1891 0 : eMode = VCL_SIZE_GROUP_VERTICAL;
1892 0 : else if (rValue.equals("both"))
1893 0 : eMode = VCL_SIZE_GROUP_BOTH;
1894 : else
1895 : {
1896 : SAL_WARN("vcl.layout", "unknown size group mode" << rValue.getStr());
1897 : }
1898 0 : set_mode(eMode);
1899 : }
1900 : else
1901 : {
1902 : SAL_INFO("vcl.layout", "unhandled property: " << rKey.getStr());
1903 0 : return false;
1904 : }
1905 0 : return true;
1906 : }
1907 :
1908 0 : void MessageDialog::create_owned_areas()
1909 : {
1910 0 : set_border_width(12);
1911 0 : m_pOwnedContentArea = new VclVBox(this, false, 24);
1912 0 : set_content_area(m_pOwnedContentArea);
1913 0 : m_pOwnedContentArea->Show();
1914 0 : m_pOwnedActionArea = new VclHButtonBox(m_pOwnedContentArea);
1915 0 : set_action_area(m_pOwnedActionArea);
1916 0 : m_pOwnedActionArea->Show();
1917 0 : }
1918 :
1919 0 : MessageDialog::MessageDialog(Window* pParent, WinBits nStyle)
1920 : : Dialog(pParent, nStyle)
1921 : , m_eButtonsType(VCL_BUTTONS_NONE)
1922 : , m_eMessageType(VCL_MESSAGE_INFO)
1923 : , m_pGrid(NULL)
1924 : , m_pImage(NULL)
1925 : , m_pPrimaryMessage(NULL)
1926 0 : , m_pSecondaryMessage(NULL)
1927 : {
1928 0 : SetType(WINDOW_MESSBOX);
1929 0 : create_owned_areas();
1930 0 : }
1931 :
1932 0 : MessageDialog::MessageDialog(Window* pParent,
1933 : const OUString &rMessage,
1934 : VclMessageType eMessageType,
1935 : VclButtonsType eButtonsType,
1936 : WinBits nStyle)
1937 : : Dialog(pParent, nStyle)
1938 : , m_eButtonsType(eButtonsType)
1939 : , m_eMessageType(eMessageType)
1940 : , m_pGrid(NULL)
1941 : , m_pImage(NULL)
1942 : , m_pPrimaryMessage(NULL)
1943 : , m_pSecondaryMessage(NULL)
1944 0 : , m_sPrimaryString(rMessage)
1945 : {
1946 0 : SetType(WINDOW_MESSBOX);
1947 0 : create_owned_areas();
1948 0 : }
1949 :
1950 0 : MessageDialog::MessageDialog(Window* pParent, const OString& rID, const OUString& rUIXMLDescription)
1951 : : Dialog(pParent, rID, rUIXMLDescription, WINDOW_MESSBOX)
1952 : , m_eButtonsType(VCL_BUTTONS_NONE)
1953 : , m_eMessageType(VCL_MESSAGE_INFO)
1954 : , m_pOwnedContentArea(NULL)
1955 : , m_pOwnedActionArea(NULL)
1956 : , m_pGrid(NULL)
1957 : , m_pImage(NULL)
1958 : , m_pPrimaryMessage(NULL)
1959 0 : , m_pSecondaryMessage(NULL)
1960 : {
1961 0 : }
1962 :
1963 0 : MessageDialog::~MessageDialog()
1964 : {
1965 0 : for (size_t i = 0; i < m_aOwnedButtons.size(); ++i)
1966 0 : delete m_aOwnedButtons[i];
1967 0 : delete m_pSecondaryMessage;
1968 0 : delete m_pPrimaryMessage;
1969 0 : delete m_pImage;
1970 0 : delete m_pGrid;
1971 0 : delete m_pOwnedActionArea;
1972 0 : delete m_pOwnedContentArea;
1973 0 : }
1974 :
1975 0 : void MessageDialog::response(short nResponseId)
1976 : {
1977 0 : EndDialog(nResponseId);
1978 0 : }
1979 :
1980 0 : IMPL_LINK(MessageDialog, ButtonHdl, Button *, pButton)
1981 : {
1982 0 : response(get_response(pButton));
1983 0 : return 0;
1984 : }
1985 :
1986 0 : short MessageDialog::get_response(const Window *pWindow) const
1987 : {
1988 0 : std::map<const Window*, short>::const_iterator aFind = m_aResponses.find(pWindow);
1989 0 : if (aFind != m_aResponses.end())
1990 0 : return aFind->second;
1991 0 : return m_pUIBuilder->get_response(pWindow);
1992 : }
1993 :
1994 0 : void MessageDialog::setButtonHandlers(VclButtonBox *pButtonBox)
1995 : {
1996 : assert(pButtonBox);
1997 0 : for (Window* pChild = pButtonBox->GetWindow(WINDOW_FIRSTCHILD); pChild;
1998 : pChild = pChild->GetWindow(WINDOW_NEXT))
1999 : {
2000 0 : switch (pChild->GetType())
2001 : {
2002 : case WINDOW_PUSHBUTTON:
2003 : {
2004 0 : PushButton* pButton = (PushButton*)pChild;
2005 0 : pButton->SetClickHdl(LINK(this, MessageDialog, ButtonHdl));
2006 0 : break;
2007 : }
2008 : //insist that the response ids match the default actions for those
2009 : //widgets, and leave their default handlers in place
2010 : case WINDOW_OKBUTTON:
2011 : assert(get_response(pChild) == RET_OK);
2012 0 : break;
2013 : case WINDOW_CANCELBUTTON:
2014 : assert(get_response(pChild) == RET_CANCEL);
2015 0 : break;
2016 : case WINDOW_HELPBUTTON:
2017 : assert(get_response(pChild) == RET_HELP);
2018 0 : break;
2019 : default:
2020 : SAL_WARN("vcl.layout", "The type of widget " <<
2021 : pChild->GetHelpId() << " is currently not handled");
2022 0 : break;
2023 : }
2024 : //The default is to stick the focus into the first widget
2025 : //that accepts it, and if that happens and it's a button
2026 : //then that becomes the new default button, so explicitly
2027 : //put the focus into the default button
2028 0 : if (pChild->GetStyle() & WB_DEFBUTTON)
2029 0 : pChild->GrabFocus();
2030 : }
2031 0 : }
2032 :
2033 0 : void MessageDialog::SetMessagesWidths(Window *pParent,
2034 : VclMultiLineEdit *pPrimaryMessage, VclMultiLineEdit *pSecondaryMessage)
2035 : {
2036 0 : if (pSecondaryMessage)
2037 : {
2038 : assert(pPrimaryMessage);
2039 0 : Font aFont = pParent->GetSettings().GetStyleSettings().GetLabelFont();
2040 0 : aFont.SetSize(Size(0, aFont.GetSize().Height() * 1.2));
2041 0 : aFont.SetWeight(WEIGHT_BOLD);
2042 0 : pPrimaryMessage->SetControlFont(aFont);
2043 0 : pPrimaryMessage->SetMaxTextWidth(pPrimaryMessage->approximate_char_width() * 44);
2044 0 : pSecondaryMessage->SetMaxTextWidth(pSecondaryMessage->approximate_char_width() * 60);
2045 : }
2046 : else
2047 0 : pPrimaryMessage->SetMaxTextWidth(pPrimaryMessage->approximate_char_width() * 60);
2048 0 : }
2049 :
2050 0 : short MessageDialog::Execute()
2051 : {
2052 0 : setDeferredProperties();
2053 :
2054 0 : if (!m_pGrid)
2055 : {
2056 0 : VclContainer *pContainer = get_content_area();
2057 : assert(pContainer);
2058 :
2059 0 : m_pGrid = new VclGrid(pContainer);
2060 0 : m_pGrid->reorderWithinParent(0);
2061 0 : m_pGrid->set_column_spacing(12);
2062 0 : m_pGrid->set_row_spacing(GetTextHeight());
2063 :
2064 0 : m_pImage = new FixedImage(m_pGrid, WB_CENTER | WB_VCENTER | WB_3DLOOK);
2065 0 : switch (m_eMessageType)
2066 : {
2067 : case VCL_MESSAGE_INFO:
2068 0 : m_pImage->SetImage(InfoBox::GetStandardImage());
2069 0 : break;
2070 : case VCL_MESSAGE_WARNING:
2071 0 : m_pImage->SetImage(WarningBox::GetStandardImage());
2072 0 : break;
2073 : case VCL_MESSAGE_QUESTION:
2074 0 : m_pImage->SetImage(QueryBox::GetStandardImage());
2075 0 : break;
2076 : case VCL_MESSAGE_ERROR:
2077 0 : m_pImage->SetImage(ErrorBox::GetStandardImage());
2078 0 : break;
2079 : }
2080 0 : m_pImage->set_grid_left_attach(0);
2081 0 : m_pImage->set_grid_top_attach(0);
2082 0 : m_pImage->set_valign(VCL_ALIGN_START);
2083 0 : m_pImage->Show();
2084 :
2085 0 : WinBits nWinStyle = WB_CLIPCHILDREN | WB_LEFT | WB_VCENTER | WB_NOLABEL | WB_NOTABSTOP;
2086 :
2087 0 : bool bHasSecondaryText = !m_sSecondaryString.isEmpty();
2088 :
2089 0 : m_pPrimaryMessage = new VclMultiLineEdit(m_pGrid, nWinStyle);
2090 0 : m_pPrimaryMessage->SetPaintTransparent(true);
2091 0 : m_pPrimaryMessage->EnableCursor(false);
2092 :
2093 0 : m_pPrimaryMessage->set_grid_left_attach(1);
2094 0 : m_pPrimaryMessage->set_grid_top_attach(0);
2095 0 : m_pPrimaryMessage->set_hexpand(true);
2096 0 : m_pPrimaryMessage->SetText(m_sPrimaryString);
2097 0 : m_pPrimaryMessage->Show(!m_sPrimaryString.isEmpty());
2098 :
2099 0 : m_pSecondaryMessage = new VclMultiLineEdit(m_pGrid, nWinStyle);
2100 0 : m_pSecondaryMessage->SetPaintTransparent(true);
2101 0 : m_pSecondaryMessage->EnableCursor(false);
2102 0 : m_pSecondaryMessage->set_grid_left_attach(1);
2103 0 : m_pSecondaryMessage->set_grid_top_attach(1);
2104 0 : m_pSecondaryMessage->set_hexpand(true);
2105 0 : m_pSecondaryMessage->SetText(m_sSecondaryString);
2106 0 : m_pSecondaryMessage->Show(bHasSecondaryText);
2107 :
2108 0 : MessageDialog::SetMessagesWidths(this, m_pPrimaryMessage, bHasSecondaryText ? m_pSecondaryMessage : NULL);
2109 :
2110 0 : VclButtonBox *pButtonBox = get_action_area();
2111 : assert(pButtonBox);
2112 :
2113 : PushButton *pBtn;
2114 0 : switch (m_eButtonsType)
2115 : {
2116 : case VCL_BUTTONS_NONE:
2117 0 : break;
2118 : case VCL_BUTTONS_OK:
2119 0 : pBtn = new OKButton(pButtonBox);
2120 0 : pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2121 0 : pBtn->Show();
2122 0 : m_aOwnedButtons.push_back(pBtn);
2123 0 : m_aResponses[pBtn] = RET_OK;
2124 0 : break;
2125 : case VCL_BUTTONS_CLOSE:
2126 0 : pBtn = new CloseButton(pButtonBox);
2127 0 : pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2128 0 : pBtn->Show();
2129 0 : m_aOwnedButtons.push_back(pBtn);
2130 0 : m_aResponses[pBtn] = RET_CLOSE;
2131 0 : break;
2132 : case VCL_BUTTONS_CANCEL:
2133 0 : pBtn = new CancelButton(pButtonBox);
2134 0 : pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2135 0 : m_aOwnedButtons.push_back(pBtn);
2136 0 : m_aResponses[pBtn] = RET_CANCEL;
2137 0 : break;
2138 : case VCL_BUTTONS_YES_NO:
2139 0 : pBtn = new PushButton(pButtonBox);
2140 0 : pBtn->SetText(Button::GetStandardText(BUTTON_YES));
2141 0 : pBtn->Show();
2142 0 : m_aOwnedButtons.push_back(pBtn);
2143 0 : m_aResponses[pBtn] = RET_YES;
2144 :
2145 0 : pBtn = new PushButton(pButtonBox);
2146 0 : pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2147 0 : pBtn->SetText(Button::GetStandardText(BUTTON_NO));
2148 0 : pBtn->Show();
2149 0 : m_aOwnedButtons.push_back(pBtn);
2150 0 : m_aResponses[pBtn] = RET_NO;
2151 0 : break;
2152 : case VCL_BUTTONS_OK_CANCEL:
2153 0 : pBtn = new OKButton(pButtonBox);
2154 0 : pBtn->Show();
2155 0 : m_aOwnedButtons.push_back(pBtn);
2156 0 : m_aResponses[pBtn] = RET_OK;
2157 :
2158 0 : pBtn = new CancelButton(pButtonBox);
2159 0 : pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
2160 0 : pBtn->Show();
2161 0 : m_aOwnedButtons.push_back(pBtn);
2162 0 : m_aResponses[pBtn] = RET_CANCEL;
2163 0 : break;
2164 : }
2165 0 : setButtonHandlers(pButtonBox);
2166 0 : pButtonBox->sort_native_button_order();
2167 0 : m_pGrid->Show();
2168 : }
2169 0 : return Dialog::Execute();
2170 : }
2171 :
2172 0 : OUString MessageDialog::get_primary_text() const
2173 : {
2174 0 : const_cast<MessageDialog*>(this)->setDeferredProperties();
2175 :
2176 0 : return m_sPrimaryString;
2177 : }
2178 :
2179 0 : OUString MessageDialog::get_secondary_text() const
2180 : {
2181 0 : const_cast<MessageDialog*>(this)->setDeferredProperties();
2182 :
2183 0 : return m_sSecondaryString;
2184 : }
2185 :
2186 0 : bool MessageDialog::set_property(const OString &rKey, const OString &rValue)
2187 : {
2188 0 : if (rKey == "text")
2189 0 : set_primary_text(OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
2190 0 : else if (rKey == "secondary-text")
2191 0 : set_secondary_text(OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
2192 0 : else if (rKey == "message-type")
2193 : {
2194 0 : VclMessageType eMode = VCL_MESSAGE_INFO;
2195 0 : if (rValue.equals("info"))
2196 0 : eMode = VCL_MESSAGE_INFO;
2197 0 : else if (rValue.equals("warning"))
2198 0 : eMode = VCL_MESSAGE_WARNING;
2199 0 : else if (rValue.equals("question"))
2200 0 : eMode = VCL_MESSAGE_QUESTION;
2201 0 : else if (rValue.equals("error"))
2202 0 : eMode = VCL_MESSAGE_ERROR;
2203 : else
2204 : {
2205 : SAL_WARN("vcl.layout", "unknown message type mode" << rValue.getStr());
2206 : }
2207 0 : m_eMessageType = eMode;
2208 : }
2209 0 : else if (rKey == "buttons")
2210 : {
2211 0 : VclButtonsType eMode = VCL_BUTTONS_NONE;
2212 0 : if (rValue.equals("none"))
2213 0 : eMode = VCL_BUTTONS_NONE;
2214 0 : else if (rValue.equals("ok"))
2215 0 : eMode = VCL_BUTTONS_OK;
2216 0 : else if (rValue.equals("cancel"))
2217 0 : eMode = VCL_BUTTONS_CANCEL;
2218 0 : else if (rValue.equals("close"))
2219 0 : eMode = VCL_BUTTONS_CLOSE;
2220 0 : else if (rValue.equals("yes-no"))
2221 0 : eMode = VCL_BUTTONS_YES_NO;
2222 0 : else if (rValue.equals("ok-cancel"))
2223 0 : eMode = VCL_BUTTONS_OK_CANCEL;
2224 : else
2225 : {
2226 : SAL_WARN("vcl.layout", "unknown buttons type mode" << rValue.getStr());
2227 : }
2228 0 : m_eButtonsType = eMode;
2229 : }
2230 : else
2231 0 : return Dialog::set_property(rKey, rValue);
2232 0 : return true;
2233 : }
2234 :
2235 0 : void MessageDialog::set_primary_text(const OUString &rPrimaryString)
2236 : {
2237 0 : m_sPrimaryString = rPrimaryString;
2238 0 : if (m_pPrimaryMessage)
2239 : {
2240 0 : m_pPrimaryMessage->SetText(m_sPrimaryString);
2241 0 : m_pPrimaryMessage->Show(!m_sPrimaryString.isEmpty());
2242 : }
2243 0 : }
2244 :
2245 0 : void MessageDialog::set_secondary_text(const OUString &rSecondaryString)
2246 : {
2247 0 : m_sSecondaryString = rSecondaryString;
2248 0 : if (m_pSecondaryMessage)
2249 : {
2250 0 : m_pSecondaryMessage->SetText(OUString("\n") + m_sSecondaryString);
2251 0 : m_pSecondaryMessage->Show(!m_sSecondaryString.isEmpty());
2252 : }
2253 0 : }
2254 :
2255 0 : Size getLegacyBestSizeForChildren(const Window &rWindow)
2256 : {
2257 0 : Rectangle aBounds;
2258 :
2259 0 : for (const Window* pChild = rWindow.GetWindow(WINDOW_FIRSTCHILD); pChild;
2260 : pChild = pChild->GetWindow(WINDOW_NEXT))
2261 : {
2262 0 : if (!pChild->IsVisible())
2263 0 : continue;
2264 :
2265 0 : Rectangle aChildBounds(pChild->GetPosPixel(), pChild->GetSizePixel());
2266 0 : aBounds.Union(aChildBounds);
2267 : }
2268 :
2269 0 : if (aBounds.IsEmpty())
2270 0 : return rWindow.GetSizePixel();
2271 :
2272 0 : Size aRet(aBounds.GetSize());
2273 0 : Point aTopLeft(aBounds.TopLeft());
2274 0 : aRet.Width() += aTopLeft.X()*2;
2275 0 : aRet.Height() += aTopLeft.Y()*2;
2276 :
2277 0 : return aRet;
2278 : }
2279 :
2280 0 : Window* getNonLayoutParent(Window *pWindow)
2281 : {
2282 0 : while (pWindow)
2283 : {
2284 0 : pWindow = pWindow->GetParent();
2285 0 : if (!pWindow || !isContainerWindow(*pWindow))
2286 0 : break;
2287 : }
2288 0 : return pWindow;
2289 : }
2290 :
2291 0 : Window* getNonLayoutRealParent(Window *pWindow)
2292 : {
2293 0 : while (pWindow)
2294 : {
2295 0 : pWindow = pWindow->ImplGetParent();
2296 0 : if (!pWindow || !isContainerWindow(*pWindow))
2297 0 : break;
2298 : }
2299 0 : return pWindow;
2300 : }
2301 :
2302 0 : bool isVisibleInLayout(const Window *pWindow)
2303 : {
2304 0 : bool bVisible = true;
2305 0 : while (bVisible)
2306 : {
2307 0 : bVisible = pWindow->IsVisible();
2308 0 : pWindow = pWindow->GetParent();
2309 0 : if (!pWindow || !isContainerWindow(*pWindow))
2310 0 : break;
2311 : }
2312 0 : return bVisible;
2313 : }
2314 :
2315 0 : bool isEnabledInLayout(const Window *pWindow)
2316 : {
2317 0 : bool bEnabled = true;
2318 0 : while (bEnabled)
2319 : {
2320 0 : bEnabled = pWindow->IsEnabled();
2321 0 : pWindow = pWindow->GetParent();
2322 0 : if (!pWindow || !isContainerWindow(*pWindow))
2323 0 : break;
2324 : }
2325 0 : return bEnabled;
2326 : }
2327 :
2328 0 : bool isLayoutEnabled(const Window *pWindow)
2329 : {
2330 : //Child is a container => we're layout enabled
2331 0 : const Window *pChild = pWindow ? pWindow->GetWindow(WINDOW_FIRSTCHILD) : NULL;
2332 0 : return pChild && isContainerWindow(*pChild) && !pChild->GetWindow(WINDOW_NEXT);
2333 : }
2334 :
2335 0 : bool isInitialLayout(const Window *pWindow)
2336 : {
2337 0 : Dialog *pParentDialog = pWindow ? pWindow->GetParentDialog() : NULL;
2338 0 : return pParentDialog && pParentDialog->isCalculatingInitialLayoutSize();
2339 3 : }
2340 :
2341 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|