source: trunk/src/gui/kernel/qlayout.cpp@ 504

Last change on this file since 504 was 2, checked in by Dmitry A. Kuminov, 17 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 43.6 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtGui module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "qlayout.h"
43
44#include "qapplication.h"
45#include "qlayoutengine_p.h"
46#include "qmenubar.h"
47#include "qtoolbar.h"
48#include "qsizegrip.h"
49#include "qevent.h"
50#include "qstyle.h"
51#include "qvariant.h"
52#include "qwidget_p.h"
53#include "qlayout_p.h"
54#include "qformlayout.h"
55
56QT_BEGIN_NAMESPACE
57
58static int menuBarHeightForWidth(QWidget *menubar, int w)
59{
60 if (menubar && !menubar->isHidden() && !menubar->isWindow()) {
61 int result = menubar->heightForWidth(qMax(w, menubar->minimumWidth()));
62 if (result != -1)
63 return result;
64 result = menubar->sizeHint().height();
65 if (result != -1)
66 return result;
67 }
68 return 0;
69}
70
71/*!
72 \class QLayout
73 \brief The QLayout class is the base class of geometry managers.
74
75 \ingroup appearance
76 \ingroup geomanagement
77
78 This is an abstract base class inherited by the concrete classes
79 QBoxLayout, QGridLayout, QFormLayout, and QStackedLayout.
80
81 For users of QLayout subclasses or of QMainWindow there is seldom
82 any need to use the basic functions provided by QLayout, such as
83 setSizeConstraint() or setMenuBar(). See \l{Layout Classes}
84 for more information.
85
86 To make your own layout manager, implement the functions
87 addItem(), sizeHint(), setGeometry(), itemAt() and takeAt(). You
88 should also implement minimumSize() to ensure your layout isn't
89 resized to zero size if there is too little space. To support
90 children whose heights depend on their widths, implement
91 hasHeightForWidth() and heightForWidth(). See the
92 \l{layouts/borderlayout}{Border Layout} and
93 \l{layouts/flowlayout}{Flow Layout} examples for
94 more information about implementing custom layout managers.
95
96 Geometry management stops when the layout manager is deleted.
97
98 \sa QLayoutItem, {Layout Classes}, {Basic Layouts Example},
99 {Border Layout Example}, {Flow Layout Example}
100*/
101
102
103/*!
104 Constructs a new top-level QLayout, with parent \a parent.
105 \a parent may not be 0.
106
107 There can be only one top-level layout for a widget. It is
108 returned by QWidget::layout().
109*/
110QLayout::QLayout(QWidget *parent)
111 : QObject(*new QLayoutPrivate, parent)
112{
113 if (!parent)
114 return;
115 parent->setLayout(this);
116}
117
118/*!
119 Constructs a new child QLayout.
120
121 This layout has to be inserted into another layout before geometry
122 management will work.
123*/
124QLayout::QLayout()
125 : QObject(*new QLayoutPrivate, 0)
126{
127}
128
129
130/*! \internal
131 */
132QLayout::QLayout(QLayoutPrivate &dd, QLayout *lay, QWidget *w)
133 : QObject(dd, lay ? static_cast<QObject*>(lay) : static_cast<QObject*>(w))
134{
135 Q_D(QLayout);
136 if (lay) {
137 lay->addItem(this);
138 } else if (w) {
139 if (w->layout()) {
140 qWarning("QLayout: Attempting to add QLayout \"%s\" to %s \"%s\", which"
141 " already has a layout",
142 qPrintable(QObject::objectName()), w->metaObject()->className(),
143 w->objectName().toLocal8Bit().data());
144 setParent(0);
145 } else {
146 d->topLevel = true;
147 w->d_func()->layout = this;
148 invalidate();
149 }
150 }
151}
152
153QLayoutPrivate::QLayoutPrivate()
154 : QObjectPrivate(), insideSpacing(-1), userLeftMargin(-1), userTopMargin(-1), userRightMargin(-1),
155 userBottomMargin(-1), topLevel(false), enabled(true), activated(true), autoNewChild(false),
156 constraint(QLayout::SetDefaultConstraint), menubar(0)
157{
158}
159
160void QLayoutPrivate::getMargin(int *result, int userMargin, QStyle::PixelMetric pm) const
161{
162 if (!result)
163 return;
164
165 Q_Q(const QLayout);
166 if (userMargin >= 0) {
167 *result = userMargin;
168 } else if (!topLevel) {
169 *result = 0;
170 } else if (QWidget *pw = q->parentWidget()) {
171 *result = pw->style()->pixelMetric(pm, 0, pw);
172 } else {
173 *result = 0;
174 }
175}
176
177// Static item factory functions that allow for hooking things in Designer
178
179QLayoutPrivate::QWidgetItemFactoryMethod QLayoutPrivate::widgetItemFactoryMethod = 0;
180QLayoutPrivate::QSpacerItemFactoryMethod QLayoutPrivate::spacerItemFactoryMethod = 0;
181
182QWidgetItem *QLayoutPrivate::createWidgetItem(const QLayout *layout, QWidget *widget)
183{
184 if (widgetItemFactoryMethod)
185 if (QWidgetItem *wi = (*widgetItemFactoryMethod)(layout, widget))
186 return wi;
187 return new QWidgetItemV2(widget);
188}
189
190QSpacerItem *QLayoutPrivate::createSpacerItem(const QLayout *layout, int w, int h, QSizePolicy::Policy hPolicy, QSizePolicy::Policy vPolicy)
191{
192 if (spacerItemFactoryMethod)
193 if (QSpacerItem *si = (*spacerItemFactoryMethod)(layout, w, h, hPolicy, vPolicy))
194 return si;
195 return new QSpacerItem(w, h, hPolicy, vPolicy);
196}
197
198#ifdef QT3_SUPPORT
199/*!
200 Constructs a new top-level QLayout called \a name, with parent
201 widget \a parent. \a parent may not be 0.
202
203 The \a margin is the number of pixels between the edge of the
204 widget and the managed children. The \a spacing sets the value of
205 spacing(), which gives the spacing between the managed widgets. If
206 \a spacing is -1 (the default), spacing is set to the value of \a
207 margin.
208
209 There can be only one top-level layout for a widget. It is
210 returned by QWidget::layout()
211
212 \sa QWidget::setLayout()
213*/
214QLayout::QLayout(QWidget *parent, int margin, int spacing, const char *name)
215 : QObject(*new QLayoutPrivate,parent)
216{
217 Q_D(QLayout);
218 setObjectName(QString::fromAscii(name));
219 setMargin(margin);
220 if (spacing < 0)
221 d->insideSpacing = margin;
222 else
223 d->insideSpacing = spacing;
224 if (parent) {
225 if (parent->layout()) {
226 qWarning("QLayout \"%s\" added to %s \"%s\", which already has a layout",
227 QObject::objectName().toLocal8Bit().data(), parent->metaObject()->className(),
228 parent->objectName().toLocal8Bit().data());
229 parent->layout()->setParent(0);
230 } else {
231 d->topLevel = true;
232 parent->d_func()->layout = this;
233 invalidate();
234 }
235 }
236}
237
238/*!
239 Constructs a new child QLayout called \a name, and places it
240 inside \a parentLayout by using the default placement defined by
241 addItem().
242
243 If \a spacing is -1, this QLayout inherits \a parentLayout's
244 spacing(), otherwise the value of \a spacing is used.
245*/
246QLayout::QLayout(QLayout *parentLayout, int spacing, const char *name)
247 : QObject(*new QLayoutPrivate,parentLayout)
248
249{
250 Q_D(QLayout);
251 setObjectName(QString::fromAscii(name));
252 d->insideSpacing = spacing;
253 parentLayout->addItem(this);
254}
255
256/*!
257 Constructs a new child QLayout called \a name. If \a spacing is
258 -1, this QLayout inherits its parent's spacing(); otherwise the
259 value of \a spacing is used.
260
261 This layout has to be inserted into another layout before geometry
262 management will work.
263*/
264QLayout::QLayout(int spacing, const char *name)
265 : QObject(*new QLayoutPrivate, 0)
266{
267 Q_D(QLayout);
268 setObjectName(QString::fromAscii(name));
269 d->insideSpacing = spacing;
270}
271
272/*!
273 Automatically adding widgets is deprecated. Use addWidget() or
274 addLayout() instead.
275*/
276void QLayout::setAutoAdd(bool a) { Q_D(QLayout); d->autoNewChild = a; }
277
278/*!
279 Automatically adding widgets is deprecated. Use addWidget() or
280 addLayout() instead.
281*/
282bool QLayout::autoAdd() const { Q_D(const QLayout); return d->autoNewChild; }
283#endif
284
285
286/*!
287 \fn void QLayout::addItem(QLayoutItem *item)
288
289 Implemented in subclasses to add an \a item. How it is added is
290 specific to each subclass.
291
292 This function is not usually called in application code. To add a widget
293 to a layout, use the addWidget() function; to add a child layout, use the
294 addLayout() function provided by the relevant QLayout subclass.
295
296 \bold{Note:} The ownership of \a item is transferred to the layout, and it's
297 the layout's responsibility to delete it.
298
299 \sa addWidget(), QBoxLayout::addLayout(), QGridLayout::addLayout()
300*/
301
302/*!
303 Adds widget \a w to this layout in a manner specific to the
304 layout. This function uses addItem().
305*/
306void QLayout::addWidget(QWidget *w)
307{
308 addChildWidget(w);
309 addItem(QLayoutPrivate::createWidgetItem(this, w));
310}
311
312
313
314/*!
315 Sets the alignment for widget \a w to \a alignment and returns
316 true if \a w is found in this layout (not including child
317 layouts); otherwise returns false.
318*/
319bool QLayout::setAlignment(QWidget *w, Qt::Alignment alignment)
320{
321 int i = 0;
322 QLayoutItem *item = itemAt(i);
323 while (item) {
324 if (item->widget() == w) {
325 item->setAlignment(alignment);
326 invalidate();
327 return true;
328 }
329 ++i;
330 item = itemAt(i);
331 }
332 return false;
333}
334
335/*!
336 \overload
337
338 Sets the alignment for the layout \a l to \a alignment and
339 returns true if \a l is found in this layout (not including child
340 layouts); otherwise returns false.
341*/
342bool QLayout::setAlignment(QLayout *l, Qt::Alignment alignment)
343{
344 int i = 0;
345 QLayoutItem *item = itemAt(i);
346 while (item) {
347 if (item->layout() == l) {
348 item->setAlignment(alignment);
349 invalidate();
350 return true;
351 }
352 ++i;
353 item = itemAt(i);
354 }
355 return false;
356}
357
358/*!
359 \fn void QLayout::setAlignment(Qt::Alignment alignment)
360
361 Sets the alignment of this item to \a alignment.
362
363 \sa QLayoutItem::setAlignment()
364*/
365
366/*!
367 \fn bool QLayout::isTopLevel() const
368
369 Returns true if this layout is a top-level layout, i.e. not a
370 child of another layout; otherwise returns false.
371*/
372
373/*!
374 \property QLayout::margin
375 \brief the width of the outside border of the layout
376 \obsolete
377
378 Use setContentsMargins() and getContentsMargins() instead.
379
380 \sa contentsRect(), spacing
381*/
382
383/*!
384 \obsolete
385*/
386int QLayout::margin() const
387{
388 int left, top, right, bottom;
389 getContentsMargins(&left, &top, &right, &bottom);
390 if (left == top && top == right && right == bottom) {
391 return left;
392 } else {
393 return -1;
394 }
395}
396
397/*!
398 \property QLayout::spacing
399 \brief the spacing between widgets inside the layout
400
401 If no value is explicitly set, the layout's spacing is inherited
402 from the parent layout, or from the style settings for the parent
403 widget.
404
405 For QGridLayout and QFormLayout, it is possible to set different horizontal and
406 vertical spacings using \l{QGridLayout::}{setHorizontalSpacing()}
407 and \l{QGridLayout::}{setVerticalSpacing()}. In that case,
408 spacing() returns -1.
409
410 \sa contentsRect(), getContentsMargins(), QStyle::layoutSpacing(),
411 QStyle::pixelMetric()
412*/
413
414int QLayout::spacing() const
415{
416 if (const QBoxLayout* boxlayout = qobject_cast<const QBoxLayout*>(this)) {
417 return boxlayout->spacing();
418 } else if (const QGridLayout* gridlayout = qobject_cast<const QGridLayout*>(this)) {
419 return gridlayout->spacing();
420 } else if (const QFormLayout* formlayout = qobject_cast<const QFormLayout*>(this)) {
421 return formlayout->spacing();
422 } else {
423 Q_D(const QLayout);
424 if (d->insideSpacing >=0) {
425 return d->insideSpacing;
426 } else {
427 // arbitrarily prefer horizontal spacing to vertical spacing
428 return qSmartSpacing(this, QStyle::PM_LayoutHorizontalSpacing);
429 }
430 }
431}
432
433/*!
434 \obsolete
435*/
436void QLayout::setMargin(int margin)
437{
438 setContentsMargins(margin, margin, margin, margin);
439}
440
441void QLayout::setSpacing(int spacing)
442{
443 if (QBoxLayout* boxlayout = qobject_cast<QBoxLayout*>(this)) {
444 boxlayout->setSpacing(spacing);
445 } else if (QGridLayout* gridlayout = qobject_cast<QGridLayout*>(this)) {
446 gridlayout->setSpacing(spacing);
447 } else if (QFormLayout* formlayout = qobject_cast<QFormLayout*>(this)) {
448 formlayout->setSpacing(spacing);
449 } else {
450 Q_D(QLayout);
451 d->insideSpacing = spacing;
452 invalidate();
453 }
454}
455
456/*!
457 \since 4.3
458
459 Sets the \a left, \a top, \a right, and \a bottom margins to use
460 around the layout.
461
462 By default, QLayout uses the values provided by the style. On
463 most platforms, the margin is 11 pixels in all directions.
464
465 \sa getContentsMargins(), QStyle::pixelMetric(),
466 {QStyle::}{PM_LayoutLeftMargin},
467 {QStyle::}{PM_LayoutTopMargin},
468 {QStyle::}{PM_LayoutRightMargin},
469 {QStyle::}{PM_LayoutBottomMargin}
470*/
471void QLayout::setContentsMargins(int left, int top, int right, int bottom)
472{
473 Q_D(QLayout);
474
475 if (d->userLeftMargin == left && d->userTopMargin == top &&
476 d->userRightMargin == right && d->userBottomMargin == bottom)
477 return;
478
479 d->userLeftMargin = left;
480 d->userTopMargin = top;
481 d->userRightMargin = right;
482 d->userBottomMargin = bottom;
483 invalidate();
484}
485
486/*!
487 \since 4.3
488
489 Extracts the left, top, right, and bottom margins used around the
490 layout, and assigns them to *\a left, *\a top, *\a right, and *\a
491 bottom (unless they are null pointers).
492
493 By default, QLayout uses the values provided by the style. On
494 most platforms, the margin is 11 pixels in all directions.
495
496 \sa setContentsMargins(), QStyle::pixelMetric(),
497 {QStyle::}{PM_LayoutLeftMargin},
498 {QStyle::}{PM_LayoutTopMargin},
499 {QStyle::}{PM_LayoutRightMargin},
500 {QStyle::}{PM_LayoutBottomMargin}
501*/
502void QLayout::getContentsMargins(int *left, int *top, int *right, int *bottom) const
503{
504 Q_D(const QLayout);
505 d->getMargin(left, d->userLeftMargin, QStyle::PM_LayoutLeftMargin);
506 d->getMargin(top, d->userTopMargin, QStyle::PM_LayoutTopMargin);
507 d->getMargin(right, d->userRightMargin, QStyle::PM_LayoutRightMargin);
508 d->getMargin(bottom, d->userBottomMargin, QStyle::PM_LayoutBottomMargin);
509}
510
511/*!
512 \since 4.3
513
514 Returns the layout's geometry() rectangle, but taking into account the
515 contents margins.
516
517 \sa setContentsMargins(), getContentsMargins()
518*/
519QRect QLayout::contentsRect() const
520{
521 Q_D(const QLayout);
522 int left, top, right, bottom;
523 getContentsMargins(&left, &top, &right, &bottom);
524 return d->rect.adjusted(+left, +top, -right, -bottom);
525}
526
527#ifdef QT3_SUPPORT
528bool QLayout::isTopLevel() const
529{
530 Q_D(const QLayout);
531 return d->topLevel;
532}
533#endif
534
535/*!
536 Returns the parent widget of this layout, or 0 if this layout is
537 not installed on any widget.
538
539 If the layout is a sub-layout, this function returns the parent
540 widget of the parent layout.
541
542 \sa parent()
543*/
544QWidget *QLayout::parentWidget() const
545{
546 Q_D(const QLayout);
547 if (!d->topLevel) {
548 if (parent()) {
549 QLayout *parentLayout = qobject_cast<QLayout*>(parent());
550 if (!parentLayout) {
551 qWarning("QLayout::parentWidget: A layout can only have another layout as a parent.");
552 return 0;
553 }
554 return parentLayout->parentWidget();
555 } else {
556 return 0;
557 }
558 } else {
559 Q_ASSERT(parent() && parent()->isWidgetType());
560 return static_cast<QWidget *>(parent());
561 }
562}
563
564/*!
565 \reimp
566*/
567bool QLayout::isEmpty() const
568{
569 int i = 0;
570 QLayoutItem *item = itemAt(i);
571 while (item) {
572 if (!item->isEmpty())
573 return false;
574 ++i;
575 item = itemAt(i);
576 }
577 return true;
578}
579
580/*!
581 \reimp
582*/
583void QLayout::setGeometry(const QRect &r)
584{
585 Q_D(QLayout);
586 d->rect = r;
587}
588
589/*!
590 \reimp
591*/
592QRect QLayout::geometry() const
593{
594 Q_D(const QLayout);
595 return d->rect;
596}
597
598/*!
599 \reimp
600*/
601void QLayout::invalidate()
602{
603 Q_D(QLayout);
604 d->rect = QRect();
605 update();
606}
607
608static bool removeWidgetRecursively(QLayoutItem *li, QWidget *w)
609{
610 QLayout *lay = li->layout();
611 if (!lay)
612 return false;
613 int i = 0;
614 QLayoutItem *child;
615 while ((child = lay->itemAt(i))) {
616 if (child->widget() == w) {
617 delete lay->takeAt(i);
618 lay->invalidate();
619 return true;
620 } else if (removeWidgetRecursively(child, w)) {
621 return true;
622 } else {
623 ++i;
624 }
625 }
626 return false;
627}
628
629
630void QLayoutPrivate::doResize(const QSize &r)
631{
632 Q_Q(QLayout);
633 int mbh = menuBarHeightForWidth(menubar, r.width());
634 QWidget *mw = q->parentWidget();
635 QRect rect = mw->testAttribute(Qt::WA_LayoutOnEntireRect) ? mw->rect() : mw->contentsRect();
636 rect.setTop(rect.top() + mbh);
637 q->setGeometry(rect);
638#ifndef QT_NO_MENUBAR
639 if (menubar)
640 menubar->setGeometry(0,0,r.width(), mbh);
641#endif
642}
643
644
645/*!
646 \internal
647 Performs child widget layout when the parent widget is
648 resized. Also handles removal of widgets. \a e is the
649 event
650*/
651void QLayout::widgetEvent(QEvent *e)
652{
653 Q_D(QLayout);
654 if (!d->enabled)
655 return;
656
657 switch (e->type()) {
658 case QEvent::Resize:
659 if (d->activated) {
660 QResizeEvent *r = (QResizeEvent *)e;
661 d->doResize(r->size());
662 } else {
663 activate();
664 }
665 break;
666 case QEvent::ChildRemoved:
667 {
668 QChildEvent *c = (QChildEvent *)e;
669 if (c->child()->isWidgetType()) {
670 QWidget *w = (QWidget *)c->child();
671#ifndef QT_NO_MENUBAR
672 if (w == d->menubar)
673 d->menubar = 0;
674#endif
675 removeWidgetRecursively(this, w);
676 }
677 }
678 break;
679#ifdef QT3_SUPPORT
680 case QEvent::ChildInserted:
681 if (d->topLevel && d->autoNewChild) {
682 QChildEvent *c = (QChildEvent *)e;
683 if (c->child()->isWidgetType()) {
684 QWidget *w = (QWidget *)c->child();
685 if (!w->isWindow()) {
686#if !defined(QT_NO_MENUBAR) && !defined(QT_NO_TOOLBAR)
687 if (qobject_cast<QMenuBar*>(w) && !qobject_cast<QToolBar*>(w->parentWidget())) {
688 d->menubar = (QMenuBar *)w;
689 invalidate();
690 } else
691#endif
692#ifndef QT_NO_SIZEGRIP
693 if (qobject_cast<QSizeGrip*>(w) ) {
694 //SizeGrip is handled by the dialog itself.
695 } else
696#endif
697 addItem(QLayoutPrivate::createWidgetItem(this, w));
698 }
699 }
700 }
701 break;
702 case QEvent::LayoutHint:
703 d->activated = false;
704 // fall through
705#endif
706 case QEvent::LayoutRequest:
707 if (static_cast<QWidget *>(parent())->isVisible())
708 activate();
709 break;
710 default:
711 break;
712 }
713}
714
715/*!
716 \reimp
717*/
718void QLayout::childEvent(QChildEvent *e)
719{
720 Q_D(QLayout);
721 if (!d->enabled)
722 return;
723
724 if (e->type() == QEvent::ChildRemoved) {
725 QChildEvent *c = (QChildEvent*)e;
726 int i = 0;
727
728 QLayoutItem *item;
729 while ((item = itemAt(i))) {
730 if (item == static_cast<QLayout*>(c->child())) {
731 takeAt(i);
732 invalidate();
733 break;
734 } else {
735 ++i;
736 }
737 }
738 }
739}
740
741/*!
742 \internal
743 Also takes contentsMargins and menu bar into account.
744*/
745int QLayout::totalHeightForWidth(int w) const
746{
747 Q_D(const QLayout);
748 int side=0, top=0;
749 if (d->topLevel) {
750 QWidget *parent = parentWidget();
751 parent->ensurePolished();
752 QWidgetPrivate *wd = parent->d_func();
753 side += wd->leftmargin + wd->rightmargin;
754 top += wd->topmargin + wd->bottommargin;
755 }
756 int h = heightForWidth(w - side) + top;
757#ifndef QT_NO_MENUBAR
758 h += menuBarHeightForWidth(d->menubar, w);
759#endif
760 return h;
761}
762
763/*!
764 \internal
765 Also takes contentsMargins and menu bar into account.
766*/
767QSize QLayout::totalMinimumSize() const
768{
769 Q_D(const QLayout);
770 int side=0, top=0;
771 if (d->topLevel) {
772 QWidget *pw = parentWidget();
773 pw->ensurePolished();
774 QWidgetPrivate *wd = pw->d_func();
775 side += wd->leftmargin + wd->rightmargin;
776 top += wd->topmargin + wd->bottommargin;
777 }
778
779 QSize s = minimumSize();
780#ifndef QT_NO_MENUBAR
781 top += menuBarHeightForWidth(d->menubar, s.width() + side);
782#endif
783 return s + QSize(side, top);
784}
785
786/*!
787 \internal
788 Also takes contentsMargins and menu bar into account.
789*/
790QSize QLayout::totalSizeHint() const
791{
792 Q_D(const QLayout);
793 int side=0, top=0;
794 if (d->topLevel) {
795 QWidget *pw = parentWidget();
796 pw->ensurePolished();
797 QWidgetPrivate *wd = pw->d_func();
798 side += wd->leftmargin + wd->rightmargin;
799 top += wd->topmargin + wd->bottommargin;
800 }
801
802 QSize s = sizeHint();
803 if (hasHeightForWidth())
804 s.setHeight(heightForWidth(s.width() + side));
805#ifndef QT_NO_MENUBAR
806 top += menuBarHeightForWidth(d->menubar, s.width());
807#endif
808 return s + QSize(side, top);
809}
810
811/*!
812 \internal
813 Also takes contentsMargins and menu bar into account.
814*/
815QSize QLayout::totalMaximumSize() const
816{
817 Q_D(const QLayout);
818 int side=0, top=0;
819 if (d->topLevel) {
820 QWidget *pw = parentWidget();
821 pw->ensurePolished();
822 QWidgetPrivate *wd = pw->d_func();
823 side += wd->leftmargin + wd->rightmargin;
824 top += wd->topmargin + wd->bottommargin;
825 }
826
827 QSize s = maximumSize();
828#ifndef QT_NO_MENUBAR
829 top += menuBarHeightForWidth(d->menubar, s.width());
830#endif
831
832 if (d->topLevel)
833 s = QSize(qMin(s.width() + side, QLAYOUTSIZE_MAX),
834 qMin(s.height() + top, QLAYOUTSIZE_MAX));
835 return s;
836}
837
838/*!
839 \internal
840 Destroys the layout, deleting all child layouts.
841 Geometry management stops when a top-level layout is deleted.
842
843 The layout classes will probably be fatally confused if you delete
844 a sublayout.
845*/
846QLayout::~QLayout()
847{
848 Q_D(QLayout);
849 /*
850 This function may be called during the QObject destructor,
851 when the parent no longer is a QWidget.
852 */
853 if (d->topLevel && parent() && parent()->isWidgetType() &&
854 ((QWidget*)parent())->layout() == this)
855 ((QWidget*)parent())->d_func()->layout = 0;
856}
857
858#ifdef QT3_SUPPORT
859/*!
860 Removes and deletes all items in this layout.
861*/
862void QLayout::deleteAllItems()
863{
864 QLayoutItem *l;
865 while ((l = takeAt(0)))
866 delete l;
867}
868#endif
869
870/*!
871 This function is called from \c addLayout() or \c insertLayout() functions in
872 subclasses to add layout \a l as a sub-layout.
873
874 The only scenario in which you need to call it directly is if you