source: vendor/trolltech/current/src/kernel/qabstractlayout.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 49.5 KB
Line 
1/****************************************************************************
2** $Id: qabstractlayout.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of the abstract layout base class
5**
6** Created : 960416
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qlayout.h"
39
40#ifndef QT_NO_LAYOUT
41#include "qapplication.h"
42#include "qlayoutengine_p.h"
43#include "qmenubar.h"
44#include "qtoolbar.h"
45
46static int menuBarHeightForWidth( QMenuBar *menubar, int w )
47{
48#ifndef QT_NO_MENUBAR
49 if ( menubar && !menubar->isHidden() && !menubar->isTopLevel() )
50 return menubar->heightForWidth( QMAX(w, menubar->minimumWidth()) );
51 else
52#endif
53 return 0;
54}
55
56/*!
57 \class QLayoutItem
58 \ingroup appearance
59 \ingroup geomanagement
60 \brief The QLayoutItem class provides an abstract item that a
61 QLayout manipulates.
62
63 This is used by custom layouts.
64
65 Pure virtual functions are provided to return information about
66 the layout, including, sizeHint(), minimumSize(), maximumSize()
67 and expanding().
68
69 The layout's geometry can be set and retrieved with setGeometry()
70 and geometry(), and its alignment with setAlignment() and
71 alignment().
72
73 isEmpty() returns whether the layout is empty. iterator() returns
74 an iterator for the layout's children. If the concrete item is a
75 QWidget, it can be retrieved using widget(). Similarly for
76 layout() and spacerItem().
77
78 \sa QLayout
79*/
80
81/*!
82 \class QSpacerItem
83 \ingroup appearance
84 \ingroup geomanagement
85 \brief The QSpacerItem class provides blank space in a layout.
86
87 This class is used by custom layouts.
88
89 \sa QLayout QLayout::spacerItem()
90*/
91
92/*!
93 \class QWidgetItem
94 \ingroup appearance
95 \ingroup geomanagement
96 \brief The QWidgetItem class is a layout item that represents a widget.
97
98 This is used by custom layouts.
99
100 \sa QLayout QLayout::widget()
101*/
102
103/*!
104 \fn QLayoutItem::QLayoutItem( int alignment )
105
106 Constructs a layout item with an \a alignment that is a bitwise OR
107 of the \l{Qt::AlignmentFlags}. Not all subclasses support
108 alignment.
109*/
110
111/*!
112 \fn int QLayoutItem::alignment() const
113
114 Returns the alignment of this item.
115*/
116
117/*!
118 Sets the alignment of this item to \a a, which is a bitwise OR of
119 the \l{Qt::AlignmentFlags}. Not all subclasses support alignment.
120*/
121void QLayoutItem::setAlignment( int a )
122{
123 align = a;
124}
125
126/*!
127 \fn QSize QLayoutItem::maximumSize() const
128
129 Implemented in subclasses to return the maximum size of this item.
130*/
131
132/*!
133 \fn QSize QLayoutItem::minimumSize() const
134
135 Implemented in subclasses to return the minimum size of this item.
136*/
137
138/*!
139 \fn QSize QLayoutItem::sizeHint() const
140
141 Implemented in subclasses to return the preferred size of this item.
142*/
143
144/*!
145 \fn QSizePolicy::ExpandData QLayoutItem::expanding() const
146
147 Implemented in subclasses to return the direction(s) this item
148 "wants" to expand in (if any).
149*/
150
151/*!
152 \fn void QLayoutItem::setGeometry( const QRect &r )
153
154 Implemented in subclasses to set this item's geometry to \a r.
155*/
156
157/*!
158 \fn QRect QLayoutItem::geometry() const
159
160 Returns the rectangle covered by this layout item.
161*/
162
163/*!
164 \fn virtual bool QLayoutItem::isEmpty() const
165
166 Implemented in subclasses to return whether this item is empty,
167 i.e. whether it contains any widgets.
168*/
169
170/*!
171 \fn QSpacerItem::QSpacerItem( int w, int h, QSizePolicy::SizeType hData, QSizePolicy::SizeType vData )
172
173 Constructs a spacer item with preferred width \a w, preferred
174 height \a h, horizontal size policy \a hData and vertical size
175 policy \a vData.
176
177 The default values provide a gap that is able to stretch if
178 nothing else wants the space.
179*/
180
181/*!
182 Changes this spacer item to have preferred width \a w, preferred
183 height \a h, horizontal size policy \a hData and vertical size
184 policy \a vData.
185
186 The default values provide a gap that is able to stretch if
187 nothing else wants the space.
188*/
189void QSpacerItem::changeSize( int w, int h, QSizePolicy::SizeType hData,
190 QSizePolicy::SizeType vData )
191{
192 width = w;
193 height = h;
194 sizeP = QSizePolicy( hData, vData );
195}
196
197/*!
198 \fn QWidgetItem::QWidgetItem (QWidget * w)
199
200 Creates an item containing widget \a w.
201*/
202
203/*!
204 Destroys the QLayoutItem.
205*/
206QLayoutItem::~QLayoutItem()
207{
208}
209
210/*!
211 Invalidates any cached information in this layout item.
212*/
213void QLayoutItem::invalidate()
214{
215}
216
217/*!
218 If this item is a QLayout, it is returned as a QLayout; otherwise
219 0 is returned. This function provides type-safe casting.
220*/
221QLayout * QLayoutItem::layout()
222{
223 return 0;
224}
225
226/*!
227 If this item is a QSpacerItem, it is returned as a QSpacerItem;
228 otherwise 0 is returned. This function provides type-safe casting.
229*/
230QSpacerItem * QLayoutItem::spacerItem()
231{
232 return 0;
233}
234
235/*!
236 \reimp
237*/
238QLayout * QLayout::layout()
239{
240 return this;
241}
242
243/*!
244 \reimp
245*/
246QSpacerItem * QSpacerItem::spacerItem()
247{
248 return this;
249}
250
251/*!
252 If this item is a QWidget, it is returned as a QWidget; otherwise
253 0 is returned. This function provides type-safe casting.
254*/
255QWidget * QLayoutItem::widget()
256{
257 return 0;
258}
259
260/*!
261 Returns the widget managed by this item.
262*/
263QWidget * QWidgetItem::widget()
264{
265 return wid;
266}
267
268/*!
269 Returns TRUE if this layout's preferred height depends on its
270 width; otherwise returns FALSE. The default implementation returns
271 FALSE.
272
273 Reimplement this function in layout managers that support height
274 for width.
275
276 \sa heightForWidth(), QWidget::heightForWidth()
277*/
278bool QLayoutItem::hasHeightForWidth() const
279{
280 return FALSE;
281}
282
283/*!
284 Returns an iterator over this item's QLayoutItem children. The
285 default implementation returns an empty iterator.
286
287 Reimplement this function in subclasses that can have children.
288*/
289QLayoutIterator QLayoutItem::iterator()
290{
291 return QLayoutIterator( 0 );
292}
293
294/*!
295 Returns the preferred height for this layout item, given the width
296 \a w.
297
298 The default implementation returns -1, indicating that the
299 preferred height is independent of the width of the item. Using
300 the function hasHeightForWidth() will typically be much faster
301 than calling this function and testing for -1.
302
303 Reimplement this function in layout managers that support height
304 for width. A typical implementation will look like this:
305 \code
306 int MyLayout::heightForWidth( int w ) const
307 {
308 if ( cache_dirty || cached_width != w ) {
309 // not all C++ compilers support "mutable"
310 MyLayout *that = (MyLayout*)this;
311 int h = calculateHeightForWidth( w );
312 that->cached_hfw = h;
313 return h;
314 }
315 return cached_hfw;
316 }
317 \endcode
318
319 Caching is strongly recommended; without it layout will take
320 exponential time.
321
322 \sa hasHeightForWidth()
323*/
324int QLayoutItem::heightForWidth( int /* w */ ) const
325{
326 return -1;
327}
328
329/*!
330 Stores the spacer item's rect \a r so that it can be returned by
331 geometry().
332*/
333void QSpacerItem::setGeometry( const QRect &r )
334{
335 rect = r;
336}
337
338/*!
339 Sets the geometry of this item's widget to be contained within
340 rect \a r, taking alignment and maximum size into account.
341*/
342void QWidgetItem::setGeometry( const QRect &r )
343{
344 QSize s = r.size().boundedTo( qSmartMaxSize( this ) );
345 int x = r.x();
346 int y = r.y();
347 if ( align & (Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask) ) {
348 QSize pref = wid->sizeHint().expandedTo( wid->minimumSize() ); //###
349 if ( align & Qt::AlignHorizontal_Mask )
350 s.setWidth( QMIN( s.width(), pref.width() ) );
351 if ( align & Qt::AlignVertical_Mask ) {
352 if ( hasHeightForWidth() )
353 s.setHeight( QMIN( s.height(), heightForWidth(s.width()) ) );
354 else
355 s.setHeight( QMIN( s.height(), pref.height() ) );
356 }
357 }
358 int alignHoriz = QApplication::horizontalAlignment( align );
359 if ( alignHoriz & Qt::AlignRight )
360 x = x + ( r.width() - s.width() );
361 else if ( !(alignHoriz & Qt::AlignLeft) )
362 x = x + ( r.width() - s.width() ) / 2;
363
364 if ( align & Qt::AlignBottom )
365 y = y + ( r.height() - s.height() );
366 else if ( !(align & Qt::AlignTop) )
367 y = y + ( r.height() - s.height() ) / 2;
368
369 if ( !isEmpty() )
370 wid->setGeometry( x, y, s.width(), s.height() );
371}
372
373/*!
374 \reimp
375*/
376QRect QSpacerItem::geometry() const
377{
378 return rect;
379}
380
381/*!
382 \reimp
383*/
384QRect QWidgetItem::geometry() const
385{
386 return wid->geometry();
387}
388
389/*!
390 \reimp
391*/
392QRect QLayout::geometry() const
393{
394 return rect;
395}
396
397/*!
398 \reimp
399*/
400bool QWidgetItem::hasHeightForWidth() const
401{
402 if ( isEmpty() )
403 return FALSE;
404 if ( wid->layout() )
405 return wid->layout()->hasHeightForWidth();
406 return wid->sizePolicy().hasHeightForWidth();
407}
408
409/*!
410 \reimp
411*/
412int QWidgetItem::heightForWidth( int w ) const
413{
414 if ( isEmpty() )
415 return -1;
416 int hfw;
417 if ( wid->layout() )
418 hfw = wid->layout()->totalHeightForWidth( w );
419 else
420 hfw = wid->heightForWidth( w );
421
422 if ( hfw > wid->maximumHeight() )
423 hfw = wid->maximumHeight();
424 if ( hfw < wid->minimumHeight() )
425 hfw = wid->minimumHeight();
426 if ( hfw < 1 )
427 hfw = 1;
428 return hfw;
429}
430
431/*!
432 Returns the direction in which this spacer item will expand.
433
434 \sa QSizePolicy::ExpandData
435*/
436QSizePolicy::ExpandData QSpacerItem::expanding() const
437{
438 return sizeP.expanding();
439}
440
441/*!
442 Returns whether this item's widget can make use of more space than
443 sizeHint(). A value of \c Vertical or \c Horizontal means that it wants
444 to grow in only one dimension, whereas \c BothDirections means that
445 it wants to grow in both dimensions and \c NoDirection means that
446 it doesn't want to grow at all.
447*/
448QSizePolicy::ExpandData QWidgetItem::expanding() const
449{
450 if ( isEmpty() )
451 return QSizePolicy::NoDirection;
452
453 int e = wid->sizePolicy().expanding();
454 /*
455 If the layout is expanding, we make the widget expanding, even if
456 its own size policy isn't expanding. This behavior should be
457 reconsidered in Qt 4.0. (###)
458 */
459 if ( wid->layout() ) {
460 if ( wid->sizePolicy().mayGrowHorizontally()
461 && (wid->layout()->expanding() & QSizePolicy::Horizontally) )
462 e |= QSizePolicy::Horizontally;
463 if ( wid->sizePolicy().mayGrowVertically()
464 && (wid->layout()->expanding() & QSizePolicy::Vertically) )
465 e |= QSizePolicy::Vertically;
466 }
467
468 if ( align & Qt::AlignHorizontal_Mask )
469 e &= ~QSizePolicy::Horizontally;
470 if ( align & Qt::AlignVertical_Mask)
471 e &= ~QSizePolicy::Vertically;
472 return (QSizePolicy::ExpandData)e;
473}
474
475/*!
476 Returns the minimum size of this spacer item.
477*/
478QSize QSpacerItem::minimumSize() const
479{
480 return QSize( sizeP.mayShrinkHorizontally() ? 0 : width,
481 sizeP.mayShrinkVertically() ? 0 : height );
482}
483
484/*!
485 Returns the minimum size of this item.
486*/
487QSize QWidgetItem::minimumSize() const
488{
489 if ( isEmpty() )
490 return QSize( 0, 0 );
491 return qSmartMinSize( this );
492}
493
494/*!
495 Returns the maximum size of this spacer item.
496*/
497QSize QSpacerItem::maximumSize() const
498{
499 return QSize( sizeP.mayGrowHorizontally() ? QLAYOUTSIZE_MAX : width,
500 sizeP.mayGrowVertically() ? QLAYOUTSIZE_MAX : height );
501}
502
503/*!
504 Returns the maximum size of this item.
505*/
506QSize QWidgetItem::maximumSize() const
507{
508 if ( isEmpty() ) {
509 return QSize( 0, 0 );
510 } else {
511 return qSmartMaxSize( this, align );
512 }
513}
514
515/*!
516 Returns the preferred size of this spacer item.
517*/
518QSize QSpacerItem::sizeHint() const
519{
520 return QSize( width, height );
521}
522
523/*!
524 Returns the preferred size of this item.
525*/
526QSize QWidgetItem::sizeHint() const
527{
528 QSize s;
529 if ( isEmpty() ) {
530 s = QSize( 0, 0 );
531 } else {
532 s = wid->sizeHint();
533 if ( wid->sizePolicy().horData() == QSizePolicy::Ignored )
534 s.setWidth( 1 );
535 if ( wid->sizePolicy().verData() == QSizePolicy::Ignored )
536 s.setHeight( 1 );
537 s = s.boundedTo( wid->maximumSize() )
538 .expandedTo( wid->minimumSize() ).expandedTo( QSize(1, 1) );
539 }
540 return s;
541}
542
543/*!
544 Returns TRUE because a spacer item never contains widgets.
545*/
546bool QSpacerItem::isEmpty() const
547{
548 return TRUE;
549}
550
551/*!
552 Returns TRUE if the widget has been hidden; otherwise returns
553 FALSE.
554*/
555bool QWidgetItem::isEmpty() const
556{
557 return wid->isHidden() || wid->isTopLevel();
558}
559
560/*!
561 \class QLayout
562 \brief The QLayout class is the base class of geometry managers.
563
564 \ingroup appearance
565 \ingroup geomanagement
566
567 This is an abstract base class inherited by the concrete classes,
568 QBoxLayout and QGridLayout.
569
570 For users of QLayout subclasses or of QMainWindow there is seldom
571 any need to use the basic functions provided by QLayout, such as
572 \l setResizeMode() or setMenuBar(). See the \link layout.html layout
573 overview page \endlink for more information.
574
575 To make your own layout manager, subclass QGLayoutIterator and
576 implement the functions addItem(), sizeHint(), setGeometry(), and
577 iterator(). You should also implement minimumSize() to ensure your
578 layout isn't resized to zero size if there is too little space. To
579 support children whose heights depend on their widths, implement
580 hasHeightForWidth() and heightForWidth(). See the \link
581 customlayout.html custom layout page \endlink for an in-depth
582 description.
583
584 Geometry management stops when the layout manager is deleted.
585*/
586
587/*!
588 Constructs a new top-level QLayout called \a name, with main
589 widget \a parent. \a parent may not be 0.
590
591 The \a margin is the number of pixels between the edge of the
592 widget and the managed children. The \a spacing sets the value of
593 spacing(), which gives the spacing between the managed widgets. If
594 \a spacing is -1 (the default), spacing is set to the value of \a
595 margin.
596
597 There can be only one top-level layout for a widget. It is
598 returned by QWidget::layout()
599*/
600QLayout::QLayout( QWidget *parent, int margin, int spacing, const char *name )
601 : QObject( parent, name )
602{
603 init();
604 if ( parent ) {
605 if ( parent->layout() ) {
606 qWarning( "QLayout \"%s\" added to %s \"%s\", which already has a"
607 " layout", QObject::name(), parent->className(),
608 parent->name() );
609 parent->removeChild( this );
610 } else {
611 topLevel = TRUE;
612 parent->installEventFilter( this );
613 setWidgetLayout( parent, this );
614 }
615 }
616 outsideBorder = margin;
617 if ( spacing < 0 )
618 insideSpacing = margin;
619 else
620 insideSpacing = spacing;
621}
622
623void QLayout::init()
624{
625 insideSpacing = 0;
626 outsideBorder = 0;
627 topLevel = FALSE;
628 enabled = TRUE;
629 autoNewChild = FALSE;
630 frozen = FALSE;
631 activated = FALSE;
632 marginImpl = FALSE;
633 autoMinimum = FALSE;
634 autoResizeMode = TRUE;
635 extraData = 0;
636#ifndef QT_NO_MENUBAR
637 menubar = 0;
638#endif
639}
640
641/*!
642 Constructs a new child QLayout called \a name, and places it
643 inside \a parentLayout by using the default placement defined by
644 addItem().
645
646 If \a spacing is -1, this QLayout inherits \a parentLayout's
647 spacing(), otherwise the value of \a spacing is used.
648*/
649QLayout::QLayout( QLayout *parentLayout, int spacing, const char *name )
650 : QObject( parentLayout, name )
651
652{
653 init();
654 insideSpacing = spacing < 0 ? parentLayout->insideSpacing : spacing;
655 parentLayout->addItem( this );
656}
657
658/*!
659 Constructs a new child QLayout called \a name. If \a spacing is
660 -1, this QLayout inherits its parent's spacing(); otherwise the
661 value of \a spacing is used.
662
663 This layout has to be inserted into another layout before geometry
664 management will work.
665*/
666QLayout::QLayout( int spacing, const char *name )
667 : QObject( 0, name )
668{
669 init();
670 insideSpacing = spacing;
671}
672
673/*!
674 \fn void QLayout::addItem( QLayoutItem *item )
675
676 Implemented in subclasses to add an \a item. How it is added is
677 specific to each subclass.
678
679 The ownership of \a item is transferred to the layout, and it's
680 the layout's responsibility to delete it.
681*/
682
683/*!
684 \fn QLayoutIterator QLayout::iterator()
685
686 Implemented in subclasses to return an iterator that iterates over
687 this layout's children.
688
689 A typical implementation will be:
690 \code
691 QLayoutIterator MyLayout::iterator()
692 {
693 QGLayoutIterator *i = new MyLayoutIterator( internal_data );
694 return QLayoutIterator( i );
695 }
696 \endcode
697 where MyLayoutIterator is a subclass of QGLayoutIterator.
698*/
699
700/*!
701 \fn void QLayout::add( QWidget *w )
702
703 Adds widget \a w to this layout in a manner specific to the
704 layout. This function uses addItem().
705*/
706
707/*!
708 \fn QMenuBar* QLayout::menuBar () const
709
710 Returns the menu bar set for this layout, or 0 if no menu bar is
711 set.
712*/
713
714/*!
715 \fn bool QLayout::isTopLevel () const
716
717 Returns TRUE if this layout is a top-level layout, i.e. not a
718 child of another layout; otherwise returns FALSE.
719*/
720
721/*!
722 \property QLayout::margin
723 \brief the width of the outside border of the layout
724
725 For some layout classes this property has an effect only on
726 top-level layouts; QBoxLayout and QGridLayout support margins for
727 child layouts. The default value is 0.
728
729 \sa spacing
730*/
731
732/*!
733 \property QLayout::spacing
734 \brief the spacing between widgets inside the layout
735
736 The default value is -1, which signifies that the layout's spacing
737 should not override the widget's spacing.
738
739 \sa margin
740*/
741void QLayout::setMargin( int margin )
742{
743 outsideBorder = margin;
744 invalidate();
745 if ( mainWidget() ) {
746 QEvent *lh = new QEvent( QEvent::LayoutHint );
747 QApplication::postEvent( mainWidget(), lh );
748 }
749}
750
751void QLayout::setSpacing( int spacing )
752{
753 insideSpacing = spacing;
754 if ( spacing >= 0 )
755 propagateSpacing( this );
756 invalidate();
757 if ( mainWidget() ) {
758 QEvent *lh = new QEvent( QEvent::LayoutHint );
759 QApplication::postEvent( mainWidget(), lh );
760 }
761}
762
763/*!
764 Returns the main widget (parent widget) of this layout, or 0 if
765 this layout is a sub-layout that is not yet inserted.
766*/
767QWidget *QLayout::mainWidget()
768{
769 if ( !topLevel ) {
770 if ( parent() ) {
771 QLayout *parentLayout = ::qt_cast<QLayout*>(parent());
772 Q_ASSERT(parentLayout);
773 return parentLayout->mainWidget();
774 } else {
775 return 0;
776 }
777 } else {
778 Q_ASSERT(parent() && parent()->isWidgetType());
779 return (QWidget*)parent();
780 }
781}
782
783/*!
784 Returns TRUE if this layout is empty. The default implementation
785 returns FALSE.
786*/
787bool QLayout::isEmpty() const
788{
789 return FALSE; //### should check
790}
791
792/*!
793 Sets widget \a w's layout to layout \a l.
794*/
795void QLayout::setWidgetLayout( QWidget *w, QLayout *l )
796{
797 w->setLayout( l );
798}
799
800/*!
801 This function is reimplemented in subclasses to perform layout.
802
803 The default implementation maintains the geometry() information
804 given by rect \a r. Reimplementors must call this function.
805*/
806void QLayout::setGeometry( const QRect &r )
807{
808 rect = r;
809}
810
811/*!
812 Invalidates cached information. Reimplementations must call this.
813*/
814void QLayout::invalidate()
815{
816 rect = QRect();
817}
818
819static bool removeWidgetRecursively( QLayoutItem *lay, QWidget *w )
820{
821 bool didSomething = FALSE;
822 QLayoutIterator it = lay->iterator();
823 QLayoutItem *child;
824 while ( (child = it.current()) != 0 ) {
825 if ( child->widget() == w ) {
826 it.deleteCurrent();
827 lay->invalidate(); // maybe redundant
828 didSomething = TRUE;
829 } else if ( removeWidgetRecursively(child, w) ) {
830 lay->invalidate(); // maybe redundant
831 didSomething = TRUE;
832 } else {
833 ++it;
834 }
835 }
836 return didSomething;
837}
838
839/*!
840 \reimp
841 Performs child widget layout when the parent widget is resized.
842 Also handles removal of widgets and child layouts. \a e is the
843 event the occurred on object \a o.
844*/
845bool QLayout::eventFilter( QObject *o, QEvent *e )
846{
847 if ( !enabled )
848 return FALSE;
849
850 if ( !o->isWidgetType() )
851 return FALSE;
852
853 switch ( e->type() ) {
854 case QEvent::Resize:
855 if ( activated ) {
856 QResizeEvent *r = (QResizeEvent *)e;
857 int mbh = 0;
858#ifndef QT_NO_MENUBAR
859 mbh = menuBarHeightForWidth( menubar, r->size().width() );
860#endif
861 int b = marginImpl ? 0 : outsideBorder;
862 setGeometry( QRect( b, mbh + b, r->size().width() - 2 * b,
863 r->size().height() - mbh - 2 * b ) );
864 } else {
865 activate();
866 }
867 break;
868 case QEvent::ChildRemoved:
869 {
870 QChildEvent *c = (QChildEvent *)e;
871 if ( c->child()->isWidgetType() ) {
872 QWidget *w = (QWidget *)c->child();
873#ifndef QT_NO_MENUBAR
874 if ( w == menubar )
875 menubar = 0;
876#endif
877 if ( removeWidgetRecursively( this, w ) ) {
878 QEvent *lh = new QEvent( QEvent::LayoutHint );
879 QApplication::postEvent( o, lh );
880 }
881 }
882 }
883 break;
884 case QEvent::ChildInserted:
885 if ( topLevel && autoNewChild ) {
886 QChildEvent *c = (QChildEvent *)e;
887 if ( c->child()->isWidgetType() ) {
888 QWidget *w = (QWidget *)c->child();
889 if ( !w->isTopLevel() ) {
890#if !defined(QT_NO_MENUBAR) && !defined(QT_NO_TOOLBAR)
891 if ( ::qt_cast<QMenuBar*>(w) && !::qt_cast<QToolBar*>(w->parentWidget()) )
892 menubar = (QMenuBar *)w;
893 else
894#endif
895 addItem( new QWidgetItem( w ) );
896 QEvent *lh = new QEvent( QEvent::LayoutHint );
897 QApplication::postEvent( o, lh );
898 }
899 }
900 }
901 break;
902 case QEvent::LayoutHint:
903 activate();
904 break;
905 default:
906 break;
907 }
908 return QObject::eventFilter( o, e );
909}
910
911/*!
912 \reimp
913*/
914void QLayout::childEvent( QChildEvent *e )
915{
916 if ( !enabled )
917 return;
918
919 if ( e->type() == QEvent::ChildRemoved ) {
920 QChildEvent *c = (QChildEvent*)e;
921 QLayoutIterator it = iterator();
922 QLayoutItem *item;
923 while ( (item = it.current() ) ) {
924 if ( item == (QLayout*)c->child() ) {
925 it.takeCurrent();
926 invalidate();
927 break;
928 } else {
929 ++it;
930 }
931 }
932 }
933}
934
935/*!
936 \internal
937 Also takes margin() and menu bar into account.
938*/
939int QLayout::totalHeightForWidth( int w ) const
940{
941 if ( topLevel ) {
942 QWidget *mw = (QWidget*)parent();
943 if ( mw && !mw->testWState(WState_Polished) ) {
944 mw->polish();
945 }
946 }
947 int b = ( topLevel && !marginImpl ) ? 2 * outsideBorder : 0;
948 int h = heightForWidth( w - b ) + b;
949#ifndef QT_NO_MENUBAR
950 h += menuBarHeightForWidth( menubar, w );
951#endif
952 return h;
953}
954
955/*!
956 \internal
957 Also takes margin() and menu bar into account.
958*/
959QSize QLayout::totalMinimumSize() const
960{
961 if ( topLevel ) {
962 QWidget *mw = (QWidget*)parent();
963 if ( mw && !mw->testWState(WState_Polished) )
964 mw->polish();
965 }
966 int b = ( topLevel && !marginImpl ) ? 2 * outsideBorder : 0;
967
968 QSize s = minimumSize();
969 int h = b;
970#ifndef QT_NO_MENUBAR
971 h += menuBarHeightForWidth( menubar, s.width() );
972#endif
973 return s + QSize( b, h );
974}
975
976/*!
977 \internal
978 Also takes margin() and menu bar into account.
979*/
980QSize QLayout::totalSizeHint() const
981{
982 if ( topLevel ) {
983 QWidget *mw = (QWidget*)parent();
984 if ( mw && !mw->testWState(WState_Polished) )
985 mw->polish();
986 }
987 int b = ( topLevel && !marginImpl ) ? 2 * outsideBorder : 0;
988
989 QSize s = sizeHint();
990 if ( hasHeightForWidth() )
991 s.setHeight( heightForWidth(s.width()) );
992 int h = b;
993#ifndef QT_NO_MENUBAR
994 h += menuBarHeightForWidth( menubar, s.width() );
995#endif
996 return s + QSize( b, h );
997}
998
999/*!
1000 \internal
1001 Also takes margin() and menu bar into account.
1002*/
1003QSize QLayout::totalMaximumSize() const
1004{
1005 if ( topLevel ) {
1006 QWidget *mw = (QWidget*)parent();
1007 if ( mw && !mw->testWState(WState_Polished) ) {
1008 mw->polish();
1009 }
1010 }
1011 int b = ( topLevel && !marginImpl ) ? 2 * outsideBorder : 0;
1012
1013 QSize s = maximumSize();
1014 int h = b;
1015#ifndef QT_NO_MENUBAR
1016 h += menuBarHeightForWidth( menubar, s.width() );
1017#endif
1018
1019 if ( isTopLevel() )
1020 s = QSize( QMIN( s.width() + b, QLAYOUTSIZE_MAX ),
1021 QMIN( s.height() + h, QLAYOUTSIZE_MAX ) );
1022 return s;
1023}
1024
1025/*!
1026 \internal
1027 Destroys the layout, deleting all child layouts.
1028 Geometry management stops when a top-level layout is deleted.
1029
1030 The layout classes will probably be fatally confused if you delete
1031 a sublayout.
1032*/
1033QLayout::~QLayout()
1034{
1035 /*
1036 This function may be called during the QObject destructor,
1037 when the parent no longer is a QWidget.
1038 */
1039 if ( isTopLevel() && parent() && parent()->isWidgetType() &&
1040 ((QWidget*)parent())->layout() == this )
1041 setWidgetLayout( (QWidget*)parent(), 0 );
1042}
1043
1044/*!
1045 Removes and deletes all items in this layout.
1046*/
1047void QLayout::deleteAllItems()
1048{
1049 QLayoutIterator it = iterator();
1050 QLayoutItem *l;
1051 while ( (l = it.takeCurrent()) )
1052 delete l;
1053}
1054
1055/*!
1056 This function is called from addLayout() functions in subclasses
1057 to add layout \a l as a sub-layout.
1058*/
1059void QLayout::addChildLayout( QLayout *l )
1060{
1061 if ( l->parent() ) {
1062#if defined(QT_CHECK_NULL)
1063 qWarning( "QLayout::addChildLayout: layout already has a parent" );
1064#endif
1065 return;
1066 }
1067 insertChild( l );
1068 if ( l->insideSpacing < 0 ) {
1069 l->insideSpacing = insideSpacing;
1070 propagateSpacing( l );
1071 }
1072}
1073
1074/*! \fn int QLayout::defaultBorder() const
1075
1076 \internal
1077*/
1078
1079/*! \fn void QLayout::freeze()
1080
1081 \internal
1082*/
1083
1084/*!
1085 \internal
1086 Fixes the size of the main widget and distributes the available
1087 space to the child widgets. For widgets which should not be
1088 resizable, but where a QLayout subclass is used to set up the initial
1089 geometry.
1090
1091 As a special case, freeze(0, 0) is equivalent to setResizeMode(Fixed).
1092*/
1093void QLayout::freeze( int w, int h )
1094{
1095 if ( w <= 0 || h <= 0 ) {
1096 setResizeMode( Fixed );
1097 } else {
1098 setResizeMode( FreeResize ); // layout will not change min/max size
1099 mainWidget()->setFixedSize( w, h );
1100 }
1101}
1102
1103#ifndef QT_NO_MENUBAR
1104
1105/*!
1106 Makes the geometry manager take account of the menu bar \a w. All
1107 child widgets are placed below the bottom edge of the menu bar.
1108
1109 A menu bar does its own geometry management: never do addWidget()
1110 on a QMenuBar.
1111*/
1112void QLayout::setMenuBar( QMenuBar *w )
1113{
1114 menubar = w;
1115}
1116
1117#endif
1118
1119/*!
1120 Returns the minimum size of this layout. This is the smallest size
1121 that the layout can have while still respecting the
1122 specifications. Does not include what's needed by margin() or
1123 menuBar().
1124
1125 The default implementation allows unlimited resizing.
1126*/
1127QSize QLayout::minimumSize() const
1128{
1129 return QSize( 0, 0 );
1130}
1131
1132/*!
1133 Returns the maximum size of this layout. This is the largest size
1134 that the layout can have while still respecting the
1135 specifications. Does not include what's needed by margin() or
1136 menuBar().
1137
1138 The default implementation allows unlimited resizing.
1139*/
1140QSize QLayout::maximumSize() const
1141{
1142 return QSize( QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX );
1143}
1144
1145/*!
1146 Returns whether this layout can make use of more space than
1147 sizeHint(). A value of \c Vertical or \c Horizontal means that it wants
1148 to grow in only one dimension, whereas \c BothDirections means that
1149 it wants to grow in both dimensions.
1150
1151 The default implementation returns \c BothDirections.
1152*/
1153QSizePolicy::ExpandData QLayout::expanding() const
1154{
1155 return QSizePolicy::BothDirections;
1156}
1157
1158static void invalidateRecursive( QLayoutItem *lay )
1159{
1160 lay->invalidate();
1161 QLayoutIterator it = lay->iterator();
1162 QLayoutItem *child;
1163 while ( (child = it.current()) != 0 ) {
1164 invalidateRecursive( child );
1165 ++it;
1166 }
1167}
1168
1169/*!
1170 Redoes the layout for mainWidget(). You should generally not need
1171 to call this because it is automatically called at the most
1172 appropriate times.
1173
1174 However, if you set up a QLayout for a visible widget without
1175 resizing that widget, you will need to call this function in order
1176 to lay it out.
1177
1178 \sa QWidget::updateGeometry()
1179*/
1180bool QLayout::activate()
1181{
1182 invalidateRecursive( this );
1183 if ( !topLevel )
1184 return FALSE;
1185
1186 QWidget *mw = mainWidget();
1187 if (!mw) {
1188#if defined( QT_CHECK_NULL )
1189 qWarning( "QLayout::activate: %s \"%s\" does not have a main widget",
1190 QObject::className(), QObject::name() );
1191#endif
1192 return FALSE;
1193 }
1194 activated = TRUE;
1195 QSize s = mw->size();
1196 QSize ms;
1197 int mbh = 0;
1198#ifndef QT_NO_MENUBAR
1199 mbh = menuBarHeightForWidth( menubar, s.width() );
1200#endif
1201 int b = marginImpl ? 0 : outsideBorder;
1202 setGeometry(QRect(b, mbh + b, s.width() - 2 * b, s.height() - mbh - 2 * b));
1203 if ( frozen ) {
1204 // will trigger resize
1205 mw->setFixedSize( totalSizeHint() );
1206 } else if ( autoMinimum ) {
1207 ms = totalMinimumSize();
1208 } else if ( autoResizeMode && topLevel && mw->isTopLevel() ) {
1209 ms = totalMinimumSize();
1210 if ( hasHeightForWidth() ) {
1211 int h;
1212
1213 // ### 4.0: remove this 'if' when minimumHeightForWidth() is virtual
1214 if ( inherits("QBoxLayout") ) {
1215 h = ((QBoxLayout *) this)->minimumHeightForWidth( ms.width() );
1216 } else if ( inherits("QGridLayout") ) {
1217 h = ((QGridLayout *) this)->minimumHeightForWidth( ms.width() );
1218 } else {
1219 h = heightForWidth( ms.width() );
1220 }
1221 if ( h > ms.height() )
1222 ms = QSize( 0, 0 );
1223 }
1224 }
1225
1226 if (ms.isValid())
1227 mw->setMinimumSize( ms );
1228
1229 // ideally only if sizeHint() or sizePolicy() has changed
1230 mw->updateGeometry();
1231 return TRUE;
1232}
1233
1234/*!
1235 \class QSizePolicy
1236 \brief The QSizePolicy class is a layout attribute describing horizontal
1237 and vertical resizing policy.
1238
1239 \ingroup appearance
1240 \ingroup geomanagement
1241
1242 The size policy of a widget is an expression of its willingness to
1243 be resized in various ways.
1244
1245 Widgets that reimplement QWidget::sizePolicy() return a QSizePolicy
1246 that describes the horizontal and vertical resizing policy they
1247 prefer when being laid out. Only \link #interesting one of the
1248 constructors\endlink is of interest in most applications.
1249
1250 QSizePolicy contains two independent SizeType objects; one describes
1251 the widgets's horizontal size policy, and the other describes its
1252 vertical size policy. It also contains a flag to indicate whether the
1253 height and width of its preferred size are related.
1254
1255 The horizontal and vertical \l{SizeType}s are set in the usual constructor
1256 and can be queried using a variety of functions.
1257
1258 The hasHeightForWidth() flag indicates whether the widget's sizeHint()
1259 is width-dependent (such as a word-wrapping label) or not.
1260
1261 \sa QSizePolicy::SizeType
1262*/
1263
1264/*!
1265 \enum QSizePolicy::SizeType
1266
1267 The per-dimension sizing types used when constructing a
1268 QSizePolicy are:
1269
1270 \value Fixed the QWidget::sizeHint() is the only acceptable
1271 alternative, so the widget can never grow or shrink (e.g. the
1272 vertical direction of a push button).
1273
1274 \value Minimum the sizeHint() is minimal, and sufficient. The
1275 widget can be expanded, but there is no advantage to it being
1276 larger (e.g. the horizontal direction of a push button).
1277
1278 \value Maximum the sizeHint() is a maximum. The widget can be
1279 shrunk any amount without detriment if other widgets need the
1280 space (e.g. a separator line).
1281
1282 \value Preferred the sizeHint() is best, but the widget can be
1283 shrunk and still be useful. The widget can be expanded, but there
1284 is no advantage to it being larger than sizeHint() (the default
1285 QWidget policy).
1286
1287 \value Expanding the sizeHint() is a sensible size, but the
1288 widget can be shrunk and still be useful. The widget can make use
1289 of extra space, so it should get as much space as possible (e.g.
1290 the horizontal direction of a slider).
1291
1292 \value MinimumExpanding the sizeHint() is minimal, and sufficient.
1293 The widget can make use of extra space, so it should get as much
1294 space as possible (e.g. the horizontal direction of a slider).
1295
1296 \value Ignored the sizeHint() is ignored. The widget will get as
1297 much space as possible.
1298*/
1299
1300/*!
1301 \enum QSizePolicy::ExpandData
1302
1303 This enum type describes in which directions a widget can make use
1304 of extra space. There are four possible values:
1305
1306 \value NoDirection the widget cannot make use of extra space in
1307 any direction.
1308
1309 \value Horizontally the widget can usefully be wider than the
1310 sizeHint().
1311
1312 \value Vertically the widget can usefully be taller than the
1313 sizeHint().
1314
1315 \value BothDirections the widget can usefully be both wider and
1316 taller than the sizeHint().
1317*/
1318
1319/*!
1320 \fn QSizePolicy::QSizePolicy()
1321
1322 Constructs a minimally initialized QSizePolicy.
1323*/
1324
1325/*!
1326 \fn QSizePolicy::QSizePolicy( SizeType hor, SizeType ver, bool hfw )
1327
1328 \target interesting
1329 This is the constructor normally used to return a value in the
1330 overridden \l QWidget::sizePolicy() function of a QWidget
1331 subclass.
1332
1333 It constructs a QSizePolicy with independent horizontal and
1334 vertical sizing types, \a hor and \a ver respectively. These \link
1335 QSizePolicy::SizeType sizing types\endlink affect how the widget
1336 is treated by the \link QLayout layout engine\endlink.
1337
1338 If \a hfw is TRUE, the preferred height of the widget is dependent
1339 on the width of the widget (for example, a QLabel with line
1340 wrapping).
1341
1342 \sa horData() verData() hasHeightForWidth()
1343*/
1344
1345/*!
1346 \fn QSizePolicy::QSizePolicy( SizeType hor, SizeType ver, uchar horStretch, uchar verStretch, bool hfw )
1347
1348 Constructs a QSizePolicy with independent horizontal and vertical
1349 sizing types \a hor and \a ver, and stretch factors \a horStretch
1350 and \a verStretch.
1351
1352 If \a hfw is TRUE, the preferred height of the widget is dependent on the
1353 width of the widget.
1354
1355 \sa horStretch() verStretch()
1356*/
1357
1358/*!
1359 \fn QSizePolicy::SizeType QSizePolicy::horData() const
1360
1361 Returns the horizontal component of the size policy.
1362
1363 \sa setHorData() verData() horStretch()
1364*/
1365
1366/*!
1367 \fn QSizePolicy::SizeType QSizePolicy::verData() const
1368
1369 Returns the vertical component of the size policy.
1370
1371 \sa setVerData() horData() verStretch()
1372*/
1373
1374/*!
1375 \fn bool QSizePolicy::mayShrinkHorizontally() const
1376
1377 Returns TRUE if the widget can sensibly be narrower than its
1378 sizeHint(); otherwise returns FALSE.
1379
1380 \sa mayShrinkVertically() mayGrowHorizontally()
1381*/
1382
1383/*!
1384 \fn bool QSizePolicy::mayShrinkVertically() const
1385
1386 Returns TRUE if the widget can sensibly be shorter than its
1387 sizeHint(); otherwise returns FALSE.
1388
1389 \sa mayShrinkHorizontally() mayGrowVertically()
1390*/
1391
1392/*!
1393 \fn bool QSizePolicy::mayGrowHorizontally() const
1394
1395 Returns TRUE if the widget can sensibly be wider than its
1396 sizeHint(); otherwise returns FALSE.
1397
1398 \sa mayGrowVertically() mayShrinkHorizontally()
1399*/
1400
1401/*!
1402 \fn bool QSizePolicy::mayGrowVertically() const
1403
1404 Returns TRUE if the widget can sensibly be taller than its
1405 sizeHint(); otherwise returns FALSE.
1406
1407 \sa mayGrowHorizontally() mayShrinkVertically()
1408*/
1409
1410/*!
1411 \fn QSizePolicy::ExpandData QSizePolicy::expanding() const
1412
1413 Returns whether this layout can make use of more space than
1414 sizeHint(). A value of \c Vertical or \c Horizontal means that it wants
1415 to grow in only one dimension, whereas \c BothDirections means that
1416 it wants to grow in both dimensions.
1417
1418 \sa mayShrinkHorizontally() mayGrowHorizontally()
1419 mayShrinkVertically() mayGrowVertically()
1420*/
1421
1422/*!
1423 \fn void QSizePolicy::setHorData( SizeType d )
1424
1425 Sets the horizontal component of the size policy to size type \a
1426 d.
1427
1428 \sa horData() setVerData()
1429*/
1430
1431/*!
1432 \fn void QSizePolicy::setVerData( SizeType d )
1433
1434 Sets the vertical component of the size policy to size type \a d.
1435
1436 \sa verData() setHorData()
1437*/
1438
1439/*!
1440 \fn bool QSizePolicy::hasHeightForWidth() const
1441
1442 Returns TRUE if the widget's preferred height depends on its
1443 width; otherwise returns FALSE.
1444
1445 \sa setHeightForWidth()
1446*/
1447
1448/*!
1449 \fn void QSizePolicy::setHeightForWidth( bool b )
1450
1451 Sets the hasHeightForWidth() flag to \a b.
1452
1453 \sa hasHeightForWidth()
1454*/
1455
1456/*!
1457 \fn uint QSizePolicy::horStretch() const
1458
1459 Returns the horizontal stretch factor of the size policy.
1460
1461 \sa setHorStretch() verStretch()
1462*/
1463
1464/*!
1465 \fn uint QSizePolicy::verStretch() const
1466
1467 Returns the vertical stretch factor of the size policy.
1468
1469 \sa setVerStretch() horStretch()
1470*/
1471
1472/*!
1473 \fn void QSizePolicy::setHorStretch( uchar sf )
1474
1475 Sets the horizontal stretch factor of the size policy to \a sf.
1476
1477 \sa horStretch() setVerStretch()
1478*/
1479
1480/*!
1481 \fn void QSizePolicy::setVerStretch( uchar sf )
1482
1483 Sets the vertical stretch factor of the size policy to \a sf.
1484
1485 \sa verStretch() setHorStretch()
1486*/
1487
1488/*!
1489 \fn void QSizePolicy::transpose()
1490
1491 Swaps the horizontal and vertical policies and stretches.
1492*/
1493
1494
1495/*!
1496 \fn bool QSizePolicy::operator==( const QSizePolicy &s ) const
1497
1498 Returns TRUE if this policy is equal to \a s; otherwise returns
1499 FALSE.
1500
1501 \sa operator!=()
1502*/
1503
1504/*!
1505 \fn bool QSizePolicy::operator!=( const QSizePolicy &s ) const
1506
1507 Returns TRUE if this policy is different from \a s; otherwise
1508 returns FALSE.
1509
1510 \sa operator==()
1511*/
1512
1513/*!
1514 \class QGLayoutIterator
1515 \brief The QGLayoutIterator class is an abstract base class of internal layout iterators.
1516
1517 \ingroup appearance
1518 \ingroup geomanagement
1519
1520 (This class is \e not OpenGL related, it just happens to start with
1521 the letters QGL...)
1522
1523 Subclass this class to create a custom layout. The functions that
1524 must be implemented are next(), current(), and takeCurrent().
1525
1526 The QGLayoutIterator implements the functionality of
1527 QLayoutIterator. Each subclass of QLayout needs a
1528 QGLayoutIterator subclass.
1529*/
1530
1531/*!
1532 \fn QLayoutItem *QGLayoutIterator::next()
1533
1534 Implemented in subclasses to move the iterator to the next item
1535 and return that item, or 0 if there is no next item.
1536*/
1537
1538/*!
1539 \fn QLayoutItem *QGLayoutIterator::current()
1540
1541 Implemented in subclasses to return the current item, or 0 if
1542 there is no current item.
1543*/
1544
1545/*!
1546 \fn QLayoutItem *QGLayoutIterator::takeCurrent()
1547
1548 Implemented in subclasses. The function must remove the current
1549 item from the layout without deleting it, move the iterator to the
1550 next item and return the removed item, or 0 if no item was
1551 removed.
1552*/
1553
1554/*!
1555 Destroys the iterator
1556*/
1557QGLayoutIterator::~QGLayoutIterator()
1558{
1559}
1560
1561/*!
1562 \class QLayoutIterator
1563 \brief The QLayoutIterator class provides iterators over QLayoutItem.
1564
1565 \ingroup appearance
1566 \ingroup geomanagement
1567
1568 Use QLayoutItem::iterator() to create an iterator over a layout.
1569
1570 QLayoutIterator uses \e explicit sharing with a reference count.
1571 If an iterator is copied and one of the copies is modified, both
1572 iterators will be modified.
1573
1574 A QLayoutIterator is not protected against changes in its layout. If
1575 the layout is modified or deleted the iterator will become invalid.
1576 It is not possible to test for validity. It is safe to delete an
1577 invalid layout; any other access may lead to an illegal memory
1578 reference and the abnormal termination of the program.
1579
1580 Calling takeCurrent() or deleteCurrent() leaves the iterator in a
1581 valid state, but may invalidate any other iterators that access the
1582 same layout.
1583
1584 The following code will draw a rectangle for each layout item in
1585 the layout structure of the widget.
1586 \code
1587 static void paintLayout( QPainter *p, QLayoutItem *lay )
1588 {
1589 QLayoutIterator it = lay->iterator();
1590 QLayoutItem *child;
1591 while ( (child = it.current()) != 0 ) {
1592 paintLayout( p, child );
1593 ++it;
1594 }
1595 p->drawRect( lay->geometry() );
1596 }
1597 void ExampleWidget::paintEvent( QPaintEvent * )
1598 {
1599 QPainter p( this );
1600 if ( layout() )
1601 paintLayout( &p, layout() );
1602 }
1603 \endcode
1604
1605 All the functionality of QLayoutIterator is implemented by
1606 subclasses of \l QGLayoutIterator. QLayoutIterator itself is not
1607 designed to be subclassed.
1608*/
1609
1610/*!
1611 \fn QLayoutIterator::QLayoutIterator( QGLayoutIterator *gi )
1612
1613 Constructs an iterator based on \a gi. The constructed iterator
1614 takes ownership of \a gi and will delete it.
1615
1616 This constructor is provided for layout implementors. Application
1617 programmers should use QLayoutItem::iterator() to create an
1618 iterator over a layout.
1619*/
1620
1621/*!
1622 \fn QLayoutIterator::QLayoutIterator( const QLayoutIterator &i )
1623
1624 Creates a shallow copy of \a i, i.e. if the copy is modified, then
1625 the original will also be modified.
1626*/
1627
1628/*!
1629 \fn QLayoutIterator::~QLayoutIterator()
1630
1631 Destroys the iterator.
1632*/
1633
1634/*!
1635 \fn QLayoutIterator &QLayoutIterator::operator=( const QLayoutIterator &i )
1636
1637 Assigns \a i to this iterator and returns a reference to this
1638 iterator.
1639*/
1640
1641/*!
1642 \fn QLayoutItem *QLayoutIterator::operator++()
1643
1644 Moves the iterator to the next child item and returns that item,
1645 or 0 if there is no such item.
1646*/
1647
1648/*!
1649 \fn QLayoutItem *QLayoutIterator::current()
1650
1651 Returns the current item, or 0 if there is no current item.
1652*/
1653
1654/*!
1655 \fn QLayoutItem *QLayoutIterator::takeCurrent()
1656
1657 Removes the current child item from the layout without deleting
1658 it, and moves the iterator to the next item. Returns the removed
1659 item, or 0 if there was no item to be removed. This iterator will
1660 still be valid, but any other iterator over the same layout may
1661 become invalid.
1662*/
1663
1664/*!
1665 \fn void QLayoutIterator::deleteCurrent()
1666
1667 Removes and deletes the current child item from the layout and
1668 moves the iterator to the next item. This iterator will still be
1669 valid, but any other iterator over the same layout may become
1670 invalid.
1671*/
1672
1673/*!
1674 \enum QLayout::ResizeMode
1675
1676 The possible values are:
1677
1678 \value Auto If the main widget is a top-level widget with no
1679 height-for-width (hasHeightForWidth()), this is
1680 the same as \c Minimium; otherwise, this is the
1681 same as \c FreeResize.
1682 \value Fixed The main widget's size is set to sizeHint(); it
1683 cannot be resized at all.
1684 \value Minimum The main widget's minimum size is set to
1685 minimumSize(); it cannot be smaller.
1686 \value FreeResize The widget is not constrained.
1687*/
1688
1689/*!
1690 \property QLayout::resizeMode
1691 \brief the resize mode of the layout
1692
1693 The default mode is \c Auto.
1694
1695 \sa QLayout::ResizeMode
1696*/
1697
1698void QLayout::setResizeMode( ResizeMode mode )
1699{
1700 if ( mode == resizeMode() )
1701 return;
1702
1703 switch ( mode ) {
1704 case Auto:
1705 frozen = FALSE;
1706 autoMinimum = FALSE;
1707 autoResizeMode = TRUE;
1708 break;
1709 case Fixed:
1710 frozen = TRUE;
1711 autoMinimum = FALSE;
1712 autoResizeMode = FALSE;
1713 break;
1714 case FreeResize:
1715 frozen = FALSE;
1716 autoMinimum = FALSE;
1717 autoResizeMode = FALSE;
1718 break;
1719 case Minimum:
1720 frozen = FALSE;
1721 autoMinimum = TRUE;
1722 autoResizeMode = FALSE;
1723 }
1724 if ( mainWidget() && mainWidget()->isVisible() )
1725 activate();
1726}
1727
1728QLayout::ResizeMode QLayout::resizeMode() const
1729{
1730 return ( autoResizeMode ? Auto :
1731 (frozen ? Fixed : (autoMinimum ? Minimum : FreeResize)) );
1732}
1733
1734/*!
1735 \fn bool QLayout::autoAdd() const
1736
1737 Returns TRUE if this layout automatically grabs all new
1738 mainWidget()'s new children and adds them as defined by addItem();
1739 otherwise returns FALSE. This has effect only for top-level
1740 layouts, i.e. layouts that are direct children of their
1741 mainWidget().
1742
1743 autoAdd() is disabled by default.
1744
1745 Note that a top-level layout is not necessarily associated with
1746 the top-level widget.
1747
1748 \sa setAutoAdd()
1749*/
1750
1751/*!
1752 If \a b is TRUE, auto-add is enabled; otherwise auto-add is
1753 disabled.
1754
1755 \sa autoAdd()
1756*/
1757void QLayout::setAutoAdd( bool b )
1758{
1759 autoNewChild = b;
1760}
1761
1762/*!
1763 \fn bool QLayout::supportsMargin() const
1764
1765 Returns TRUE if this layout supports \l QLayout::margin on
1766 non-top-level layouts; otherwise returns FALSE.
1767
1768 \sa margin
1769*/
1770
1771/*!
1772 Sets the value returned by supportsMargin(). If \a b is TRUE,
1773 margin() handling is implemented by the subclass. If \a b is
1774 FALSE (the default), QLayout will add margin() around top-level
1775 layouts.
1776
1777 If \a b is TRUE, margin handling needs to be implemented in
1778 setGeometry(), maximumSize(), minimumSize(), sizeHint() and
1779 heightForWidth().
1780
1781 \sa supportsMargin()
1782*/
1783void QLayout::setSupportsMargin( bool b )
1784{
1785 marginImpl = b;
1786}
1787
1788/*!
1789 Returns the rectangle that should be covered when the geometry of
1790 this layout is set to \a r, provided that this layout supports
1791 setAlignment().
1792
1793 The result is derived from sizeHint() and expanding(). It is never
1794 larger than \a r.
1795*/
1796QRect QLayout::alignmentRect( const QRect &r ) const
1797{
1798 QSize s = sizeHint();
1799 int a = alignment();
1800
1801 /*
1802 This is a hack to obtain the real maximum size, not
1803 QSize(QLAYOUTSIZE_MAX, QLAYOUTSIZE_MAX), the value consistently
1804 returned by QLayoutItems that have an alignment.
1805 */
1806 QLayout *that = (QLayout *) this;
1807 that->setAlignment( 0 );
1808 QSize ms = maximumSize();
1809 that->setAlignment( a );
1810
1811 if ( (expanding() & QSizePolicy::Horizontally) ||
1812 !(a & Qt::AlignHorizontal_Mask ) ) {
1813 s.setWidth( QMIN(r.width(), ms.width()) );
1814 }
1815 if ( (expanding() & QSizePolicy::Vertically) ||
1816 !(a & Qt::AlignVertical_Mask) ) {
1817 s.setHeight( QMIN(r.height(), ms.height()) );
1818 } else if ( hasHeightForWidth() ) {
1819 int hfw = heightForWidth( s.width() );
1820 if ( hfw < s.height() )
1821 s.setHeight( QMIN(hfw, ms.height()) );
1822 }
1823
1824 int x = r.x();
1825 int y = r.y();
1826
1827 if ( a & Qt::AlignBottom )
1828 y += ( r.height() - s.height() );
1829 else if ( !(a & Qt::AlignTop) )
1830 y += ( r.height() - s.height() ) / 2;
1831
1832 a = QApplication::horizontalAlignment( a );
1833 if ( a & Qt::AlignRight )
1834 x += ( r.width() - s.width() );
1835 else if ( !(a & Qt::AlignLeft) )
1836 x += ( r.width() - s.width() ) / 2;
1837
1838 return QRect( x, y, s.width(), s.height() );
1839}
1840
1841/*!
1842 Removes the widget \a widget from the layout. After this call, it
1843 is the caller's responsibility to give the widget a reasonable
1844 geometry or to put the widget back into a layout.
1845
1846 \sa removeItem(), QWidget::setGeometry(), add()
1847*/
1848void QLayout::remove( QWidget *widget )
1849{
1850 QLayoutIterator it = iterator();
1851 QLayoutItem *child;
1852 while ( (child = it.current()) != 0 ) {
1853 if ( child->widget() == widget ) {
1854 it.deleteCurrent();
1855 invalidate(); // maybe redundant
1856 QApplication::postEvent( mainWidget(),
1857 new QEvent(QEvent::LayoutHint) );
1858 } else {
1859 ++it;
1860 }
1861 }
1862}
1863
1864/*!
1865 Removes the layout item \a item from the layout. It is the
1866 caller's responsibility to delete the item.
1867
1868 Notice that \a item can be a layout (since QLayout inherits
1869 QLayoutItem).
1870
1871 \sa remove(), addItem()
1872*/
1873void QLayout::removeItem( QLayoutItem *item )
1874{
1875 QLayoutIterator it = iterator();
1876 QLayoutItem *child;
1877 while ( (child = it.current()) != 0 ) {
1878 if ( child == item ) {
1879 it.takeCurrent();
1880 invalidate(); // maybe redundant
1881 QApplication::postEvent( mainWidget(),
1882 new QEvent(QEvent::LayoutHint) );
1883 } else {
1884 ++it;
1885 }
1886 }
1887}
1888
1889/*!
1890 Enables this layout if \a enable is TRUE, otherwise disables it.
1891
1892 An enabled layout adjusts dynamically to changes; a disabled
1893 layout acts as if it did not exist.
1894
1895 By default all layouts are enabled.
1896
1897 \sa isEnabled()
1898*/
1899void QLayout::setEnabled( bool enable )
1900{
1901 enabled = enable;
1902}
1903
1904/*!
1905 Returns TRUE if the layout is enabled; otherwise returns FALSE.
1906
1907 \sa setEnabled()
1908*/
1909bool QLayout::isEnabled() const
1910{
1911 return enabled;
1912}
1913
1914void QLayout::propagateSpacing( QLayout *parent )
1915{
1916 QLayoutIterator it = parent->iterator();
1917 QLayoutItem *child;
1918 while ( (child = it.current()) ) {
1919 QLayout *childLayout = child->layout();
1920 if ( childLayout && childLayout->insideSpacing < 0 ) {
1921 childLayout->insideSpacing = parent->insideSpacing;
1922 propagateSpacing( childLayout );
1923 }
1924 ++it;
1925 }
1926}
1927
1928#endif // QT_NO_LAYOUT
Note: See TracBrowser for help on using the repository browser.