LCOV - code coverage report
Current view: top level - vcl/source/window - layout.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 434 1335 32.5 %
Date: 2014-11-03 Functions: 33 117 28.2 %
Legend: Lines: hit not hit

          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       11160 : VclContainer::VclContainer(vcl::Window *pParent, WinBits nStyle)
      19             :     : Window(WINDOW_CONTAINER)
      20       11160 :     , m_bLayoutDirty(true)
      21             : {
      22       11160 :     ImplInit(pParent, nStyle, NULL);
      23       11160 :     EnableChildTransparentMode();
      24       11160 :     SetPaintTransparent(true);
      25       11160 :     SetBackground();
      26       11160 : }
      27             : 
      28           6 : sal_uInt16 VclContainer::getDefaultAccessibleRole() const
      29             : {
      30           6 :     return com::sun::star::accessibility::AccessibleRole::PANEL;
      31             : }
      32             : 
      33       11992 : Size VclContainer::GetOptimalSize() const
      34             : {
      35       11992 :     return calculateRequisition();
      36             : }
      37             : 
      38       64747 : void VclContainer::setLayoutPosSize(vcl::Window &rWindow, const Point &rPos, const Size &rSize)
      39             : {
      40       64747 :     sal_Int32 nBorderWidth = rWindow.get_border_width();
      41       64747 :     sal_Int32 nLeft = rWindow.get_margin_left() + nBorderWidth;
      42       64747 :     sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
      43       64747 :     sal_Int32 nRight = rWindow.get_margin_right() + nBorderWidth;
      44       64747 :     sal_Int32 nBottom = rWindow.get_margin_bottom() + nBorderWidth;
      45       64747 :     Point aPos(rPos.X() + nLeft, rPos.Y() + nTop);
      46       64747 :     Size aSize(rSize.Width() - nLeft - nRight, rSize.Height() - nTop - nBottom);
      47       64747 :     rWindow.SetPosSizePixel(aPos, aSize);
      48       64747 : }
      49             : 
      50       64747 : void VclContainer::setLayoutAllocation(vcl::Window &rChild, const Point &rAllocPos, const Size &rChildAlloc)
      51             : {
      52       64747 :     VclAlign eHalign = rChild.get_halign();
      53       64747 :     VclAlign eValign = rChild.get_valign();
      54             : 
      55             :     //typical case
      56       64747 :     if (eHalign == VCL_ALIGN_FILL && eValign == VCL_ALIGN_FILL)
      57             :     {
      58       52264 :         setLayoutPosSize(rChild, rAllocPos, rChildAlloc);
      59      117011 :         return;
      60             :     }
      61             : 
      62       12483 :     Point aChildPos(rAllocPos);
      63       12483 :     Size aChildSize(rChildAlloc);
      64       12483 :     Size aChildPreferredSize(getLayoutRequisition(rChild));
      65             : 
      66       12483 :     switch (eHalign)
      67             :     {
      68             :         case VCL_ALIGN_FILL:
      69           0 :             break;
      70             :         case VCL_ALIGN_START:
      71        1478 :             if (aChildPreferredSize.Width() < rChildAlloc.Width())
      72           0 :                 aChildSize.Width() = aChildPreferredSize.Width();
      73        1478 :             break;
      74             :         case VCL_ALIGN_END:
      75        2195 :             if (aChildPreferredSize.Width() < rChildAlloc.Width())
      76         742 :                 aChildSize.Width() = aChildPreferredSize.Width();
      77        2195 :             aChildPos.X() += rChildAlloc.Width();
      78        2195 :             aChildPos.X() -= aChildSize.Width();
      79        2195 :             break;
      80             :         case VCL_ALIGN_CENTER:
      81        8810 :             if (aChildPreferredSize.Width() < aChildSize.Width())
      82           0 :                 aChildSize.Width() = aChildPreferredSize.Width();
      83        8810 :             aChildPos.X() += (rChildAlloc.Width() - aChildSize.Width()) / 2;
      84        8810 :             break;
      85             :     }
      86             : 
      87       12483 :     switch (eValign)
      88             :     {
      89             :         case VCL_ALIGN_FILL:
      90        5103 :             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        7380 :             if (aChildPreferredSize.Height() < aChildSize.Height())
     103        7380 :                 aChildSize.Height() = aChildPreferredSize.Height();
     104        7380 :             aChildPos.Y() += (rChildAlloc.Height() - aChildSize.Height()) / 2;
     105        7380 :             break;
     106             :     }
     107             : 
     108       12483 :     setLayoutPosSize(rChild, aChildPos, aChildSize);
     109             : }
     110             : 
     111      149127 : Size VclContainer::getLayoutRequisition(const vcl::Window &rWindow)
     112             : {
     113      149127 :     sal_Int32 nBorderWidth = rWindow.get_border_width();
     114      149127 :     sal_Int32 nLeft = rWindow.get_margin_left() + nBorderWidth;
     115      149127 :     sal_Int32 nTop = rWindow.get_margin_top() + nBorderWidth;
     116      149127 :     sal_Int32 nRight = rWindow.get_margin_right() + nBorderWidth;
     117      149127 :     sal_Int32 nBottom = rWindow.get_margin_bottom() + nBorderWidth;
     118      149127 :     Size aSize(rWindow.get_preferred_size());
     119      149127 :     return Size(aSize.Width() + nLeft + nRight, aSize.Height() + nTop + nBottom);
     120             : }
     121             : 
     122       23131 : void VclContainer::SetPosSizePixel(const Point& rAllocPos, const Size& rAllocation)
     123             : {
     124       23131 :     bool bSizeChanged = rAllocation != GetOutputSizePixel();
     125       23131 :     Window::SetPosSizePixel(rAllocPos, rAllocation);
     126       23131 :     if (m_bLayoutDirty || bSizeChanged)
     127             :     {
     128       21611 :         m_bLayoutDirty = false;
     129       21611 :         setAllocation(rAllocation);
     130             :     }
     131       23131 : }
     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      454522 : void VclContainer::queue_resize(StateChangedType eReason)
     161             : {
     162      454522 :     markLayoutDirty();
     163      454522 :     Window::queue_resize(eReason);
     164      454522 : }
     165             : 
     166       46024 : void VclBox::accumulateMaxes(const Size &rChildSize, Size &rSize) const
     167             : {
     168       46024 :     long nSecondaryChildDimension = getSecondaryDimension(rChildSize);
     169       46024 :     long nSecondaryBoxDimension = getSecondaryDimension(rSize);
     170       46024 :     setSecondaryDimension(rSize, std::max(nSecondaryChildDimension, nSecondaryBoxDimension));
     171             : 
     172       46024 :     long nPrimaryChildDimension = getPrimaryDimension(rChildSize);
     173       46024 :     long nPrimaryBoxDimension = getPrimaryDimension(rSize);
     174       46024 :     if (m_bHomogeneous)
     175           4 :         setPrimaryDimension(rSize, std::max(nPrimaryBoxDimension, nPrimaryChildDimension));
     176             :     else
     177       46020 :         setPrimaryDimension(rSize, nPrimaryBoxDimension + nPrimaryChildDimension);
     178       46024 : }
     179             : 
     180       20072 : Size VclBox::calculateRequisition() const
     181             : {
     182       20072 :     sal_uInt16 nVisibleChildren = 0;
     183             : 
     184       20072 :     Size aSize;
     185       68878 :     for (vcl::Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
     186             :     {
     187       48806 :         if (!pChild->IsVisible())
     188        2782 :             continue;
     189       46024 :         ++nVisibleChildren;
     190       46024 :         Size aChildSize = getLayoutRequisition(*pChild);
     191             : 
     192       46024 :         long nPrimaryDimension = getPrimaryDimension(aChildSize);
     193       46024 :         nPrimaryDimension += pChild->get_padding() * 2;
     194       46024 :         setPrimaryDimension(aChildSize, nPrimaryDimension);
     195             : 
     196       46024 :         accumulateMaxes(aChildSize, aSize);
     197             :     }
     198             : 
     199       20072 :     return finalizeMaxes(aSize, nVisibleChildren);
     200             : }
     201             : 
     202       19350 : void VclBox::setAllocation(const Size &rAllocation)
     203             : {
     204       19350 :     sal_uInt16 nVisibleChildren = 0, nExpandChildren = 0;
     205       73404 :     for (vcl::Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
     206             :     {
     207       54054 :         if (!pChild->IsVisible())
     208        4998 :             continue;
     209       49056 :         ++nVisibleChildren;
     210       49056 :         bool bExpand = getPrimaryDimensionChildExpand(*pChild);
     211       49056 :         if (bExpand)
     212        8892 :             ++nExpandChildren;
     213             :     }
     214             : 
     215       19350 :     if (!nVisibleChildren)
     216       19350 :         return;
     217             : 
     218       19350 :     long nAllocPrimaryDimension = getPrimaryDimension(rAllocation);
     219             : 
     220       19350 :     long nHomogeneousDimension = 0, nExtraSpace = 0;
     221       19350 :     if (m_bHomogeneous)
     222             :     {
     223           4 :         nHomogeneousDimension = ((nAllocPrimaryDimension -
     224           8 :             (nVisibleChildren - 1) * m_nSpacing)) / nVisibleChildren;
     225             :     }
     226       19346 :     else if (nExpandChildren)
     227             :     {
     228        8886 :         Size aRequisition = calculateRequisition();
     229        8886 :         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       58050 :     std::vector<vcl::Window*> aWindows[2];
     234       73404 :     for (vcl::Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
     235             :     {
     236       54054 :         if (!pChild->IsVisible())
     237        4998 :             continue;
     238             : 
     239       49056 :         sal_Int32 ePacking = pChild->get_pack_type();
     240       49056 :         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       19350 :     std::reverse(aWindows[VCL_PACK_END].begin(),aWindows[VCL_PACK_END].end());
     247             : 
     248       58050 :     for (sal_Int32 ePackType = VCL_PACK_START; ePackType <= VCL_PACK_END; ++ePackType)
     249             :     {
     250       38700 :         Point aPos(0, 0);
     251       38700 :         if (ePackType == VCL_PACK_END)
     252             :         {
     253       19350 :             long nPrimaryCoordinate = getPrimaryCoordinate(aPos);
     254       19350 :             setPrimaryCoordinate(aPos, nPrimaryCoordinate + nAllocPrimaryDimension);
     255             :         }
     256             : 
     257       87756 :         for (std::vector<vcl::Window*>::iterator aI = aWindows[ePackType].begin(), aEnd = aWindows[ePackType].end(); aI != aEnd; ++aI)
     258             :         {
     259       49056 :             vcl::Window *pChild = *aI;
     260             : 
     261       49056 :             long nPadding = pChild->get_padding();
     262             : 
     263       49056 :             Size aBoxSize;
     264       49056 :             if (m_bHomogeneous)
     265           8 :                 setPrimaryDimension(aBoxSize, nHomogeneousDimension);
     266             :             else
     267             :             {
     268       49048 :                 aBoxSize = getLayoutRequisition(*pChild);
     269       49048 :                 long nPrimaryDimension = getPrimaryDimension(aBoxSize);
     270       49048 :                 nPrimaryDimension += nPadding * 2;
     271       49048 :                 if (getPrimaryDimensionChildExpand(*pChild))
     272        8892 :                     nPrimaryDimension += nExtraSpace;
     273       49048 :                 setPrimaryDimension(aBoxSize, nPrimaryDimension);
     274             :             }
     275       49056 :             setSecondaryDimension(aBoxSize, getSecondaryDimension(rAllocation));
     276             : 
     277       49056 :             Point aChildPos(aPos);
     278       49056 :             Size aChildSize(aBoxSize);
     279       49056 :             long nPrimaryCoordinate = getPrimaryCoordinate(aPos);
     280             : 
     281       49056 :             bool bFill = pChild->get_fill();
     282       49056 :             if (bFill)
     283             :             {
     284             :                 setPrimaryDimension(aChildSize, std::max(static_cast<long>(1),
     285       49056 :                     getPrimaryDimension(aBoxSize) - nPadding * 2));
     286             : 
     287       49056 :                 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       49056 :             long nDiff = getPrimaryDimension(aBoxSize) + m_nSpacing;
     299       49056 :             if (ePackType == VCL_PACK_START)
     300       43114 :                 setPrimaryCoordinate(aPos, nPrimaryCoordinate + nDiff);
     301             :             else
     302             :             {
     303        5942 :                 setPrimaryCoordinate(aPos, nPrimaryCoordinate - nDiff);
     304        5942 :                 setPrimaryCoordinate(aChildPos, getPrimaryCoordinate(aChildPos) -
     305       11884 :                     getPrimaryDimension(aBoxSize));
     306             :             }
     307             : 
     308       49056 :             setLayoutAllocation(*pChild, aChildPos, aChildSize);
     309             :         }
     310       58050 :     }
     311             : }
     312             : 
     313       28994 : bool VclBox::set_property(const OString &rKey, const OString &rValue)
     314             : {
     315       28994 :     if (rKey == "spacing")
     316        8860 :         set_spacing(rValue.toInt32());
     317       20134 :     else if (rKey == "homogeneous")
     318           2 :         set_homogeneous(toBool(rValue));
     319             :     else
     320       20132 :         return VclContainer::set_property(rKey, rValue);
     321        8862 :     return true;
     322             : }
     323             : 
     324         150 : 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         150 :     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       20072 : Size VclBox::finalizeMaxes(const Size &rSize, sal_uInt16 nVisibleChildren) const
     339             : {
     340       20072 :     Size aRet;
     341             : 
     342       20072 :     if (nVisibleChildren)
     343             :     {
     344       20072 :         long nPrimaryDimension = getPrimaryDimension(rSize);
     345       20072 :         if (m_bHomogeneous)
     346           2 :             nPrimaryDimension *= nVisibleChildren;
     347       20072 :         setPrimaryDimension(aRet, nPrimaryDimension + m_nSpacing * (nVisibleChildren-1));
     348       20072 :         setSecondaryDimension(aRet, getSecondaryDimension(rSize));
     349             :     }
     350             : 
     351       20072 :     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 vcl::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 (vcl::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 vcl::Window*, const vcl::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 vcl::Window *pA, const vcl::Window *pB) const;
     702             : };
     703             : 
     704           0 : bool sortButtons::operator()(const vcl::Window *pA, const vcl::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<vcl::Window*> aChilds;
     739           0 :     for (vcl::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        7473 : VclGrid::array_type VclGrid::assembleGrid() const
     752             : {
     753        7473 :     ext_array_type A;
     754             : 
     755       40855 :     for (vcl::Window* pChild = GetWindow(WINDOW_FIRSTCHILD); pChild;
     756             :         pChild = pChild->GetWindow(WINDOW_NEXT))
     757             :     {
     758       33382 :         sal_Int32 nLeftAttach = pChild->get_grid_left_attach();
     759       33382 :         sal_Int32 nWidth = pChild->get_grid_width();
     760       33382 :         sal_Int32 nMaxXPos = nLeftAttach+nWidth-1;
     761             : 
     762       33382 :         sal_Int32 nTopAttach = pChild->get_grid_top_attach();
     763       33382 :         sal_Int32 nHeight = pChild->get_grid_height();
     764       33382 :         sal_Int32 nMaxYPos = nTopAttach+nHeight-1;
     765             : 
     766       33382 :         sal_Int32 nCurrentMaxXPos = A.shape()[0]-1;
     767       33382 :         sal_Int32 nCurrentMaxYPos = A.shape()[1]-1;
     768       33382 :         if (nMaxXPos > nCurrentMaxXPos || nMaxYPos > nCurrentMaxYPos)
     769             :         {
     770       25994 :             nCurrentMaxXPos = std::max(nMaxXPos, nCurrentMaxXPos);
     771       25994 :             nCurrentMaxYPos = std::max(nMaxYPos, nCurrentMaxYPos);
     772       25994 :             A.resize(boost::extents[nCurrentMaxXPos+1][nCurrentMaxYPos+1]);
     773             :         }
     774             : 
     775       33382 :         ExtendedGridEntry &rEntry = A[nLeftAttach][nTopAttach];
     776       33382 :         rEntry.pChild = pChild;
     777       33382 :         rEntry.nSpanWidth = nWidth;
     778       33382 :         rEntry.nSpanHeight = nHeight;
     779       33382 :         rEntry.x = nLeftAttach;
     780       33382 :         rEntry.y = nTopAttach;
     781             : 
     782       70458 :         for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
     783             :         {
     784       74152 :             for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
     785             :             {
     786       37076 :                 ExtendedGridEntry &rSpan = A[nLeftAttach+nSpanX][nTopAttach+nSpanY];
     787       37076 :                 rSpan.x = nLeftAttach;
     788       37076 :                 rSpan.y = nTopAttach;
     789             :             }
     790             :         }
     791             :     }
     792             : 
     793             :     //see if we have any empty rows/cols
     794        7473 :     sal_Int32 nMaxX = A.shape()[0];
     795        7473 :     sal_Int32 nMaxY = A.shape()[1];
     796             : 
     797       14946 :     std::vector<bool> aNonEmptyCols(nMaxX);
     798       14946 :     std::vector<bool> aNonEmptyRows(nMaxY);
     799             : 
     800       29365 :     for (sal_Int32 x = 0; x < nMaxX; ++x)
     801             :     {
     802       58968 :         for (sal_Int32 y = 0; y < nMaxY; ++y)
     803             :         {
     804       37076 :             const GridEntry &rEntry = A[x][y];
     805       37076 :             const vcl::Window *pChild = rEntry.pChild;
     806       37076 :             if (pChild && pChild->IsVisible())
     807             :             {
     808       33382 :                 aNonEmptyCols[x] = true;
     809       33382 :                 if (get_column_homogeneous())
     810             :                 {
     811       36464 :                     for (sal_Int32 nSpanX = 1; nSpanX < rEntry.nSpanWidth; ++nSpanX)
     812        3694 :                         aNonEmptyCols[x+nSpanX] = true;
     813             :                 }
     814       33382 :                 aNonEmptyRows[y] = true;
     815       33382 :                 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        7473 :     if (!get_column_homogeneous())
     825             :     {
     826             :         //reduce the spans of elements that span empty columns
     827         408 :         for (sal_Int32 x = 0; x < nMaxX; ++x)
     828             :         {
     829         204 :             std::set<ExtendedGridEntry*> candidates;
     830         816 :             for (sal_Int32 y = 0; y < nMaxY; ++y)
     831             :             {
     832         612 :                 if (aNonEmptyCols[x])
     833         612 :                     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         204 :             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         204 :         }
     853             :     }
     854             : 
     855        7473 :     if (!get_row_homogeneous())
     856             :     {
     857             :         //reduce the spans of elements that span empty rows
     858       22742 :         for (sal_Int32 y = 0; y < nMaxY; ++y)
     859             :         {
     860       15269 :             std::set<ExtendedGridEntry*> candidates;
     861       52345 :             for (sal_Int32 x = 0; x < nMaxX; ++x)
     862             :             {
     863       37076 :                 if (aNonEmptyRows[y])
     864       37076 :                     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       15269 :             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       15269 :         }
     884             :     }
     885             : 
     886        7473 :     sal_Int32 nNonEmptyCols = std::count(aNonEmptyCols.begin(), aNonEmptyCols.end(), true);
     887        7473 :     sal_Int32 nNonEmptyRows = std::count(aNonEmptyRows.begin(), aNonEmptyRows.end(), true);
     888             : 
     889             :     //make new grid without empty rows and columns
     890        7473 :     array_type B(boost::extents[nNonEmptyCols][nNonEmptyRows]);
     891       29365 :     for (sal_Int32 x = 0, x2 = 0; x < nMaxX; ++x)
     892             :     {
     893       21892 :         if (aNonEmptyCols[x] == false)
     894           0 :             continue;
     895       58968 :         for (sal_Int32 y = 0, y2 = 0; y < nMaxY; ++y)
     896             :         {
     897       37076 :             if (aNonEmptyRows[y] == false)
     898           0 :                 continue;
     899       37076 :             GridEntry &rEntry = A[x][y];
     900       37076 :             B[x2][y2++] = rEntry;
     901             :         }
     902       21892 :         ++x2;
     903             :     }
     904             : 
     905       14946 :     return B;
     906             : }
     907             : 
     908        7473 : bool VclGrid::isNullGrid(const array_type &A) const
     909             : {
     910        7473 :     sal_Int32 nMaxX = A.shape()[0];
     911        7473 :     sal_Int32 nMaxY = A.shape()[1];
     912             : 
     913        7473 :     if (!nMaxX || !nMaxY)
     914           0 :         return true;
     915        7473 :     return false;
     916             : }
     917             : 
     918        7473 : void VclGrid::calcMaxs(const array_type &A, std::vector<Value> &rWidths, std::vector<Value> &rHeights) const
     919             : {
     920        7473 :     sal_Int32 nMaxX = A.shape()[0];
     921        7473 :     sal_Int32 nMaxY = A.shape()[1];
     922             : 
     923        7473 :     rWidths.resize(nMaxX);
     924        7473 :     rHeights.resize(nMaxY);
     925             : 
     926             :     //first use the non spanning entries to set default width/heights
     927       29365 :     for (sal_Int32 x = 0; x < nMaxX; ++x)
     928             :     {
     929       58968 :         for (sal_Int32 y = 0; y < nMaxY; ++y)
     930             :         {
     931       37076 :             const GridEntry &rEntry = A[x][y];
     932       37076 :             const vcl::Window *pChild = rEntry.pChild;
     933       37076 :             if (!pChild || !pChild->IsVisible())
     934        3694 :                 continue;
     935             : 
     936       33382 :             sal_Int32 nWidth = rEntry.nSpanWidth;
     937       33382 :             sal_Int32 nHeight = rEntry.nSpanHeight;
     938             : 
     939       70458 :             for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
     940       37076 :                 rWidths[x+nSpanX].m_bExpand |= pChild->get_hexpand();
     941             : 
     942       66764 :             for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
     943       33382 :                 rHeights[y+nSpanY].m_bExpand |= pChild->get_vexpand();
     944             : 
     945       33382 :             if (nWidth == 1 || nHeight == 1)
     946             :             {
     947       33382 :                 Size aChildSize = getLayoutRequisition(*pChild);
     948       33382 :                 if (nWidth == 1)
     949       29688 :                     rWidths[x].m_nValue = std::max(rWidths[x].m_nValue, aChildSize.Width());
     950       33382 :                 if (nHeight == 1)
     951       33382 :                     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       29365 :     for (sal_Int32 x = 0; x < nMaxX; ++x)
     959             :     {
     960       58968 :         for (sal_Int32 y = 0; y < nMaxY; ++y)
     961             :         {
     962       37076 :             const GridEntry &rEntry = A[x][y];
     963       37076 :             const vcl::Window *pChild = rEntry.pChild;
     964       37076 :             if (!pChild || !pChild->IsVisible())
     965       37076 :                 continue;
     966             : 
     967       33382 :             sal_Int32 nWidth = rEntry.nSpanWidth;
     968       33382 :             sal_Int32 nHeight = rEntry.nSpanHeight;
     969             : 
     970       33382 :             if (nWidth == 1 && nHeight == 1)
     971       29688 :                 continue;
     972             : 
     973        3694 :             Size aChildSize = getLayoutRequisition(*pChild);
     974             : 
     975        3694 :             if (nWidth > 1)
     976             :             {
     977        3694 :                 sal_Int32 nExistingWidth = 0;
     978       11082 :                 for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
     979        7388 :                     nExistingWidth += rWidths[x+nSpanX].m_nValue;
     980             : 
     981        3694 :                 sal_Int32 nExtraWidth = aChildSize.Width() - nExistingWidth;
     982             : 
     983        3694 :                 if (nExtraWidth > 0)
     984             :                 {
     985           4 :                     bool bForceExpandAll = false;
     986           4 :                     sal_Int32 nExpandables = 0;
     987          12 :                     for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
     988           8 :                         if (rWidths[x+nSpanX].m_bExpand)
     989           0 :                             ++nExpandables;
     990           4 :                     if (nExpandables == 0)
     991             :                     {
     992           4 :                         nExpandables = nWidth;
     993           4 :                         bForceExpandAll = true;
     994             :                     }
     995             : 
     996          12 :                     for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
     997             :                     {
     998           8 :                         if (rWidths[x+nSpanX].m_bExpand || bForceExpandAll)
     999           8 :                             rWidths[x+nSpanX].m_nValue += nExtraWidth/nExpandables;
    1000             :                     }
    1001             :                 }
    1002             :             }
    1003             : 
    1004        3694 :             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        7473 : }
    1035             : 
    1036       10796 : bool compareValues(const VclGrid::Value &i, const VclGrid::Value &j)
    1037             : {
    1038       10796 :     return i.m_nValue < j.m_nValue;
    1039             : }
    1040             : 
    1041       10052 : VclGrid::Value accumulateValues(const VclGrid::Value &i, const VclGrid::Value &j)
    1042             : {
    1043       10052 :     VclGrid::Value aRet;
    1044       10052 :     aRet.m_nValue = i.m_nValue + j.m_nValue;
    1045       10052 :     aRet.m_bExpand = i.m_bExpand || j.m_bExpand;
    1046       10052 :     return aRet;
    1047             : }
    1048             : 
    1049        3067 : Size VclGrid::calculateRequisition() const
    1050             : {
    1051        3067 :     return calculateRequisitionForSpacings(get_row_spacing(), get_column_spacing());
    1052             : }
    1053             : 
    1054        5212 : Size VclGrid::calculateRequisitionForSpacings(sal_Int32 nRowSpacing, sal_Int32 nColSpacing) const
    1055             : {
    1056        5212 :     array_type A = assembleGrid();
    1057             : 
    1058        5212 :     if (isNullGrid(A))
    1059           0 :         return Size();
    1060             : 
    1061       10424 :     std::vector<Value> aWidths;
    1062       10424 :     std::vector<Value> aHeights;
    1063        5212 :     calcMaxs(A, aWidths, aHeights);
    1064             : 
    1065        5212 :     long nTotalWidth = 0;
    1066        5212 :     if (get_column_homogeneous())
    1067             :     {
    1068        5076 :         nTotalWidth = std::max_element(aWidths.begin(), aWidths.end(), compareValues)->m_nValue;
    1069        5076 :         nTotalWidth *= aWidths.size();
    1070             :     }
    1071             :     else
    1072             :     {
    1073         136 :         nTotalWidth = std::accumulate(aWidths.begin(), aWidths.end(), Value(), accumulateValues).m_nValue;
    1074             :     }
    1075             : 
    1076        5212 :     nTotalWidth += nColSpacing * (aWidths.size()-1);
    1077             : 
    1078        5212 :     long nTotalHeight = 0;
    1079        5212 :     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        5212 :         nTotalHeight = std::accumulate(aHeights.begin(), aHeights.end(), Value(), accumulateValues).m_nValue;
    1087             :     }
    1088             : 
    1089        5212 :     nTotalHeight += nRowSpacing * (aHeights.size()-1);
    1090             : 
    1091       10424 :     return Size(nTotalWidth, nTotalHeight);
    1092             : }
    1093             : 
    1094        2261 : void VclGrid::setAllocation(const Size& rAllocation)
    1095             : {
    1096        2261 :     array_type A = assembleGrid();
    1097             : 
    1098        2261 :     if (isNullGrid(A))
    1099        2261 :         return;
    1100             : 
    1101        2261 :     sal_Int32 nMaxX = A.shape()[0];
    1102        2261 :     sal_Int32 nMaxY = A.shape()[1];
    1103             : 
    1104        2261 :     Size aRequisition;
    1105        4522 :     std::vector<Value> aWidths(nMaxX);
    1106        4522 :     std::vector<Value> aHeights(nMaxY);
    1107        2261 :     if (!get_column_homogeneous() || !get_row_homogeneous())
    1108             :     {
    1109        2261 :         aRequisition = calculateRequisition();
    1110        2261 :         calcMaxs(A, aWidths, aHeights);
    1111             :     }
    1112             : 
    1113        2261 :     sal_Int32 nColSpacing(get_column_spacing());
    1114        2261 :     sal_Int32 nRowSpacing(get_row_spacing());
    1115             : 
    1116        2261 :     long nAvailableWidth = rAllocation.Width();
    1117        2261 :     if (nMaxX)
    1118        2261 :         nAvailableWidth -= nColSpacing * (nMaxX - 1);
    1119        2261 :     if (get_column_homogeneous())
    1120             :     {
    1121        8009 :         for (sal_Int32 x = 0; x < nMaxX; ++x)
    1122        5816 :             aWidths[x].m_nValue = nAvailableWidth/nMaxX;
    1123             :     }
    1124          68 :     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        2261 :     long nAvailableHeight = rAllocation.Height();
    1160        2261 :     if (nMaxY)
    1161        2261 :         nAvailableHeight -= nRowSpacing * (nMaxY - 1);
    1162        2261 :     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        2261 :     else if (rAllocation.Height() != aRequisition.Height())
    1168             :     {
    1169         715 :         sal_Int32 nExpandables = 0;
    1170        1430 :         for (sal_Int32 y = 0; y < nMaxY; ++y)
    1171         715 :             if (aHeights[y].m_bExpand)
    1172           0 :                 ++nExpandables;
    1173         715 :         long nExtraHeightForExpanders = nExpandables ? (rAllocation.Height() - aRequisition.Height()) / nExpandables : 0;
    1174             : 
    1175             :         //We don't fit and there is no volunteer to be shrunk
    1176         715 :         if (!nExpandables && rAllocation.Height() < aRequisition.Height())
    1177             :         {
    1178             :             //first reduce spacing
    1179        3575 :             while (nRowSpacing)
    1180             :             {
    1181        2145 :                 nRowSpacing /= 2;
    1182        2145 :                 aRequisition = calculateRequisitionForSpacings(nRowSpacing, nColSpacing);
    1183        2145 :                 if (aRequisition.Height() <= rAllocation.Height())
    1184           0 :                     break;
    1185             :             }
    1186             : 
    1187             :             //share out the remaining pain to everyone
    1188         715 :             long nExtraHeight = (rAllocation.Height() - aRequisition.Height()) / nMaxY;
    1189             : 
    1190        1430 :             for (sal_Int32 y = 0; y < nMaxY; ++y)
    1191         715 :                 aHeights[y].m_nValue += nExtraHeight;
    1192             :         }
    1193             : 
    1194         715 :         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        2261 :     Point aAllocPos(0, 0);
    1203        8145 :     for (sal_Int32 x = 0; x < nMaxX; ++x)
    1204             :     {
    1205       17816 :         for (sal_Int32 y = 0; y < nMaxY; ++y)
    1206             :         {
    1207       11932 :             GridEntry &rEntry = A[x][y];
    1208       11932 :             vcl::Window *pChild = rEntry.pChild;
    1209       11932 :             if (pChild)
    1210             :             {
    1211       10454 :                 Size aChildAlloc(0, 0);
    1212             : 
    1213       10454 :                 sal_Int32 nWidth = rEntry.nSpanWidth;
    1214       22386 :                 for (sal_Int32 nSpanX = 0; nSpanX < nWidth; ++nSpanX)
    1215       11932 :                     aChildAlloc.Width() += aWidths[x+nSpanX].m_nValue;
    1216       10454 :                 aChildAlloc.Width() += nColSpacing*(nWidth-1);
    1217             : 
    1218       10454 :                 sal_Int32 nHeight = rEntry.nSpanHeight;
    1219       20908 :                 for (sal_Int32 nSpanY = 0; nSpanY < nHeight; ++nSpanY)
    1220       10454 :                     aChildAlloc.Height() += aHeights[y+nSpanY].m_nValue;
    1221       10454 :                 aChildAlloc.Height() += nRowSpacing*(nHeight-1);
    1222             : 
    1223       10454 :                 setLayoutAllocation(*pChild, aAllocPos, aChildAlloc);
    1224             :             }
    1225       11932 :             aAllocPos.Y() += aHeights[y].m_nValue + nRowSpacing;
    1226             :         }
    1227        5884 :         aAllocPos.X() += aWidths[x].m_nValue + nColSpacing;
    1228        5884 :         aAllocPos.Y() = 0;
    1229        2261 :     }
    1230             : }
    1231             : 
    1232       76872 : bool toBool(const OString &rValue)
    1233             : {
    1234       76872 :     return (!rValue.isEmpty() && (rValue[0] == 't' || rValue[0] == 'T' || rValue[0] == '1'));
    1235             : }
    1236             : 
    1237        9792 : bool VclGrid::set_property(const OString &rKey, const OString &rValue)
    1238             : {
    1239        9792 :     if (rKey == "row-spacing")
    1240        1514 :         set_row_spacing(rValue.toInt32());
    1241        8278 :     else if (rKey == "column-spacing")
    1242        1480 :         set_column_spacing(rValue.toInt32());
    1243        6798 :     else if (rKey == "row-homogeneous")
    1244           0 :         set_row_homogeneous(toBool(rValue));
    1245        6798 :     else if (rKey == "column-homogeneous")
    1246        1480 :         set_column_homogeneous(toBool(rValue));
    1247        5318 :     else if (rKey == "n-rows")
    1248             :         /*nothing to do*/;
    1249             :     else
    1250        5318 :         return VclContainer::set_property(rKey, rValue);
    1251        4474 :     return true;
    1252             : }
    1253             : 
    1254           0 : void setGridAttach(vcl::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 vcl::Window *VclBin::get_child() const
    1263             : {
    1264           0 :     const WindowImpl* pWindowImpl = ImplGetWindowImpl();
    1265             : 
    1266           0 :     return pWindowImpl->mpFirstChild;
    1267             : }
    1268             : 
    1269           0 : vcl::Window *VclBin::get_child()
    1270             : {
    1271           0 :     return const_cast<vcl::Window*>(const_cast<const VclBin*>(this)->get_child());
    1272             : }
    1273             : 
    1274           0 : Size VclBin::calculateRequisition() const
    1275             : {
    1276           0 :     const vcl::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 :     vcl::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 vcl::Window *pChild = get_child();
    1296           0 :     const vcl::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 :     vcl::Window *pChild = get_child();
    1327           0 :     vcl::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 : IMPL_LINK(VclFrame, WindowEventListener, VclSimpleEvent*, pEvent)
    1344             : {
    1345           0 :     if (pEvent && pEvent->GetId() == VCLEVENT_OBJECT_DYING)
    1346           0 :         designate_label(NULL);
    1347           0 :     return 0;
    1348             : }
    1349             : 
    1350           0 : void VclFrame::designate_label(vcl::Window *pWindow)
    1351             : {
    1352             :     assert(!pWindow || pWindow->GetParent() == this);
    1353           0 :     if (m_pLabel)
    1354           0 :         m_pLabel->RemoveEventListener(LINK(this, VclFrame, WindowEventListener));
    1355           0 :     m_pLabel = pWindow;
    1356           0 :     if (m_pLabel)
    1357           0 :         m_pLabel->AddEventListener(LINK(this, VclFrame, WindowEventListener));
    1358           0 : }
    1359             : 
    1360           0 : const vcl::Window *VclFrame::get_label_widget() const
    1361             : {
    1362             :     assert(GetChildCount() == 2);
    1363           0 :     if (m_pLabel)
    1364           0 :         return m_pLabel;
    1365             :     //The label widget is normally the first (of two) children
    1366           0 :     const WindowImpl* pWindowImpl = ImplGetWindowImpl();
    1367           0 :     if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //no label exists
    1368           0 :         return NULL;
    1369           0 :     return pWindowImpl->mpFirstChild;
    1370             : }
    1371             : 
    1372           0 : vcl::Window *VclFrame::get_label_widget()
    1373             : {
    1374           0 :     return const_cast<vcl::Window*>(const_cast<const VclFrame*>(this)->get_label_widget());
    1375             : }
    1376             : 
    1377           0 : const vcl::Window *VclFrame::get_child() const
    1378             : {
    1379             :     assert(GetChildCount() == 2);
    1380             :     //The child widget is the normally the last (of two) children
    1381           0 :     const WindowImpl* pWindowImpl = ImplGetWindowImpl();
    1382           0 :     if (!m_pLabel)
    1383           0 :         return pWindowImpl->mpLastChild;
    1384           0 :     if (pWindowImpl->mpFirstChild == pWindowImpl->mpLastChild) //only label exists
    1385           0 :         return NULL;
    1386           0 :     return pWindowImpl->mpLastChild;
    1387             : }
    1388             : 
    1389           0 : vcl::Window *VclFrame::get_child()
    1390             : {
    1391           0 :     return const_cast<vcl::Window*>(const_cast<const VclFrame*>(this)->get_child());
    1392             : }
    1393             : 
    1394           0 : void VclFrame::set_label(const OUString &rLabel)
    1395             : {
    1396           0 :     vcl::Window *pLabel = get_label_widget();
    1397             :     assert(pLabel);
    1398           0 :     pLabel->SetText(rLabel);
    1399           0 : }
    1400             : 
    1401           0 : OUString VclFrame::get_label() const
    1402             : {
    1403           0 :     const vcl::Window *pLabel = get_label_widget();
    1404             :     assert(pLabel);
    1405           0 :     return pLabel->GetText();
    1406             : }
    1407             : 
    1408           0 : OUString VclFrame::getDefaultAccessibleName() const
    1409             : {
    1410           0 :     const vcl::Window *pLabel = get_label_widget();
    1411           0 :     if (pLabel)
    1412           0 :         return pLabel->GetAccessibleName();
    1413           0 :     return VclBin::getDefaultAccessibleName();
    1414             : }
    1415             : 
    1416           0 : Size VclAlignment::calculateRequisition() const
    1417             : {
    1418           0 :     Size aRet(m_nLeftPadding + m_nRightPadding,
    1419           0 :         m_nTopPadding + m_nBottomPadding);
    1420             : 
    1421           0 :     const vcl::Window *pChild = get_child();
    1422           0 :     if (pChild && pChild->IsVisible())
    1423             :     {
    1424           0 :         Size aChildSize = getLayoutRequisition(*pChild);
    1425           0 :         aRet.Width() += aChildSize.Width();
    1426           0 :         aRet.Height() += aChildSize.Height();
    1427             :     }
    1428             : 
    1429           0 :     return aRet;
    1430             : }
    1431             : 
    1432           0 : void VclAlignment::setAllocation(const Size &rAllocation)
    1433             : {
    1434           0 :     vcl::Window *pChild = get_child();
    1435           0 :     if (!pChild || !pChild->IsVisible())
    1436           0 :         return;
    1437             : 
    1438           0 :     Point aChildPos(m_nLeftPadding, m_nTopPadding);
    1439             : 
    1440           0 :     Size aAllocation;
    1441           0 :     aAllocation.Width() = rAllocation.Width() - (m_nLeftPadding + m_nRightPadding);
    1442           0 :     aAllocation.Height() = rAllocation.Height() - (m_nTopPadding + m_nBottomPadding);
    1443             : 
    1444           0 :     setLayoutAllocation(*pChild, aChildPos, aAllocation);
    1445             : }
    1446             : 
    1447           0 : bool VclAlignment::set_property(const OString &rKey, const OString &rValue)
    1448             : {
    1449           0 :     if (rKey == "bottom-padding")
    1450           0 :         m_nBottomPadding = rValue.toInt32();
    1451           0 :     else if (rKey == "left-padding")
    1452           0 :         m_nLeftPadding = rValue.toInt32();
    1453           0 :     else if (rKey == "right-padding")
    1454           0 :         m_nRightPadding = rValue.toInt32();
    1455           0 :     else if (rKey == "top-padding")
    1456           0 :         m_nTopPadding = rValue.toInt32();
    1457           0 :     else if (rKey == "xalign")
    1458           0 :         m_fXAlign = rValue.toFloat();
    1459           0 :     else if (rKey == "xscale")
    1460           0 :         m_fXScale = rValue.toFloat();
    1461           0 :     else if (rKey == "yalign")
    1462           0 :         m_fYAlign = rValue.toFloat();
    1463           0 :     else if (rKey == "yscale")
    1464           0 :         m_fYScale = rValue.toFloat();
    1465             :     else
    1466           0 :         return VclBin::set_property(rKey, rValue);
    1467           0 :     return true;
    1468             : }
    1469             : 
    1470           0 : const vcl::Window *VclExpander::get_child() const
    1471             : {
    1472           0 :     const WindowImpl* pWindowImpl = ImplGetWindowImpl();
    1473             : 
    1474             :     assert(pWindowImpl->mpFirstChild == m_pDisclosureButton.get());
    1475             : 
    1476           0 :     return pWindowImpl->mpFirstChild->GetWindow(WINDOW_NEXT);
    1477             : }
    1478             : 
    1479           0 : vcl::Window *VclExpander::get_child()
    1480             : {
    1481           0 :     return const_cast<vcl::Window*>(const_cast<const VclExpander*>(this)->get_child());
    1482             : }
    1483             : 
    1484           0 : Size VclExpander::calculateRequisition() const
    1485             : {
    1486           0 :     Size aRet(0, 0);
    1487             : 
    1488           0 :     WindowImpl* pWindowImpl = ImplGetWindowImpl();
    1489             : 
    1490           0 :     const vcl::Window *pChild = get_child();
    1491           0 :     const vcl::Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
    1492             : 
    1493           0 :     if (pChild && pChild->IsVisible() && m_pDisclosureButton->IsChecked())
    1494           0 :         aRet = getLayoutRequisition(*pChild);
    1495             : 
    1496           0 :     Size aExpanderSize = getLayoutRequisition(*m_pDisclosureButton.get());
    1497             : 
    1498           0 :     if (pLabel && pLabel->IsVisible())
    1499             :     {
    1500           0 :         Size aLabelSize = getLayoutRequisition(*pLabel);
    1501           0 :         aExpanderSize.Height() = std::max(aExpanderSize.Height(), aLabelSize.Height());
    1502           0 :         aExpanderSize.Width() += aLabelSize.Width();
    1503             :     }
    1504             : 
    1505           0 :     aRet.Height() += aExpanderSize.Height();
    1506           0 :     aRet.Width() = std::max(aExpanderSize.Width(), aRet.Width());
    1507             : 
    1508             :     const FrameStyle &rFrameStyle =
    1509           0 :         GetSettings().GetStyleSettings().GetFrameStyle();
    1510           0 :     aRet.Width() += rFrameStyle.left + rFrameStyle.right;
    1511           0 :     aRet.Height() += rFrameStyle.top + rFrameStyle.bottom;
    1512             : 
    1513           0 :     return aRet;
    1514             : }
    1515             : 
    1516           0 : void VclExpander::setAllocation(const Size &rAllocation)
    1517             : {
    1518             :     const FrameStyle &rFrameStyle =
    1519           0 :         GetSettings().GetStyleSettings().GetFrameStyle();
    1520           0 :     Size aAllocation(rAllocation.Width() - rFrameStyle.left - rFrameStyle.right,
    1521           0 :         rAllocation.Height() - rFrameStyle.top - rFrameStyle.bottom);
    1522           0 :     Point aChildPos(rFrameStyle.left, rFrameStyle.top);
    1523             : 
    1524           0 :     WindowImpl* pWindowImpl = ImplGetWindowImpl();
    1525             : 
    1526             :     //The label widget is the last (of two) children
    1527           0 :     vcl::Window *pChild = get_child();
    1528           0 :     vcl::Window *pLabel = pChild != pWindowImpl->mpLastChild ? pWindowImpl->mpLastChild : NULL;
    1529             : 
    1530           0 :     Size aButtonSize = getLayoutRequisition(*m_pDisclosureButton.get());
    1531           0 :     Size aLabelSize;
    1532           0 :     Size aExpanderSize = aButtonSize;
    1533           0 :     if (pLabel && pLabel->IsVisible())
    1534             :     {
    1535           0 :         aLabelSize = getLayoutRequisition(*pLabel);
    1536           0 :         aExpanderSize.Height() = std::max(aExpanderSize.Height(), aLabelSize.Height());
    1537           0 :         aExpanderSize.Width() += aLabelSize.Width();
    1538             :     }
    1539             : 
    1540           0 :     aExpanderSize.Height() = std::min(aExpanderSize.Height(), aAllocation.Height());
    1541           0 :     aExpanderSize.Width() = std::min(aExpanderSize.Width(), aAllocation.Width());
    1542             : 
    1543           0 :     aButtonSize.Height() = std::min(aButtonSize.Height(), aExpanderSize.Height());
    1544           0 :     aButtonSize.Width() = std::min(aButtonSize.Width(), aExpanderSize.Width());
    1545             : 
    1546           0 :     long nExtraExpanderHeight = aExpanderSize.Height() - aButtonSize.Height();
    1547           0 :     Point aButtonPos(aChildPos.X(), aChildPos.Y() + nExtraExpanderHeight/2);
    1548           0 :     setLayoutAllocation(*m_pDisclosureButton.get(), aButtonPos, aButtonSize);
    1549             : 
    1550           0 :     if (pLabel && pLabel->IsVisible())
    1551             :     {
    1552           0 :         aLabelSize.Height() = std::min(aLabelSize.Height(), aExpanderSize.Height());
    1553           0 :         aLabelSize.Width() = std::min(aLabelSize.Width(),
    1554           0 :             aExpanderSize.Width() - aButtonSize.Width());
    1555             : 
    1556           0 :         long nExtraLabelHeight = aExpanderSize.Height() - aLabelSize.Height();
    1557           0 :         Point aLabelPos(aChildPos.X() + aButtonSize.Width(), aChildPos.Y() + nExtraLabelHeight/2);
    1558           0 :         setLayoutAllocation(*pLabel, aLabelPos, aLabelSize);
    1559             :     }
    1560             : 
    1561           0 :     aAllocation.Height() -= aExpanderSize.Height();
    1562           0 :     aChildPos.Y() += aExpanderSize.Height();
    1563             : 
    1564           0 :     if (pChild && pChild->IsVisible())
    1565             :     {
    1566           0 :         if (!m_pDisclosureButton->IsChecked())
    1567           0 :             aAllocation = Size();
    1568           0 :         setLayoutAllocation(*pChild, aChildPos, aAllocation);
    1569             :     }
    1570           0 : }
    1571             : 
    1572           0 : bool VclExpander::set_property(const OString &rKey, const OString &rValue)
    1573             : {
    1574           0 :     if (rKey == "expanded")
    1575           0 :         set_expanded(toBool(rValue));
    1576           0 :     else if (rKey == "resize-toplevel")
    1577           0 :         m_bResizeTopLevel = toBool(rValue);
    1578             :     else
    1579           0 :         return VclBin::set_property(rKey, rValue);
    1580           0 :     return true;
    1581             : }
    1582             : 
    1583           0 : void VclExpander::StateChanged(StateChangedType nType)
    1584             : {
    1585           0 :     VclBin::StateChanged( nType );
    1586             : 
    1587           0 :     if (nType == StateChangedType::INITSHOW)
    1588             :     {
    1589           0 :         vcl::Window *pChild = get_child();
    1590           0 :         if (pChild)
    1591           0 :             pChild->Show(m_pDisclosureButton->IsChecked());
    1592             :     }
    1593           0 : }
    1594             : 
    1595           0 : IMPL_LINK( VclExpander, ClickHdl, DisclosureButton*, pBtn )
    1596             : {
    1597           0 :     vcl::Window *pChild = get_child();
    1598           0 :     if (pChild)
    1599             :     {
    1600           0 :         pChild->Show(pBtn->IsChecked());
    1601           0 :         queue_resize();
    1602           0 :         Dialog* pResizeDialog = m_bResizeTopLevel ? GetParentDialog() : NULL;
    1603           0 :         if (pResizeDialog)
    1604           0 :             pResizeDialog->setOptimalLayoutSize();
    1605             :     }
    1606           0 :     maExpandedHdl.Call(this);
    1607           0 :     return 0;
    1608             : }
    1609             : 
    1610           0 : VclScrolledWindow::VclScrolledWindow(vcl::Window *pParent, WinBits nStyle)
    1611             :     : VclBin(pParent, nStyle)
    1612             :     , m_bUserManagedScrolling(false)
    1613           0 :     , m_pVScroll(new ScrollBar(this, WB_HIDE | WB_VERT))
    1614           0 :     , m_pHScroll(new ScrollBar(this, WB_HIDE | WB_HORZ))
    1615           0 :     , m_aScrollBarBox(this, WB_HIDE)
    1616             : {
    1617           0 :     SetType(WINDOW_SCROLLWINDOW);
    1618             : 
    1619           0 :     Link aLink( LINK( this, VclScrolledWindow, ScrollBarHdl ) );
    1620           0 :     m_pVScroll->SetScrollHdl(aLink);
    1621           0 :     m_pHScroll->SetScrollHdl(aLink);
    1622           0 : }
    1623             : 
    1624           0 : IMPL_LINK_NOARG(VclScrolledWindow, ScrollBarHdl)
    1625             : {
    1626           0 :     vcl::Window *pChild = get_child();
    1627           0 :     if (!pChild)
    1628           0 :         return 1;
    1629             : 
    1630             :     assert(dynamic_cast<VclViewport*>(pChild) && "scrolledwindow child should be a Viewport");
    1631             : 
    1632           0 :     pChild = pChild->GetWindow(WINDOW_FIRSTCHILD);
    1633             : 
    1634           0 :     if (!pChild)
    1635           0 :         return 1;
    1636             : 
    1637           0 :     Point aWinPos;
    1638             : 
    1639           0 :     if (m_pHScroll->IsVisible())
    1640             :     {
    1641           0 :         aWinPos.X() = -m_pHScroll->GetThumbPos();
    1642             :     }
    1643             : 
    1644           0 :     if (m_pVScroll->IsVisible())
    1645             :     {
    1646           0 :         aWinPos.Y() = -m_pVScroll->GetThumbPos();
    1647             :     }
    1648             : 
    1649           0 :     pChild->SetPosPixel(aWinPos);
    1650             : 
    1651           0 :     return 1;
    1652             : }
    1653             : 
    1654           0 : const vcl::Window *VclScrolledWindow::get_child() const
    1655             : {
    1656             :     assert(GetChildCount() == 4);
    1657           0 :     const WindowImpl* pWindowImpl = ImplGetWindowImpl();
    1658           0 :     return pWindowImpl->mpLastChild;
    1659             : }
    1660             : 
    1661           0 : vcl::Window *VclScrolledWindow::get_child()
    1662             : {
    1663           0 :     return const_cast<vcl::Window*>(const_cast<const VclScrolledWindow*>(this)->get_child());
    1664             : }
    1665             : 
    1666           0 : Size VclScrolledWindow::calculateRequisition() const
    1667             : {
    1668           0 :     Size aRet(0, 0);
    1669             : 
    1670           0 :     const vcl::Window *pChild = get_child();
    1671           0 :     if (pChild && pChild->IsVisible())
    1672           0 :         aRet = getLayoutRequisition(*pChild);
    1673             : 
    1674           0 :     if (GetStyle() & WB_VSCROLL)
    1675           0 :         aRet.Width() += getLayoutRequisition(*m_pVScroll.get()).Width();
    1676             : 
    1677           0 :     if (GetStyle() & WB_HSCROLL)
    1678           0 :         aRet.Height() += getLayoutRequisition(*m_pHScroll.get()).Height();
    1679             : 
    1680           0 :     return aRet;
    1681             : }
    1682             : 
    1683           0 : void VclScrolledWindow::InitScrollBars(const Size &rRequest)
    1684             : {
    1685           0 :     const vcl::Window *pChild = get_child();
    1686           0 :     if (!pChild || !pChild->IsVisible())
    1687           0 :         return;
    1688             : 
    1689           0 :     Size aOutSize(getVisibleChildSize());
    1690             : 
    1691           0 :     if (m_pVScroll->IsVisible())
    1692             :     {
    1693           0 :         m_pVScroll->SetRangeMax(rRequest.Height());
    1694           0 :         m_pVScroll->SetVisibleSize(aOutSize.Height());
    1695           0 :         m_pVScroll->SetPageSize(16);
    1696             :     }
    1697             : 
    1698           0 :     if (m_pHScroll->IsVisible())
    1699             :     {
    1700           0 :         m_pHScroll->SetRangeMax(rRequest.Width());
    1701           0 :         m_pHScroll->SetVisibleSize(aOutSize.Width());
    1702           0 :         m_pHScroll->SetPageSize(16);
    1703             :     }
    1704             : }
    1705             : 
    1706           0 : void VclScrolledWindow::setAllocation(const Size &rAllocation)
    1707             : {
    1708           0 :     Size aChildAllocation(rAllocation);
    1709           0 :     Size aChildReq;
    1710             : 
    1711           0 :     vcl::Window *pChild = get_child();
    1712           0 :     if (pChild && pChild->IsVisible())
    1713           0 :         aChildReq = getLayoutRequisition(*pChild);
    1714             : 
    1715           0 :     long nAvailHeight = rAllocation.Height();
    1716           0 :     long nAvailWidth = rAllocation.Width();
    1717             :     // vert. ScrollBar
    1718           0 :     if (GetStyle() & WB_AUTOVSCROLL)
    1719             :     {
    1720           0 :         m_pVScroll->Show(nAvailHeight < aChildReq.Height());
    1721             :     }
    1722             : 
    1723           0 :     if (m_pVScroll->IsVisible())
    1724           0 :         nAvailWidth -= getLayoutRequisition(*m_pVScroll.get()).Width();
    1725             : 
    1726             :     // horz. ScrollBar
    1727           0 :     if (GetStyle() & WB_AUTOHSCROLL)
    1728             :     {
    1729           0 :         bool bShowHScroll = nAvailWidth < aChildReq.Width();
    1730           0 :         m_pHScroll->Show(bShowHScroll);
    1731             : 
    1732           0 :         if (bShowHScroll)
    1733           0 :             nAvailHeight -= getLayoutRequisition(*m_pHScroll.get()).Height();
    1734             : 
    1735           0 :         if (GetStyle() & WB_AUTOVSCROLL)
    1736           0 :             m_pVScroll->Show(nAvailHeight < aChildReq.Height());
    1737             :     }
    1738             : 
    1739           0 :     Size aInnerSize(aChildAllocation);
    1740           0 :     long nScrollBarWidth = 0, nScrollBarHeight = 0;
    1741             : 
    1742           0 :     if (m_pVScroll->IsVisible())
    1743             :     {
    1744           0 :         nScrollBarWidth = getLayoutRequisition(*m_pVScroll.get()).Width();
    1745           0 :         Point aScrollPos(rAllocation.Width() - nScrollBarWidth, 0);
    1746           0 :         Size aScrollSize(nScrollBarWidth, rAllocation.Height());
    1747           0 :         setLayoutAllocation(*m_pVScroll.get(), aScrollPos, aScrollSize);
    1748           0 :         aChildAllocation.Width() -= nScrollBarWidth;
    1749           0 :         aInnerSize.Width() -= nScrollBarWidth;
    1750           0 :         aChildAllocation.Height() = aChildReq.Height();
    1751             :     }
    1752             : 
    1753           0 :     if (m_pHScroll->IsVisible())
    1754             :     {
    1755           0 :         nScrollBarHeight = getLayoutRequisition(*m_pHScroll.get()).Height();
    1756           0 :         Point aScrollPos(0, rAllocation.Height() - nScrollBarHeight);
    1757           0 :         Size aScrollSize(rAllocation.Width(), nScrollBarHeight);
    1758           0 :         setLayoutAllocation(*m_pHScroll.get(), aScrollPos, aScrollSize);
    1759           0 :         aChildAllocation.Height() -= nScrollBarHeight;
    1760           0 :         aInnerSize.Height() -= nScrollBarHeight;
    1761           0 :         aChildAllocation.Width() = aChildReq.Width();
    1762             :     }
    1763             : 
    1764           0 :     if (m_pVScroll->IsVisible() && m_pHScroll->IsVisible())
    1765             :     {
    1766           0 :         Point aBoxPos(aInnerSize.Width(), aInnerSize.Height());
    1767           0 :         m_aScrollBarBox.SetPosSizePixel(aBoxPos, Size(nScrollBarWidth, nScrollBarHeight));
    1768           0 :         m_aScrollBarBox.Show();
    1769             :     }
    1770             :     else
    1771             :     {
    1772           0 :         m_aScrollBarBox.Hide();
    1773             :     }
    1774             : 
    1775           0 :     if (pChild && pChild->IsVisible())
    1776             :     {
    1777             :         assert(dynamic_cast<VclViewport*>(pChild) && "scrolledwindow child should be a Viewport");
    1778           0 :         setLayoutAllocation(*pChild, Point(0, 0), aInnerSize);
    1779             :     }
    1780             : 
    1781           0 :     if (!m_bUserManagedScrolling)
    1782           0 :         InitScrollBars(aChildReq);
    1783           0 : }
    1784             : 
    1785           0 : Size VclScrolledWindow::getVisibleChildSize() const
    1786             : {
    1787           0 :     Size aRet(GetSizePixel());
    1788           0 :     if (m_pVScroll->IsVisible())
    1789           0 :         aRet.Width() -= m_pVScroll->GetSizePixel().Width();
    1790           0 :     if (m_pHScroll->IsVisible())
    1791           0 :         aRet.Height() -= m_pHScroll->GetSizePixel().Height();
    1792           0 :     return aRet;
    1793             : }
    1794             : 
    1795           0 : bool VclScrolledWindow::set_property(const OString &rKey, const OString &rValue)
    1796             : {
    1797           0 :     bool bRet = VclBin::set_property(rKey, rValue);
    1798           0 :     m_pVScroll->Show((GetStyle() & WB_VSCROLL) != 0);
    1799           0 :     m_pHScroll->Show((GetStyle() & WB_HSCROLL) != 0);
    1800           0 :     return bRet;
    1801             : }
    1802             : 
    1803           0 : bool VclScrolledWindow::Notify(NotifyEvent& rNEvt)
    1804             : {
    1805           0 :     bool nDone = false;
    1806           0 :     if ( rNEvt.GetType() == EVENT_COMMAND )
    1807             :     {
    1808           0 :         const CommandEvent& rCEvt = *rNEvt.GetCommandEvent();
    1809           0 :         if ( rCEvt.GetCommand() == COMMAND_WHEEL )
    1810             :         {
    1811           0 :             const CommandWheelData* pData = rCEvt.GetWheelData();
    1812           0 :             if( !pData->GetModifier() && ( pData->GetMode() == CommandWheelMode::SCROLL ) )
    1813             :             {
    1814           0 :                 nDone = HandleScrollCommand(rCEvt, m_pHScroll.get(), m_pVScroll.get());
    1815             :             }
    1816             :         }
    1817             :     }
    1818             : 
    1819           0 :     return nDone || VclBin::Notify( rNEvt );
    1820             : }
    1821             : 
    1822           0 : void VclViewport::setAllocation(const Size &rAllocation)
    1823             : {
    1824           0 :     vcl::Window *pChild = get_child();
    1825           0 :     if (pChild && pChild->IsVisible())
    1826             :     {
    1827           0 :         Size aReq(getLayoutRequisition(*pChild));
    1828           0 :         aReq.Width() = std::max(aReq.Width(), rAllocation.Width());
    1829           0 :         aReq.Height() = std::max(aReq.Height(), rAllocation.Height());
    1830           0 :         setLayoutAllocation(*pChild, Point(0, 0), aReq);
    1831             :     }
    1832           0 : }
    1833             : 
    1834           0 : const vcl::Window *VclEventBox::get_child() const
    1835             : {
    1836           0 :     const WindowImpl* pWindowImpl = ImplGetWindowImpl();
    1837             : 
    1838             :     assert(pWindowImpl->mpFirstChild == &m_aEventBoxHelper);
    1839             : 
    1840           0 :     return pWindowImpl->mpFirstChild->GetWindow(WINDOW_NEXT);
    1841             : }
    1842             : 
    1843           0 : vcl::Window *VclEventBox::get_child()
    1844             : {
    1845           0 :     return const_cast<vcl::Window*>(const_cast<const VclEventBox*>(this)->get_child());
    1846             : }
    1847             : 
    1848           0 : void VclEventBox::setAllocation(const Size& rAllocation)
    1849             : {
    1850           0 :     Point aChildPos(0, 0);
    1851           0 :     for (vcl::Window *pChild = GetWindow(WINDOW_FIRSTCHILD); pChild; pChild = pChild->GetWindow(WINDOW_NEXT))
    1852             :     {
    1853           0 :         if (!pChild->IsVisible())
    1854           0 :             continue;
    1855           0 :         setLayoutAllocation(*pChild, aChildPos, rAllocation);
    1856             :     }
    1857           0 : }
    1858             : 
    1859           0 : Size VclEventBox::calculateRequisition() const
    1860             : {
    1861           0 :     Size aRet(0, 0);
    1862             : 
    1863           0 :     for (const vcl::Window* pChild = get_child(); pChild;
    1864             :         pChild = pChild->GetWindow(WINDOW_NEXT))
    1865             :     {
    1866           0 :         if (!pChild->IsVisible())
    1867           0 :             continue;
    1868           0 :         Size aChildSize = getLayoutRequisition(*pChild);
    1869           0 :         aRet.Width() = std::max(aRet.Width(), aChildSize.Width());
    1870           0 :         aRet.Height() = std::max(aRet.Height(), aChildSize.Height());
    1871             :     }
    1872             : 
    1873           0 :     return aRet;
    1874             : }
    1875             : 
    1876           0 : void VclEventBox::Command(const CommandEvent&)
    1877             : {
    1878             :     //discard events by default to block them reaching children
    1879           0 : }
    1880             : 
    1881         738 : void VclSizeGroup::trigger_queue_resize()
    1882             : {
    1883             :     //sufficient to trigger one widget to trigger all of them
    1884         738 :     if (!m_aWindows.empty())
    1885             :     {
    1886           0 :         vcl::Window *pWindow = *m_aWindows.begin();
    1887           0 :         pWindow->queue_resize();
    1888             :     }
    1889         738 : }
    1890             : 
    1891           0 : void VclSizeGroup::set_ignore_hidden(bool bIgnoreHidden)
    1892             : {
    1893           0 :     if (bIgnoreHidden != m_bIgnoreHidden)
    1894             :     {
    1895           0 :         m_bIgnoreHidden = bIgnoreHidden;
    1896           0 :         trigger_queue_resize();
    1897             :     }
    1898           0 : }
    1899             : 
    1900         738 : void VclSizeGroup::set_mode(VclSizeGroupMode eMode)
    1901             : {
    1902         738 :     if (eMode != m_eMode)
    1903             :     {
    1904         738 :         m_eMode = eMode;
    1905         738 :         trigger_queue_resize();
    1906             :     }
    1907             : 
    1908         738 : }
    1909             : 
    1910         738 : bool VclSizeGroup::set_property(const OString &rKey, const OString &rValue)
    1911             : {
    1912         738 :     if (rKey == "ignore-hidden")
    1913           0 :         set_ignore_hidden(toBool(rValue));
    1914         738 :     else if (rKey == "mode")
    1915             :     {
    1916         738 :         VclSizeGroupMode eMode = VCL_SIZE_GROUP_HORIZONTAL;
    1917         738 :         if (rValue.equals("none"))
    1918           0 :             eMode = VCL_SIZE_GROUP_NONE;
    1919         738 :         else if (rValue.equals("horizontal"))
    1920           0 :             eMode = VCL_SIZE_GROUP_HORIZONTAL;
    1921         738 :         else if (rValue.equals("vertical"))
    1922         738 :             eMode = VCL_SIZE_GROUP_VERTICAL;
    1923           0 :         else if (rValue.equals("both"))
    1924           0 :             eMode = VCL_SIZE_GROUP_BOTH;
    1925             :         else
    1926             :         {
    1927             :             SAL_WARN("vcl.layout", "unknown size group mode" << rValue.getStr());
    1928             :         }
    1929         738 :         set_mode(eMode);
    1930             :     }
    1931             :     else
    1932             :     {
    1933             :         SAL_INFO("vcl.layout", "unhandled property: " << rKey.getStr());
    1934           0 :         return false;
    1935             :     }
    1936         738 :     return true;
    1937             : }
    1938             : 
    1939           0 : void MessageDialog::create_owned_areas()
    1940             : {
    1941           0 :     set_border_width(12);
    1942           0 :     m_pOwnedContentArea = new VclVBox(this, false, 24);
    1943           0 :     set_content_area(m_pOwnedContentArea);
    1944           0 :     m_pOwnedContentArea->Show();
    1945           0 :     m_pOwnedActionArea = new VclHButtonBox(m_pOwnedContentArea);
    1946           0 :     set_action_area(m_pOwnedActionArea);
    1947           0 :     m_pOwnedActionArea->Show();
    1948           0 : }
    1949             : 
    1950           0 : MessageDialog::MessageDialog(vcl::Window* pParent, WinBits nStyle)
    1951             :     : Dialog(pParent, nStyle)
    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 :     SetType(WINDOW_MESSBOX);
    1962           0 : }
    1963             : 
    1964           0 : MessageDialog::MessageDialog(vcl::Window* pParent,
    1965             :     const OUString &rMessage,
    1966             :     VclMessageType eMessageType,
    1967             :     VclButtonsType eButtonsType,
    1968             :     WinBits nStyle)
    1969             :     : Dialog(pParent, nStyle)
    1970             :     , m_eButtonsType(eButtonsType)
    1971             :     , m_eMessageType(eMessageType)
    1972             :     , m_pGrid(NULL)
    1973             :     , m_pImage(NULL)
    1974             :     , m_pPrimaryMessage(NULL)
    1975             :     , m_pSecondaryMessage(NULL)
    1976           0 :     , m_sPrimaryString(rMessage)
    1977             : {
    1978           0 :     SetType(WINDOW_MESSBOX);
    1979           0 :     create_owned_areas();
    1980           0 : }
    1981             : 
    1982           0 : MessageDialog::MessageDialog(vcl::Window* pParent, const OString& rID, const OUString& rUIXMLDescription)
    1983             :     : Dialog(pParent, rID, rUIXMLDescription, WINDOW_MESSBOX)
    1984             :     , m_eButtonsType(VCL_BUTTONS_NONE)
    1985             :     , m_eMessageType(VCL_MESSAGE_INFO)
    1986             :     , m_pOwnedContentArea(NULL)
    1987             :     , m_pOwnedActionArea(NULL)
    1988             :     , m_pGrid(NULL)
    1989             :     , m_pImage(NULL)
    1990             :     , m_pPrimaryMessage(NULL)
    1991           0 :     , m_pSecondaryMessage(NULL)
    1992             : {
    1993           0 : }
    1994             : 
    1995           0 : MessageDialog::~MessageDialog()
    1996             : {
    1997           0 :     for (size_t i = 0; i < m_aOwnedButtons.size(); ++i)
    1998           0 :         delete m_aOwnedButtons[i];
    1999           0 :     delete m_pSecondaryMessage;
    2000           0 :     delete m_pPrimaryMessage;
    2001           0 :     delete m_pImage;
    2002           0 :     delete m_pGrid;
    2003           0 :     delete m_pOwnedActionArea;
    2004           0 :     delete m_pOwnedContentArea;
    2005           0 : }
    2006             : 
    2007           0 : void MessageDialog::response(short nResponseId)
    2008             : {
    2009           0 :     EndDialog(nResponseId);
    2010           0 : }
    2011             : 
    2012           0 : IMPL_LINK(MessageDialog, ButtonHdl, Button *, pButton)
    2013             : {
    2014           0 :     response(get_response(pButton));
    2015           0 :     return 0;
    2016             : }
    2017             : 
    2018           0 : short MessageDialog::get_response(const vcl::Window *pWindow) const
    2019             : {
    2020           0 :     std::map<const vcl::Window*, short>::const_iterator aFind = m_aResponses.find(pWindow);
    2021           0 :     if (aFind != m_aResponses.end())
    2022           0 :         return aFind->second;
    2023           0 :     if (!m_pUIBuilder)
    2024           0 :         return RET_CANCEL;
    2025           0 :     return m_pUIBuilder->get_response(pWindow);
    2026             : }
    2027             : 
    2028           0 : void MessageDialog::setButtonHandlers(VclButtonBox *pButtonBox)
    2029             : {
    2030             :     assert(pButtonBox);
    2031           0 :     for (vcl::Window* pChild = pButtonBox->GetWindow(WINDOW_FIRSTCHILD); pChild;
    2032             :         pChild = pChild->GetWindow(WINDOW_NEXT))
    2033             :     {
    2034           0 :         switch (pChild->GetType())
    2035             :         {
    2036             :             case WINDOW_PUSHBUTTON:
    2037             :             {
    2038           0 :                 PushButton* pButton = static_cast<PushButton*>(pChild);
    2039           0 :                 pButton->SetClickHdl(LINK(this, MessageDialog, ButtonHdl));
    2040           0 :                 break;
    2041             :             }
    2042             :             //insist that the response ids match the default actions for those
    2043             :             //widgets, and leave their default handlers in place
    2044             :             case WINDOW_OKBUTTON:
    2045             :                 assert(get_response(pChild) == RET_OK);
    2046           0 :                 break;
    2047             :             case WINDOW_CANCELBUTTON:
    2048             :                 assert(get_response(pChild) == RET_CANCEL);
    2049           0 :                 break;
    2050             :             case WINDOW_HELPBUTTON:
    2051             :                 assert(get_response(pChild) == RET_HELP);
    2052           0 :                 break;
    2053             :             default:
    2054             :                 SAL_WARN("vcl.layout", "The type of widget " <<
    2055             :                     pChild->GetHelpId() << " is currently not handled");
    2056           0 :                 break;
    2057             :         }
    2058             :         //The default is to stick the focus into the first widget
    2059             :         //that accepts it, and if that happens and it's a button
    2060             :         //then that becomes the new default button, so explicitly
    2061             :         //put the focus into the default button
    2062           0 :         if (pChild->GetStyle() & WB_DEFBUTTON)
    2063           0 :             pChild->GrabFocus();
    2064             :     }
    2065           0 : }
    2066             : 
    2067           0 : void MessageDialog::SetMessagesWidths(vcl::Window *pParent,
    2068             :     VclMultiLineEdit *pPrimaryMessage, VclMultiLineEdit *pSecondaryMessage)
    2069             : {
    2070           0 :     if (pSecondaryMessage)
    2071             :     {
    2072             :         assert(pPrimaryMessage);
    2073           0 :         vcl::Font aFont = pParent->GetSettings().GetStyleSettings().GetLabelFont();
    2074           0 :         aFont.SetSize(Size(0, aFont.GetSize().Height() * 1.2));
    2075           0 :         aFont.SetWeight(WEIGHT_BOLD);
    2076           0 :         pPrimaryMessage->SetControlFont(aFont);
    2077           0 :         pPrimaryMessage->SetMaxTextWidth(pPrimaryMessage->approximate_char_width() * 44);
    2078           0 :         pSecondaryMessage->SetMaxTextWidth(pSecondaryMessage->approximate_char_width() * 60);
    2079             :     }
    2080             :     else
    2081           0 :         pPrimaryMessage->SetMaxTextWidth(pPrimaryMessage->approximate_char_width() * 60);
    2082           0 : }
    2083             : 
    2084           0 : short MessageDialog::Execute()
    2085             : {
    2086           0 :     setDeferredProperties();
    2087             : 
    2088           0 :     if (!m_pGrid)
    2089             :     {
    2090           0 :         VclContainer *pContainer = get_content_area();
    2091             :         assert(pContainer);
    2092             : 
    2093           0 :         m_pGrid = new VclGrid(pContainer);
    2094           0 :         m_pGrid->reorderWithinParent(0);
    2095           0 :         m_pGrid->set_column_spacing(12);
    2096           0 :         m_pGrid->set_row_spacing(GetTextHeight());
    2097             : 
    2098           0 :         m_pImage = new FixedImage(m_pGrid, WB_CENTER | WB_VCENTER | WB_3DLOOK);
    2099           0 :         switch (m_eMessageType)
    2100             :         {
    2101             :             case VCL_MESSAGE_INFO:
    2102           0 :                 m_pImage->SetImage(InfoBox::GetStandardImage());
    2103           0 :                 break;
    2104             :             case VCL_MESSAGE_WARNING:
    2105           0 :                 m_pImage->SetImage(WarningBox::GetStandardImage());
    2106           0 :                 break;
    2107             :             case VCL_MESSAGE_QUESTION:
    2108           0 :                 m_pImage->SetImage(QueryBox::GetStandardImage());
    2109           0 :                 break;
    2110             :             case VCL_MESSAGE_ERROR:
    2111           0 :                 m_pImage->SetImage(ErrorBox::GetStandardImage());
    2112           0 :                 break;
    2113             :         }
    2114           0 :         m_pImage->set_grid_left_attach(0);
    2115           0 :         m_pImage->set_grid_top_attach(0);
    2116           0 :         m_pImage->set_valign(VCL_ALIGN_START);
    2117           0 :         m_pImage->Show();
    2118             : 
    2119           0 :         WinBits nWinStyle = WB_CLIPCHILDREN | WB_LEFT | WB_VCENTER | WB_NOLABEL | WB_NOTABSTOP;
    2120             : 
    2121           0 :         bool bHasSecondaryText = !m_sSecondaryString.isEmpty();
    2122             : 
    2123           0 :         m_pPrimaryMessage = new VclMultiLineEdit(m_pGrid, nWinStyle);
    2124           0 :         m_pPrimaryMessage->SetPaintTransparent(true);
    2125           0 :         m_pPrimaryMessage->EnableCursor(false);
    2126             : 
    2127           0 :         m_pPrimaryMessage->set_grid_left_attach(1);
    2128           0 :         m_pPrimaryMessage->set_grid_top_attach(0);
    2129           0 :         m_pPrimaryMessage->set_hexpand(true);
    2130           0 :         m_pPrimaryMessage->SetText(m_sPrimaryString);
    2131           0 :         m_pPrimaryMessage->Show(!m_sPrimaryString.isEmpty());
    2132             : 
    2133           0 :         m_pSecondaryMessage = new VclMultiLineEdit(m_pGrid, nWinStyle);
    2134           0 :         m_pSecondaryMessage->SetPaintTransparent(true);
    2135           0 :         m_pSecondaryMessage->EnableCursor(false);
    2136           0 :         m_pSecondaryMessage->set_grid_left_attach(1);
    2137           0 :         m_pSecondaryMessage->set_grid_top_attach(1);
    2138           0 :         m_pSecondaryMessage->set_hexpand(true);
    2139           0 :         m_pSecondaryMessage->SetText(m_sSecondaryString);
    2140           0 :         m_pSecondaryMessage->Show(bHasSecondaryText);
    2141             : 
    2142           0 :         MessageDialog::SetMessagesWidths(this, m_pPrimaryMessage, bHasSecondaryText ? m_pSecondaryMessage : NULL);
    2143             : 
    2144           0 :         VclButtonBox *pButtonBox = get_action_area();
    2145             :         assert(pButtonBox);
    2146             : 
    2147             :         PushButton *pBtn;
    2148           0 :         switch (m_eButtonsType)
    2149             :         {
    2150             :             case VCL_BUTTONS_NONE:
    2151           0 :                 break;
    2152             :             case VCL_BUTTONS_OK:
    2153           0 :                 pBtn = new OKButton(pButtonBox);
    2154           0 :                 pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
    2155           0 :                 pBtn->Show();
    2156           0 :                 m_aOwnedButtons.push_back(pBtn);
    2157           0 :                 m_aResponses[pBtn] = RET_OK;
    2158           0 :                 break;
    2159             :             case VCL_BUTTONS_CLOSE:
    2160           0 :                 pBtn = new CloseButton(pButtonBox);
    2161           0 :                 pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
    2162           0 :                 pBtn->Show();
    2163           0 :                 m_aOwnedButtons.push_back(pBtn);
    2164           0 :                 m_aResponses[pBtn] = RET_CLOSE;
    2165           0 :                 break;
    2166             :             case VCL_BUTTONS_CANCEL:
    2167           0 :                 pBtn = new CancelButton(pButtonBox);
    2168           0 :                 pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
    2169           0 :                 m_aOwnedButtons.push_back(pBtn);
    2170           0 :                 m_aResponses[pBtn] = RET_CANCEL;
    2171           0 :                 break;
    2172             :             case VCL_BUTTONS_YES_NO:
    2173           0 :                 pBtn = new PushButton(pButtonBox);
    2174           0 :                 pBtn->SetText(Button::GetStandardText(BUTTON_YES));
    2175           0 :                 pBtn->Show();
    2176           0 :                 m_aOwnedButtons.push_back(pBtn);
    2177           0 :                 m_aResponses[pBtn] = RET_YES;
    2178             : 
    2179           0 :                 pBtn = new PushButton(pButtonBox);
    2180           0 :                 pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
    2181           0 :                 pBtn->SetText(Button::GetStandardText(BUTTON_NO));
    2182           0 :                 pBtn->Show();
    2183           0 :                 m_aOwnedButtons.push_back(pBtn);
    2184           0 :                 m_aResponses[pBtn] = RET_NO;
    2185           0 :                 break;
    2186             :             case VCL_BUTTONS_OK_CANCEL:
    2187           0 :                 pBtn = new OKButton(pButtonBox);
    2188           0 :                 pBtn->Show();
    2189           0 :                 m_aOwnedButtons.push_back(pBtn);
    2190           0 :                 m_aResponses[pBtn] = RET_OK;
    2191             : 
    2192           0 :                 pBtn = new CancelButton(pButtonBox);
    2193           0 :                 pBtn->SetStyle(pBtn->GetStyle() & WB_DEFBUTTON);
    2194           0 :                 pBtn->Show();
    2195           0 :                 m_aOwnedButtons.push_back(pBtn);
    2196           0 :                 m_aResponses[pBtn] = RET_CANCEL;
    2197           0 :                 break;
    2198             :         }
    2199           0 :         setButtonHandlers(pButtonBox);
    2200           0 :         pButtonBox->sort_native_button_order();
    2201           0 :         m_pGrid->Show();
    2202             :     }
    2203           0 :     return Dialog::Execute();
    2204             : }
    2205             : 
    2206           0 : OUString MessageDialog::get_primary_text() const
    2207             : {
    2208           0 :     const_cast<MessageDialog*>(this)->setDeferredProperties();
    2209             : 
    2210           0 :     return m_sPrimaryString;
    2211             : }
    2212             : 
    2213           0 : OUString MessageDialog::get_secondary_text() const
    2214             : {
    2215           0 :     const_cast<MessageDialog*>(this)->setDeferredProperties();
    2216             : 
    2217           0 :     return m_sSecondaryString;
    2218             : }
    2219             : 
    2220           0 : bool MessageDialog::set_property(const OString &rKey, const OString &rValue)
    2221             : {
    2222           0 :     if (rKey == "text")
    2223           0 :         set_primary_text(OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
    2224           0 :     else if (rKey == "secondary-text")
    2225           0 :         set_secondary_text(OStringToOUString(rValue, RTL_TEXTENCODING_UTF8));
    2226           0 :     else if (rKey == "message-type")
    2227             :     {
    2228           0 :         VclMessageType eMode = VCL_MESSAGE_INFO;
    2229           0 :         if (rValue.equals("info"))
    2230           0 :             eMode = VCL_MESSAGE_INFO;
    2231           0 :         else if (rValue.equals("warning"))
    2232           0 :             eMode = VCL_MESSAGE_WARNING;
    2233           0 :         else if (rValue.equals("question"))
    2234           0 :             eMode = VCL_MESSAGE_QUESTION;
    2235           0 :         else if (rValue.equals("error"))
    2236           0 :             eMode = VCL_MESSAGE_ERROR;
    2237             :         else
    2238             :         {
    2239             :             SAL_WARN("vcl.layout", "unknown message type mode" << rValue.getStr());
    2240             :         }
    2241           0 :         m_eMessageType = eMode;
    2242             :     }
    2243           0 :     else if (rKey == "buttons")
    2244             :     {
    2245           0 :         VclButtonsType eMode = VCL_BUTTONS_NONE;
    2246           0 :         if (rValue.equals("none"))
    2247           0 :             eMode = VCL_BUTTONS_NONE;
    2248           0 :         else if (rValue.equals("ok"))
    2249           0 :             eMode = VCL_BUTTONS_OK;
    2250           0 :         else if (rValue.equals("cancel"))
    2251           0 :             eMode = VCL_BUTTONS_CANCEL;
    2252           0 :         else if (rValue.equals("close"))
    2253           0 :             eMode = VCL_BUTTONS_CLOSE;
    2254           0 :         else if (rValue.equals("yes-no"))
    2255           0 :             eMode = VCL_BUTTONS_YES_NO;
    2256           0 :         else if (rValue.equals("ok-cancel"))
    2257           0 :             eMode = VCL_BUTTONS_OK_CANCEL;
    2258             :         else
    2259             :         {
    2260             :             SAL_WARN("vcl.layout", "unknown buttons type mode" << rValue.getStr());
    2261             :         }
    2262           0 :         m_eButtonsType = eMode;
    2263             :     }
    2264             :     else
    2265           0 :         return Dialog::set_property(rKey, rValue);
    2266           0 :     return true;
    2267             : }
    2268             : 
    2269           0 : void MessageDialog::set_primary_text(const OUString &rPrimaryString)
    2270             : {
    2271           0 :     m_sPrimaryString = rPrimaryString;
    2272           0 :     if (m_pPrimaryMessage)
    2273             :     {
    2274           0 :         m_pPrimaryMessage->SetText(m_sPrimaryString);
    2275           0 :         m_pPrimaryMessage->Show(!m_sPrimaryString.isEmpty());
    2276             :     }
    2277           0 : }
    2278             : 
    2279           0 : void MessageDialog::set_secondary_text(const OUString &rSecondaryString)
    2280             : {
    2281           0 :     m_sSecondaryString = rSecondaryString;
    2282           0 :     if (m_pSecondaryMessage)
    2283             :     {
    2284           0 :         m_pSecondaryMessage->SetText(OUString("\n") + m_sSecondaryString);
    2285           0 :         m_pSecondaryMessage->Show(!m_sSecondaryString.isEmpty());
    2286             :     }
    2287           0 : }
    2288             : 
    2289           0 : Size getLegacyBestSizeForChildren(const vcl::Window &rWindow)
    2290             : {
    2291           0 :     Rectangle aBounds;
    2292             : 
    2293           0 :     for (const vcl::Window* pChild = rWindow.GetWindow(WINDOW_FIRSTCHILD); pChild;
    2294             :         pChild = pChild->GetWindow(WINDOW_NEXT))
    2295             :     {
    2296           0 :         if (!pChild->IsVisible())
    2297           0 :             continue;
    2298             : 
    2299           0 :         Rectangle aChildBounds(pChild->GetPosPixel(), pChild->GetSizePixel());
    2300           0 :         aBounds.Union(aChildBounds);
    2301             :     }
    2302             : 
    2303           0 :     if (aBounds.IsEmpty())
    2304           0 :         return rWindow.GetSizePixel();
    2305             : 
    2306           0 :     Size aRet(aBounds.GetSize());
    2307           0 :     Point aTopLeft(aBounds.TopLeft());
    2308           0 :     aRet.Width() += aTopLeft.X()*2;
    2309           0 :     aRet.Height() += aTopLeft.Y()*2;
    2310             : 
    2311           0 :     return aRet;
    2312             : }
    2313             : 
    2314      118993 : vcl::Window* getNonLayoutParent(vcl::Window *pWindow)
    2315             : {
    2316      241500 :     while (pWindow)
    2317             :     {
    2318      122507 :         pWindow = pWindow->GetParent();
    2319      122507 :         if (!pWindow || !isContainerWindow(*pWindow))
    2320      118993 :             break;
    2321             :     }
    2322      118993 :     return pWindow;
    2323             : }
    2324             : 
    2325           0 : vcl::Window* getNonLayoutRealParent(vcl::Window *pWindow)
    2326             : {
    2327           0 :     while (pWindow)
    2328             :     {
    2329           0 :         pWindow = pWindow->ImplGetParent();
    2330           0 :         if (!pWindow || !isContainerWindow(*pWindow))
    2331           0 :             break;
    2332             :     }
    2333           0 :     return pWindow;
    2334             : }
    2335             : 
    2336      315369 : bool isVisibleInLayout(const vcl::Window *pWindow)
    2337             : {
    2338      315369 :     bool bVisible = true;
    2339      638800 :     while (bVisible)
    2340             :     {
    2341      323313 :         bVisible = pWindow->IsVisible();
    2342      323313 :         pWindow = pWindow->GetParent();
    2343      323313 :         if (!pWindow || !isContainerWindow(*pWindow))
    2344      315251 :             break;
    2345             :     }
    2346      315369 :     return bVisible;
    2347             : }
    2348             : 
    2349        1340 : bool isEnabledInLayout(const vcl::Window *pWindow)
    2350             : {
    2351        1340 :     bool bEnabled = true;
    2352        2692 :     while (bEnabled)
    2353             :     {
    2354        1352 :         bEnabled = pWindow->IsEnabled();
    2355        1352 :         pWindow = pWindow->GetParent();
    2356        1352 :         if (!pWindow || !isContainerWindow(*pWindow))
    2357        1340 :             break;
    2358             :     }
    2359        1340 :     return bEnabled;
    2360             : }
    2361             : 
    2362      719023 : bool isLayoutEnabled(const vcl::Window *pWindow)
    2363             : {
    2364             :     //Child is a container => we're layout enabled
    2365      719023 :     const vcl::Window *pChild = pWindow ? pWindow->GetWindow(WINDOW_FIRSTCHILD) : NULL;
    2366      719023 :     return pChild && isContainerWindow(*pChild) && !pChild->GetWindow(WINDOW_NEXT);
    2367             : }
    2368             : 
    2369           0 : bool isInitialLayout(const vcl::Window *pWindow)
    2370             : {
    2371           0 :     Dialog *pParentDialog = pWindow ? pWindow->GetParentDialog() : NULL;
    2372           0 :     return pParentDialog && pParentDialog->isCalculatingInitialLayoutSize();
    2373        1233 : }
    2374             : 
    2375             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10