src/gui/kernel/qboxlayout.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the QtGui module of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "qboxlayout.h"
       
    43 #include "qapplication.h"
       
    44 #include "qwidget.h"
       
    45 #include "qlist.h"
       
    46 #include "qsizepolicy.h"
       
    47 #include "qvector.h"
       
    48 
       
    49 #include "qlayoutengine_p.h"
       
    50 #include "qlayout_p.h"
       
    51 
       
    52 QT_BEGIN_NAMESPACE
       
    53 
       
    54 /*
       
    55     Returns true if the \a widget can be added to the \a layout;
       
    56     otherwise returns false.
       
    57 */
       
    58 static bool checkWidget(QLayout *layout, QWidget *widget)
       
    59 {
       
    60     if (!widget) {
       
    61         qWarning("QLayout: Cannot add null widget to %s/%s", layout->metaObject()->className(),
       
    62                   layout->objectName().toLocal8Bit().data());
       
    63         return false;
       
    64     }
       
    65     return true;
       
    66 }
       
    67 
       
    68 struct QBoxLayoutItem
       
    69 {
       
    70     QBoxLayoutItem(QLayoutItem *it, int stretch_ = 0)
       
    71         : item(it), stretch(stretch_), magic(false) { }
       
    72     ~QBoxLayoutItem() { delete item; }
       
    73 
       
    74     int hfw(int w) {
       
    75         if (item->hasHeightForWidth()) {
       
    76             return item->heightForWidth(w);
       
    77         } else {
       
    78             return item->sizeHint().height();
       
    79         }
       
    80     }
       
    81     int mhfw(int w) {
       
    82         if (item->hasHeightForWidth()) {
       
    83             return item->heightForWidth(w);
       
    84         } else {
       
    85             return item->minimumSize().height();
       
    86         }
       
    87     }
       
    88     int hStretch() {
       
    89         if (stretch == 0 && item->widget()) {
       
    90             return item->widget()->sizePolicy().horizontalStretch();
       
    91         } else {
       
    92             return stretch;
       
    93         }
       
    94     }
       
    95     int vStretch() {
       
    96         if (stretch == 0 && item->widget()) {
       
    97             return item->widget()->sizePolicy().verticalStretch();
       
    98         } else {
       
    99             return stretch;
       
   100         }
       
   101     }
       
   102 
       
   103     QLayoutItem *item;
       
   104     int stretch;
       
   105     bool magic;
       
   106 };
       
   107 
       
   108 class QBoxLayoutPrivate : public QLayoutPrivate
       
   109 {
       
   110     Q_DECLARE_PUBLIC(QBoxLayout)
       
   111 public:
       
   112     QBoxLayoutPrivate() : hfwWidth(-1), dirty(true), spacing(-1) { }
       
   113     ~QBoxLayoutPrivate();
       
   114 
       
   115     void setDirty() {
       
   116         geomArray.clear();
       
   117         hfwWidth = -1;
       
   118         hfwHeight = -1;
       
   119         dirty = true;
       
   120     }
       
   121 
       
   122     QList<QBoxLayoutItem *> list;
       
   123     QVector<QLayoutStruct> geomArray;
       
   124     int hfwWidth;
       
   125     int hfwHeight;
       
   126     int hfwMinHeight;
       
   127     QSize sizeHint;
       
   128     QSize minSize;
       
   129     QSize maxSize;
       
   130     int leftMargin, topMargin, rightMargin, bottomMargin;
       
   131     Qt::Orientations expanding;
       
   132     uint hasHfw : 1;
       
   133     uint dirty : 1;
       
   134     QBoxLayout::Direction dir;
       
   135     int spacing;
       
   136 
       
   137     inline void deleteAll() { while (!list.isEmpty()) delete list.takeFirst(); }
       
   138 
       
   139     void setupGeom();
       
   140     void calcHfw(int);
       
   141 
       
   142     void effectiveMargins(int *left, int *top, int *right, int *bottom) const;
       
   143 };
       
   144 
       
   145 QBoxLayoutPrivate::~QBoxLayoutPrivate()
       
   146 {
       
   147 }
       
   148 
       
   149 static inline bool horz(QBoxLayout::Direction dir)
       
   150 {
       
   151     return dir == QBoxLayout::RightToLeft || dir == QBoxLayout::LeftToRight;
       
   152 }
       
   153 
       
   154 /**
       
   155  * The purpose of this function is to make sure that widgets are not laid out outside its layout.
       
   156  * E.g. the layoutItemRect margins are only meant to take of the surrounding margins/spacings.
       
   157  * However, if the margin is 0, it can easily cover the area of a widget above it.
       
   158  */
       
   159 void QBoxLayoutPrivate::effectiveMargins(int *left, int *top, int *right, int *bottom) const
       
   160 {
       
   161     int l = leftMargin;
       
   162     int t = topMargin;
       
   163     int r = rightMargin;
       
   164     int b = bottomMargin;
       
   165 #ifdef Q_WS_MAC
       
   166     Q_Q(const QBoxLayout);
       
   167     if (horz(dir)) {
       
   168         QBoxLayoutItem *leftBox = 0;
       
   169         QBoxLayoutItem *rightBox = 0;
       
   170 
       
   171         if (left || right) {
       
   172             leftBox = list.value(0);
       
   173             rightBox = list.value(list.count() - 1);
       
   174             if (dir == QBoxLayout::RightToLeft)
       
   175                 qSwap(leftBox, rightBox);
       
   176 
       
   177             int leftDelta = 0;
       
   178             int rightDelta = 0;
       
   179             if (leftBox) {
       
   180                 QLayoutItem *itm = leftBox->item;
       
   181                 if (QWidget *w = itm->widget())
       
   182                     leftDelta = itm->geometry().left() - w->geometry().left();
       
   183             }
       
   184             if (rightBox) {
       
   185                 QLayoutItem *itm = rightBox->item;
       
   186                 if (QWidget *w = itm->widget())
       
   187                     rightDelta = w->geometry().right() - itm->geometry().right();
       
   188             }
       
   189             QWidget *w = q->parentWidget();
       
   190             Qt::LayoutDirection layoutDirection = w ? w->layoutDirection() : QApplication::layoutDirection();
       
   191             if (layoutDirection == Qt::RightToLeft)
       
   192                 qSwap(leftDelta, rightDelta);
       
   193 
       
   194             l = qMax(l, leftDelta);
       
   195             r = qMax(r, rightDelta);
       
   196         }
       
   197 
       
   198         int count = top || bottom ? list.count() : 0;
       
   199         for (int i = 0; i < count; ++i) {
       
   200             QBoxLayoutItem *box = list.at(i);
       
   201             QLayoutItem *itm = box->item;
       
   202             QWidget *w = itm->widget();
       
   203             if (w) {
       
   204                 QRect lir = itm->geometry();
       
   205                 QRect wr = w->geometry();
       
   206                 if (top)
       
   207                     t = qMax(t, lir.top() - wr.top());
       
   208                 if (bottom)
       
   209                     b = qMax(b, wr.bottom() - lir.bottom());
       
   210             }
       
   211         }
       
   212     } else {    // vertical layout
       
   213         QBoxLayoutItem *topBox = 0;
       
   214         QBoxLayoutItem *bottomBox = 0;
       
   215 
       
   216         if (top || bottom) {
       
   217             topBox = list.value(0);
       
   218             bottomBox = list.value(list.count() - 1);
       
   219             if (dir == QBoxLayout::BottomToTop) {
       
   220                 qSwap(topBox, bottomBox);
       
   221             }
       
   222 
       
   223             if (top && topBox) {
       
   224                 QLayoutItem *itm = topBox->item;
       
   225                 QWidget *w = itm->widget();
       
   226                 if (w)
       
   227                     t = qMax(t, itm->geometry().top() - w->geometry().top());
       
   228             }
       
   229 
       
   230             if (bottom && bottomBox) {
       
   231                 QLayoutItem *itm = bottomBox->item;
       
   232                 QWidget *w = itm->widget();
       
   233                 if (w)
       
   234                     b = qMax(b, w->geometry().bottom() - itm->geometry().bottom());
       
   235             }
       
   236         }
       
   237 
       
   238         int count = left || right ? list.count() : 0;
       
   239         for (int i = 0; i < count; ++i) {
       
   240             QBoxLayoutItem *box = list.at(i);
       
   241             QLayoutItem *itm = box->item;
       
   242             QWidget *w = itm->widget();
       
   243             if (w) {
       
   244                 QRect lir = itm->geometry();
       
   245                 QRect wr = w->geometry();
       
   246                 if (left)
       
   247                     l = qMax(l, lir.left() - wr.left());
       
   248                 if (right)
       
   249                     r = qMax(r, wr.right() - lir.right());
       
   250             }
       
   251         }        
       
   252     }
       
   253 #endif
       
   254     if (left)
       
   255         *left = l;
       
   256     if (top)
       
   257         *top = t;
       
   258     if (right)
       
   259         *right = r;
       
   260     if (bottom)
       
   261         *bottom = b;
       
   262 }
       
   263 
       
   264 
       
   265 /*
       
   266     Initializes the data structure needed by qGeomCalc and
       
   267     recalculates max/min and size hint.
       
   268 */
       
   269 void QBoxLayoutPrivate::setupGeom()
       
   270 {
       
   271     if (!dirty)
       
   272         return;
       
   273 
       
   274     Q_Q(QBoxLayout);
       
   275     int maxw = horz(dir) ? 0 : QLAYOUTSIZE_MAX;
       
   276     int maxh = horz(dir) ? QLAYOUTSIZE_MAX : 0;
       
   277     int minw = 0;
       
   278     int minh = 0;
       
   279     int hintw = 0;
       
   280     int hinth = 0;
       
   281 
       
   282     bool horexp = false;
       
   283     bool verexp = false;
       
   284 
       
   285     hasHfw = false;
       
   286 
       
   287     int n = list.count();
       
   288     geomArray.clear();
       
   289     QVector<QLayoutStruct> a(n);
       
   290 
       
   291     QSizePolicy::ControlTypes controlTypes1;
       
   292     QSizePolicy::ControlTypes controlTypes2;
       
   293     int fixedSpacing = q->spacing();
       
   294     int previousNonEmptyIndex = -1;
       
   295 
       
   296     QStyle *style = 0;
       
   297     if (fixedSpacing < 0) {
       
   298         if (QWidget *parentWidget = q->parentWidget())
       
   299             style = parentWidget->style();
       
   300     }
       
   301 
       
   302     for (int i = 0; i < n; i++) {
       
   303         QBoxLayoutItem *box = list.at(i);
       
   304         QSize max = box->item->maximumSize();
       
   305         QSize min = box->item->minimumSize();
       
   306         QSize hint = box->item->sizeHint();
       
   307         Qt::Orientations exp = box->item->expandingDirections();
       
   308         bool empty = box->item->isEmpty();
       
   309         int spacing = 0;
       
   310 
       
   311         if (!empty) {
       
   312             if (fixedSpacing >= 0) {
       
   313                 spacing = (previousNonEmptyIndex >= 0) ? fixedSpacing : 0;
       
   314 #ifdef Q_WS_MAC
       
   315                 if (!horz(dir) && previousNonEmptyIndex >= 0) {
       
   316                     QBoxLayoutItem *sibling = (dir == QBoxLayout::TopToBottom  ? box : list.at(previousNonEmptyIndex));
       
   317                     if (sibling) {
       
   318                         QWidget *wid = sibling->item->widget();
       
   319                         if (wid)
       
   320                             spacing = qMax(spacing, sibling->item->geometry().top() - wid->geometry().top());
       
   321                     }
       
   322                 }
       
   323 #endif
       
   324             } else {
       
   325                 controlTypes1 = controlTypes2;
       
   326                 controlTypes2 = box->item->controlTypes();
       
   327                 if (previousNonEmptyIndex >= 0) {
       
   328                     QSizePolicy::ControlTypes actual1 = controlTypes1;
       
   329                     QSizePolicy::ControlTypes actual2 = controlTypes2;
       
   330                     if (dir == QBoxLayout::RightToLeft || dir == QBoxLayout::BottomToTop)
       
   331                         qSwap(actual1, actual2);
       
   332 
       
   333                     if (style) {
       
   334                         spacing = style->combinedLayoutSpacing(actual1, actual2,
       
   335                                              horz(dir) ? Qt::Horizontal : Qt::Vertical,
       
   336                                              0, q->parentWidget());
       
   337                         if (spacing < 0)
       
   338                             spacing = 0;
       
   339                     }
       
   340                 }
       
   341             }
       
   342 
       
   343             if (previousNonEmptyIndex >= 0)
       
   344                 a[previousNonEmptyIndex].spacing = spacing;
       
   345             previousNonEmptyIndex = i;
       
   346         }
       
   347 
       
   348         bool ignore = empty && box->item->widget(); // ignore hidden widgets
       
   349         bool dummy = true;
       
   350         if (horz(dir)) {
       
   351             bool expand = (exp & Qt::Horizontal || box->stretch > 0);
       
   352             horexp = horexp || expand;
       
   353             maxw += spacing + max.width();
       
   354             minw += spacing + min.width();
       
   355             hintw += spacing + hint.width();
       
   356             if (!ignore)
       
   357                 qMaxExpCalc(maxh, verexp, dummy,
       
   358                             max.height(), exp & Qt::Vertical, box->item->isEmpty());
       
   359             minh = qMax(minh, min.height());
       
   360             hinth = qMax(hinth, hint.height());
       
   361 
       
   362             a[i].sizeHint = hint.width();
       
   363             a[i].maximumSize = max.width();
       
   364             a[i].minimumSize = min.width();
       
   365             a[i].expansive = expand;
       
   366             a[i].stretch = box->stretch ? box->stretch : box->hStretch();
       
   367         } else {
       
   368             bool expand = (exp & Qt::Vertical || box->stretch > 0);
       
   369             verexp = verexp || expand;
       
   370             maxh += spacing + max.height();
       
   371             minh += spacing + min.height();
       
   372             hinth += spacing + hint.height();
       
   373             if (!ignore)
       
   374                 qMaxExpCalc(maxw, horexp, dummy,
       
   375                             max.width(), exp & Qt::Horizontal, box->item->isEmpty());
       
   376             minw = qMax(minw, min.width());
       
   377             hintw = qMax(hintw, hint.width());
       
   378 
       
   379             a[i].sizeHint = hint.height();
       
   380             a[i].maximumSize = max.height();
       
   381             a[i].minimumSize = min.height();
       
   382             a[i].expansive = expand;
       
   383             a[i].stretch = box->stretch ? box->stretch : box->vStretch();
       
   384         }
       
   385 
       
   386         a[i].empty = empty;
       
   387         a[i].spacing = 0;   // might be be initialized with a non-zero value in a later iteration
       
   388         hasHfw = hasHfw || box->item->hasHeightForWidth();
       
   389     }
       
   390 
       
   391     geomArray = a;
       
   392 
       
   393     expanding = (Qt::Orientations)
       
   394                        ((horexp ? Qt::Horizontal : 0)
       
   395                          | (verexp ? Qt::Vertical : 0));
       
   396 
       
   397     minSize = QSize(minw, minh);
       
   398     maxSize = QSize(maxw, maxh).expandedTo(minSize);
       
   399     sizeHint = QSize(hintw, hinth).expandedTo(minSize).boundedTo(maxSize);
       
   400 
       
   401     q->getContentsMargins(&leftMargin, &topMargin, &rightMargin, &bottomMargin);
       
   402     int left, top, right, bottom;
       
   403     effectiveMargins(&left, &top, &right, &bottom);
       
   404     QSize extra(left + right, top + bottom);
       
   405 
       
   406     minSize += extra;
       
   407     maxSize += extra;
       
   408     sizeHint += extra;
       
   409 
       
   410     dirty = false;
       
   411 }
       
   412 
       
   413 /*
       
   414   Calculates and stores the preferred height given the width \a w.
       
   415 */
       
   416 void QBoxLayoutPrivate::calcHfw(int w)
       
   417 {
       
   418     QVector<QLayoutStruct> &a = geomArray;
       
   419     int n = a.count();
       
   420     int h = 0;
       
   421     int mh = 0;
       
   422 
       
   423     Q_ASSERT(n == list.size());
       
   424 
       
   425     if (horz(dir)) {
       
   426         qGeomCalc(a, 0, n, 0, w);
       
   427         for (int i = 0; i < n; i++) {
       
   428             QBoxLayoutItem *box = list.at(i);
       
   429             h = qMax(h, box->hfw(a.at(i).size));
       
   430             mh = qMax(mh, box->mhfw(a.at(i).size));
       
   431         }
       
   432     } else {
       
   433         for (int i = 0; i < n; ++i) {
       
   434             QBoxLayoutItem *box = list.at(i);
       
   435             int spacing = a.at(i).spacing;
       
   436             h += box->hfw(w);
       
   437             mh += box->mhfw(w);
       
   438             h += spacing;
       
   439             mh += spacing;
       
   440         }
       
   441     }
       
   442     hfwWidth = w;
       
   443     hfwHeight = h;
       
   444     hfwMinHeight = mh;
       
   445 }
       
   446 
       
   447 
       
   448 /*!
       
   449     \class QBoxLayout
       
   450 
       
   451     \brief The QBoxLayout class lines up child widgets horizontally or
       
   452     vertically.
       
   453 
       
   454     \ingroup geomanagement
       
   455 
       
   456     QBoxLayout takes the space it gets (from its parent layout or from
       
   457     the parentWidget()), divides it up into a row of boxes, and makes
       
   458     each managed widget fill one box.
       
   459 
       
   460     \image qhboxlayout-with-5-children.png Horizontal box layout with five child widgets
       
   461 
       
   462     If the QBoxLayout's orientation is Qt::Horizontal the boxes are
       
   463     placed in a row, with suitable sizes. Each widget (or other box)
       
   464     will get at least its minimum size and at most its maximum size.
       
   465     Any excess space is shared according to the stretch factors (more
       
   466     about that below).
       
   467 
       
   468     \image qvboxlayout-with-5-children.png Vertical box layout with five child widgets
       
   469 
       
   470     If the QBoxLayout's orientation is Qt::Vertical, the boxes are
       
   471     placed in a column, again with suitable sizes.
       
   472 
       
   473     The easiest way to create a QBoxLayout is to use one of the
       
   474     convenience classes, e.g. QHBoxLayout (for Qt::Horizontal boxes)
       
   475     or QVBoxLayout (for Qt::Vertical boxes). You can also use the
       
   476     QBoxLayout constructor directly, specifying its direction as
       
   477     LeftToRight, RightToLeft, TopToBottom, or BottomToTop.
       
   478 
       
   479     If the QBoxLayout is not the top-level layout (i.e. it is not
       
   480     managing all of the widget's area and children), you must add it
       
   481     to its parent layout before you can do anything with it. The
       
   482     normal way to add a layout is by calling
       
   483     parentLayout-\>addLayout().
       
   484 
       
   485     Once you have done this, you can add boxes to the QBoxLayout using
       
   486     one of four functions:
       
   487 
       
   488     \list
       
   489     \o addWidget() to add a widget to the QBoxLayout and set the
       
   490     widget's stretch factor. (The stretch factor is along the row of
       
   491     boxes.)
       
   492 
       
   493     \o addSpacing() to create an empty box; this is one of the
       
   494     functions you use to create nice and spacious dialogs. See below
       
   495     for ways to set margins.
       
   496 
       
   497     \o addStretch() to create an empty, stretchable box.
       
   498 
       
   499     \o addLayout() to add a box containing another QLayout to the row
       
   500     and set that layout's stretch factor.
       
   501     \endlist
       
   502 
       
   503     Use insertWidget(), insertSpacing(), insertStretch() or
       
   504     insertLayout() to insert a box at a specified position in the
       
   505     layout.
       
   506 
       
   507     QBoxLayout also includes two margin widths:
       
   508 
       
   509     \list
       
   510     \o setContentsMargins() sets the width of the outer border on 
       
   511        each side of the widget. This is the width of the reserved space 
       
   512        along each of the QBoxLayout's four sides.
       
   513     \o setSpacing() sets the width between neighboring boxes. (You
       
   514        can use addSpacing() to get more space at a particular spot.)
       
   515     \endlist
       
   516 
       
   517     The margin default is provided by the style. The default margin
       
   518     most Qt styles specify is 9 for child widgets and 11 for windows.
       
   519     The spacing defaults to the same as the margin width for a
       
   520     top-level layout, or to the same as the parent layout.
       
   521 
       
   522     To remove a widget from a layout, call removeWidget(). Calling
       
   523     QWidget::hide() on a widget also effectively removes the widget
       
   524     from the layout until QWidget::show() is called.
       
   525 
       
   526     You will almost always want to use QVBoxLayout and QHBoxLayout
       
   527     rather than QBoxLayout because of their convenient constructors.
       
   528 
       
   529     \sa QGridLayout, QStackedLayout, {Layout Management}
       
   530 */
       
   531 
       
   532 /*!
       
   533     \enum QBoxLayout::Direction
       
   534 
       
   535     This type is used to determine the direction of a box layout.
       
   536 
       
   537     \value LeftToRight  Horizontal from left to right.
       
   538     \value RightToLeft  Horizontal from right to left.
       
   539     \value TopToBottom  Vertical from top to bottom.
       
   540     \value BottomToTop  Vertical from bottom to top.
       
   541 
       
   542     \omitvalue Down
       
   543     \omitvalue Up
       
   544 */
       
   545 
       
   546 /*!
       
   547     Constructs a new QBoxLayout with direction \a dir and parent widget \a
       
   548     parent.
       
   549 
       
   550     \sa direction()
       
   551 */
       
   552 QBoxLayout::QBoxLayout(Direction dir, QWidget *parent)
       
   553     : QLayout(*new QBoxLayoutPrivate, 0, parent)
       
   554 {
       
   555     Q_D(QBoxLayout);
       
   556     d->dir = dir;
       
   557 }
       
   558 
       
   559 #ifdef QT3_SUPPORT
       
   560 /*!
       
   561     Constructs a new QBoxLayout with direction \a dir and main widget \a
       
   562     parent. \a parent may not be 0.
       
   563 
       
   564     The \a margin is the number of pixels between the edge of the
       
   565     widget and its managed children. The \a spacing is the default
       
   566     number of pixels between neighboring children. If \a spacing is -1
       
   567     the value of \a margin is used for \a spacing.
       
   568 
       
   569     \a name is the internal object name.
       
   570 
       
   571     \sa direction()
       
   572 */
       
   573 QBoxLayout::QBoxLayout(QWidget *parent, Direction dir,
       
   574                         int margin, int spacing, const char *name)
       
   575     : QLayout(*new QBoxLayoutPrivate, 0, parent)
       
   576 {
       
   577     Q_D(QBoxLayout);
       
   578     d->dir = dir;
       
   579     setMargin(margin);
       
   580     setObjectName(QString::fromAscii(name));
       
   581     setSpacing(spacing<0 ? margin : spacing);
       
   582 }
       
   583 
       
   584 /*!
       
   585     Constructs a new QBoxLayout called \a name, with direction \a dir,
       
   586     and inserts it into \a parentLayout.
       
   587 
       
   588     The \a spacing is the default number of pixels between neighboring
       
   589     children. If \a spacing is -1, the layout will inherit its
       
   590     parent's spacing().
       
   591 */
       
   592 QBoxLayout::QBoxLayout(QLayout *parentLayout, Direction dir, int spacing,
       
   593                         const char *name)
       
   594     : QLayout(*new QBoxLayoutPrivate, parentLayout, 0)
       
   595 {
       
   596     Q_D(QBoxLayout);
       
   597     d->dir = dir;
       
   598     setObjectName(QString::fromAscii(name));
       
   599     setSpacing(spacing);
       
   600 }
       
   601 
       
   602 /*!
       
   603     Constructs a new QBoxLayout called \a name, with direction \a dir.
       
   604 
       
   605     If \a spacing is -1, the layout will inherit its parent's
       
   606     spacing(); otherwise \a spacing is used.
       
   607 
       
   608     You must insert this box into another layout.
       
   609 */
       
   610 QBoxLayout::QBoxLayout(Direction dir, int spacing, const char *name)
       
   611     : QLayout(*new QBoxLayoutPrivate,0, 0)
       
   612 {
       
   613     Q_D(QBoxLayout);
       
   614     d->dir = dir;
       
   615     setObjectName(QString::fromAscii(name));
       
   616     setSpacing(spacing);
       
   617 }
       
   618 #endif // QT3_SUPPORT
       
   619 
       
   620 
       
   621 /*!
       
   622     Destroys this box layout.
       
   623 
       
   624     The layout's widgets aren't destroyed.
       
   625 */
       
   626 QBoxLayout::~QBoxLayout()
       
   627 {
       
   628     Q_D(QBoxLayout);
       
   629     d->deleteAll(); // must do it before QObject deletes children, so can't be in ~QBoxLayoutPrivate
       
   630 }
       
   631 
       
   632 /*!
       
   633   Reimplements QLayout::spacing(). If the spacing property is
       
   634   valid, that value is returned. Otherwise, a value for the spacing
       
   635   property is computed and returned. Since layout spacing in a widget
       
   636   is style dependent, if the parent is a widget, it queries the style
       
   637   for the (horizontal or vertical) spacing of the layout. Otherwise,
       
   638   the parent is a layout, and it queries the parent layout for the
       
   639   spacing().
       
   640 
       
   641   \sa QLayout::spacing(), setSpacing()
       
   642  */
       
   643 int QBoxLayout::spacing() const
       
   644 {
       
   645     Q_D(const QBoxLayout);
       
   646     if (d->spacing >=0) {
       
   647         return d->spacing;
       
   648     } else {
       
   649         return qSmartSpacing(this, d->dir == LeftToRight || d->dir == RightToLeft
       
   650                                            ? QStyle::PM_LayoutHorizontalSpacing
       
   651                                            : QStyle::PM_LayoutVerticalSpacing);
       
   652     }
       
   653 }
       
   654 
       
   655 /*!
       
   656   Reimplements QLayout::setSpacing(). Sets the spacing
       
   657   property to \a spacing. 
       
   658 
       
   659   \sa QLayout::setSpacing(), spacing()
       
   660  */
       
   661 void QBoxLayout::setSpacing(int spacing)
       
   662 {
       
   663     Q_D(QBoxLayout);
       
   664     d->spacing = spacing;
       
   665     invalidate();
       
   666 }
       
   667 
       
   668 /*!
       
   669     \reimp
       
   670 */
       
   671 QSize QBoxLayout::sizeHint() const
       
   672 {
       
   673     Q_D(const QBoxLayout);
       
   674     if (d->dirty)
       
   675         const_cast<QBoxLayout*>(this)->d_func()->setupGeom();
       
   676     return d->sizeHint;
       
   677 }
       
   678 
       
   679 /*!
       
   680     \reimp
       
   681 */
       
   682 QSize QBoxLayout::minimumSize() const
       
   683 {
       
   684     Q_D(const QBoxLayout);
       
   685     if (d->dirty)
       
   686         const_cast<QBoxLayout*>(this)->d_func()->setupGeom();
       
   687     return d->minSize;
       
   688 }
       
   689 
       
   690 /*!
       
   691     \reimp
       
   692 */
       
   693 QSize QBoxLayout::maximumSize() const
       
   694 {
       
   695     Q_D(const QBoxLayout);
       
   696     if (d->dirty)
       
   697         const_cast<QBoxLayout*>(this)->d_func()->setupGeom();
       
   698 
       
   699     QSize s = d->maxSize.boundedTo(QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX));
       
   700 
       
   701     if (alignment() & Qt::AlignHorizontal_Mask)
       
   702         s.setWidth(QLAYOUTSIZE_MAX);
       
   703     if (alignment() & Qt::AlignVertical_Mask)
       
   704         s.setHeight(QLAYOUTSIZE_MAX);
       
   705     return s;
       
   706 }
       
   707 
       
   708 /*!
       
   709     \reimp
       
   710 */
       
   711 bool QBoxLayout::hasHeightForWidth() const
       
   712 {
       
   713     Q_D(const QBoxLayout);
       
   714     if (d->dirty)
       
   715         const_cast<QBoxLayout*>(this)->d_func()->setupGeom();
       
   716     return d->hasHfw;
       
   717 }
       
   718 
       
   719 /*!
       
   720     \reimp
       
   721 */
       
   722 int QBoxLayout::heightForWidth(int w) const
       
   723 {
       
   724     Q_D(const QBoxLayout);
       
   725     if (!hasHeightForWidth())
       
   726         return -1;
       
   727 
       
   728     int left, top, right, bottom;
       
   729     d->effectiveMargins(&left, &top, &right, &bottom);
       
   730 
       
   731     w -= left + right;
       
   732     if (w != d->hfwWidth)
       
   733         const_cast<QBoxLayout*>(this)->d_func()->calcHfw(w);
       
   734 
       
   735     return d->hfwHeight + top + bottom;
       
   736 }
       
   737 
       
   738 /*!
       
   739     \reimp
       
   740 */
       
   741 int QBoxLayout::minimumHeightForWidth(int w) const
       
   742 {
       
   743     Q_D(const QBoxLayout);
       
   744     (void) heightForWidth(w);
       
   745     int top, bottom;
       
   746     d->effectiveMargins(0, &top, 0, &bottom);
       
   747     return d->hasHfw ? (d->hfwMinHeight + top + bottom) : -1;
       
   748 }
       
   749 
       
   750 /*!
       
   751     Resets cached information.
       
   752 */
       
   753 void QBoxLayout::invalidate()
       
   754 {
       
   755     Q_D(QBoxLayout);
       
   756     d->setDirty();
       
   757     QLayout::invalidate();
       
   758 }
       
   759 
       
   760 /*!
       
   761     \reimp
       
   762 */
       
   763 int QBoxLayout::count() const
       
   764 {
       
   765     Q_D(const QBoxLayout);
       
   766     return d->list.count();
       
   767 }
       
   768 
       
   769 /*!
       
   770     \reimp
       
   771 */
       
   772 QLayoutItem *QBoxLayout::itemAt(int index) const
       
   773 {
       
   774     Q_D(const QBoxLayout);
       
   775     return index >= 0 && index < d->list.count() ? d->list.at(index)->item : 0;
       
   776 }
       
   777 
       
   778 /*!
       
   779     \reimp
       
   780 */
       
   781 QLayoutItem *QBoxLayout::takeAt(int index)
       
   782 {
       
   783     Q_D(QBoxLayout);
       
   784     if (index < 0 || index >= d->list.count())
       
   785         return 0;
       
   786     QBoxLayoutItem *b = d->list.takeAt(index);
       
   787     QLayoutItem *item = b->item;
       
   788     b->item = 0;
       
   789     delete b;
       
   790 
       
   791     invalidate();
       
   792     return item;
       
   793 }
       
   794 
       
   795 
       
   796 /*!
       
   797     \reimp
       
   798 */
       
   799 Qt::Orientations QBoxLayout::expandingDirections() const
       
   800 {
       
   801     Q_D(const QBoxLayout);
       
   802     if (d->dirty)
       
   803         const_cast<QBoxLayout*>(this)->d_func()->setupGeom();
       
   804     return d->expanding;
       
   805 }
       
   806 
       
   807 /*!
       
   808     \reimp
       
   809 */
       
   810 void QBoxLayout::setGeometry(const QRect &r)
       
   811 {
       
   812     Q_D(QBoxLayout);
       
   813     if (d->dirty || r != geometry()) {
       
   814         QRect oldRect = geometry();
       
   815         QLayout::setGeometry(r);
       
   816         if (d->dirty)
       
   817             d->setupGeom();
       
   818         QRect cr = alignment() ? alignmentRect(r) : r;
       
   819 
       
   820         int left, top, right, bottom;
       
   821         d->effectiveMargins(&left, &top, &right, &bottom);
       
   822         QRect s(cr.x() + left, cr.y() + top,
       
   823                 cr.width() - (left + right),
       
   824                 cr.height() - (top + bottom));
       
   825 
       
   826         QVector<QLayoutStruct> a = d->geomArray;
       
   827         int pos = horz(d->dir) ? s.x() : s.y();
       
   828         int space = horz(d->dir) ? s.width() : s.height();
       
   829         int n = a.count();
       
   830         if (d->hasHfw && !horz(d->dir)) {
       
   831             for (int i = 0; i < n; i++) {
       
   832                 QBoxLayoutItem *box = d->list.at(i);
       
   833                 if (box->item->hasHeightForWidth())
       
   834                     a[i].sizeHint = a[i].minimumSize =
       
   835                                     box->item->heightForWidth(s.width());
       
   836             }
       
   837         }
       
   838 
       
   839         Direction visualDir = d->dir;
       
   840         QWidget *parent = parentWidget();
       
   841         if (parent && parent->isRightToLeft()) {
       
   842             if (d->dir == LeftToRight)
       
   843                 visualDir = RightToLeft;
       
   844             else if (d->dir == RightToLeft)
       
   845                 visualDir = LeftToRight;
       
   846         }
       
   847 
       
   848         qGeomCalc(a, 0, n, pos, space);
       
   849 
       
   850         bool reverse = (horz(visualDir)
       
   851                         ? ((r.right() > oldRect.right()) != (visualDir == RightToLeft))
       
   852                         : r.bottom() > oldRect.bottom());
       
   853         for (int j = 0; j < n; j++) {
       
   854             int i = reverse ? n-j-1 : j;
       
   855             QBoxLayoutItem *box = d->list.at(i);
       
   856 
       
   857             switch (visualDir) {
       
   858             case LeftToRight:
       
   859                 box->item->setGeometry(QRect(a.at(i).pos, s.y(), a.at(i).size, s.height()));
       
   860                 break;
       
   861             case RightToLeft:
       
   862                 box->item->setGeometry(QRect(s.left() + s.right() - a.at(i).pos - a.at(i).size + 1,
       
   863                                              s.y(), a.at(i).size, s.height()));
       
   864                 break;
       
   865             case TopToBottom:
       
   866                 box->item->setGeometry(QRect(s.x(), a.at(i).pos, s.width(), a.at(i).size));
       
   867                 break;
       
   868             case BottomToTop:
       
   869                 box->item->setGeometry(QRect(s.x(),
       
   870                                              s.top() + s.bottom() - a.at(i).pos - a.at(i).size + 1,
       
   871                                              s.width(), a.at(i).size));
       
   872             }
       
   873         }
       
   874     }
       
   875 }
       
   876 
       
   877 /*!
       
   878     \reimp
       
   879 */
       
   880 void QBoxLayout::addItem(QLayoutItem *item)
       
   881 {
       
   882     Q_D(QBoxLayout);
       
   883     QBoxLayoutItem *it = new QBoxLayoutItem(item);
       
   884     d->list.append(it);
       
   885     invalidate();
       
   886 }
       
   887 
       
   888 /*!
       
   889     Inserts \a item into this box layout at position \a index. If \a
       
   890     index is negative, the item is added at the end.
       
   891 
       
   892     \sa addItem(), insertWidget(), insertLayout(), insertStretch(),
       
   893         insertSpacing()
       
   894 */
       
   895 void QBoxLayout::insertItem(int index, QLayoutItem *item)
       
   896 {
       
   897     Q_D(QBoxLayout);
       
   898     if (index < 0)                                // append
       
   899         index = d->list.count();
       
   900 
       
   901     QBoxLayoutItem *it = new QBoxLayoutItem(item);
       
   902     d->list.insert(index, it);
       
   903     invalidate();
       
   904 }
       
   905 
       
   906 /*!
       
   907     Inserts a non-stretchable space (a QSpacerItem) at position \a index, with
       
   908     size \a size. If \a index is negative the space is added at the end.
       
   909 
       
   910     The box layout has default margin and spacing. This function adds
       
   911     additional space.
       
   912 
       
   913     \sa addSpacing(), insertItem(), QSpacerItem
       
   914 */
       
   915 void QBoxLayout::insertSpacing(int index, int size)
       
   916 {
       
   917     Q_D(QBoxLayout);
       
   918     if (index < 0)                                // append
       
   919         index = d->list.count();
       
   920 
       
   921     QLayoutItem *b;
       
   922     if (horz(d->dir))
       
   923         b = QLayoutPrivate::createSpacerItem(this, size, 0, QSizePolicy::Fixed, QSizePolicy::Minimum);
       
   924     else
       
   925         b = QLayoutPrivate::createSpacerItem(this, 0, size, QSizePolicy::Minimum, QSizePolicy::Fixed);
       
   926 
       
   927     QT_TRY {
       
   928         QBoxLayoutItem *it = new QBoxLayoutItem(b);
       
   929         it->magic = true;
       
   930         d->list.insert(index, it);
       
   931 
       
   932     } QT_CATCH(...) {
       
   933         delete b;
       
   934         QT_RETHROW;
       
   935     }
       
   936     invalidate();
       
   937 }
       
   938 
       
   939 /*!
       
   940     Inserts a stretchable space (a QSpacerItem) at position \a
       
   941     index, with zero minimum size and stretch factor \a stretch. If \a
       
   942     index is negative the space is added at the end.
       
   943 
       
   944     \sa addStretch(), insertItem(), QSpacerItem
       
   945 */
       
   946 void QBoxLayout::insertStretch(int index, int stretch)
       
   947 {
       
   948     Q_D(QBoxLayout);
       
   949     if (index < 0)                                // append
       
   950         index = d->list.count();
       
   951 
       
   952     QLayoutItem *b;
       
   953     if (horz(d->dir))
       
   954         b = QLayoutPrivate::createSpacerItem(this, 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
       
   955     else
       
   956         b = QLayoutPrivate::createSpacerItem(this, 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
       
   957 
       
   958     QBoxLayoutItem *it = new QBoxLayoutItem(b, stretch);
       
   959     it->magic = true;
       
   960     d->list.insert(index, it);
       
   961     invalidate();
       
   962 }
       
   963 
       
   964 /*!
       
   965     \since 4.4
       
   966 
       
   967     Inserts \a spacerItem at position \a index, with zero minimum
       
   968     size and stretch factor. If \a index is negative the
       
   969     space is added at the end.
       
   970 
       
   971     \sa addSpacerItem(), insertStretch(), insertSpacing()
       
   972 */
       
   973 void QBoxLayout::insertSpacerItem(int index, QSpacerItem *spacerItem)
       
   974 {
       
   975     Q_D(QBoxLayout);
       
   976     if (index < 0)                                // append
       
   977         index = d->list.count();
       
   978 
       
   979     QBoxLayoutItem *it = new QBoxLayoutItem(spacerItem);
       
   980     it->magic = true;
       
   981     d->list.insert(index, it);
       
   982     invalidate();
       
   983 }
       
   984 
       
   985 /*!
       
   986     Inserts \a layout at position \a index, with stretch factor \a
       
   987     stretch. If \a index is negative, the layout is added at the end.
       
   988 
       
   989     \a layout becomes a child of the box layout.
       
   990 
       
   991     \sa addLayout(), insertItem()
       
   992 */
       
   993 void QBoxLayout::insertLayout(int index, QLayout *layout, int stretch)
       
   994 {
       
   995     Q_D(QBoxLayout);
       
   996     addChildLayout(layout);
       
   997     if (index < 0)                                // append
       
   998         index = d->list.count();
       
   999     QBoxLayoutItem *it = new QBoxLayoutItem(layout, stretch);
       
  1000     d->list.insert(index, it);
       
  1001     invalidate();
       
  1002 }
       
  1003 
       
  1004 /*!
       
  1005     Inserts \a widget at position \a index, with stretch factor \a
       
  1006     stretch and alignment \a alignment. If \a index is negative, the
       
  1007     widget is added at the end.
       
  1008 
       
  1009     The stretch factor applies only in the \l{direction()}{direction}
       
  1010     of the QBoxLayout, and is relative to the other boxes and widgets
       
  1011     in this QBoxLayout. Widgets and boxes with higher stretch factors
       
  1012     grow more.
       
  1013 
       
  1014     If the stretch factor is 0 and nothing else in the QBoxLayout has
       
  1015     a stretch factor greater than zero, the space is distributed
       
  1016     according to the QWidget:sizePolicy() of each widget that's
       
  1017     involved.
       
  1018 
       
  1019     The alignment is specified by \a alignment. The default alignment
       
  1020     is 0, which means that the widget fills the entire cell.
       
  1021 
       
  1022     \sa addWidget(), insertItem()
       
  1023 */
       
  1024 void QBoxLayout::insertWidget(int index, QWidget *widget, int stretch,
       
  1025                               Qt::Alignment alignment)
       
  1026 {
       
  1027     Q_D(QBoxLayout);
       
  1028     if (!checkWidget(this, widget))
       
  1029          return;
       
  1030     addChildWidget(widget);
       
  1031     if (index < 0)                                // append
       
  1032         index = d->list.count();
       
  1033     QWidgetItem *b = QLayoutPrivate::createWidgetItem(this, widget);
       
  1034     b->setAlignment(alignment);
       
  1035 
       
  1036     QBoxLayoutItem *it;
       
  1037     QT_TRY{
       
  1038         it = new QBoxLayoutItem(b, stretch);
       
  1039     } QT_CATCH(...) {
       
  1040         delete b;
       
  1041         QT_RETHROW;
       
  1042     }
       
  1043 
       
  1044     QT_TRY{
       
  1045         d->list.insert(index, it);
       
  1046     } QT_CATCH(...) {
       
  1047         delete it;
       
  1048         QT_RETHROW;
       
  1049     }
       
  1050     invalidate();
       
  1051 }
       
  1052 
       
  1053 /*!
       
  1054     Adds a non-stretchable space (a QSpacerItem) with size \a size
       
  1055     to the end of this box layout. QBoxLayout provides default margin
       
  1056     and spacing. This function adds additional space.
       
  1057 
       
  1058     \sa insertSpacing(), addItem(), QSpacerItem
       
  1059 */
       
  1060 void QBoxLayout::addSpacing(int size)
       
  1061 {
       
  1062     insertSpacing(-1, size);
       
  1063 }
       
  1064 
       
  1065 /*!
       
  1066     Adds a stretchable space (a QSpacerItem) with zero minimum
       
  1067     size and stretch factor \a stretch to the end of this box layout.
       
  1068 
       
  1069     \sa insertStretch(), addItem(), QSpacerItem
       
  1070 */
       
  1071 void QBoxLayout::addStretch(int stretch)
       
  1072 {
       
  1073     insertStretch(-1, stretch);
       
  1074 }
       
  1075 
       
  1076 /*!
       
  1077     \since 4.4
       
  1078 
       
  1079     Adds \a spacerItem to the end of this box layout.
       
  1080 
       
  1081     \sa addSpacing(), addStretch()
       
  1082 */
       
  1083 void QBoxLayout::addSpacerItem(QSpacerItem *spacerItem)
       
  1084 {
       
  1085     insertSpacerItem(-1, spacerItem);
       
  1086 }
       
  1087 
       
  1088 /*!
       
  1089     Adds \a widget to the end of this box layout, with a stretch
       
  1090     factor of \a stretch and alignment \a alignment.
       
  1091 
       
  1092     The stretch factor applies only in the \l{direction()}{direction}
       
  1093     of the QBoxLayout, and is relative to the other boxes and widgets
       
  1094     in this QBoxLayout. Widgets and boxes with higher stretch factors
       
  1095     grow more.
       
  1096 
       
  1097     If the stretch factor is 0 and nothing else in the QBoxLayout has
       
  1098     a stretch factor greater than zero, the space is distributed
       
  1099     according to the QWidget:sizePolicy() of each widget that's
       
  1100     involved.
       
  1101 
       
  1102     The alignment is specified by \a alignment. The default
       
  1103     alignment is 0, which means that the widget fills the entire cell.
       
  1104 
       
  1105     \sa insertWidget(), addItem(), addLayout(), addStretch(),
       
  1106         addSpacing(), addStrut()
       
  1107 */
       
  1108 void QBoxLayout::addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
       
  1109 {
       
  1110     insertWidget(-1, widget, stretch, alignment);
       
  1111 }
       
  1112 
       
  1113 /*!
       
  1114     Adds \a layout to the end of the box, with serial stretch factor
       
  1115     \a stretch.
       
  1116 
       
  1117     \sa insertLayout(), addItem(), addWidget()
       
  1118 */
       
  1119 void QBoxLayout::addLayout(QLayout *layout, int stretch)
       
  1120 {
       
  1121     insertLayout(-1, layout, stretch);
       
  1122 }
       
  1123 
       
  1124 /*!
       
  1125     Limits the perpendicular dimension of the box (e.g. height if the
       
  1126     box is \l LeftToRight) to a minimum of \a size. Other constraints
       
  1127     may increase the limit.
       
  1128 
       
  1129     \sa addItem()
       
  1130 */
       
  1131 void QBoxLayout::addStrut(int size)
       
  1132 {
       
  1133     Q_D(QBoxLayout);
       
  1134     QLayoutItem *b;
       
  1135     if (horz(d->dir))
       
  1136         b = QLayoutPrivate::createSpacerItem(this, 0, size, QSizePolicy::Fixed, QSizePolicy::Minimum);
       
  1137     else
       
  1138         b = QLayoutPrivate::createSpacerItem(this, size, 0, QSizePolicy::Minimum, QSizePolicy::Fixed);
       
  1139 
       
  1140     QBoxLayoutItem *it = new QBoxLayoutItem(b);
       
  1141     it->magic = true;
       
  1142     d->list.append(it);
       
  1143     invalidate();
       
  1144 }
       
  1145 
       
  1146 /*!
       
  1147     \fn int QBoxLayout::findWidget(QWidget *widget)
       
  1148 
       
  1149     Use indexOf(\a widget) instead.
       
  1150 */
       
  1151 
       
  1152 /*!
       
  1153     Sets the stretch factor for \a widget to \a stretch and returns
       
  1154     true if \a widget is found in this layout (not including child
       
  1155     layouts); otherwise returns false.
       
  1156 
       
  1157     \sa setAlignment()
       
  1158 */
       
  1159 bool QBoxLayout::setStretchFactor(QWidget *widget, int stretch)
       
  1160 {
       
  1161     Q_D(QBoxLayout);
       
  1162     if (!widget)
       
  1163         return false;
       
  1164     for (int i = 0; i < d->list.size(); ++i) {
       
  1165         QBoxLayoutItem *box = d->list.at(i);
       
  1166         if (box->item->widget() == widget) {
       
  1167             box->stretch = stretch;
       
  1168             invalidate();
       
  1169             return true;
       
  1170         }
       
  1171     }
       
  1172     return false;
       
  1173 }
       
  1174 
       
  1175 /*!
       
  1176     \overload
       
  1177 
       
  1178     Sets the stretch factor for the layout \a layout to \a stretch and
       
  1179     returns true if \a layout is found in this layout (not including
       
  1180     child layouts); otherwise returns false.
       
  1181 */
       
  1182 bool QBoxLayout::setStretchFactor(QLayout *layout, int stretch)
       
  1183 {
       
  1184     Q_D(QBoxLayout);
       
  1185     for (int i = 0; i < d->list.size(); ++i) {
       
  1186         QBoxLayoutItem *box = d->list.at(i);
       
  1187         if (box->item->layout() == layout) {
       
  1188             if (box->stretch != stretch) {
       
  1189                 box->stretch = stretch;
       
  1190                 invalidate();
       
  1191             }
       
  1192             return true;
       
  1193         }
       
  1194     }
       
  1195     return false;
       
  1196 }
       
  1197 
       
  1198 /*!
       
  1199     Sets the stretch factor at position \a index. to \a stretch.
       
  1200 
       
  1201     \since 4.5
       
  1202 */
       
  1203 
       
  1204 void QBoxLayout::setStretch(int index, int stretch)
       
  1205 {
       
  1206     Q_D(QBoxLayout);
       
  1207     if (index >= 0 && index < d->list.size()) {
       
  1208         QBoxLayoutItem *box = d->list.at(index);
       
  1209         if (box->stretch != stretch) {
       
  1210             box->stretch = stretch;
       
  1211             invalidate();
       
  1212         }
       
  1213     }
       
  1214 }
       
  1215 
       
  1216 /*!
       
  1217     Returns the stretch factor at position \a index.
       
  1218 
       
  1219     \since 4.5
       
  1220 */
       
  1221 
       
  1222 int QBoxLayout::stretch(int index) const
       
  1223 {
       
  1224     Q_D(const QBoxLayout);
       
  1225     if (index >= 0 && index < d->list.size())
       
  1226         return d->list.at(index)->stretch;
       
  1227     return -1;
       
  1228 }
       
  1229 
       
  1230 /*!
       
  1231     Sets the direction of this layout to \a direction.
       
  1232 */
       
  1233 void QBoxLayout::setDirection(Direction direction)
       
  1234 {
       
  1235     Q_D(QBoxLayout);
       
  1236     if (d->dir == direction)
       
  1237         return;
       
  1238     if (horz(d->dir) != horz(direction)) {
       
  1239         //swap around the spacers (the "magic" bits)
       
  1240         //#### a bit yucky, knows too much.
       
  1241         //#### probably best to add access functions to spacerItem
       
  1242         //#### or even a QSpacerItem::flip()
       
  1243         for (int i = 0; i < d->list.size(); ++i) {
       
  1244             QBoxLayoutItem *box = d->list.at(i);
       
  1245             if (box->magic) {
       
  1246                 QSpacerItem *sp = box->item->spacerItem();
       
  1247                 if (sp) {
       
  1248                     if (sp->expandingDirections() == Qt::Orientations(0) /*No Direction*/) {
       
  1249                         //spacing or strut
       
  1250                         QSize s = sp->sizeHint();
       
  1251                         sp->changeSize(s.height(), s.width(),
       
  1252                             horz(direction) ? QSizePolicy::Fixed:QSizePolicy::Minimum,
       
  1253                             horz(direction) ? QSizePolicy::Minimum:QSizePolicy::Fixed);
       
  1254 
       
  1255                     } else {
       
  1256                         //stretch
       
  1257                         if (horz(direction))
       
  1258                             sp->changeSize(0, 0, QSizePolicy::Expanding,
       
  1259                                             QSizePolicy::Minimum);
       
  1260                         else
       
  1261                             sp->changeSize(0, 0, QSizePolicy::Minimum,
       
  1262                                             QSizePolicy::Expanding);
       
  1263                     }
       
  1264                 }
       
  1265             }
       
  1266         }
       
  1267     }
       
  1268     d->dir = direction;
       
  1269     invalidate();
       
  1270 }
       
  1271 
       
  1272 /*!
       
  1273     \fn QBoxLayout::Direction QBoxLayout::direction() const
       
  1274 
       
  1275     Returns the direction of the box. addWidget() and addSpacing()
       
  1276     work in this direction; the stretch stretches in this direction.
       
  1277 
       
  1278     \sa QBoxLayout::Direction addWidget() addSpacing()
       
  1279 */
       
  1280 
       
  1281 QBoxLayout::Direction QBoxLayout::direction() const
       
  1282 {
       
  1283     Q_D(const QBoxLayout);
       
  1284     return d->dir;
       
  1285 }
       
  1286 
       
  1287 /*!
       
  1288     \class QHBoxLayout
       
  1289     \brief The QHBoxLayout class lines up widgets horizontally.
       
  1290 
       
  1291     \ingroup geomanagement
       
  1292 
       
  1293     This class is used to construct horizontal box layout objects. See
       
  1294     QBoxLayout for details.
       
  1295 
       
  1296     The simplest use of the class is like this:
       
  1297 
       
  1298     \snippet doc/src/snippets/layouts/layouts.cpp 0
       
  1299     \snippet doc/src/snippets/layouts/layouts.cpp 1
       
  1300     \snippet doc/src/snippets/layouts/layouts.cpp 2
       
  1301     \codeline
       
  1302     \snippet doc/src/snippets/layouts/layouts.cpp 3
       
  1303     \snippet doc/src/snippets/layouts/layouts.cpp 4
       
  1304     \snippet doc/src/snippets/layouts/layouts.cpp 5
       
  1305 
       
  1306     First, we create the widgets we want in the layout. Then, we
       
  1307     create the QHBoxLayout object and add the widgets into the
       
  1308     layout. Finally, we call QWidget::setLayout() to install the
       
  1309     QHBoxLayout object onto the widget. At that point, the widgets in
       
  1310     the layout are reparented to have \c window as their parent.
       
  1311 
       
  1312     \image qhboxlayout-with-5-children.png Horizontal box layout with five child widgets
       
  1313 
       
  1314     \sa QVBoxLayout, QGridLayout, QStackedLayout, {Layout Management}, {Basic Layouts Example}
       
  1315 */
       
  1316 
       
  1317 
       
  1318 /*!
       
  1319     Constructs a new top-level horizontal box with
       
  1320     parent \a parent.
       
  1321 */
       
  1322 QHBoxLayout::QHBoxLayout(QWidget *parent)
       
  1323     : QBoxLayout(LeftToRight, parent)
       
  1324 {
       
  1325 }
       
  1326 
       
  1327 /*!
       
  1328     Constructs a new horizontal box. You must add
       
  1329     it to another layout.
       
  1330 */
       
  1331 QHBoxLayout::QHBoxLayout()
       
  1332     : QBoxLayout(LeftToRight)
       
  1333 {
       
  1334 }
       
  1335 
       
  1336 
       
  1337 
       
  1338 #ifdef QT3_SUPPORT
       
  1339 /*!
       
  1340     Constructs a new top-level horizontal box called \a name, with
       
  1341     parent \a parent.
       
  1342 
       
  1343     The \a margin is the number of pixels between the edge of the
       
  1344     widget and its managed children. The \a spacing is the default
       
  1345     number of pixels between neighboring children. If \a spacing is -1
       
  1346     the value of \a margin is used for \a spacing.
       
  1347 */
       
  1348 QHBoxLayout::QHBoxLayout(QWidget *parent, int margin,
       
  1349                          int spacing, const char *name)
       
  1350     : QBoxLayout(LeftToRight, parent)
       
  1351 {
       
  1352     setMargin(margin);
       
  1353     setSpacing(spacing<0 ? margin : spacing);
       
  1354     setObjectName(QString::fromAscii(name));
       
  1355 }
       
  1356 
       
  1357 /*!
       
  1358     Constructs a new horizontal box called name \a name and adds it to
       
  1359     \a parentLayout.
       
  1360 
       
  1361     The \a spacing is the default number of pixels between neighboring
       
  1362     children. If \a spacing is -1, this QHBoxLayout will inherit its
       
  1363     parent's spacing().
       
  1364 */
       
  1365 QHBoxLayout::QHBoxLayout(QLayout *parentLayout, int spacing,
       
  1366                           const char *name)
       
  1367     : QBoxLayout(LeftToRight)
       
  1368 {
       
  1369     setSpacing(spacing);
       
  1370     setObjectName(QString::fromAscii(name));
       
  1371     if (parentLayout) {
       
  1372         setParent(parentLayout);
       
  1373         parentLayout->addItem(this);
       
  1374     }
       
  1375 }
       
  1376 
       
  1377 /*!
       
  1378     Constructs a new horizontal box called name \a name. You must add
       
  1379     it to another layout.
       
  1380 
       
  1381     The \a spacing is the default number of pixels between neighboring
       
  1382     children. If \a spacing is -1, this QHBoxLayout will inherit its
       
  1383     parent's spacing().
       
  1384 */
       
  1385 QHBoxLayout::QHBoxLayout(int spacing, const char *name)
       
  1386     : QBoxLayout(LeftToRight)
       
  1387 {
       
  1388     setSpacing(spacing);
       
  1389     setObjectName(QString::fromAscii(name));
       
  1390 }
       
  1391 #endif
       
  1392 
       
  1393 
       
  1394 /*!
       
  1395     Destroys this box layout.
       
  1396 
       
  1397     The layout's widgets aren't destroyed.
       
  1398 */
       
  1399 QHBoxLayout::~QHBoxLayout()
       
  1400 {
       
  1401 }
       
  1402 
       
  1403 /*!
       
  1404     \class QVBoxLayout
       
  1405     \brief The QVBoxLayout class lines up widgets vertically.
       
  1406 
       
  1407     \ingroup geomanagement
       
  1408 
       
  1409     This class is used to construct vertical box layout objects. See
       
  1410     QBoxLayout for details.
       
  1411 
       
  1412     The simplest use of the class is like this:
       
  1413 
       
  1414     \snippet doc/src/snippets/layouts/layouts.cpp 6
       
  1415     \snippet doc/src/snippets/layouts/layouts.cpp 7
       
  1416     \snippet doc/src/snippets/layouts/layouts.cpp 8
       
  1417     \codeline
       
  1418     \snippet doc/src/snippets/layouts/layouts.cpp 9
       
  1419     \snippet doc/src/snippets/layouts/layouts.cpp 10
       
  1420     \snippet doc/src/snippets/layouts/layouts.cpp 11
       
  1421 
       
  1422     First, we create the widgets we want in the layout. Then, we
       
  1423     create the QVBoxLayout object and add the widgets into the
       
  1424     layout. Finally, we call QWidget::setLayout() to install the
       
  1425     QVBoxLayout object onto the widget. At that point, the widgets in
       
  1426     the layout are reparented to have \c window as their parent.
       
  1427 
       
  1428     \image qvboxlayout-with-5-children.png Horizontal box layout with five child widgets
       
  1429 
       
  1430     \sa QHBoxLayout, QGridLayout, QStackedLayout, {Layout Management}, {Basic Layouts Example}
       
  1431 */
       
  1432 
       
  1433 /*!
       
  1434     Constructs a new top-level vertical box with
       
  1435     parent \a parent.
       
  1436 */
       
  1437 QVBoxLayout::QVBoxLayout(QWidget *parent)
       
  1438     : QBoxLayout(TopToBottom, parent)
       
  1439 {
       
  1440 }
       
  1441 
       
  1442 /*!
       
  1443     Constructs a new vertical box. You must add
       
  1444     it to another layout.
       
  1445 
       
  1446 */
       
  1447 QVBoxLayout::QVBoxLayout()
       
  1448     : QBoxLayout(TopToBottom)
       
  1449 {
       
  1450 }
       
  1451 
       
  1452 #ifdef QT3_SUPPORT
       
  1453 /*!
       
  1454     Constructs a new top-level vertical box called \a name, with
       
  1455     parent \a parent.
       
  1456 
       
  1457     The \a margin is the number of pixels between the edge of the
       
  1458     widget and its managed children. The \a spacing is the default
       
  1459     number of pixels between neighboring children. If \a spacing is -1
       
  1460     the value of \a margin is used for \a spacing.
       
  1461 */
       
  1462 QVBoxLayout::QVBoxLayout(QWidget *parent, int margin, int spacing,
       
  1463                          const char *name)
       
  1464     : QBoxLayout(TopToBottom, parent)
       
  1465 {
       
  1466     setMargin(margin);
       
  1467     setSpacing(spacing<0 ? margin : spacing);
       
  1468     setObjectName(QString::fromAscii(name));
       
  1469 }
       
  1470 
       
  1471 /*!
       
  1472     Constructs a new vertical box called name \a name and adds it to
       
  1473     \a parentLayout.
       
  1474 
       
  1475     The \a spacing is the default number of pixels between neighboring
       
  1476     children. If \a spacing is -1, this QVBoxLayout will inherit its
       
  1477     parent's spacing().
       
  1478 */
       
  1479 QVBoxLayout::QVBoxLayout(QLayout *parentLayout, int spacing,
       
  1480                           const char *name)
       
  1481     : QBoxLayout(TopToBottom)
       
  1482 {
       
  1483     setSpacing(spacing);
       
  1484     setObjectName(QString::fromAscii(name));
       
  1485     if (parentLayout) {
       
  1486         setParent(parentLayout);
       
  1487         parentLayout->addItem(this);
       
  1488     }
       
  1489 }
       
  1490 
       
  1491 /*!
       
  1492     Constructs a new vertical box called name \a name. You must add
       
  1493     it to another layout.
       
  1494 
       
  1495     The \a spacing is the default number of pixels between neighboring
       
  1496     children. If \a spacing is -1, this QVBoxLayout will inherit its
       
  1497     parent's spacing().
       
  1498 */
       
  1499 QVBoxLayout::QVBoxLayout(int spacing, const char *name)
       
  1500     : QBoxLayout(TopToBottom)
       
  1501 {
       
  1502     setSpacing(spacing);
       
  1503     setObjectName(QString::fromAscii(name));
       
  1504 }
       
  1505 
       
  1506 
       
  1507 #endif
       
  1508 
       
  1509 /*!
       
  1510     Destroys this box layout.
       
  1511 
       
  1512     The layout's widgets aren't destroyed.
       
  1513 */
       
  1514 QVBoxLayout::~QVBoxLayout()
       
  1515 {
       
  1516 }
       
  1517 
       
  1518 /*!
       
  1519     \fn QWidget *QLayout::mainWidget() const
       
  1520 
       
  1521     Use parentWidget() instead.
       
  1522 */
       
  1523 
       
  1524 /*!
       
  1525     \fn void QLayout::remove(QWidget *widget)
       
  1526 
       
  1527     Use removeWidget(\a widget) instead.
       
  1528 */
       
  1529 
       
  1530 /*!
       
  1531     \fn void QLayout::add(QWidget *widget)
       
  1532 
       
  1533     Use addWidget(\a widget) instead.
       
  1534 */
       
  1535 
       
  1536 /*!
       
  1537     \fn QLayoutIterator QLayout::iterator()
       
  1538 
       
  1539     Use a QLayoutIterator() constructor instead.
       
  1540 */
       
  1541 
       
  1542 /*!
       
  1543     \fn int QLayout::defaultBorder() const
       
  1544 
       
  1545     Use spacing() instead.
       
  1546 */
       
  1547 
       
  1548 QT_END_NAMESPACE