src/gui/kernel/qlayout.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 **
00003 ** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.
00004 **
00005 ** This file is part of the QtGui module of the Qt Toolkit.
00006 **
00007 ** This file may be used under the terms of the GNU General Public
00008 ** License version 2.0 as published by the Free Software Foundation
00009 ** and appearing in the file LICENSE.GPL included in the packaging of
00010 ** this file.  Please review the following information to ensure GNU
00011 ** General Public Licensing requirements will be met:
00012 ** http://www.trolltech.com/products/qt/opensource.html
00013 **
00014 ** If you are unsure which license is appropriate for your use, please
00015 ** review the following information:
00016 ** http://www.trolltech.com/products/qt/licensing.html or contact the
00017 ** sales department at sales@trolltech.com.
00018 **
00019 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00020 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00021 **
00022 ****************************************************************************/
00023 
00024 #include "qlayout.h"
00025 
00026 #include "qapplication.h"
00027 #include "qlayoutengine_p.h"
00028 #include "qmenubar.h"
00029 #include "qtoolbar.h"
00030 #include "qevent.h"
00031 #include "qstyle.h"
00032 #include "qvariant.h"
00033 #include "qwidget_p.h"
00034 #include "qlayout_p.h"
00035 
00036 static int menuBarHeightForWidth(QWidget *menubar, int w)
00037 {
00038     if (menubar && !menubar->isHidden() && !menubar->isWindow())
00039         return menubar->heightForWidth(qMax(w, menubar->minimumWidth()));
00040     return 0;
00041 }
00042 
00082 QLayout::QLayout(QWidget *parent)
00083     : QObject(*new QLayoutPrivate, parent)
00084 {
00085     if (!parent)
00086         return;
00087     parent->setLayout(this);
00088 }
00089 
00096 QLayout::QLayout()
00097     : QObject(*new QLayoutPrivate, 0)
00098 {
00099 }
00100 
00101 
00104 QLayout::QLayout(QLayoutPrivate &dd, QLayout *lay, QWidget *w)
00105     : QObject(dd, lay ? static_cast<QObject*>(lay) : static_cast<QObject*>(w))
00106 {
00107    Q_D(QLayout);
00108      if (lay) {
00109         lay->addItem(this);
00110     } else if (w) {
00111         if (w->layout()) {
00112             qWarning("QLayout: Attempting to add QLayout \"%s\" to %s \"%s\", which"
00113                      " already has a layout",
00114                      qPrintable(QObject::objectName()), w->metaObject()->className(),
00115                      w->objectName().toLocal8Bit().data());
00116             setParent(0);
00117         } else {
00118             d->topLevel = true;
00119             w->d_func()->layout = this;
00120             invalidate();
00121         }
00122     }
00123 }
00124 
00125 QLayoutPrivate::QLayoutPrivate()
00126     : QObjectPrivate(), insideSpacing(-1), outsideBorder(-1), topLevel(false), enabled(true),
00127       activated(true), autoNewChild(false), constraint(QLayout::SetDefaultConstraint)
00128       , menubar(0)
00129 {
00130 }
00131 
00132 
00133 
00134 
00135 #ifdef QT3_SUPPORT
00136 
00151 QLayout::QLayout(QWidget *parent, int margin, int spacing, const char *name)
00152     : QObject(*new QLayoutPrivate,parent)
00153 {
00154     Q_D(QLayout);
00155      setObjectName(QString::fromAscii(name));
00156     d->outsideBorder = margin;
00157     if (spacing < 0)
00158         d->insideSpacing = margin;
00159     else
00160         d->insideSpacing = spacing;
00161     if (parent) {
00162         if (parent->layout()) {
00163             qWarning("QLayout \"%s\" added to %s \"%s\", which already has a layout",
00164                      QObject::objectName().toLocal8Bit().data(), parent->metaObject()->className(),
00165                      parent->objectName().toLocal8Bit().data());
00166             parent->layout()->setParent(0);
00167         } else {
00168             d->topLevel = true;
00169             parent->d_func()->layout = this;
00170             invalidate();
00171         }
00172     }
00173 }
00174 
00183 QLayout::QLayout(QLayout *parentLayout, int spacing, const char *name)
00184     : QObject(*new QLayoutPrivate,parentLayout)
00185 
00186 {
00187     Q_D(QLayout);
00188     setObjectName(QString::fromAscii(name));
00189     d->insideSpacing = spacing;
00190     parentLayout->addItem(this);
00191 }
00192 
00201 QLayout::QLayout(int spacing, const char *name)
00202     : QObject(*new QLayoutPrivate, 0)
00203 {
00204     Q_D(QLayout);
00205     setObjectName(QString::fromAscii(name));
00206     d->insideSpacing = spacing;
00207 }
00208 
00213 void QLayout::setAutoAdd(bool a) { Q_D(QLayout); d->autoNewChild = a; }
00214 
00219 bool QLayout::autoAdd() const { Q_D(const QLayout); return d->autoNewChild; }
00220 #endif
00221 
00222 
00237 void QLayout::addWidget(QWidget *w)
00238 {
00239     addChildWidget(w);
00240     addItem(new QWidgetItem(w));
00241 }
00242 
00243 
00244 
00250 bool QLayout::setAlignment(QWidget *w, Qt::Alignment alignment)
00251 {
00252     int i = 0;
00253     QLayoutItem *item = itemAt(i);
00254     while (item) {
00255         if (item->widget() == w) {
00256             item->setAlignment(alignment);
00257             invalidate();
00258             return true;
00259         }
00260         ++i;
00261         item = itemAt(i);
00262     }
00263     return false;
00264 }
00265 
00273 bool QLayout::setAlignment(QLayout *l, Qt::Alignment alignment)
00274 {
00275     int i = 0;
00276     QLayoutItem *item = itemAt(i);
00277     while (item) {
00278         if (item->layout() == l) {
00279             item->setAlignment(alignment);
00280             invalidate();
00281             return true;
00282         }
00283         ++i;
00284         item = itemAt(i);
00285     }
00286     return false;
00287 }
00288 
00317 int QLayout::margin() const
00318 {
00319     Q_D(const QLayout);
00320     if ( d->outsideBorder >= 0 )
00321         return d->outsideBorder;
00322     if (!d->topLevel)
00323         return 0;
00324     QWidget *pw = parentWidget();
00325     if (pw)
00326         return pw->style()->pixelMetric(
00327             (pw->isWindow() || (pw->windowType() == Qt::SubWindow))
00328             ? QStyle::PM_DefaultTopLevelMargin
00329             : QStyle::PM_DefaultChildMargin
00330             );
00331     return 0;
00332 }
00333 
00334 
00335 int QLayout::spacing() const
00336 {
00337     Q_D(const QLayout);
00338     if (d->insideSpacing >=0) {
00339         return d->insideSpacing;
00340     } else if (d->topLevel) {
00341         QWidget *pw = parentWidget();
00342         if (pw)
00343             return pw->style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing);
00344         else
00345             return QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing);
00346     } else if (parent()) {
00347         return static_cast<QLayout*>(parent())->spacing();
00348     } else {
00349         return -1; //this is a layout that hasn't been inserted yet
00350     }
00351 }
00352 
00353 #ifdef QT3_SUPPORT
00354 bool QLayout::isTopLevel() const
00355 {
00356     Q_D(const QLayout);
00357     return d->topLevel;
00358 }
00359 #endif
00360 
00361 void QLayout::setMargin(int margin)
00362 {
00363     Q_D(QLayout);
00364     d->outsideBorder = margin;
00365     invalidate();
00366 }
00367 
00368 
00369 void QLayout::setSpacing(int spacing)
00370 {
00371     Q_D(QLayout);
00372     d->insideSpacing = spacing;
00373     invalidate();
00374 }
00375 
00385 QWidget *QLayout::parentWidget() const
00386 {
00387     Q_D(const QLayout);
00388     if (!d->topLevel) {
00389         if (parent()) {
00390             QLayout *parentLayout = ::qobject_cast<QLayout*>(parent());
00391             Q_ASSERT(parentLayout);
00392             return parentLayout->parentWidget();
00393         } else {
00394             return 0;
00395         }
00396     } else {
00397         Q_ASSERT(parent() && parent()->isWidgetType());
00398         return static_cast<QWidget *>(parent());
00399     }
00400 }
00401 
00405 bool QLayout::isEmpty() const
00406 {
00407     int i = 0;
00408     QLayoutItem *item = itemAt(i);
00409     while (item) {
00410         if (!item->isEmpty())
00411             return false;
00412         ++i;
00413         item = itemAt(i);
00414     }
00415     return true;
00416 }
00417 
00421 void QLayout::setGeometry(const QRect &r)
00422 {
00423     Q_D(QLayout);
00424     d->rect = r;
00425 }
00426 
00430 QRect QLayout::geometry() const
00431 {
00432     Q_D(const QLayout);
00433     return d->rect;
00434 }
00435 
00439 void QLayout::invalidate()
00440 {
00441     Q_D(QLayout);
00442     d->rect = QRect();
00443     update();
00444 }
00445 
00446 static bool removeWidgetRecursively(QLayoutItem *li, QWidget *w)
00447 {
00448     QLayout *lay = li->layout();
00449     if (!lay)
00450         return false;
00451     int i = 0;
00452     QLayoutItem *child;
00453     while ((child = lay->itemAt(i))) {
00454         if (child->widget() == w) {
00455             delete lay->takeAt(i);
00456             lay->invalidate();
00457             return true;
00458         } else if (removeWidgetRecursively(child, w)) {
00459             return true;
00460         } else {
00461             ++i;
00462         }
00463     }
00464     return false;
00465 }
00466 
00467 
00468 void QLayoutPrivate::doResize(const QSize &r)
00469 {
00470     Q_Q(QLayout);
00471     int mbh = menuBarHeightForWidth(menubar, r.width());
00472     QWidget *mw = q->parentWidget();
00473     QRect rect = mw->testAttribute(Qt::WA_LayoutOnEntireRect) ? mw->rect() : mw->contentsRect();
00474     rect.setTop(rect.top() + mbh);
00475     q->setGeometry(rect);
00476 #ifndef QT_NO_MENUBAR
00477     if (menubar)
00478         menubar->setGeometry(0,0,r.width(), mbh);
00479 #endif
00480 }
00481 
00482 
00489 void QLayout::widgetEvent(QEvent *e)
00490 {
00491     Q_D(QLayout);
00492     if (!d->enabled)
00493         return;
00494 
00495     switch (e->type()) {
00496     case QEvent::Resize:
00497         if (d->activated) {
00498             QResizeEvent *r = (QResizeEvent *)e;
00499             d->doResize(r->size());
00500         } else {
00501             activate();
00502         }
00503         break;
00504     case QEvent::ChildRemoved:
00505         {
00506             QChildEvent *c = (QChildEvent *)e;
00507             if (c->child()->isWidgetType()) {
00508                 QWidget *w = (QWidget *)c->child();
00509 #ifndef QT_NO_MENUBAR
00510                 if (w == d->menubar)
00511                     d->menubar = 0;
00512 #endif
00513                 removeWidgetRecursively(this, w);
00514             }
00515         }
00516         break;
00517 #ifdef QT3_SUPPORT
00518     case QEvent::ChildInserted:
00519         if (d->topLevel && d->autoNewChild) {
00520             QChildEvent *c = (QChildEvent *)e;
00521             if (c->child()->isWidgetType()) {
00522                 QWidget *w = (QWidget *)c->child();
00523                 if (!w->isWindow()) {
00524 #if !defined(QT_NO_MENUBAR) && !defined(QT_NO_TOOLBAR)
00525                     if (qobject_cast<QMenuBar*>(w) && !::qobject_cast<QToolBar*>(w->parentWidget())) {
00526                         d->menubar = (QMenuBar *)w;
00527                         invalidate();
00528                     } else
00529 #endif
00530                         addItem(new QWidgetItem(w));
00531                 }
00532             }
00533         }
00534         break;
00535     case QEvent::LayoutHint:
00536         d->activated = false;
00537         // fall through
00538 #endif
00539     case QEvent::LayoutRequest:
00540         activate();
00541         break;
00542     default:
00543         break;
00544     }
00545 }
00546 
00550 void QLayout::childEvent(QChildEvent *e)
00551 {
00552     Q_D(QLayout);
00553     if (!d->enabled)
00554         return;
00555 
00556     if (e->type() == QEvent::ChildRemoved) {
00557         QChildEvent *c = (QChildEvent*)e;
00558         int i = 0;
00559 
00560         QLayoutItem *item;
00561         while ((item = itemAt(i))) {
00562             if (item == static_cast<QLayout*>(c->child())) {
00563                 takeAt(i);
00564                 invalidate();
00565                 break;
00566             } else {
00567                 ++i;
00568             }
00569         }
00570     }
00571 }
00572 
00577 int QLayout::totalHeightForWidth(int w) const
00578 {
00579     Q_D(const QLayout);
00580     int side=0, top=0;
00581     if (d->topLevel) {
00582         QWidget *parent = parentWidget();
00583         parent->ensurePolished();
00584         QWidgetPrivate *wd = parent->d_func();
00585         side += wd->leftmargin + wd->rightmargin;
00586         top += wd->topmargin + wd->bottommargin;
00587     }
00588     int h = heightForWidth(w - side) + top;
00589 #ifndef QT_NO_MENUBAR
00590     h += menuBarHeightForWidth(d->menubar, w);
00591 #endif
00592     return h;
00593 }
00594 
00599 QSize QLayout::totalMinimumSize() const
00600 {
00601     Q_D(const QLayout);
00602     int side=0, top=0;
00603     if (d->topLevel) {
00604         QWidget *pw = parentWidget();
00605         pw->ensurePolished();
00606         QWidgetPrivate *wd = pw->d_func();
00607         side += wd->leftmargin + wd->rightmargin;
00608         top += wd->topmargin + wd->bottommargin;
00609     }
00610 
00611     QSize s = minimumSize();
00612 #ifndef QT_NO_MENUBAR
00613     top += menuBarHeightForWidth(d->menubar, s.width() + side);
00614 #endif
00615     return s + QSize(side, top);
00616 }
00617 
00622 QSize QLayout::totalSizeHint() const
00623 {
00624     Q_D(const QLayout);
00625     int side=0, top=0;
00626     if (d->topLevel) {
00627         QWidget *pw = parentWidget();
00628         pw->ensurePolished();
00629         QWidgetPrivate *wd = pw->d_func();
00630         side += wd->leftmargin + wd->rightmargin;
00631         top += wd->topmargin + wd->bottommargin;
00632     }
00633 
00634     QSize s = sizeHint();
00635     if (hasHeightForWidth())
00636         s.setHeight(heightForWidth(s.width() + side));
00637 #ifndef QT_NO_MENUBAR
00638     top += menuBarHeightForWidth(d->menubar, s.width());
00639 #endif
00640     return s + QSize(side, top);
00641 }
00642 
00647 QSize QLayout::totalMaximumSize() const
00648 {
00649     Q_D(const QLayout);
00650     int side=0, top=0;
00651     if (d->topLevel) {
00652         QWidget *pw = parentWidget();
00653         pw->ensurePolished();
00654         QWidgetPrivate *wd = pw->d_func();
00655         side += wd->leftmargin + wd->rightmargin;
00656         top += wd->topmargin + wd->bottommargin;
00657     }
00658 
00659     QSize s = maximumSize();
00660 #ifndef QT_NO_MENUBAR
00661     top += menuBarHeightForWidth(d->menubar, s.width());
00662 #endif
00663 
00664     if (d->topLevel)
00665         s = QSize(qMin(s.width() + side, QLAYOUTSIZE_MAX),
00666                    qMin(s.height() + top, QLAYOUTSIZE_MAX));
00667     return s;
00668 }
00669 
00678 QLayout::~QLayout()
00679 {
00680     Q_D(QLayout);
00681     /*
00682       This function may be called during the QObject destructor,
00683       when the parent no longer is a QWidget.
00684     */
00685     if (d->topLevel && parent() && parent()->isWidgetType() &&
00686          ((QWidget*)parent())->layout() == this)
00687         ((QWidget*)parent())->d_func()->layout = 0;
00688 }
00689 
00690 #ifdef QT3_SUPPORT
00691 
00694 void QLayout::deleteAllItems()
00695 {
00696     QLayoutItem *l;
00697     while ((l = takeAt(0)))
00698         delete l;
00699 }
00700 #endif
00701 
00706 void QLayout::addChildLayout(QLayout *l)
00707 {
00708     if (l->parent()) {
00709         qWarning("QLayout::addChildLayout: layout \"%s\" already has a parent",
00710                  l->objectName().toLocal8Bit().data());
00711         return;
00712     }
00713     l->setParent(this);
00714 
00715     if (QWidget *mw = parentWidget()) {
00716         l->d_func()->reparentChildWidgets(mw);
00717     }
00718 
00719 }
00720 
00721 #ifdef QT_DEBUG
00722 static bool layoutDebug()
00723 {
00724     static int checked_env = -1;
00725     if(checked_env == -1)
00726         checked_env = !!qgetenv("QT_LAYOUT_DEBUG").toInt();
00727 
00728     return checked_env;
00729 }
00730 #endif
00731 
00732 void QLayoutPrivate::reparentChildWidgets(QWidget *mw)
00733 {
00734     Q_Q(QLayout);
00735     int n =  q->count();
00736 
00737 #ifndef QT_NO_MENUBAR
00738     if (menubar && menubar->parentWidget() != mw) {
00739         menubar->setParent(mw);
00740     }
00741 #endif
00742     for (int i = 0; i < n; ++i) {
00743         QLayoutItem *item = q->itemAt(i);
00744         if (QWidget *w = item->widget()) {
00745             QWidget *pw = w->parentWidget();
00746 #ifdef QT_DEBUG
00747             if (pw && pw != mw && layoutDebug()) {
00748                 qWarning("QLayout::addChildLayout: widget %s \"%s\" in wrong parent; moved to correct parent",
00749                          w->metaObject()->className(), w->objectName().toLocal8Bit().data());
00750             }
00751 #endif
00752             if (pw != mw)
00753                 w->setParent(mw);
00754         } else if (QLayout *l = item->layout()) {
00755             l->d_func()->reparentChildWidgets(mw);
00756         }
00757     }
00758 }
00759 
00768 void QLayout::addChildWidget(QWidget *w)
00769 {
00770     QWidget *mw = parentWidget();
00771     QWidget *pw = w->parentWidget();
00772 
00773     //Qt::WA_LaidOut is never reset. It only means that the widget at some point has
00774     //been in a layout.
00775     if (pw && w->testAttribute(Qt::WA_LaidOut)) {
00776         QLayout *l = pw->layout();
00777         if (l && removeWidgetRecursively(l, w)) {
00778 #ifdef QT_DEBUG
00779             if (layoutDebug())
00780                 qWarning("QLayout::addChildWidget: %s \"%s\" is already in a layout; moved to new layout",
00781                          w->metaObject()->className(), w->objectName().toLocal8Bit().data());
00782 #endif
00783         }
00784     }
00785     if (pw && mw && pw != mw) {
00786 #ifdef QT_DEBUG
00787             if (layoutDebug())
00788                 qWarning("QLayout::addChildWidget: %s \"%s\" in wrong parent; moved to correct parent",
00789                          w->metaObject()->className(), w->objectName().toLocal8Bit().data());
00790 #endif
00791         pw = 0;
00792     }
00793     bool needShow = mw && mw->isVisible() && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide));
00794     if (!pw && mw)
00795         w->setParent(mw);
00796     w->setAttribute(Qt::WA_LaidOut);
00797     if (needShow)
00798         QMetaObject::invokeMethod(w, "_q_showIfNotHidden", Qt::QueuedConnection); //show later
00799 }
00800 
00801 #ifdef QT3_SUPPORT
00802 
00822 void QLayout::freeze(int w, int h)
00823 {
00824     Q_D(QLayout);
00825     if (!d->topLevel)
00826         return;
00827     if (w <= 0 || h <= 0) {
00828         QSize s = totalSizeHint();
00829         w = s.width();
00830         h = s.height();
00831     }
00832     setSizeConstraint(SetNoConstraint); // layout will not change min/max size
00833     QWidget *parent = parentWidget();
00834     if (parent)
00835         parent->setFixedSize(w, h);
00836 }
00837 
00838 #endif
00839 
00840 
00841 
00842 
00843 
00844 
00845 
00851 void QLayout::setMenuBar(QWidget *widget)
00852 {
00853     Q_D(QLayout);
00854     if (widget)
00855         addChildWidget(widget);
00856     d->menubar = widget;
00857 }
00858 
00864 QWidget *QLayout::menuBar() const
00865 {
00866     Q_D(const QLayout);
00867     return d->menubar;
00868 }
00869 
00870 
00881 QSize QLayout::minimumSize() const
00882 {
00883     return QSize(0, 0);
00884 }
00885 
00896 QSize QLayout::maximumSize() const
00897 {
00898     return QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX);
00899 }
00900 
00913 Qt::Orientations QLayout::expandingDirections() const
00914 {
00915     return Qt::Horizontal | Qt::Vertical;
00916 }
00917 
00918 void QLayout::activateRecursiveHelper(QLayoutItem *item)
00919 {
00920     item->invalidate();
00921     QLayout *layout = item->layout();
00922     if (layout) {
00923         QLayoutItem *child;
00924         int i=0;
00925         while ((child = layout->itemAt(i++)))
00926             activateRecursiveHelper(child);
00927         layout->d_func()->activated = true;
00928     }
00929 }
00930 
00940 void QLayout::update()
00941 {
00942     QLayout *layout = this;
00943     while (layout && layout->d_func()->activated) {
00944         layout->d_func()->activated = false;
00945         if (layout->d_func()->topLevel) {
00946             Q_ASSERT(layout->parent()->isWidgetType());
00947             QWidget *mw = static_cast<QWidget*>(layout->parent());
00948             if (mw->isVisible())
00949                 QApplication::postEvent(mw, new QEvent(QEvent::LayoutRequest));
00950             break;
00951         }
00952         layout = static_cast<QLayout*>(layout->parent());
00953     }
00954 }
00955 
00964 bool QLayout::activate()
00965 {
00966     Q_D(QLayout);
00967     if (!d->enabled || !parent())
00968         return false;
00969     if (!d->topLevel)
00970         return static_cast<QLayout*>(parent())->activate();
00971     if (d->activated)
00972         return false;
00973     QWidget *mw = static_cast<QWidget*>(parent());
00974     if (mw == 0) {
00975         qWarning("QLayout::activate: %s \"%s\" does not have a main widget",
00976                  QObject::metaObject()->className(), QObject::objectName().toLocal8Bit().data());
00977         return false;
00978     }
00979     activateRecursiveHelper(this);
00980 
00981     QWidgetPrivate *md = mw->d_func();
00982     uint explMin = md->extra ? md->extra->explicitMinSize : 0;
00983 
00984     switch (d->constraint) {
00985     case SetFixedSize:
00986         // will trigger resize
00987         mw->setFixedSize(totalSizeHint());
00988         break;
00989     case SetMinimumSize:
00990         mw->setMinimumSize(totalMinimumSize());
00991         break;
00992     case SetMaximumSize:
00993         mw->setMaximumSize(totalMaximumSize());
00994         break;
00995     case SetMinAndMaxSize:
00996         mw->setMinimumSize(totalMinimumSize());
00997         mw->setMaximumSize(totalMaximumSize());
00998         break;
00999     case SetDefaultConstraint: {
01000         bool widthSet = explMin & Qt::Horizontal;
01001         bool heightSet = explMin & Qt::Vertical;
01002         if (mw->isWindow()) {
01003             QSize ms = totalMinimumSize();
01004             if (widthSet)
01005                 ms.setWidth(mw->minimumSize().width());
01006             if (heightSet)
01007                 ms.setHeight(mw->minimumSize().height());
01008             if ((!heightSet || !widthSet) && hasHeightForWidth()) {
01009                 int h = minimumHeightForWidth(ms.width());
01010                 if (h > ms.height()) {
01011                     if (!heightSet)
01012                         ms.setHeight(0);
01013                     if (!widthSet)
01014                         ms.setWidth(0);
01015                 }
01016             }
01017             mw->setMinimumSize(ms);
01018         } else if (!widthSet || !heightSet) {
01019             QSize ms = mw->minimumSize();
01020             if (!widthSet)
01021                 ms.setWidth(0);
01022             if (!heightSet)
01023                 ms.setHeight(0);
01024             mw->setMinimumSize(ms);
01025         }
01026         break;
01027     }
01028     case SetNoConstraint:
01029         break;
01030     }
01031 
01032     d->doResize(mw->size());
01033 
01034     if (md->extra)
01035         md->extra->explicitMinSize = explMin;
01036     // ideally only if sizeHint() or sizePolicy() has changed
01037     mw->updateGeometry();
01038     return true;
01039 }
01040 
01113 int QLayout::indexOf(QWidget *widget) const
01114 {
01115     int i = 0;
01116     QLayoutItem *item = itemAt(i);
01117     while (item) {
01118         if (item->widget() == widget)
01119             return i;
01120         ++i;
01121         item = itemAt(i);
01122     }
01123     return -1;
01124 }
01125 
01126 
01164 void QLayout::setSizeConstraint(SizeConstraint constraint)
01165 {
01166     Q_D(QLayout);
01167     if (constraint == d->constraint)
01168         return;
01169 
01170     d->constraint = constraint;
01171     invalidate();
01172 }
01173 
01174 QLayout::SizeConstraint QLayout::sizeConstraint() const
01175 {
01176     Q_D(const QLayout);
01177     return d->constraint;
01178 }
01179 
01188 QRect QLayout::alignmentRect(const QRect &r) const
01189 {
01190     QSize s = sizeHint();
01191     Qt::Alignment a = alignment();
01192 
01193     /*
01194       This is a hack to obtain the real maximum size, not
01195       QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX), the value consistently
01196       returned by QLayoutItems that have an alignment.
01197     */
01198     QLayout *that = const_cast<QLayout *>(this);
01199     that->setAlignment(0);
01200     QSize ms = that->maximumSize();
01201     that->setAlignment(a);
01202 
01203     if ((expandingDirections() & Qt::Horizontal) ||
01204          !(a & Qt::AlignHorizontal_Mask)) {
01205         s.setWidth(qMin(r.width(), ms.width()));
01206     }
01207     if ((expandingDirections() & Qt::Vertical) ||
01208          !(a & Qt::AlignVertical_Mask)) {
01209         s.setHeight(qMin(r.height(), ms.height()));
01210     } else if (hasHeightForWidth()) {
01211         int hfw = heightForWidth(s.width());
01212         if (hfw < s.height())
01213             s.setHeight(qMin(hfw, ms.height()));
01214     }
01215 
01216     int x = r.x();
01217     int y = r.y();
01218 
01219     if (a & Qt::AlignBottom)
01220         y += (r.height() - s.height());
01221     else if (!(a & Qt::AlignTop))
01222         y += (r.height() - s.height()) / 2;
01223 
01224     QWidget *parent = parentWidget();
01225     a = QStyle::visualAlignment(parent ? parent->layoutDirection() : QApplication::layoutDirection(), a);
01226     if (a & Qt::AlignRight)
01227         x += (r.width() - s.width());
01228     else if (!(a & Qt::AlignLeft))
01229         x += (r.width() - s.width()) / 2;
01230 
01231     return QRect(x, y, s.width(), s.height());
01232 }
01233 
01241 void QLayout::removeWidget(QWidget *widget)
01242 {
01243     int i = 0;
01244     QLayoutItem *child;
01245     while ((child = itemAt(i))) {
01246         if (child->widget() == widget) {
01247             delete takeAt(i);
01248             invalidate();
01249         } else {
01250             ++i;
01251         }
01252     }
01253 }
01254 
01264 void QLayout::removeItem(QLayoutItem *item)
01265 {
01266     int i = 0;
01267     QLayoutItem *child;
01268     while ((child = itemAt(i))) {
01269         if (child == item) {
01270             takeAt(i);
01271             invalidate();
01272         } else {
01273             ++i;
01274         }
01275     }
01276 }
01277 
01288 void QLayout::setEnabled(bool enable)
01289 {
01290     Q_D(QLayout);
01291     d->enabled = enable;
01292 }
01293 
01299 bool QLayout::isEnabled() const
01300 {
01301     Q_D(const QLayout);
01302     return d->enabled;
01303 }
01304 
01311 QSize QLayout::closestAcceptableSize(const QWidget *widget, const QSize &size)
01312 {
01313     QSize result = size.boundedTo(qSmartMaxSize(widget));
01314     result = result.expandedTo(qSmartMinSize(widget));
01315     QLayout *l = widget->layout();
01316     if (l && l->hasHeightForWidth() && result.height() < l->minimumHeightForWidth(result.width()) ) {
01317         QSize current = widget->size();
01318         int currentHfw =  l->minimumHeightForWidth(current.width());
01319         int newHfw = l->minimumHeightForWidth(result.width());
01320         if (current.height() < currentHfw || currentHfw == newHfw) {
01321             //handle the constant hfw case and the vertical-only case, as well as the
01322             // current-size-is-not-correct case
01323             result.setHeight(newHfw);
01324         } else {
01325             // binary search; assume hfw is decreasing ###
01326 
01327             int maxw = qMax(widget->width(),result.width());
01328             int maxh = qMax(widget->height(), result.height());
01329             int minw = qMin(widget->width(),result.width());
01330             int minh = qMin(widget->height(), result.height());
01331 
01332             int minhfw = l->minimumHeightForWidth(minw);
01333             int maxhfw = l->minimumHeightForWidth(maxw);
01334             while (minw < maxw) {
01335                 if (minhfw > maxh) { //assume decreasing
01336                     minw = maxw - (maxw-minw)/2;
01337                     minhfw = l->minimumHeightForWidth(minw);
01338                 } else if (maxhfw < minh ) { //assume decreasing
01339                     maxw = minw + (maxw-minw)/2;
01340                     maxhfw = l->minimumHeightForWidth(maxw);
01341                 } else  {
01342                     break;
01343                 }
01344             }
01345             result = result.expandedTo(QSize(minw, minhfw));
01346         }
01347     }
01348     return result;
01349 }
01350 
01363 #ifndef QT_NO_DATASTREAM
01364 
01372 QDataStream &operator<<(QDataStream &stream, const QSizePolicy &policy)
01373 {
01374     stream << policy.data;
01375     return stream;
01376 }
01377 
01386 QDataStream &operator>>(QDataStream &stream, QSizePolicy &policy)
01387 {
01388     stream >> policy.data;
01389     return stream;
01390 }
01391 #endif
01392 

Generated on Thu Mar 15 11:55:11 2007 for Qt 4.2 User's Guide by  doxygen 1.5.1