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

Generated by: LCOV version 1.11