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

Last change on this file since 476 was 2, checked in by Dmitry A. Kuminov, 16 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
875 implement a custom layout that supports nested layouts.
876
877 \sa QBoxLayout::addLayout(), QBoxLayout::insertLayout(), QGridLayout::addLayout()
878*/
879void QLayout::addChildLayout(QLayout *l)
880{
881 if (l->parent()) {
882 qWarning("QLayout::addChildLayout: layout \"%s\" already has a parent",
883 l->objectName().toLocal8Bit().data());
884 return;
885 }
886 l->setParent(this);
887
888 if (QWidget *mw = parentWidget()) {
889 l->d_func()->reparentChildWidgets(mw);
890 }
891
892}
893
894#ifdef QT_DEBUG
895static bool layoutDebug()
896{
897 static int checked_env = -1;
898 if(checked_env == -1)
899 checked_env = !!qgetenv("QT_LAYOUT_DEBUG").toInt();
900
901 return checked_env;
902}
903#endif
904
905void QLayoutPrivate::reparentChildWidgets(QWidget *mw)
906{
907 Q_Q(QLayout);
908 int n = q->count();
909
910#ifndef QT_NO_MENUBAR
911 if (menubar && menubar->parentWidget() != mw) {
912 menubar->setParent(mw);
913 }
914#endif
915 bool mwVisible = mw && mw->isVisible();
916 for (int i = 0; i < n; ++i) {
917 QLayoutItem *item = q->itemAt(i);
918 if (QWidget *w = item->widget()) {
919 QWidget *pw = w->parentWidget();
920#ifdef QT_DEBUG
921 if (pw && pw != mw && layoutDebug()) {
922 qWarning("QLayout::addChildLayout: widget %s \"%s\" in wrong parent; moved to correct parent",
923 w->metaObject()->className(), w->objectName().toLocal8Bit().data());
924 }
925#endif
926 bool needShow = mwVisible && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide));
927 if (pw != mw)
928 w->setParent(mw);
929 if (needShow)
930 QMetaObject::invokeMethod(w, "_q_showIfNotHidden", Qt::QueuedConnection); //show later
931 } else if (QLayout *l = item->layout()) {
932 l->d_func()->reparentChildWidgets(mw);
933 }
934 }
935}
936
937/*!
938 This function is called from \c addWidget() functions in
939 subclasses to add \a w as a child widget.
940
941 If \a w is already in a layout, this function will give a warning
942 and remove \a w from the layout. This function must therefore be
943 called before adding \a w to the layout's data structure.
944*/
945void QLayout::addChildWidget(QWidget *w)
946{
947 QWidget *mw = parentWidget();
948 QWidget *pw = w->parentWidget();
949
950 //Qt::WA_LaidOut is never reset. It only means that the widget at some point has
951 //been in a layout.
952 if (pw && w->testAttribute(Qt::WA_LaidOut)) {
953 QLayout *l = pw->layout();
954 if (l && removeWidgetRecursively(l, w)) {
955#ifdef QT_DEBUG
956 if (layoutDebug())
957 qWarning("QLayout::addChildWidget: %s \"%s\" is already in a layout; moved to new layout",
958 w->metaObject()->className(), w->objectName().toLocal8Bit().data());
959#endif
960 }
961 }
962 if (pw && mw && pw != mw) {
963#ifdef QT_DEBUG
964 if (layoutDebug())
965 qWarning("QLayout::addChildWidget: %s \"%s\" in wrong parent; moved to correct parent",
966 w->metaObject()->className(), w->objectName().toLocal8Bit().data());
967#endif
968 pw = 0;
969 }
970 bool needShow = mw && mw->isVisible() && !(w->isHidden() && w->testAttribute(Qt::WA_WState_ExplicitShowHide));
971 if (!pw && mw)
972 w->setParent(mw);
973 w->setAttribute(Qt::WA_LaidOut);
974 if (needShow)
975 QMetaObject::invokeMethod(w, "_q_showIfNotHidden", Qt::QueuedConnection); //show later
976}
977
978#ifdef QT3_SUPPORT
979/*!
980 \compat
981
982 Sets this layout's parent widget to a fixed size with width \a w
983 and height \a h, stopping the user from resizing it, and also
984 prevents the layout from resizing it, even if the layout's size
985 hint should change. Does nothing if this is not a top-level
986 layout (i.e., if parent()->isWidgetType()).
987
988 As a special case, if both \a w and \a h are 0, then the layout's
989 current sizeHint() is used.
990
991 Use \c setResizeMode(Fixed) to stop the widget from being resized
992 by the user, while still allowing the layout to resize it when
993 the sizeHint() changes.
994
995 Use \c setResizeMode(FreeResize) to allow the user to resize the
996 widget, while preventing the layout from resizing it.
997
998*/
999void QLayout::freeze(int w, int h)
1000{
1001 Q_D(QLayout);
1002 if (!d->topLevel)
1003 return;
1004 if (w <= 0 || h <= 0) {
1005 QSize s = totalSizeHint();
1006 w = s.width();
1007 h = s.height();
1008 }
1009 setSizeConstraint(SetNoConstraint); // layout will not change min/max size
1010 QWidget *parent = parentWidget();
1011 if (parent)
1012 parent->setFixedSize(w, h);
1013}
1014
1015#endif
1016
1017
1018
1019
1020
1021
1022
1023/*!
1024 Tells the geometry manager to place the menu bar \a widget at the
1025 top of parentWidget(), outside QWidget::contentsMargins(). All
1026 child widgets are placed below the bottom edge of the menu bar.
1027*/
1028void QLayout::setMenuBar(QWidget *widget)
1029{
1030 Q_D(QLayout);
1031 if (widget)
1032 addChildWidget(widget);
1033 d->menubar = widget;
1034}
1035
1036/*!
1037 Returns the menu bar set for this layout, or 0 if no menu bar is
1038 set.
1039*/
1040
1041QWidget *QLayout::menuBar() const
1042{
1043 Q_D(const QLayout);
1044 return d->menubar;
1045}
1046
1047
1048/*!
1049 Returns the minimum size of this layout. This is the smallest
1050 size that the layout can have while still respecting the
1051 specifications.
1052
1053 The returned value doesn't include the space required by
1054 QWidget::setContentsMargins() or menuBar().
1055
1056 The default implementation allows unlimited resizing.
1057*/
1058QSize QLayout::minimumSize() const
1059{
1060 return QSize(0, 0);
1061}
1062
1063/*!
1064 Returns the maximum size of this layout. This is the largest size
1065 that the layout can have while still respecting the
1066 specifications.
1067
1068 The returned value doesn't include the space required by
1069 QWidget::setContentsMargins() or menuBar().
1070
1071 The default implementation allows unlimited resizing.
1072*/
1073QSize QLayout::maximumSize() const
1074{
1075 return QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX);
1076}
1077
1078/*!
1079 Returns whether this layout can make use of more space than
1080 sizeHint(). A value of Qt::Vertical or Qt::Horizontal means that
1081 it wants to grow in only one dimension, whereas Qt::Vertical |
1082 Qt::Horizontal means that it wants to grow in both dimensions.
1083
1084 The default implementation returns Qt::Horizontal | Qt::Vertical.
1085 Subclasses reimplement it to return a meaningful value based on
1086 their child widgets's \l{QSizePolicy}{size policies}.
1087
1088 \sa sizeHint()
1089*/
1090Qt::Orientations QLayout::expandingDirections() const
1091{
1092 return Qt::Horizontal | Qt::Vertical;
1093}
1094
1095void QLayout::activateRecursiveHelper(QLayoutItem *item)
1096{
1097 item->invalidate();
1098 QLayout *layout = item->layout();
1099 if (layout) {
1100 QLayoutItem *child;
1101 int i=0;
1102 while ((child = layout->itemAt(i++)))
1103 activateRecursiveHelper(child);
1104 layout->d_func()->activated = true;
1105 }
1106}
1107
1108/*!
1109 Updates the layout for parentWidget().
1110
1111 You should generally not need to call this because it is
1112 automatically called at the most appropriate times.
1113
1114 \sa activate(), invalidate()
1115*/
1116
1117void QLayout::update()
1118{
1119 QLayout *layout = this;
1120 while (layout && layout->d_func()->activated) {
1121 layout->d_func()->activated = false;
1122 if (layout->d_func()->topLevel) {
1123 Q_ASSERT(layout->parent()->isWidgetType());
1124 QWidget *mw = static_cast<QWidget*>(layout->parent());
1125 QApplication::postEvent(mw, new QEvent(QEvent::LayoutRequest));
1126 break;
1127 }
1128 layout = static_cast<QLayout*>(layout->parent());
1129 }
1130}
1131
1132/*!
1133 Redoes the layout for parentWidget() if necessary.
1134
1135 You should generally not need to call this because it is
1136 automatically called at the most appropriate times. It returns
1137 true if the layout was redone.
1138
1139 \sa update(), QWidget::updateGeometry()
1140*/
1141bool QLayout::activate()
1142{
1143 Q_D(QLayout);
1144 if (!d->enabled || !parent())
1145 return false;
1146 if (!d->topLevel)
1147 return static_cast<QLayout*>(parent())->activate();
1148 if (d->activated)
1149 return false;
1150 QWidget *mw = static_cast<QWidget*>(parent());
1151 if (mw == 0) {
1152 qWarning("QLayout::activate: %s \"%s\" does not have a main widget",
1153 QObject::metaObject()->className(), QObject::objectName().toLocal8Bit().data());
1154 return false;
1155 }
1156 activateRecursiveHelper(this);
1157
1158 QWidgetPrivate *md = mw->d_func();
1159 uint explMin = md->extra ? md->extra->explicitMinSize : 0;
1160 uint explMax = md->extra ? md->extra->explicitMaxSize : 0;
1161
1162 switch (d->constraint) {
1163 case SetFixedSize:
1164 // will trigger resize
1165 mw->setFixedSize(totalSizeHint());
1166 break;
1167 case SetMinimumSize:
1168 mw->setMinimumSize(totalMinimumSize());
1169 break;
1170 case SetMaximumSize:
1171 mw->setMaximumSize(totalMaximumSize());
1172 break;
1173 case SetMinAndMaxSize:
1174 mw->setMinimumSize(totalMinimumSize());
1175 mw->setMaximumSize(totalMaximumSize());
1176 break;
1177 case SetDefaultConstraint: {
1178 bool widthSet = explMin & Qt::Horizontal;
1179 bool heightSet = explMin & Qt::Vertical;
1180 if (mw->isWindow()) {
1181 QSize ms = totalMinimumSize();
1182 if (widthSet)
1183 ms.setWidth(mw->minimumSize().width());
1184 if (heightSet)
1185 ms.setHeight(mw->minimumSize().height());
1186 if ((!heightSet || !widthSet) && hasHeightForWidth()) {
1187 int h = minimumHeightForWidth(ms.width());
1188 if (h > ms.height()) {
1189 if (!heightSet)
1190 ms.setHeight(0);
1191 if (!widthSet)
1192 ms.setWidth(0);
1193 }
1194 }
1195 mw->setMinimumSize(ms);
1196 } else if (!widthSet || !heightSet) {
1197 QSize ms = mw->minimumSize();
1198 if (!widthSet)
1199 ms.setWidth(0);
1200 if (!heightSet)
1201 ms.setHeight(0);
1202 mw->setMinimumSize(ms);
1203 }
1204 break;
1205 }
1206 case SetNoConstraint:
1207 break;
1208 }
1209
1210 d->doResize(mw->size());
1211
1212 if (md->extra) {
1213 md->extra->explicitMinSize = explMin;
1214 md->extra->explicitMaxSize = explMax;
1215 }
1216 // ideally only if sizeHint() or sizePolicy() has changed
1217 mw->updateGeometry();
1218 return true;
1219}
1220
1221/*!
1222 \fn QLayoutItem *QLayout::itemAt(int index) const
1223
1224 Must be implemented in subclasses to return the layout item at \a
1225 index. If there is no such item, the function must return 0.
1226 Items are numbered consecutively from 0. If an item is deleted, other items will be renumbered.
1227
1228 This function can be used to iterate over a layout. The following
1229 code will draw a rectangle for each layout item in the layout structure of the widget.
1230
1231 \snippet doc/src/snippets/code/src_gui_kernel_qlayout.cpp 0
1232
1233 \sa count(), takeAt()
1234*/
1235
1236/*!
1237 \fn QLayoutItem *QLayout::takeAt(int index)
1238
1239 Must be implemented in subclasses to remove the layout item at \a
1240 index from the layout, and return the item. If there is no such
1241 item, the function must do nothing and return 0. Items are numbered
1242 consecutively from 0. If an item is deleted, other items will be
1243 renumbered.
1244
1245 The following code fragment shows a safe way to remove all items
1246 from a layout:
1247
1248 \snippet doc/src/snippets/code/src_gui_kernel_qlayout.cpp 1
1249
1250 \sa itemAt(), count()
1251*/
1252
1253/*!
1254 \fn int *QLayout::count() const
1255
1256 Must be implemented in subclasses to return the number of items
1257 in the layout.
1258
1259 \sa itemAt()
1260*/
1261
1262/*!
1263 Searches for widget \a widget in this layout (not including child
1264 layouts).
1265
1266 Returns the index of \a widget, or -1 if \a widget is not found.
1267
1268 The default implementation iterates over all items using itemAt()
1269*/
1270int QLayout::indexOf(QWidget *widget) const
1271{
1272 int i = 0;
1273 QLayoutItem *item = itemAt(i);
1274 while (item) {
1275 if (item->widget() == widget)
1276 return i;
1277 ++i;
1278 item = itemAt(i);
1279 }
1280 return -1;
1281}
1282
1283/*!
1284 \enum QLayout::SizeConstraint
1285
1286 The possible values are:
1287
1288 \value SetDefaultConstraint The main widget's minimum size is set
1289 to minimumSize(), unless the widget already has
1290 a minimum size.
1291
1292 \value SetFixedSize The main widget's size is set to sizeHint(); it
1293 cannot be resized at all.
1294 \value SetMinimumSize The main widget's minimum size is set to
1295 minimumSize(); it cannot be smaller.
1296
1297 \value SetMaximumSize The main widget's maximum size is set to
1298 maximumSize(); it cannot be larger.
1299
1300 \value SetMinAndMaxSize The main widget's minimum size is set to
1301 minimumSize() and its maximum size is set to
1302 maximumSize().
1303
1304 \value SetNoConstraint The widget is not constrained.
1305
1306 \omitvalue Auto
1307 \omitvalue FreeResize
1308 \omitvalue Minimum
1309 \omitvalue Fixed
1310
1311 \sa setSizeConstraint()
1312*/
1313
1314/*!
1315 \property QLayout::sizeConstraint
1316 \brief the resize mode of the layout
1317
1318 The default mode is \l {QLayout::SetDefaultConstraint}
1319 {SetDefaultConstraint}.
1320*/
1321void QLayout::setSizeConstraint(SizeConstraint constraint)
1322{
1323 Q_D(QLayout);
1324 if (constraint == d->constraint)
1325 return;
1326
1327 d->constraint = constraint;
1328 invalidate();
1329}
1330
1331QLayout::SizeConstraint QLayout::sizeConstraint() const
1332{
1333 Q_D(const QLayout);
1334 return d->constraint;
1335}
1336
1337/*!
1338 Returns the rectangle that should be covered when the geometry of
1339 this layout is set to \a r, provided that this layout supports
1340 setAlignment().
1341
1342 The result is derived from sizeHint() and expanding(). It is never
1343 larger than \a r.
1344*/
1345QRect QLayout::alignmentRect(const QRect &r) const
1346{
1347 QSize s = sizeHint();
1348 Qt::Alignment a = alignment();
1349
1350 /*
1351 This is a hack to obtain the real maximum size, not
1352 QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX), the value consistently
1353 returned by QLayoutItems that have an alignment.
1354 */
1355 QLayout *that = const_cast<QLayout *>(this);
1356 that->setAlignment(0);
1357 QSize ms = that->maximumSize();
1358 that->setAlignment(a);
1359
1360 if ((expandingDirections() & Qt::Horizontal) ||
1361 !(a & Qt::AlignHorizontal_Mask)) {
1362 s.setWidth(qMin(r.width(), ms.width()));
1363 }
1364 if ((expandingDirections() & Qt::Vertical) ||
1365 !(a & Qt::AlignVertical_Mask)) {
1366 s.setHeight(qMin(r.height(), ms.height()));
1367 } else if (hasHeightForWidth()) {
1368 int hfw = heightForWidth(s.width());
1369 if (hfw < s.height())
1370 s.setHeight(qMin(hfw, ms.height()));
1371 }
1372
1373 s = s.boundedTo(r.size());
1374 int x = r.x();
1375 int y = r.y();
1376
1377 if (a & Qt::AlignBottom)
1378 y += (r.height() - s.height());
1379 else if (!(a & Qt::AlignTop))
1380 y += (r.height() - s.height()) / 2;
1381
1382 QWidget *parent = parentWidget();
1383 a = QStyle::visualAlignment(parent ? parent->layoutDirection() : QApplication::layoutDirection(), a);
1384 if (a & Qt::AlignRight)
1385 x += (r.width() - s.width());
1386 else if (!(a & Qt::AlignLeft))
1387 x += (r.width() - s.width()) / 2;
1388
1389 return QRect(x, y, s.width(), s.height());
1390}
1391
1392/*!
1393 Removes the widget \a widget from the layout. After this call, it
1394 is the caller's responsibility to give the widget a reasonable
1395 geometry or to put the widget back into a layout.
1396
1397 \bold{Note:} The ownership of \a widget remains the same as
1398 when it was added.
1399
1400 \sa removeItem(), QWidget::setGeometry(), addWidget()
1401*/
1402void QLayout::removeWidget(QWidget *widget)
1403{
1404 int i = 0;
1405 QLayoutItem *child;
1406 while ((child = itemAt(i))) {
1407 if (child->widget() == widget) {
1408 delete takeAt(i);
1409 invalidate();
1410 } else {
1411 ++i;
1412 }
1413 }
1414}
1415
1416/*!
1417 Removes the layout item \a item from the layout. It is the
1418 caller's responsibility to delete the item.
1419
1420 Notice that \a item can be a layout (since QLayout inherits
1421 QLayoutItem).
1422
1423 \sa removeWidget(), addItem()
1424*/
1425void QLayout::removeItem(QLayoutItem *item)
1426{
1427 int i = 0;
1428 QLayoutItem *child;
1429 while ((child = itemAt(i))) {
1430 if (child == item) {
1431 takeAt(i);
1432 invalidate();
1433 } else {
1434 ++i;
1435 }
1436 }
1437}
1438
1439/*!
1440 Enables this layout if \a enable is true, otherwise disables it.
1441
1442 An enabled layout adjusts dynamically to changes; a disabled
1443 layout acts as if it did not exist.
1444
1445 By default all layouts are enabled.
1446
1447 \sa isEnabled()
1448*/
1449void QLayout::setEnabled(bool enable)
1450{
1451 Q_D(QLayout);
1452 d->enabled = enable;
1453}
1454
1455/*!
1456 Returns true if the layout is enabled; otherwise returns false.
1457
1458 \sa setEnabled()
1459*/
1460bool QLayout::isEnabled() const
1461{
1462 Q_D(const QLayout);
1463 return d->enabled;
1464}
1465
1466/*!
1467 Returns a size that satisfies all size constraints on \a widget,
1468 including heightForWidth() and that is as close as possible to \a
1469 size.
1470*/
1471
1472QSize QLayout::closestAcceptableSize(const QWidget *widget, const QSize &size)
1473{
1474 QSize result = size.boundedTo(qSmartMaxSize(widget));
1475 result = result.expandedTo(qSmartMinSize(widget));
1476 QLayout *l = widget->layout();
1477 if (l && l->hasHeightForWidth() && result.height() < l->minimumHeightForWidth(result.width()) ) {
1478 QSize current = widget->size();
1479 int currentHfw = l->minimumHeightForWidth(current.width());
1480 int newHfw = l->minimumHeightForWidth(result.width());
1481 if (current.height() < currentHfw || currentHfw == newHfw) {
1482 //handle the constant hfw case and the vertical-only case, as well as the
1483 // current-size-is-not-correct case
1484 result.setHeight(newHfw);
1485 } else {
1486 // binary search; assume hfw is decreasing ###
1487
1488 int maxw = qMax(widget->width(),result.width());
1489 int maxh = qMax(widget->height(), result.height());
1490 int minw = qMin(widget->width(),result.width());
1491 int minh = qMin(widget->height(), result.height());
1492
1493 int minhfw = l->minimumHeightForWidth(minw);
1494 int maxhfw = l->minimumHeightForWidth(maxw);
1495 while (minw < maxw) {
1496 if (minhfw > maxh) { //assume decreasing
1497 minw = maxw - (maxw-minw)/2;
1498 minhfw = l->minimumHeightForWidth(minw);
1499 } else if (maxhfw < minh ) { //assume decreasing
1500 maxw = minw + (maxw-minw)/2;
1501 maxhfw = l->minimumHeightForWidth(maxw);
1502 } else {
1503 break;
1504 }
1505 }
1506 result = result.expandedTo(QSize(minw, minhfw));
1507 }
1508 }
1509 return result;
1510}
1511
1512/*!
1513 \fn void QLayout::setResizeMode(SizeConstraint constraint)
1514
1515 Use setSizeConstraint(\a constraint) instead.
1516*/
1517
1518/*!
1519 \fn QLayout::SizeConstraint QLayout::resizeMode() const
1520
1521 Use sizeConstraint() instead.
1522*/
1523
1524void QSizePolicy::setControlType(ControlType type)
1525{
1526 /*
1527 The control type is a flag type, with values 0x1, 0x2, 0x4, 0x8, 0x10,
1528 etc. In memory, we pack it onto the available bits (CTSize) in
1529 setControlType(), and unpack it here.
1530
1531 Example:
1532
1533 0x00000001 maps to 0x00000000
1534 0x00000002 maps to 0x00000200
1535 0x00000004 maps to 0x00000400
1536 0x00000008 maps to 0x00000600
1537 etc.
1538 */
1539
1540 int i = 0;
1541 while (true) {
1542 if (type & (0x1 << i)) {
1543 data = (data & ~CTMask) | (i << CTShift);
1544 return;
1545 }
1546 ++i;
1547 }
1548}
1549
1550QSizePolicy::ControlType QSizePolicy::controlType() const
1551{
1552 return QSizePolicy::ControlType(0x1 << ((data & CTMask) >> CTShift));
1553}
1554
1555#ifndef QT_NO_DATASTREAM
1556/*!
1557 \relates QSizePolicy
1558 \since 4.2
1559
1560 Writes the size \a policy to the data stream \a stream.
1561
1562 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
1563*/
1564QDataStream &operator<<(QDataStream &stream, const QSizePolicy &policy)
1565{
1566 return stream << policy.data;
1567}
1568
1569/*!
1570 \relates QSizePolicy
1571 \since 4.2
1572
1573 Reads the size \a policy from the data stream \a stream.
1574
1575 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
1576*/
1577QDataStream &operator>>(QDataStream &stream, QSizePolicy &policy)
1578{
1579 return stream >> policy.data;
1580}
1581
1582#endif
1583
1584
1585QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.