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

Generated by: LCOV version 1.10