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

Last change on this file since 808 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 44.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the QtGui module of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** 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 have questions regarding the use of this file, please contact
37** Nokia 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()
65 .expandedTo(menubar->minimumSize())
66 .expandedTo(menubar->minimumSizeHint())
67 .boundedTo(menubar->maximumSize()).height();
68 if (result != -1)
69 return result;
70 }
71 return 0;
72}
73
74/*!
75 \class QLayout
76 \brief The QLayout class is the base class of geometry managers.
77
78 \ingroup geomanagement
79
80 This is an abstract base class inherited by the concrete classes
81 QBoxLayout, QGridLayout, QFormLayout, and QStackedLayout.
82
83 For users of QLayout subclasses or of QMainWindow there is seldom
84 any need to use the basic functions provided by QLayout, such as
85 setSizeConstraint() or setMenuBar(). See \l{Layout Management}
86 for more information.
87
88 To make your own layout manager, implement the functions
89 addItem(), sizeHint(), setGeometry(), itemAt() and takeAt(). You
90 should also implement minimumSize() to ensure your layout isn't
91 resized to zero size if there is too little space. To support
92 children whose heights depend on their widths, implement
93 hasHeightForWidth() and heightForWidth(). See the
94 \l{layouts/borderlayout}{Border Layout} and
95 \l{layouts/flowlayout}{Flow Layout} examples for
96 more information about implementing custom layout managers.
97
98 Geometry management stops when the layout manager is deleted.
99
100 \sa QLayoutItem, {Layout Management}, {Basic Layouts Example},
101 {Border Layout Example}, {Flow Layout Example}
102*/
103
104
105/*!
106 Constructs a new top-level QLayout, with parent \a parent.
107 \a parent may not be 0.
108
109 There can be only one top-level layout for a widget. It is
110 returned by QWidget::layout().
111*/
112QLayout::QLayout(QWidget *parent)
113 : QObject(*new QLayoutPrivate, parent)
114{
115 if (!parent)
116 return;
117 parent->setLayout(this);
118}
119
120/*!
121 Constructs a new child QLayout.
122
123 This layout has to be inserted into another layout before geometry
124 management will work.
125*/
126QLayout::QLayout()
127 : QObject(*new QLayoutPrivate, 0)
128{
129}
130
131
132/*! \internal
133 */
134QLayout::QLayout(QLayoutPrivate &dd, QLayout *lay, QWidget *w)
135 : QObject(dd, lay ? static_cast<QObject*>(lay) : static_cast<QObject*>(w))
136{
137 Q_D(QLayout);
138 if (lay) {
139 lay->addItem(this);
140 } else if (w) {
141 if (w->layout()) {
142 qWarning("QLayout: Attempting to add QLayout \"%s\" to %s \"%s\", which"
143 " already has a layout",
144 qPrintable(QObject::objectName()), w->metaObject()->className(),
145 w->objectName().toLocal8Bit().data());
146 setParent(0);
147 } else {
148 d->topLevel = true;
149 w->d_func()->layout = this;
150 QT_TRY {
151 invalidate();
152 } QT_CATCH(...) {
153 w->d_func()->layout = 0;
154 QT_RETHROW;
155 }
156 }
157 }
158}
159
160QLayoutPrivate::QLayoutPrivate()
161 : QObjectPrivate(), insideSpacing(-1), userLeftMargin(-1), userTopMargin(-1), userRightMargin(-1),
162 userBottomMargin(-1), topLevel(false), enabled(true), activated(true), autoNewChild(false),
163 constraint(QLayout::SetDefaultConstraint), menubar(0)
164{
165}
166
167void QLayoutPrivate::getMargin(int *result, int userMargin, QStyle::PixelMetric pm) const
168{
169 if (!result)
170 return;
171
172 Q_Q(const QLayout);
173 if (userMargin >= 0) {
174 *result = userMargin;
175 } else if (!topLevel) {
176 *result = 0;
177 } else if (QWidget *pw = q->parentWidget()) {
178 *result = pw->style()->pixelMetric(pm, 0, pw);
179 } else {
180 *result = 0;
181 }
182}
183
184// Static item factory functions that allow for hooking things in Designer
185
186QLayoutPrivate::QWidgetItemFactoryMethod QLayoutPrivate::widgetItemFactoryMethod = 0;
187QLayoutPrivate::QSpacerItemFactoryMethod QLayoutPrivate::spacerItemFactoryMethod = 0;
188
189QWidgetItem *QLayoutPrivate::createWidgetItem(const QLayout *layout, QWidget *widget)
190{
191 if (widgetItemFactoryMethod)
192 if (QWidgetItem *wi = (*widgetItemFactoryMethod)(layout, widget))
193 return wi;
194 return new QWidgetItemV2(widget);
195}
196
197QSpacerItem *QLayoutPrivate::createSpacerItem(const QLayout *layout, int w, int h, QSizePolicy::Policy hPolicy, QSizePolicy::Policy vPolicy)
198{
199 if (spacerItemFactoryMethod)
200 if (QSpacerItem *si = (*spacerItemFactoryMethod)(layout, w, h, hPolicy, vPolicy))
201 return si;
202 return new QSpacerItem(w, h, hPolicy, vPolicy);
203}
204
205#ifdef QT3_SUPPORT
206/*!
207 Constructs a new top-level QLayout called \a name, with parent
208 widget \a parent. \a parent may not be 0.
209
210 The \a margin is the number of pixels between the edge of the
211 widget and the managed children. The \a spacing sets the value of
212 spacing(), which gives the spacing between the managed widgets. If
213 \a spacing is -1 (the default), spacing is set to the value of \a
214 margin.
215
216 There can be only one top-level layout for a widget. It is
217 returned by QWidget::layout()
218
219 \sa QWidget::setLayout()
220*/
221QLayout::QLayout(QWidget *parent, int margin, int spacing, const char *name)
222 : QObject(*new QLayoutPrivate,parent)
223{
224 Q_D(QLayout);
225 setObjectName(QString::fromAscii(name));
226 setMargin(margin);
227 if (spacing < 0)
228 d->insideSpacing = margin;
229 else
230 d->insideSpacing = spacing;
231 if (parent) {
232 if (parent->layout()) {
233 qWarning("QLayout \"%s\" added to %s \"%s\", which already has a layout",
234 QObject::objectName().toLocal8Bit().data(), parent->metaObject()->className(),
235 parent->objectName().toLocal8Bit().data());
236 parent->layout()->setParent(0);
237 } else {
238 d->topLevel = true;
239 parent->d_func()->layout = this;
240 QT_TRY {
241 invalidate();
242 } QT_CATCH(...) {
243 parent->d_func()->layout = 0;
244 QT_RETHROW;
245 }
246 }
247 }
248}
249
250/*!
251 Constructs a new child QLayout called \a name, and places it
252 inside \a parentLayout by using the default placement defined by
253 addItem().
254
255 If \a spacing is -1, this QLayout inherits \a parentLayout's
256 spacing(), otherwise the value of \a spacing is used.
257*/
258QLayout::QLayout(QLayout *parentLayout, int spacing, const char *name)
259 : QObject(*new QLayoutPrivate,parentLayout)
260
261{
262 Q_D(QLayout);
263 setObjectName(QString::fromAscii(name));
264 d->insideSpacing = spacing;
265 parentLayout->addItem(this);
266}
267
268/*!
269 Constructs a new child QLayout called \a name. If \a spacing is
270 -1, this QLayout inherits its parent's spacing(); otherwise the
271 value of \a spacing is used.
272
273 This layout has to be inserted into another layout before geometry
274 management will work.
275*/
276QLayout::QLayout(int spacing, const char *name)
277 : QObject(*new QLayoutPrivate, 0)
278{
279 Q_D(QLayout);
280 setObjectName(QString::fromAscii(name));
281 d->insideSpacing = spacing;
282}
283
284/*!
285 Automatically adding widgets is deprecated. Use addWidget() or
286 addLayout() instead.
287*/
288void QLayout::setAutoAdd(bool a) { Q_D(QLayout); d->autoNewChild = a; }
289
290/*!
291 Automatically adding widgets is deprecated. Use addWidget() or
292 addLayout() instead.
293*/
294bool QLayout::autoAdd() const { Q_D(const QLayout); return d->autoNewChild; }
295#endif
296
297
298/*!
299 \fn void QLayout::addItem(QLayoutItem *item)
300
301 Implemented in subclasses to add an \a item. How it is added is
302 specific to each subclass.
303
304 This function is not usually called in application code. To add a widget
305 to a layout, use the addWidget() function; to add a child layout, use the
306 addLayout() function provided by the relevant QLayout subclass.
307
308 \bold{Note:} The ownership of \a item is transferred to the layout, and it's
309 the layout's responsibility to delete it.
310
311 \sa addWidget(), QBoxLayout::addLayout(), QGridLayout::addLayout()
312*/
313
314/*!
315 Adds widget \a w to this layout in a manner specific to the
316 layout. This function uses addItem().
317*/
318void QLayout::addWidget(QWidget *w)
319{
320 addChildWidget(w);
321 addItem(QLayoutPrivate::createWidgetItem(this, w));
322}
323
324
325
326/*!
327 Sets the alignment for widget \a w to \a alignment and returns
328 true if \a w is found in this layout (not including child
329 layouts); otherwise returns false.
330*/
331bool QLayout::setAlignment(QWidget *w, Qt::Alignment alignment)
332{
333 int i = 0;
334 QLayoutItem *item = itemAt(i);
335 while (item) {
336 if (item->widget() == w) {
337 item->setAlignment(alignment);
338 invalidate();
339 return true;
340 }
341 ++i;
342 item = itemAt(i);
343 }
344 return false;
345}
346
347/*!
348 \overload
349
350 Sets the alignment for the layout \a l to \a alignment and
351 returns true if \a l is found in this layout (not including child
352 layouts); otherwise returns false.
353*/
354bool QLayout::setAlignment(QLayout *l, Qt::Alignment alignment)
355{
356 int i = 0;
357 QLayoutItem *item = itemAt(i);
358 while (item) {
359 if (item->layout() == l) {
360 item->setAlignment(alignment);
361 invalidate();
362 return true;
363 }
364 ++i;
365 item = itemAt(i);
366 }
367 return false;
368}
369
370/*!
371 \fn void QLayout::setAlignment(Qt::Alignment alignment)
372
373 Sets the alignment of this item to \a alignment.
374
375 \sa QLayoutItem::setAlignment()
376*/
377
378/*!
379 \fn bool QLayout::isTopLevel() const
380
381 Returns true if this layout is a top-level layout, i.e. not a
382 child of another layout; otherwise returns false.
383*/
384
385/*!
386 \property QLayout::margin
387 \brief the width of the outside border of the layout
388 \obsolete
389
390 Use setContentsMargins() and getContentsMargins() instead.
391
392 \sa contentsRect(), spacing
393*/
394
395/*!
396 \obsolete
397*/
398int QLayout::margin() const
399{
400 int left, top, right, bottom;
401 getContentsMargins(&left, &top, &right, &bottom);
402 if (left == top && top == right && right == bottom) {
403 return left;
404 } else {
405 return -1;
406 }
407}
408
409/*!
410 \property QLayout::spacing
411 \brief the spacing between widgets inside the layout
412
413 If no value is explicitly set, the layout's spacing is inherited
414 from the parent layout, or from the style settings for the parent
415 widget.
416
417 For QGridLayout and QFormLayout, it is possible to set different horizontal and
418 vertical spacings using \l{QGridLayout::}{setHorizontalSpacing()}
419 and \l{QGridLayout::}{setVerticalSpacing()}. In that case,
420 spacing() returns -1.
421
422 \sa contentsRect(), getContentsMargins(), QStyle::layoutSpacing(),
423 QStyle::pixelMetric()
424*/
425
426int QLayout::spacing() const
427{
428 if (const QBoxLayout* boxlayout = qobject_cast<const QBoxLayout*>(this)) {
429 return boxlayout->spacing();
430 } else if (const QGridLayout* gridlayout = qobject_cast<const QGridLayout*>(this)) {
431 return gridlayout->spacing();
432 } else if (const QFormLayout* formlayout = qobject_cast<const QFormLayout*>(this)) {
433 return formlayout->spacing();
434 } else {
435 Q_D(const QLayout);
436 if (d->insideSpacing >=0) {
437 return d->insideSpacing;
438 } else {
439 // arbitrarily prefer horizontal spacing to vertical spacing
440 return qSmartSpacing(this, QStyle::PM_LayoutHorizontalSpacing);
441 }
442 }
443}
444
445/*!
446 \obsolete
447*/
448void QLayout::setMargin(int margin)
449{
450 setContentsMargins(margin, margin, margin, margin);
451}
452
453void QLayout::setSpacing(int spacing)
454{
455 if (QBoxLayout* boxlayout = qobject_cast<QBoxLayout*>(this)) {
456 boxlayout->setSpacing(spacing);
457 } else if (QGridLayout* gridlayout = qobject_cast<QGridLayout*>(this)) {
458 gridlayout->setSpacing(spacing);
459 } else if (QFormLayout* formlayout = qobject_cast<QFormLayout*>(this)) {
460 formlayout->setSpacing(spacing);
461 } else {
462 Q_D(QLayout);
463 d->insideSpacing = spacing;
464 invalidate();
465 }
466}
467
468/*!
469 \since 4.3
470
471 Sets the \a left, \a top, \a right, and \a bottom margins to use
472 around the layout.
473
474 By default, QLayout uses the values provided by the style. On
475 most platforms, the margin is 11 pixels in all directions.
476
477 \sa getContentsMargins(), QStyle::pixelMetric(),
478 {QStyle::}{PM_LayoutLeftMargin},
479 {QStyle::}{PM_LayoutTopMargin},
480 {QStyle::}{PM_LayoutRightMargin},
481 {QStyle::}{PM_LayoutBottomMargin}
482*/
483void QLayout::setContentsMargins(int left, int top, int right, int bottom)
484{
485 Q_D(QLayout);
486
487 if (d->userLeftMargin == left && d->userTopMargin == top &&
488 d->userRightMargin == right && d->userBottomMargin == bottom)
489 return;
490
491 d->userLeftMargin = left;
492 d->userTopMargin = top;
493 d->userRightMargin = right;
494 d->userBottomMargin = bottom;
495 invalidate();
496}
497
498/*!
499 \since 4.6
500
501 Sets the \a margins to use around the layout.
502
503 By default, QLayout uses the values provided by the style. On
504 most platforms, the margin is 11 pixels in all directions.
505
506 \sa contentsMargins()
507*/
508void QLayout::setContentsMargins(const QMargins &margins)
509{
510 setContentsMargins(margins.left(), margins.top(), margins.right(), margins.bottom());
511}
512
513/*!
514 \since 4.3
515
516 Extracts the left, top, right, and bottom margins used around the
517 layout, and assigns them to *\a left, *\a top, *\a right, and *\a
518 bottom (unless they are null pointers).
519
520 By default, QLayout uses the values provided by the style. On
521 most platforms, the margin is 11 pixels in all directions.
522
523 \sa setContentsMargins(), QStyle::pixelMetric(),
524 {QStyle::}{PM_LayoutLeftMargin},
525 {QStyle::}{PM_LayoutTopMargin},
526 {QStyle::}{PM_LayoutRightMargin},
527 {QStyle::}{PM_LayoutBottomMargin}
528*/
529void QLayout::getContentsMargins(int *left, int *top, int *right, int *bottom) const
530{
531 Q_D(const QLayout);
532 d->getMargin(left, d->userLeftMargin, QStyle::PM_LayoutLeftMargin);
533 d->getMargin(top, d->userTopMargin, QStyle::PM_LayoutTopMargin);
534 d->getMargin(right, d->userRightMargin, QStyle::PM_LayoutRightMargin);
535 d->getMargin(bottom, d->userBottomMargin, QStyle::PM_LayoutBottomMargin);
536}
537
538/*!
539 \since 4.6
540
541 Returns the margins used around the layout.
542
543 By default, QLayout uses the values provided by the style. On
544 most platforms, the margin is 11 pixels in all directions.
545
546 \sa setContentsMargins()
547*/
548QMargins QLayout::contentsMargins() const
549{
550 int left, top, right, bottom;
551 getContentsMargins(&left, &top, &right, &bottom);
552 return QMargins(left, top, right, bottom);
553}
554
555/*!
556 \since 4.3
557
558 Returns the layout's geometry() rectangle, but taking into account the
559 contents margins.
560
561 \sa setContentsMargins(), getContentsMargins()
562*/
563QRect QLayout::contentsRect() const
564{
565 Q_D(const QLayout);
566 int left, top, right, bottom;
567 getContentsMargins(&left, &top, &right, &bottom);
568 return d->rect.adjusted(+left, +top, -right, -bottom);
569}
570
571#ifdef QT3_SUPPORT
572bool QLayout::isTopLevel() const
573{
574 Q_D(const QLayout);
575 return d->topLevel;
576}
577#endif
578
579/*!
580 Returns the parent widget of this layout, or 0 if this layout is
581 not installed on any widget.
582
583 If the layout is a sub-layout, this function returns the parent
584 widget of the parent layout.
585
586 \sa parent()
587*/
588QWidget *QLayout::parentWidget() const
589{
590 Q_D(const QLayout);
591 if (!d->topLevel) {
592 if (parent()) {
593 QLayout *parentLayout = qobject_cast<QLayout*>(parent());
594 if (!parentLayout) {
595 qWarning("QLayout::parentWidget: A layout can only have another layout as a parent.");
596 return 0;
597 }
598 return parentLayout->parentWidget();
599 } else {
600 return 0;
601 }
602 } else {
603 Q_ASSERT(parent() && parent()->isWidgetType());
604 return static_cast<QWidget *>(parent());
605 }
606}
607
608/*!
609 \reimp
610*/
611bool QLayout::isEmpty() const
612{
613 int i = 0;
614 QLayoutItem *item = itemAt(i);
615 while (item) {
616 if (!item->isEmpty())
617 return false;
618 ++i;
619 item = itemAt(i);
620 }
621 return true;
622}
623
624/*!
625 \reimp
626*/
627void QLayout::setGeometry(const QRect &r)
628{
629 Q_D(QLayout);
630 d->rect = r;
631}
632
633/*!
634 \reimp
635*/
636QRect QLayout::geometry() const
637{
638 Q_D(const QLayout);
639 return d->rect;
640}
641
642/*!
643 \reimp
644*/
645void QLayout::invalidate()
646{
647 Q_D(QLayout);
648 d->rect = QRect();
649 update();
650}
651
652static bool removeWidgetRecursively(QLayoutItem *li, QWidget *w)
653{
654 QLayout *lay = li->layout();
655 if (!lay)
656 return false;
657 int i = 0;
658 QLayoutItem *child;
659 while ((child = lay->itemAt(i))) {
660 if (child->widget() == w) {
661 delete lay->takeAt(i);
662 lay->invalidate();
663 return true;
664 } else if (removeWidgetRecursively(child, w)) {
665 return true;
666 } else {
667 ++i;
668 }
669 }
670 return false;
671}
672
673
674void QLayoutPrivate::doResize(const QSize &r)
675{
676 Q_Q(QLayout);
677 int mbh = menuBarHeightForWidth(menubar, r.width());
678 QWidget *mw = q->parentWidget();
679 QRect rect = mw->testAttribute(Qt::WA_LayoutOnEntireRect) ? mw->rect() : mw->contentsRect();
680 rect.setTop(rect.top() + mbh);
681 q->setGeometry(rect);
682#ifndef QT_NO_MENUBAR
683 if (menubar)
684 menubar->setGeometry(0,0,r.width(), mbh);
685#endif
686}
687
688
689/*!
690 \internal
691 Performs child widget layout when the parent widget is
692 resized. Also handles removal of widgets. \a e is the
693 event
694*/
695void QLayout::widgetEvent(QEvent *e)
696{
697 Q_D(QLayout);
698 if (!d->enabled)
699 return;
700
701 switch (e->type()) {
702 case QEvent::Resize:
703 if (d->activated) {
704 QResizeEvent *r = (QResizeEvent *)e;
705 d->doResize(r->size());
706 } else {
707 activate();
708 }
709 break;
710 case QEvent::ChildRemoved:
711 {
712 QChildEvent *c = (QChildEvent *)e;
713 if (c->child()->isWidgetType()) {
714 QWidget *w = (QWidget *)c->child();
715#ifndef QT_NO_MENUBAR
716 if (w == d->menubar)
717 d->menubar = 0;
718#endif
719 removeWidgetRecursively(this, w);
720 }
721 }
722 break;
723#ifdef QT3_SUPPORT
724 case QEvent::ChildInserted:
725 if (d->topLevel && d->autoNewChild) {
726 QChildEvent *c = (QChildEvent *)e;
727 if (c->child()->isWidgetType()) {
728 QWidget *w = (QWidget *)c->child();
729 if (!w->isWindow()) {
730#if !defined(QT_NO_MENUBAR) && !defined(QT_NO_TOOLBAR)
731 if (qobject_cast<QMenuBar*>(w) && !qobject_cast<QToolBar*>(w->parentWidget())) {
732 d->menubar = (QMenuBar *)w;
733 invalidate();
734 } else
735#endif
736#ifndef QT_NO_SIZEGRIP
737 if (qobject_cast<QSizeGrip*>(w) ) {
738 //SizeGrip is handled by the dialog itself.
739 } else
740#endif
741 addItem(QLayoutPrivate::createWidgetItem(this, w));
742 }
743 }
744 }
745 break;
746 case QEvent::LayoutHint:
747 d->activated = false;
748 // fall through
749#endif
750 case QEvent::LayoutRequest:
751 if (static_cast<QWidget *>(parent())->isVisible())
752 activate();
753 break;
754 default:
755 break;
756 }
757}
758
759/*!
760 \reimp
761*/
762void QLayout::childEvent(QChildEvent *e)
763{
764 Q_D(QLayout);
765 if (!d->enabled)
766 return;
767
768 if (e->type() == QEvent::ChildRemoved) {
769 QChildEvent *c = (QChildEvent*)e;
770 int i = 0;
771
772 QLayoutItem *item;
773 while ((item = itemAt(i))) {
774 if (item == static_cast<QLayout*>(c->child())) {
775 takeAt(i);
776 invalidate();
777 break;
778 } else {
779 ++i;
780 }
781 }
782 }
783}
784
785/*!
786 \internal
787 Also takes contentsMargins and menu bar into account.
788*/
789int QLayout::totalHeightForWidth(int w) const
790{
791 Q_D(const QLayout);
792 int side=0, top=0;
793 if (d->topLevel) {
794 QWidget *parent = parentWidget();
795 parent->ensurePolished();
796 QWidgetPrivate *wd = parent->d_func();
797 side += wd->leftmargin + wd->rightmargin;
798 top += wd->topmargin + wd->bottommargin;
799 }
800 int h = heightForWidth(w - side) + top;
801#ifndef QT_NO_MENUBAR
802 h += menuBarHeightForWidth(d->menubar, w);
803#endif
804 return h;
805}
806
807/*!
808 \internal
809 Also takes contentsMargins and menu bar into account.
810*/
811QSize QLayout::totalMinimumSize() const
812{
813 Q_D(const QLayout);
814 int side=0, top=0;
815 if (d->topLevel) {
816 QWidget *pw = parentWidget();
817 pw->ensurePolished();
818 QWidgetPrivate *wd = pw->d_func();
819 side += wd->leftmargin + wd->rightmargin;
820 top += wd->topmargin + wd->bottommargin;
821 }
822
823 QSize s = minimumSize();
824#ifndef QT_NO_MENUBAR
825 top += menuBarHeightForWidth(d->menubar, s.width() + side);
826#endif
827 return s + QSize(side, top);
828}
829
830/*!
831 \internal
832 Also takes contentsMargins and menu bar into account.
833*/
834QSize QLayout::totalSizeHint() const
835{
836 Q_D(const QLayout);
837 int side=0, top=0;
838 if (d->topLevel) {
839 QWidget *pw = parentWidget();
840 pw->ensurePolished();
841 QWidgetPrivate *wd = pw->d_func();
842 side += wd->leftmargin + wd->rightmargin;
843 top += wd->topmargin + wd->bottommargin;
844 }
845
846 QSize s = sizeHint();
847 if (hasHeightForWidth())
848 s.setHeight(heightForWidth(s.width() + side));
849#ifndef QT_NO_MENUBAR
850 top += menuBarHeightForWidth(d->menubar, s.width());
851#endif
852 return s + QSize(side, top);
853}
854
855/*!
856 \internal
857 Also takes contentsMargins and menu bar into account.
858*/
859QSize QLayout::totalMaximumSize() const
860{
861 Q_D(const QLayout);
862 int side=0, top=0;
863 if (d->topLevel) {
864 QWidget *pw = parentWidget();
865 pw->ensurePolished();
866 QWidgetPrivate *wd = pw->d_func();
867 side += wd->leftmargin + wd->rightmargin;
868 top += wd->topmargin + wd->bottommargin;
869 }
870
871 QSize s = maximumSize();
872#ifndef QT_NO_MENUBAR
873 top += menuBarHeightForWidth(d->menubar, s.width());
874#endif
875
876 if (d->topLevel)
877 s = QSize(qMin(s.width() + side, QLAYOUTSIZE_MAX),
878 qMin(s.height() + top, QLAYOUTSIZE_MAX));
879 return s;
880}
881
882/*!
883 \internal
884 Destroys the layout, deleting all child layouts.
885 Geometry management stops when a top-level layout is deleted.
886
887 The layout classes will probably be fatally confused if you delete
888 a sublayout.
889*/
890QLayout::~QLayout()
891{
892 Q_D(QLayout);
893 /*
894 This function may be called during the QObject destructor,
895 when the parent no longer is a QWidget.
896 */
897 if (d->topLevel && parent() && parent()->isWidgetType() &&
898 ((QWidget*)parent())->layout() == this)
899 ((QWidget*)parent())->d_func()->layout = 0;
900}
901
902#ifdef QT3_SUPPORT
903/*!
904 Removes and deletes all items in this layout.
905*/
906void QLayout::deleteAllItems()
907{
908 QLayoutItem *l;
909 while ((l = takeAt(0)))
910 delete l;
911}
912#endif
913
914/*!
915 This function is called from \c addLayout() or \c insertLayout() functions in
916 subclasses to add layout \a l as a sub-layout.
917
918 The only scenario in which you need to call it directly is if you
919 implement a custom layout that supports nested layouts.
920
921 \sa QBoxLayout::addLayout(), QBoxLayout::insertLayout(), QGridLayout::addLayout()
922*/
923void QLayout::addChildLayout(QLayout *l)
924{
925 if (l->parent()) {
926 qWarning("QLayout::addChildLayout: layout \"%s\" already has a parent",
927 l->objectName().toLocal8Bit().data());
928 return;
929 }
930 l->setParent(this);
931
932 if (QWidget *mw = parentWidget()) {
933 l->d_func()->reparentChildWidgets(mw);
934 }
935
936}
937
938#ifdef QT_DEBUG
939static bool layoutDebug()
940{
941 static int checked_env = -1;
942 if(checked_env == -1)
943 checked_env = !!qgetenv("QT_LAYOUT_DEBUG").toInt();
944
945 return checked_env;
946}
947#endif
948
949void QLayoutPrivate::reparentChildWidgets(QWidget *mw)
950{
951 Q_Q(QLayout);
952 int n = q->count();
953
954#ifndef QT_NO_MENUBAR
955 if (menubar && menubar->parentWidget() != mw) {
956 menubar->setParent(mw);
957 }
958#endif
959 bool mwVisible = mw && mw->isVisible();
960 for (int i = 0; i < n; ++i) {
961 QLayoutItem *item = q->itemAt(i);
962 if (QWidget *w = item->widget()) {
963 QWidget *pw = w->parentWidget();
964#ifdef QT_DEBUG
965 if (pw && pw != mw && layoutDebug()) {
966 qWarning("QLayout::addChildLayout: widget %s \"%s\" in wrong parent; moved to correct parent",
967 w->metaObject()->className(), w->objectName().toLocal8Bit().data());
968 }
969#endif
970 bool needShow = mwVisible && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide));
971 if (pw != mw)
972 w->setParent(mw);
973 if (needShow)
974 QMetaObject::invokeMethod(w, "_q_showIfNotHidden", Qt::QueuedConnection); //show later
975 } else if (QLayout *l = item->layout()) {
976 l->d_func()->reparentChildWidgets(mw);
977 }
978 }
979}
980
981/*!
982 This function is called from \c addWidget() functions in
983 subclasses to add \a w as a child widget.
984
985 If \a w is already in a layout, this function will give a warning
986 and remove \a w from the layout. This function must therefore be
987 called before adding \a w to the layout's data structure.
988*/
989void QLayout::addChildWidget(QWidget *w)
990{
991 QWidget *mw = parentWidget();
992 QWidget *pw = w->parentWidget();
993
994 //Qt::WA_LaidOut is never reset. It only means that the widget at some point has
995 //been in a layout.
996 if (pw && w->testAttribute(Qt::WA_LaidOut)) {
997 QLayout *l = pw->layout();
998 if (l && removeWidgetRecursively(l, w)) {
999#ifdef QT_DEBUG
1000 if (layoutDebug())
1001 qWarning("QLayout::addChildWidget: %s \"%s\" is already in a layout; moved to new layout",
1002 w->metaObject()->className(), w->objectName().toLocal8Bit().data());
1003#endif
1004 }
1005 }
1006 if (pw && mw && pw != mw) {
1007#ifdef QT_DEBUG
1008 if (layoutDebug())
1009 qWarning("QLayout::addChildWidget: %s \"%s\" in wrong parent; moved to correct parent",
1010 w->metaObject()->className(), w->objectName().toLocal8Bit().data());
1011#endif
1012 pw = 0;
1013 }
1014 bool needShow = mw && mw->isVisible() && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide));
1015 if (!pw && mw)
1016 w->setParent(mw);
1017 w->setAttribute(Qt::WA_LaidOut);
1018 if (needShow)
1019 QMetaObject::invokeMethod(w, "_q_showIfNotHidden", Qt::QueuedConnection); //show later
1020}
1021
1022#ifdef QT3_SUPPORT
1023/*!
1024 \compat
1025
1026 Sets this layout's parent widget to a fixed size with width \a w
1027 and height \a h, stopping the user from resizing it, and also
1028 prevents the layout from resizing it, even if the layout's size
1029 hint should change. Does nothing if this is not a top-level
1030 layout (i.e., if parent()->isWidgetType()).
1031
1032 As a special case, if both \a w and \a h are 0, then the layout's
1033 current sizeHint() is used.
1034
1035 Use \c setResizeMode(Fixed) to stop the widget from being resized
1036 by the user, while still allowing the layout to resize it when
1037 the sizeHint() changes.
1038
1039 Use \c setResizeMode(FreeResize) to allow the user to resize the
1040 widget, while preventing the layout from resizing it.
1041
1042*/
1043void QLayout::freeze(int w, int h)
1044{
1045 Q_D(QLayout);
1046 if (!d->topLevel)
1047 return;
1048 if (w <= 0 || h <= 0) {
1049 QSize s = totalSizeHint();
1050 w = s.width();
1051 h = s.height();
1052 }
1053 setSizeConstraint(SetNoConstraint); // layout will not change min/max size
1054 QWidget *parent = parentWidget();
1055 if (parent)
1056 parent->setFixedSize(w, h);
1057}
1058
1059#endif
1060
1061
1062
1063
1064
1065
1066
1067/*!
1068 Tells the geometry manager to place the menu bar \a widget at the
1069 top of parentWidget(), outside QWidget::contentsMargins(). All
1070 child widgets are placed below the bottom edge of the menu bar.
1071*/
1072void QLayout::setMenuBar(QWidget *widget)
1073{
1074 Q_D(QLayout);
1075
1076#ifdef Q_OS_WINCE_WM
1077 if (widget && widget->size().height() > 0)
1078#else
1079 if (widget)
1080#endif
1081 addChildWidget(widget);
1082 d->menubar = widget;
1083}
1084
1085/*!
1086 Returns the menu bar set for this layout, or 0 if no menu bar is
1087 set.
1088*/
1089
1090QWidget *QLayout::menuBar() const
1091{
1092 Q_D(const QLayout);
1093 return d->menubar;
1094}
1095
1096
1097/*!
1098 Returns the minimum size of this layout. This is the smallest
1099 size that the layout can have while still respecting the
1100 specifications.
1101
1102 The returned value doesn't include the space required by
1103 QWidget::setContentsMargins() or menuBar().
1104
1105 The default implementation allows unlimited resizing.
1106*/
1107QSize QLayout::minimumSize() const
1108{
1109 return QSize(0, 0);
1110}
1111
1112/*!
1113 Returns the maximum size of this layout. This is the largest size
1114 that the layout can have while still respecting the
1115 specifications.
1116
1117 The returned value doesn't include the space required by
1118 QWidget::setContentsMargins() or menuBar().
1119
1120 The default implementation allows unlimited resizing.
1121*/
1122QSize QLayout::maximumSize() const
1123{
1124 return QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX);
1125}
1126
1127/*!
1128 Returns whether this layout can make use of more space than
1129 sizeHint(). A value of Qt::Vertical or Qt::Horizontal means that
1130 it wants to grow in only one dimension, whereas Qt::Vertical |
1131 Qt::Horizontal means that it wants to grow in both dimensions.
1132
1133 The default implementation returns Qt::Horizontal | Qt::Vertical.
1134 Subclasses reimplement it to return a meaningful value based on
1135 their child widgets's \l{QSizePolicy}{size policies}.
1136
1137 \sa sizeHint()
1138*/
1139Qt::Orientations QLayout::expandingDirections() const
1140{
1141 return Qt::Horizontal | Qt::Vertical;
1142}
1143
1144void QLayout::activateRecursiveHelper(QLayoutItem *item)
1145{
1146 item->invalidate();
1147 QLayout *layout = item->layout();
1148 if (layout) {
1149 QLayoutItem *child;
1150 int i=0;
1151 while ((child = layout->itemAt(i++)))
1152 activateRecursiveHelper(child);
1153 layout->d_func()->activated = true;
1154 }
1155}
1156
1157/*!
1158 Updates the layout for parentWidget().
1159
1160 You should generally not need to call this because it is
1161 automatically called at the most appropriate times.
1162
1163 \sa activate(), invalidate()
1164*/
1165
1166void QLayout::update()
1167{
1168 QLayout *layout = this;
1169 while (layout && layout->d_func()->activated) {
1170 layout->d_func()->activated = false;
1171 if (layout->d_func()->topLevel) {
1172 Q_ASSERT(layout->parent()->isWidgetType());
1173 QWidget *mw = static_cast<QWidget*>(layout->parent());
1174 QApplication::postEvent(mw, new QEvent(QEvent::LayoutRequest));
1175 break;
1176 }
1177 layout = static_cast<QLayout*>(layout->parent());
1178 }
1179}
1180
1181/*!
1182 Redoes the layout for parentWidget() if necessary.
1183
1184 You should generally not need to call this because it is
1185 automatically called at the most appropriate times. It returns
1186 true if the layout was redone.
1187
1188 \sa update(), QWidget::updateGeometry()
1189*/
1190bool QLayout::activate()
1191{
1192 Q_D(QLayout);
1193 if (!d->enabled || !parent())
1194 return false;
1195 if (!d->topLevel)
1196 return static_cast<QLayout*>(parent())->activate();
1197 if (d->activated)
1198 return false;
1199 QWidget *mw = static_cast<QWidget*>(parent());
1200 if (mw == 0) {
1201 qWarning("QLayout::activate: %s \"%s\" does not have a main widget",
1202 QObject::metaObject()->className(), QObject::objectName().toLocal8Bit().data());
1203 return false;
1204 }
1205 activateRecursiveHelper(this);
1206
1207 QWidgetPrivate *md = mw->d_func();
1208 uint explMin = md->extra ? md->extra->explicitMinSize : 0;
1209 uint explMax = md->extra ? md->extra->explicitMaxSize : 0;
1210
1211 switch (d->constraint) {
1212 case SetFixedSize:
1213 // will trigger resize
1214 mw->setFixedSize(totalSizeHint());
1215 break;
1216 case SetMinimumSize:
1217 mw->setMinimumSize(totalMinimumSize());
1218 break;
1219 case SetMaximumSize:
1220 mw->setMaximumSize(totalMaximumSize());
1221 break;
1222 case SetMinAndMaxSize:
1223 mw->setMinimumSize(totalMinimumSize());
1224 mw->setMaximumSize(totalMaximumSize());
1225 break;
1226 case SetDefaultConstraint: {
1227 bool widthSet = explMin & Qt::Horizontal;
1228 bool heightSet = explMin & Qt::Vertical;
1229 if (mw->isWindow()) {
1230 QSize ms = totalMinimumSize();
1231 if (widthSet)
1232 ms.setWidth(mw->minimumSize().width());
1233 if (heightSet)
1234 ms.setHeight(mw->minimumSize().height());
1235 if ((!heightSet || !widthSet) && hasHeightForWidth()) {
1236 int h = minimumHeightForWidth(ms.width());
1237 if (h > ms.height()) {
1238 if (!heightSet)
1239 ms.setHeight(0);
1240 if (!widthSet)
1241 ms.setWidth(0);
1242 }
1243 }
1244 mw->setMinimumSize(ms);
1245 } else if (!widthSet || !heightSet) {
1246 QSize ms = mw->minimumSize();
1247 if (!widthSet)
1248 ms.setWidth(0);
1249 if (!heightSet)
1250 ms.setHeight(0);
1251 mw->setMinimumSize(ms);
1252 }
1253 break;
1254 }
1255 case SetNoConstraint:
1256 break;
1257 }
1258
1259 d->doResize(mw->size());
1260
1261 if (md->extra) {
1262 md->extra->explicitMinSize = explMin;
1263 md->extra->explicitMaxSize = explMax;
1264 }
1265 // ideally only if sizeHint() or sizePolicy() has changed
1266 mw->updateGeometry();
1267 return true;
1268}
1269
1270/*!
1271 \fn QLayoutItem *QLayout::itemAt(int index) const
1272
1273 Must be implemented in subclasses to return the layout item at \a
1274 index. If there is no such item, the function must return 0.
1275 Items are numbered consecutively from 0. If an item is deleted, other items will be renumbered.
1276
1277 This function can be used to iterate over a layout. The following
1278 code will draw a rectangle for each layout item in the layout structure of the widget.
1279
1280 \snippet doc/src/snippets/code/src_gui_kernel_qlayout.cpp 0
1281
1282 \sa count(), takeAt()
1283*/
1284
1285/*!
1286 \fn QLayoutItem *QLayout::takeAt(int index)
1287
1288 Must be implemented in subclasses to remove the layout item at \a
1289 index from the layout, and return the item. If there is no such
1290 item, the function must do nothing and return 0. Items are numbered
1291 consecutively from 0. If an item is removed, other items will be
1292 renumbered.
1293
1294 The following code fragment shows a safe way to remove all items
1295 from a layout:
1296
1297 \snippet doc/src/snippets/code/src_gui_kernel_qlayout.cpp 1
1298
1299 \sa itemAt(), count()
1300*/
1301
1302/*!
1303 \fn int *QLayout::count() const
1304
1305 Must be implemented in subclasses to return the number of items
1306 in the layout.
1307
1308 \sa itemAt()
1309*/
1310
1311/*!
1312 Searches for widget \a widget in this layout (not including child
1313 layouts).
1314
1315 Returns the index of \a widget, or -1 if \a widget is not found.
1316
1317 The default implementation iterates over all items using itemAt()
1318*/
1319int QLayout::indexOf(QWidget *widget) const
1320{
1321 int i = 0;
1322 QLayoutItem *item = itemAt(i);
1323 while (item) {
1324 if (item->widget() == widget)
1325 return i;
1326 ++i;
1327 item = itemAt(i);
1328 }
1329 return -1;
1330}
1331
1332/*!
1333 \enum QLayout::SizeConstraint
1334
1335 The possible values are:
1336
1337 \value SetDefaultConstraint The main widget's minimum size is set
1338 to minimumSize(), unless the widget already has
1339 a minimum size.
1340
1341 \value SetFixedSize The main widget's size is set to sizeHint(); it
1342 cannot be resized at all.
1343 \value SetMinimumSize The main widget's minimum size is set to
1344 minimumSize(); it cannot be smaller.
1345
1346 \value SetMaximumSize The main widget's maximum size is set to
1347 maximumSize(); it cannot be larger.
1348
1349 \value SetMinAndMaxSize The main widget's minimum size is set to
1350 minimumSize() and its maximum size is set to
1351 maximumSize().
1352
1353 \value SetNoConstraint The widget is not constrained.
1354
1355 \omitvalue Auto
1356 \omitvalue FreeResize
1357 \omitvalue Minimum
1358 \omitvalue Fixed
1359
1360 \sa setSizeConstraint()
1361*/
1362
1363/*!
1364 \property QLayout::sizeConstraint
1365 \brief the resize mode of the layout
1366
1367 The default mode is \l {QLayout::SetDefaultConstraint}
1368 {SetDefaultConstraint}.
1369*/
1370void QLayout::setSizeConstraint(SizeConstraint constraint)
1371{
1372 Q_D(QLayout);
1373 if (constraint == d->constraint)
1374 return;
1375
1376 d->constraint = constraint;
1377 invalidate();
1378}
1379
1380QLayout::SizeConstraint QLayout::sizeConstraint() const
1381{
1382 Q_D(const QLayout);
1383 return d->constraint;
1384}
1385
1386/*!
1387 Returns the rectangle that should be covered when the geometry of
1388 this layout is set to \a r, provided that this layout supports
1389 setAlignment().
1390
1391 The result is derived from sizeHint() and expanding(). It is never
1392 larger than \a r.
1393*/
1394QRect QLayout::alignmentRect(const QRect &r) const
1395{
1396 QSize s = sizeHint();
1397 Qt::Alignment a = alignment();
1398
1399 /*
1400 This is a hack to obtain the real maximum size, not
1401 QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX), the value consistently
1402 returned by QLayoutItems that have an alignment.
1403 */
1404 QLayout *that = const_cast<QLayout *>(this);
1405 that->setAlignment(0);
1406 QSize ms = that->maximumSize();
1407 that->setAlignment(a);
1408
1409 if ((expandingDirections() & Qt::Horizontal) ||
1410 !(a & Qt::AlignHorizontal_Mask)) {
1411 s.setWidth(qMin(r.width(), ms.width()));
1412 }
1413 if ((expandingDirections() & Qt::Vertical) ||
1414 !(a & Qt::AlignVertical_Mask)) {
1415 s.setHeight(qMin(r.height(), ms.height()));
1416 } else if (hasHeightForWidth()) {
1417 int hfw = heightForWidth(s.width());
1418 if (hfw < s.height())
1419 s.setHeight(qMin(hfw, ms.height()));
1420 }
1421
1422 s = s.boundedTo(r.size());
1423 int x = r.x();
1424 int y = r.y();
1425
1426 if (a & Qt::AlignBottom)
1427 y += (r.height() - s.height());
1428 else if (!(a & Qt::AlignTop))
1429 y += (r.height() - s.height()) / 2;
1430
1431 QWidget *parent = parentWidget();
1432 a = QStyle::visualAlignment(parent ? parent->layoutDirection() : QApplication::layoutDirection(), a);
1433 if (a & Qt::AlignRight)
1434 x += (r.width() - s.width());
1435 else if (!(a & Qt::AlignLeft))
1436 x += (r.width() - s.width()) / 2;
1437
1438 return QRect(x, y, s.width(), s.height());
1439}
1440
1441/*!
1442 Removes the widget \a widget from the layout. After this call, it
1443 is the caller's responsibility to give the widget a reasonable
1444 geometry or to put the widget back into a layout.
1445
1446 \bold{Note:} The ownership of \a widget remains the same as
1447 when it was added.
1448
1449 \sa removeItem(), QWidget::setGeometry(), addWidget()
1450*/
1451void QLayout::removeWidget(QWidget *widget)
1452{
1453 int i = 0;
1454 QLayoutItem *child;
1455 while ((child = itemAt(i))) {
1456 if (child->widget() == widget) {
1457 delete takeAt(i);
1458 invalidate();
1459 } else {
1460 ++i;
1461 }
1462 }
1463}
1464
1465/*!
1466 Removes the layout item \a item from the layout. It is the
1467 caller's responsibility to delete the item.
1468
1469 Notice that \a item can be a layout (since QLayout inherits
1470 QLayoutItem).
1471
1472 \sa removeWidget(), addItem()
1473*/
1474void QLayout::removeItem(QLayoutItem *item)
1475{
1476 int i = 0;
1477 QLayoutItem *child;
1478 while ((child = itemAt(i))) {
1479 if (child == item) {
1480 takeAt(i);
1481 invalidate();
1482 } else {
1483 ++i;
1484 }
1485 }
1486}
1487
1488/*!
1489 Enables this layout if \a enable is true, otherwise disables it.
1490
1491 An enabled layout adjusts dynamically to changes; a disabled
1492 layout acts as if it did not exist.
1493
1494 By default all layouts are enabled.
1495
1496 \sa isEnabled()
1497*/
1498void QLayout::setEnabled(bool enable)
1499{
1500 Q_D(QLayout);
1501 d->enabled = enable;
1502}
1503
1504/*!
1505 Returns true if the layout is enabled; otherwise returns false.
1506
1507 \sa setEnabled()
1508*/
1509bool QLayout::isEnabled() const
1510{
1511 Q_D(const QLayout);
1512 return d->enabled;
1513}
1514
1515/*!
1516 Returns a size that satisfies all size constraints on \a widget,
1517 including heightForWidth() and that is as close as possible to \a
1518 size.
1519*/
1520
1521QSize QLayout::closestAcceptableSize(const QWidget *widget, const QSize &size)
1522{
1523 QSize result = size.boundedTo(qSmartMaxSize(widget));
1524 result = result.expandedTo(qSmartMinSize(widget));
1525 QLayout *l = widget->layout();
1526 if (l && l->hasHeightForWidth() && result.height() < l->minimumHeightForWidth(result.width()) ) {
1527 QSize current = widget->size();
1528 int currentHfw = l->minimumHeightForWidth(current.width());
1529 int newHfw = l->minimumHeightForWidth(result.width());
1530 if (current.height() < currentHfw || currentHfw == newHfw) {
1531 //handle the constant hfw case and the vertical-only case, as well as the
1532 // current-size-is-not-correct case
1533 result.setHeight(newHfw);
1534 } else {
1535 // binary search; assume hfw is decreasing ###
1536
1537 int maxw = qMax(widget->width(),result.width());
1538 int maxh = qMax(widget->height(), result.height());
1539 int minw = qMin(widget->width(),result.width());
1540 int minh = qMin(widget->height(), result.height());
1541
1542 int minhfw = l->minimumHeightForWidth(minw);
1543 int maxhfw = l->minimumHeightForWidth(maxw);
1544 while (minw < maxw) {
1545 if (minhfw > maxh) { //assume decreasing
1546 minw = maxw - (maxw-minw)/2;
1547 minhfw = l->minimumHeightForWidth(minw);
1548 } else if (maxhfw < minh ) { //assume decreasing
1549 maxw = minw + (maxw-minw)/2;
1550 maxhfw = l->minimumHeightForWidth(maxw);
1551 } else {
1552 break;
1553 }
1554 }
1555 result = result.expandedTo(QSize(minw, minhfw));
1556 }
1557 }
1558 return result;
1559}
1560
1561/*!
1562 \fn void QLayout::setResizeMode(SizeConstraint constraint)
1563
1564 Use setSizeConstraint(\a constraint) instead.
1565*/
1566
1567/*!
1568 \fn QLayout::SizeConstraint QLayout::resizeMode() const
1569
1570 Use sizeConstraint() instead.
1571*/
1572
1573void QSizePolicy::setControlType(ControlType type)
1574{
1575 /*
1576 The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10,
1577 etc. In memory, we pack it onto the available bits (CTSize) in
1578 setControlType(), and unpack it here.
1579
1580 Example:
1581
1582 0x00000001 maps to 0x00000000
1583 0x00000002 maps to 0x00000200
1584 0x00000004 maps to 0x00000400
1585 0x00000008 maps to 0x00000600
1586 etc.
1587 */
1588
1589 int i = 0;
1590 while (true) {
1591 if (type & (0x1 << i)) {
1592 data = (data & ~CTMask) | (i << CTShift);
1593 return;
1594 }
1595 ++i;
1596 }
1597}
1598
1599QSizePolicy::ControlType QSizePolicy::controlType() const
1600{
1601 return QSizePolicy::ControlType(0x1 << ((data & CTMask) >> CTShift));
1602}
1603
1604#ifndef QT_NO_DATASTREAM
1605/*!
1606 \relates QSizePolicy
1607 \since 4.2
1608
1609 Writes the size \a policy to the data stream \a stream.
1610
1611 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
1612*/
1613QDataStream &operator<<(QDataStream &stream, const QSizePolicy &policy)
1614{
1615 return stream << policy.data;
1616}
1617
1618/*!
1619 \relates QSizePolicy
1620 \since 4.2
1621
1622 Reads the size \a policy from the data stream \a stream.
1623
1624 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
1625*/
1626QDataStream &operator>>(QDataStream &stream, QSizePolicy &policy)
1627{
1628 return stream >> policy.data;
1629}
1630#endif // QT_NO_DATASTREAM
1631
1632QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.