util/src/gui/kernel/qboxlayout.cpp
changeset 7 f7bc934e204c
equal deleted inserted replaced
3:41300fa6a67c 7:f7bc934e204c
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2010 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                     int width = qBound(box->item->minimumSize().width(), s.width(), box->item->maximumSize().width());
       
   835                     a[i].sizeHint = a[i].minimumSize =
       
   836                                     box->item->heightForWidth(width);
       
   837                 }
       
   838             }
       
   839         }
       
   840 
       
   841         Direction visualDir = d->dir;
       
   842         QWidget *parent = parentWidget();
       
   843         if (parent && parent->isRightToLeft()) {
       
   844             if (d->dir == LeftToRight)
       
   845                 visualDir = RightToLeft;
       
   846             else if (d->dir == RightToLeft)
       
   847                 visualDir = LeftToRight;
       
   848         }
       
   849 
       
   850         qGeomCalc(a, 0, n, pos, space);
       
   851 
       
   852         bool reverse = (horz(visualDir)
       
   853                         ? ((r.right() > oldRect.right()) != (visualDir == RightToLeft))
       
   854                         : r.bottom() > oldRect.bottom());
       
   855         for (int j = 0; j < n; j++) {
       
   856             int i = reverse ? n-j-1 : j;
       
   857             QBoxLayoutItem *box = d->list.at(i);
       
   858 
       
   859             switch (visualDir) {
       
   860             case LeftToRight:
       
   861                 box->item->setGeometry(QRect(a.at(i).pos, s.y(), a.at(i).size, s.height()));
       
   862                 break;
       
   863             case RightToLeft:
       
   864                 box->item->setGeometry(QRect(s.left() + s.right() - a.at(i).pos - a.at(i).size + 1,
       
   865                                              s.y(), a.at(i).size, s.height()));
       
   866                 break;
       
   867             case TopToBottom:
       
   868                 box->item->setGeometry(QRect(s.x(), a.at(i).pos, s.width(), a.at(i).size));
       
   869                 break;
       
   870             case BottomToTop:
       
   871                 box->item->setGeometry(QRect(s.x(),
       
   872                                              s.top() + s.bottom() - a.at(i).pos - a.at(i).size + 1,
       
   873                                              s.width(), a.at(i).size));
       
   874             }
       
   875         }
       
   876     }
       
   877 }
       
   878 
       
   879 /*!
       
   880     \reimp
       
   881 */
       
   882 void QBoxLayout::addItem(QLayoutItem *item)
       
   883 {
       
   884     Q_D(QBoxLayout);
       
   885     QBoxLayoutItem *it = new QBoxLayoutItem(item);
       
   886     d->list.append(it);
       
   887     invalidate();
       
   888 }
       
   889 
       
   890 /*!
       
   891     Inserts \a item into this box layout at position \a index. If \a
       
   892     index is negative, the item is added at the end.
       
   893 
       
   894     \sa addItem(), insertWidget(), insertLayout(), insertStretch(),
       
   895         insertSpacing()
       
   896 */
       
   897 void QBoxLayout::insertItem(int index, QLayoutItem *item)
       
   898 {
       
   899     Q_D(QBoxLayout);
       
   900     if (index < 0)                                // append
       
   901         index = d->list.count();
       
   902 
       
   903     QBoxLayoutItem *it = new QBoxLayoutItem(item);
       
   904     d->list.insert(index, it);
       
   905     invalidate();
       
   906 }
       
   907 
       
   908 /*!
       
   909     Inserts a non-stretchable space (a QSpacerItem) at position \a index, with
       
   910     size \a size. If \a index is negative the space is added at the end.
       
   911 
       
   912     The box layout has default margin and spacing. This function adds
       
   913     additional space.
       
   914 
       
   915     \sa addSpacing(), insertItem(), QSpacerItem
       
   916 */
       
   917 void QBoxLayout::insertSpacing(int index, int size)
       
   918 {
       
   919     Q_D(QBoxLayout);
       
   920     if (index < 0)                                // append
       
   921         index = d->list.count();
       
   922 
       
   923     QLayoutItem *b;
       
   924     if (horz(d->dir))
       
   925         b = QLayoutPrivate::createSpacerItem(this, size, 0, QSizePolicy::Fixed, QSizePolicy::Minimum);
       
   926     else
       
   927         b = QLayoutPrivate::createSpacerItem(this, 0, size, QSizePolicy::Minimum, QSizePolicy::Fixed);
       
   928 
       
   929     QT_TRY {
       
   930         QBoxLayoutItem *it = new QBoxLayoutItem(b);
       
   931         it->magic = true;
       
   932         d->list.insert(index, it);
       
   933 
       
   934     } QT_CATCH(...) {
       
   935         delete b;
       
   936         QT_RETHROW;
       
   937     }
       
   938     invalidate();
       
   939 }
       
   940 
       
   941 /*!
       
   942     Inserts a stretchable space (a QSpacerItem) at position \a
       
   943     index, with zero minimum size and stretch factor \a stretch. If \a
       
   944     index is negative the space is added at the end.
       
   945 
       
   946     \sa addStretch(), insertItem(), QSpacerItem
       
   947 */
       
   948 void QBoxLayout::insertStretch(int index, int stretch)
       
   949 {
       
   950     Q_D(QBoxLayout);
       
   951     if (index < 0)                                // append
       
   952         index = d->list.count();
       
   953 
       
   954     QLayoutItem *b;
       
   955     if (horz(d->dir))
       
   956         b = QLayoutPrivate::createSpacerItem(this, 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
       
   957     else
       
   958         b = QLayoutPrivate::createSpacerItem(this, 0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding);
       
   959 
       
   960     QBoxLayoutItem *it = new QBoxLayoutItem(b, stretch);
       
   961     it->magic = true;
       
   962     d->list.insert(index, it);
       
   963     invalidate();
       
   964 }
       
   965 
       
   966 /*!
       
   967     \since 4.4
       
   968 
       
   969     Inserts \a spacerItem at position \a index, with zero minimum
       
   970     size and stretch factor. If \a index is negative the
       
   971     space is added at the end.
       
   972 
       
   973     \sa addSpacerItem(), insertStretch(), insertSpacing()
       
   974 */
       
   975 void QBoxLayout::insertSpacerItem(int index, QSpacerItem *spacerItem)
       
   976 {
       
   977     Q_D(QBoxLayout);
       
   978     if (index < 0)                                // append
       
   979         index = d->list.count();
       
   980 
       
   981     QBoxLayoutItem *it = new QBoxLayoutItem(spacerItem);
       
   982     it->magic = true;
       
   983     d->list.insert(index, it);
       
   984     invalidate();
       
   985 }
       
   986 
       
   987 /*!
       
   988     Inserts \a layout at position \a index, with stretch factor \a
       
   989     stretch. If \a index is negative, the layout is added at the end.
       
   990 
       
   991     \a layout becomes a child of the box layout.
       
   992 
       
   993     \sa addLayout(), insertItem()
       
   994 */
       
   995 void QBoxLayout::insertLayout(int index, QLayout *layout, int stretch)
       
   996 {
       
   997     Q_D(QBoxLayout);
       
   998     addChildLayout(layout);
       
   999     if (index < 0)                                // append
       
  1000         index = d->list.count();
       
  1001     QBoxLayoutItem *it = new QBoxLayoutItem(layout, stretch);
       
  1002     d->list.insert(index, it);
       
  1003     invalidate();
       
  1004 }
       
  1005 
       
  1006 /*!
       
  1007     Inserts \a widget at position \a index, with stretch factor \a
       
  1008     stretch and alignment \a alignment. If \a index is negative, the
       
  1009     widget is added at the end.
       
  1010 
       
  1011     The stretch factor applies only in the \l{direction()}{direction}
       
  1012     of the QBoxLayout, and is relative to the other boxes and widgets
       
  1013     in this QBoxLayout. Widgets and boxes with higher stretch factors
       
  1014     grow more.
       
  1015 
       
  1016     If the stretch factor is 0 and nothing else in the QBoxLayout has
       
  1017     a stretch factor greater than zero, the space is distributed
       
  1018     according to the QWidget:sizePolicy() of each widget that's
       
  1019     involved.
       
  1020 
       
  1021     The alignment is specified by \a alignment. The default alignment
       
  1022     is 0, which means that the widget fills the entire cell.
       
  1023 
       
  1024     \sa addWidget(), insertItem()
       
  1025 */
       
  1026 void QBoxLayout::insertWidget(int index, QWidget *widget, int stretch,
       
  1027                               Qt::Alignment alignment)
       
  1028 {
       
  1029     Q_D(QBoxLayout);
       
  1030     if (!checkWidget(this, widget))
       
  1031          return;
       
  1032     addChildWidget(widget);
       
  1033     if (index < 0)                                // append
       
  1034         index = d->list.count();
       
  1035     QWidgetItem *b = QLayoutPrivate::createWidgetItem(this, widget);
       
  1036     b->setAlignment(alignment);
       
  1037 
       
  1038     QBoxLayoutItem *it;
       
  1039     QT_TRY{
       
  1040         it = new QBoxLayoutItem(b, stretch);
       
  1041     } QT_CATCH(...) {
       
  1042         delete b;
       
  1043         QT_RETHROW;
       
  1044     }
       
  1045 
       
  1046     QT_TRY{
       
  1047         d->list.insert(index, it);
       
  1048     } QT_CATCH(...) {
       
  1049         delete it;
       
  1050         QT_RETHROW;
       
  1051     }
       
  1052     invalidate();
       
  1053 }
       
  1054 
       
  1055 /*!
       
  1056     Adds a non-stretchable space (a QSpacerItem) with size \a size
       
  1057     to the end of this box layout. QBoxLayout provides default margin
       
  1058     and spacing. This function adds additional space.
       
  1059 
       
  1060     \sa insertSpacing(), addItem(), QSpacerItem
       
  1061 */
       
  1062 void QBoxLayout::addSpacing(int size)
       
  1063 {
       
  1064     insertSpacing(-1, size);
       
  1065 }
       
  1066 
       
  1067 /*!
       
  1068     Adds a stretchable space (a QSpacerItem) with zero minimum
       
  1069     size and stretch factor \a stretch to the end of this box layout.
       
  1070 
       
  1071     \sa insertStretch(), addItem(), QSpacerItem
       
  1072 */
       
  1073 void QBoxLayout::addStretch(int stretch)
       
  1074 {
       
  1075     insertStretch(-1, stretch);
       
  1076 }
       
  1077 
       
  1078 /*!
       
  1079     \since 4.4
       
  1080 
       
  1081     Adds \a spacerItem to the end of this box layout.
       
  1082 
       
  1083     \sa addSpacing(), addStretch()
       
  1084 */
       
  1085 void QBoxLayout::addSpacerItem(QSpacerItem *spacerItem)
       
  1086 {
       
  1087     insertSpacerItem(-1, spacerItem);
       
  1088 }
       
  1089 
       
  1090 /*!
       
  1091     Adds \a widget to the end of this box layout, with a stretch
       
  1092     factor of \a stretch and alignment \a alignment.
       
  1093 
       
  1094     The stretch factor applies only in the \l{direction()}{direction}
       
  1095     of the QBoxLayout, and is relative to the other boxes and widgets
       
  1096     in this QBoxLayout. Widgets and boxes with higher stretch factors
       
  1097     grow more.
       
  1098 
       
  1099     If the stretch factor is 0 and nothing else in the QBoxLayout has
       
  1100     a stretch factor greater than zero, the space is distributed
       
  1101     according to the QWidget:sizePolicy() of each widget that's
       
  1102     involved.
       
  1103 
       
  1104     The alignment is specified by \a alignment. The default
       
  1105     alignment is 0, which means that the widget fills the entire cell.
       
  1106 
       
  1107     \sa insertWidget(), addItem(), addLayout(), addStretch(),
       
  1108         addSpacing(), addStrut()
       
  1109 */
       
  1110 void QBoxLayout::addWidget(QWidget *widget, int stretch, Qt::Alignment alignment)
       
  1111 {
       
  1112     insertWidget(-1, widget, stretch, alignment);
       
  1113 }
       
  1114 
       
  1115 /*!
       
  1116     Adds \a layout to the end of the box, with serial stretch factor
       
  1117     \a stretch.
       
  1118 
       
  1119     \sa insertLayout(), addItem(), addWidget()
       
  1120 */
       
  1121 void QBoxLayout::addLayout(QLayout *layout, int stretch)
       
  1122 {
       
  1123     insertLayout(-1, layout, stretch);
       
  1124 }
       
  1125 
       
  1126 /*!
       
  1127     Limits the perpendicular dimension of the box (e.g. height if the
       
  1128     box is \l LeftToRight) to a minimum of \a size. Other constraints
       
  1129     may increase the limit.
       
  1130 
       
  1131     \sa addItem()
       
  1132 */
       
  1133 void QBoxLayout::addStrut(int size)
       
  1134 {
       
  1135     Q_D(QBoxLayout);
       
  1136     QLayoutItem *b;
       
  1137     if (horz(d->dir))
       
  1138         b = QLayoutPrivate::createSpacerItem(this, 0, size, QSizePolicy::Fixed, QSizePolicy::Minimum);
       
  1139     else
       
  1140         b = QLayoutPrivate::createSpacerItem(this, size, 0, QSizePolicy::Minimum, QSizePolicy::Fixed);
       
  1141 
       
  1142     QBoxLayoutItem *it = new QBoxLayoutItem(b);
       
  1143     it->magic = true;
       
  1144     d->list.append(it);
       
  1145     invalidate();
       
  1146 }
       
  1147 
       
  1148 /*!
       
  1149     \fn int QBoxLayout::findWidget(QWidget *widget)
       
  1150 
       
  1151     Use indexOf(\a widget) instead.
       
  1152 */
       
  1153 
       
  1154 /*!
       
  1155     Sets the stretch factor for \a widget to \a stretch and returns
       
  1156     true if \a widget is found in this layout (not including child
       
  1157     layouts); otherwise returns false.
       
  1158 
       
  1159     \sa setAlignment()
       
  1160 */
       
  1161 bool QBoxLayout::setStretchFactor(QWidget *widget, int stretch)
       
  1162 {
       
  1163     Q_D(QBoxLayout);
       
  1164     if (!widget)
       
  1165         return false;
       
  1166     for (int i = 0; i < d->list.size(); ++i) {
       
  1167         QBoxLayoutItem *box = d->list.at(i);
       
  1168         if (box->item->widget() == widget) {
       
  1169             box->stretch = stretch;
       
  1170             invalidate();
       
  1171             return true;
       
  1172         }
       
  1173     }
       
  1174     return false;
       
  1175 }
       
  1176 
       
  1177 /*!
       
  1178     \overload
       
  1179 
       
  1180     Sets the stretch factor for the layout \a layout to \a stretch and
       
  1181     returns true if \a layout is found in this layout (not including
       
  1182     child layouts); otherwise returns false.
       
  1183 */
       
  1184 bool QBoxLayout::setStretchFactor(QLayout *layout, int stretch)
       
  1185 {
       
  1186     Q_D(QBoxLayout);
       
  1187     for (int i = 0; i < d->list.size(); ++i) {
       
  1188         QBoxLayoutItem *box = d->list.at(i);
       
  1189         if (box->item->layout() == layout) {
       
  1190             if (box->stretch != stretch) {
       
  1191                 box->stretch = stretch;
       
  1192                 invalidate();
       
  1193             }
       
  1194             return true;
       
  1195         }
       
  1196     }
       
  1197     return false;
       
  1198 }
       
  1199 
       
  1200 /*!
       
  1201     Sets the stretch factor at position \a index. to \a stretch.
       
  1202 
       
  1203     \since 4.5
       
  1204 */
       
  1205 
       
  1206 void QBoxLayout::setStretch(int index, int stretch)
       
  1207 {
       
  1208     Q_D(QBoxLayout);
       
  1209     if (index >= 0 && index < d->list.size()) {
       
  1210         QBoxLayoutItem *box = d->list.at(index);
       
  1211         if (box->stretch != stretch) {
       
  1212             box->stretch = stretch;
       
  1213             invalidate();
       
  1214         }
       
  1215     }
       
  1216 }
       
  1217 
       
  1218 /*!
       
  1219     Returns the stretch factor at position \a index.
       
  1220 
       
  1221     \since 4.5
       
  1222 */
       
  1223 
       
  1224 int QBoxLayout::stretch(int index) const
       
  1225 {
       
  1226     Q_D(const QBoxLayout);
       
  1227     if (index >= 0 && index < d->list.size())
       
  1228         return d->list.at(index)->stretch;
       
  1229     return -1;
       
  1230 }
       
  1231 
       
  1232 /*!
       
  1233     Sets the direction of this layout to \a direction.
       
  1234 */
       
  1235 void QBoxLayout::setDirection(Direction direction)
       
  1236 {
       
  1237     Q_D(QBoxLayout);
       
  1238     if (d->dir == direction)
       
  1239         return;
       
  1240     if (horz(d->dir) != horz(direction)) {
       
  1241         //swap around the spacers (the "magic" bits)
       
  1242         //#### a bit yucky, knows too much.
       
  1243         //#### probably best to add access functions to spacerItem
       
  1244         //#### or even a QSpacerItem::flip()
       
  1245         for (int i = 0; i < d->list.size(); ++i) {
       
  1246             QBoxLayoutItem *box = d->list.at(i);
       
  1247             if (box->magic) {
       
  1248                 QSpacerItem *sp = box->item->spacerItem();
       
  1249                 if (sp) {
       
  1250                     if (sp->expandingDirections() == Qt::Orientations(0) /*No Direction*/) {
       
  1251                         //spacing or strut
       
  1252                         QSize s = sp->sizeHint();
       
  1253                         sp->changeSize(s.height(), s.width(),
       
  1254                             horz(direction) ? QSizePolicy::Fixed:QSizePolicy::Minimum,
       
  1255                             horz(direction) ? QSizePolicy::Minimum:QSizePolicy::Fixed);
       
  1256 
       
  1257                     } else {
       
  1258                         //stretch
       
  1259                         if (horz(direction))
       
  1260                             sp->changeSize(0, 0, QSizePolicy::Expanding,
       
  1261                                             QSizePolicy::Minimum);
       
  1262                         else
       
  1263                             sp->changeSize(0, 0, QSizePolicy::Minimum,
       
  1264                                             QSizePolicy::Expanding);
       
  1265                     }
       
  1266                 }
       
  1267             }
       
  1268         }
       
  1269     }
       
  1270     d->dir = direction;
       
  1271     invalidate();
       
  1272 }
       
  1273 
       
  1274 /*!
       
  1275     \fn QBoxLayout::Direction QBoxLayout::direction() const
       
  1276 
       
  1277     Returns the direction of the box. addWidget() and addSpacing()
       
  1278     work in this direction; the stretch stretches in this direction.
       
  1279 
       
  1280     \sa QBoxLayout::Direction addWidget() addSpacing()
       
  1281 */
       
  1282 
       
  1283 QBoxLayout::Direction QBoxLayout::direction() const
       
  1284 {
       
  1285     Q_D(const QBoxLayout);
       
  1286     return d->dir;
       
  1287 }
       
  1288 
       
  1289 /*!
       
  1290     \class QHBoxLayout
       
  1291     \brief The QHBoxLayout class lines up widgets horizontally.
       
  1292 
       
  1293     \ingroup geomanagement
       
  1294 
       
  1295     This class is used to construct horizontal box layout objects. See
       
  1296     QBoxLayout for details.
       
  1297 
       
  1298     The simplest use of the class is like this:
       
  1299 
       
  1300     \snippet doc/src/snippets/layouts/layouts.cpp 0
       
  1301     \snippet doc/src/snippets/layouts/layouts.cpp 1
       
  1302     \snippet doc/src/snippets/layouts/layouts.cpp 2
       
  1303     \codeline
       
  1304     \snippet doc/src/snippets/layouts/layouts.cpp 3
       
  1305     \snippet doc/src/snippets/layouts/layouts.cpp 4
       
  1306     \snippet doc/src/snippets/layouts/layouts.cpp 5
       
  1307 
       
  1308     First, we create the widgets we want in the layout. Then, we
       
  1309     create the QHBoxLayout object and add the widgets into the
       
  1310     layout. Finally, we call QWidget::setLayout() to install the
       
  1311     QHBoxLayout object onto the widget. At that point, the widgets in
       
  1312     the layout are reparented to have \c window as their parent.
       
  1313 
       
  1314     \image qhboxlayout-with-5-children.png Horizontal box layout with five child widgets
       
  1315 
       
  1316     \sa QVBoxLayout, QGridLayout, QStackedLayout, {Layout Management}, {Basic Layouts Example}
       
  1317 */
       
  1318 
       
  1319 
       
  1320 /*!
       
  1321     Constructs a new top-level horizontal box with
       
  1322     parent \a parent.
       
  1323 */
       
  1324 QHBoxLayout::QHBoxLayout(QWidget *parent)
       
  1325     : QBoxLayout(LeftToRight, parent)
       
  1326 {
       
  1327 }
       
  1328 
       
  1329 /*!
       
  1330     Constructs a new horizontal box. You must add
       
  1331     it to another layout.
       
  1332 */
       
  1333 QHBoxLayout::QHBoxLayout()
       
  1334     : QBoxLayout(LeftToRight)
       
  1335 {
       
  1336 }
       
  1337 
       
  1338 
       
  1339 
       
  1340 #ifdef QT3_SUPPORT
       
  1341 /*!
       
  1342     Constructs a new top-level horizontal box called \a name, with
       
  1343     parent \a parent.
       
  1344 
       
  1345     The \a margin is the number of pixels between the edge of the
       
  1346     widget and its managed children. The \a spacing is the default
       
  1347     number of pixels between neighboring children. If \a spacing is -1
       
  1348     the value of \a margin is used for \a spacing.
       
  1349 */
       
  1350 QHBoxLayout::QHBoxLayout(QWidget *parent, int margin,
       
  1351                          int spacing, const char *name)
       
  1352     : QBoxLayout(LeftToRight, parent)
       
  1353 {
       
  1354     setMargin(margin);
       
  1355     setSpacing(spacing<0 ? margin : spacing);
       
  1356     setObjectName(QString::fromAscii(name));
       
  1357 }
       
  1358 
       
  1359 /*!
       
  1360     Constructs a new horizontal box called name \a name and adds it to
       
  1361     \a parentLayout.
       
  1362 
       
  1363     The \a spacing is the default number of pixels between neighboring
       
  1364     children. If \a spacing is -1, this QHBoxLayout will inherit its
       
  1365     parent's spacing().
       
  1366 */
       
  1367 QHBoxLayout::QHBoxLayout(QLayout *parentLayout, int spacing,
       
  1368                           const char *name)
       
  1369     : QBoxLayout(LeftToRight)
       
  1370 {
       
  1371     setSpacing(spacing);
       
  1372     setObjectName(QString::fromAscii(name));
       
  1373     if (parentLayout) {
       
  1374         setParent(parentLayout);
       
  1375         parentLayout->addItem(this);
       
  1376     }
       
  1377 }
       
  1378 
       
  1379 /*!
       
  1380     Constructs a new horizontal box called name \a name. You must add
       
  1381     it to another layout.
       
  1382 
       
  1383     The \a spacing is the default number of pixels between neighboring
       
  1384     children. If \a spacing is -1, this QHBoxLayout will inherit its
       
  1385     parent's spacing().
       
  1386 */
       
  1387 QHBoxLayout::QHBoxLayout(int spacing, const char *name)
       
  1388     : QBoxLayout(LeftToRight)
       
  1389 {
       
  1390     setSpacing(spacing);
       
  1391     setObjectName(QString::fromAscii(name));
       
  1392 }
       
  1393 #endif
       
  1394 
       
  1395 
       
  1396 /*!
       
  1397     Destroys this box layout.
       
  1398 
       
  1399     The layout's widgets aren't destroyed.
       
  1400 */
       
  1401 QHBoxLayout::~QHBoxLayout()
       
  1402 {
       
  1403 }
       
  1404 
       
  1405 /*!
       
  1406     \class QVBoxLayout
       
  1407     \brief The QVBoxLayout class lines up widgets vertically.
       
  1408 
       
  1409     \ingroup geomanagement
       
  1410 
       
  1411     This class is used to construct vertical box layout objects. See
       
  1412     QBoxLayout for details.
       
  1413 
       
  1414     The simplest use of the class is like this:
       
  1415 
       
  1416     \snippet doc/src/snippets/layouts/layouts.cpp 6
       
  1417     \snippet doc/src/snippets/layouts/layouts.cpp 7
       
  1418     \snippet doc/src/snippets/layouts/layouts.cpp 8
       
  1419     \codeline
       
  1420     \snippet doc/src/snippets/layouts/layouts.cpp 9
       
  1421     \snippet doc/src/snippets/layouts/layouts.cpp 10
       
  1422     \snippet doc/src/snippets/layouts/layouts.cpp 11
       
  1423 
       
  1424     First, we create the widgets we want in the layout. Then, we
       
  1425     create the QVBoxLayout object and add the widgets into the
       
  1426     layout. Finally, we call QWidget::setLayout() to install the
       
  1427     QVBoxLayout object onto the widget. At that point, the widgets in
       
  1428     the layout are reparented to have \c window as their parent.
       
  1429 
       
  1430     \image qvboxlayout-with-5-children.png Horizontal box layout with five child widgets
       
  1431 
       
  1432     \sa QHBoxLayout, QGridLayout, QStackedLayout, {Layout Management}, {Basic Layouts Example}
       
  1433 */
       
  1434 
       
  1435 /*!
       
  1436     Constructs a new top-level vertical box with
       
  1437     parent \a parent.
       
  1438 */
       
  1439 QVBoxLayout::QVBoxLayout(QWidget *parent)
       
  1440     : QBoxLayout(TopToBottom, parent)
       
  1441 {
       
  1442 }
       
  1443 
       
  1444 /*!
       
  1445     Constructs a new vertical box. You must add
       
  1446     it to another layout.
       
  1447 
       
  1448 */
       
  1449 QVBoxLayout::QVBoxLayout()
       
  1450     : QBoxLayout(TopToBottom)
       
  1451 {
       
  1452 }
       
  1453 
       
  1454 #ifdef QT3_SUPPORT
       
  1455 /*!
       
  1456     Constructs a new top-level vertical box called \a name, with
       
  1457     parent \a parent.
       
  1458 
       
  1459     The \a margin is the number of pixels between the edge of the
       
  1460     widget and its managed children. The \a spacing is the default
       
  1461     number of pixels between neighboring children. If \a spacing is -1
       
  1462     the value of \a margin is used for \a spacing.
       
  1463 */
       
  1464 QVBoxLayout::QVBoxLayout(QWidget *parent, int margin, int spacing,
       
  1465                          const char *name)
       
  1466     : QBoxLayout(TopToBottom, parent)
       
  1467 {
       
  1468     setMargin(margin);
       
  1469     setSpacing(spacing<0 ? margin : spacing);
       
  1470     setObjectName(QString::fromAscii(name));
       
  1471 }
       
  1472 
       
  1473 /*!
       
  1474     Constructs a new vertical box called name \a name and adds it to
       
  1475     \a parentLayout.
       
  1476 
       
  1477     The \a spacing is the default number of pixels between neighboring
       
  1478     children. If \a spacing is -1, this QVBoxLayout will inherit its
       
  1479     parent's spacing().
       
  1480 */
       
  1481 QVBoxLayout::QVBoxLayout(QLayout *parentLayout, int spacing,
       
  1482                           const char *name)
       
  1483     : QBoxLayout(TopToBottom)
       
  1484 {
       
  1485     setSpacing(spacing);
       
  1486     setObjectName(QString::fromAscii(name));
       
  1487     if (parentLayout) {
       
  1488         setParent(parentLayout);
       
  1489         parentLayout->addItem(this);
       
  1490     }
       
  1491 }
       
  1492 
       
  1493 /*!
       
  1494     Constructs a new vertical box called name \a name. You must add
       
  1495     it to another layout.
       
  1496 
       
  1497     The \a spacing is the default number of pixels between neighboring
       
  1498     children. If \a spacing is -1, this QVBoxLayout will inherit its
       
  1499     parent's spacing().
       
  1500 */
       
  1501 QVBoxLayout::QVBoxLayout(int spacing, const char *name)
       
  1502     : QBoxLayout(TopToBottom)
       
  1503 {
       
  1504     setSpacing(spacing);
       
  1505     setObjectName(QString::fromAscii(name));
       
  1506 }
       
  1507 
       
  1508 
       
  1509 #endif
       
  1510 
       
  1511 /*!
       
  1512     Destroys this box layout.
       
  1513 
       
  1514     The layout's widgets aren't destroyed.
       
  1515 */
       
  1516 QVBoxLayout::~QVBoxLayout()
       
  1517 {
       
  1518 }
       
  1519 
       
  1520 /*!
       
  1521     \fn QWidget *QLayout::mainWidget() const
       
  1522 
       
  1523     Use parentWidget() instead.
       
  1524 */
       
  1525 
       
  1526 /*!
       
  1527     \fn void QLayout::remove(QWidget *widget)
       
  1528 
       
  1529     Use removeWidget(\a widget) instead.
       
  1530 */
       
  1531 
       
  1532 /*!
       
  1533     \fn void QLayout::add(QWidget *widget)
       
  1534 
       
  1535     Use addWidget(\a widget) instead.
       
  1536 */
       
  1537 
       
  1538 /*!
       
  1539     \fn QLayoutIterator QLayout::iterator()
       
  1540 
       
  1541     Use a QLayoutIterator() constructor instead.
       
  1542 */
       
  1543 
       
  1544 /*!
       
  1545     \fn int QLayout::defaultBorder() const
       
  1546 
       
  1547     Use spacing() instead.
       
  1548 */
       
  1549 
       
  1550 QT_END_NAMESPACE