1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 
43 #include <QtTest/QtTest>
44 #include <qgraphicslinearlayout.h>
45 #include <qgraphicsproxywidget.h>
46 #include <qgraphicswidget.h>
47 #include <qgraphicsscene.h>
48 #include <qgraphicsview.h>
49 #include <qapplication.h>
50 #include <qplastiquestyle.h>
51 
52 class tst_QGraphicsLinearLayout : public QObject {
53 Q_OBJECT
54 
55 public slots:
56     void initTestCase();
57     void cleanupTestCase();
58     void init();
59     void cleanup();
60 
61 private slots:
62     void qgraphicslinearlayout_data();
63     void qgraphicslinearlayout();
64 
65     void alignment_data();
66     void alignment();
67     void count_data();
68     void count();
69     void dump_data();
70     void dump();
71     void geometry_data();
72     void geometry();
73     void insertItem_data();
74     void insertItem();
75     void insertStretch_data();
76     void insertStretch();
77     void invalidate_data();
78     void invalidate();
79     void itemAt_data();
80     void itemAt();
81     void itemAt_visualOrder();
82     void orientation_data();
83     void orientation();
84     void removeAt_data();
85     void removeAt();
86     void removeItem_data();
87     void removeItem();
88     void setGeometry_data();
89     void setGeometry();
90     void setSpacing_data();
91     void setSpacing();
92     void setItemSpacing_data();
93     void setItemSpacing();
94     void itemSpacing();
95     void setStretchFactor_data();
96     void setStretchFactor();
97     void testStretch();
98     void defaultStretchFactors_data();
99     void defaultStretchFactors();
100     void sizeHint_data();
101     void sizeHint();
102     void updateGeometry();
103     void layoutDirection();
104     void removeLayout();
105     void avoidRecursionInInsertItem();
106     void styleInfoLeak();
107     void testAlignmentInLargerLayout();
108     void testOffByOneInLargerLayout();
109     void testDefaultAlignment();
110     void combineSizePolicies();
111     void hiddenItems();
112 
113     // Task specific tests
114     void task218400_insertStretchCrash();
115 };
116 
117 // Subclass that exposes the protected functions.
118 class SubQGraphicsLinearLayout : public QGraphicsLinearLayout {
119 public:
SubQGraphicsLinearLayout(Qt::Orientation orientation=Qt::Horizontal)120     SubQGraphicsLinearLayout(Qt::Orientation orientation = Qt::Horizontal) : QGraphicsLinearLayout(orientation),
121         graphicsSceneResize(0),
122         layoutRequest(0),
123         layoutDirectionChange(0)
124         { }
125 
widgetEvent(QEvent * e)126     void widgetEvent(QEvent *e)
127     {
128         switch (e->type()) {
129         case QEvent::GraphicsSceneResize:
130             graphicsSceneResize++;
131             break;
132         case QEvent::LayoutRequest:
133             layoutRequest++;
134             break;
135         case QEvent::LayoutDirectionChange:
136             layoutDirectionChange++;
137             break;
138         default:
139             break;
140         }
141 
142         QGraphicsLinearLayout::widgetEvent(e);
143     }
144 
145     int graphicsSceneResize;
146     int layoutRequest;
147     int layoutDirectionChange;
148 };
149 
150 // This will be called before the first test function is executed.
151 // It is only called once.
initTestCase()152 void tst_QGraphicsLinearLayout::initTestCase()
153 {
154     // since the style will influence the results, we have to ensure
155     // that the tests are run using the same style on all platforms
156 #if defined( Q_WS_S60 )|| defined (Q_WS_WINCE)
157     QApplication::setStyle(new QWindowsStyle);
158 #else
159     QApplication::setStyle(new QPlastiqueStyle);
160 #endif
161 }
162 
163 // This will be called after the last test function is executed.
164 // It is only called once.
cleanupTestCase()165 void tst_QGraphicsLinearLayout::cleanupTestCase()
166 {
167 }
168 
169 // This will be called before each test function is executed.
init()170 void tst_QGraphicsLinearLayout::init()
171 {
172 }
173 
174 // This will be called after every test function.
cleanup()175 void tst_QGraphicsLinearLayout::cleanup()
176 {
177 }
178 
179 class RectWidget : public QGraphicsWidget
180 {
181 public:
RectWidget(QGraphicsItem * parent=0,const QBrush & brush=QBrush ())182     RectWidget(QGraphicsItem *parent = 0, const QBrush &brush = QBrush()) : QGraphicsWidget(parent){ m_brush = brush;}
183 
paint(QPainter * painter,const QStyleOptionGraphicsItem * option,QWidget * widget)184     void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
185     {
186         Q_UNUSED(option);
187         Q_UNUSED(widget);
188         painter->setBrush(m_brush);
189         painter->drawRoundRect(rect());
190     }
191 
setSizeHint(Qt::SizeHint which,const QSizeF & size)192     void setSizeHint(Qt::SizeHint which, const QSizeF &size) {
193         m_sizeHints[which] = size;
194         updateGeometry();
195     }
196 
sizeHint(Qt::SizeHint which,const QSizeF & constraint=QSizeF ()) const197     virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const {
198         if (m_sizeHints[which].isValid()) {
199             return m_sizeHints[which];
200         }
201         return QGraphicsWidget::sizeHint(which, constraint);
202     }
203 
204     QSizeF m_sizeHints[Qt::NSizeHints];
205     QBrush m_brush;
206 };
207 
208 
Q_DECLARE_METATYPE(Qt::Orientation)209 Q_DECLARE_METATYPE(Qt::Orientation)
210 void tst_QGraphicsLinearLayout::qgraphicslinearlayout_data()
211 {
212     QTest::addColumn<Qt::Orientation>("orientation");
213     QTest::newRow("vertical") << Qt::Vertical;
214     QTest::newRow("horizontal") << Qt::Horizontal;
215 }
216 
qgraphicslinearlayout()217 void tst_QGraphicsLinearLayout::qgraphicslinearlayout()
218 {
219     QFETCH(Qt::Orientation, orientation);
220     SubQGraphicsLinearLayout layout(orientation);
221     QVERIFY(layout.isLayout());
222 
223     qApp->processEvents();
224     QCOMPARE(layout.graphicsSceneResize, 0);
225     QCOMPARE(layout.layoutRequest, 0);
226     QCOMPARE(layout.layoutDirectionChange, 0);
227 
228     layout.setOrientation(Qt::Vertical);
229     layout.orientation();
230     QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::insertItem: cannot insert null item");
231     QCOMPARE(layout.count(), 0);
232     layout.addItem(0);
233     QCOMPARE(layout.count(), 0);
234     layout.addStretch(0);
235     QCOMPARE(layout.count(), 0);
236     QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::insertItem: cannot insert null item");
237     layout.insertItem(0, 0);
238     layout.insertStretch(0, 0);
239     layout.removeItem(0);
240     QCOMPARE(layout.count(), 0);
241     layout.setSpacing(0);
242     layout.spacing();
243     QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::setStretchFactor: cannot assign a stretch factor to a null item");
244     layout.setStretchFactor(0, 0);
245     QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::setStretchFactor: cannot return a stretch factor for a null item");
246     layout.stretchFactor(0);
247     layout.setAlignment(0, Qt::AlignHCenter);
248     QCOMPARE(layout.alignment(0), 0);
249     layout.setGeometry(QRectF());
250     layout.geometry();
251     QCOMPARE(layout.count(), 0);
252     layout.invalidate();
253     layout.sizeHint(Qt::MinimumSize, QSizeF());
254 }
255 
Q_DECLARE_METATYPE(Qt::AlignmentFlag)256 Q_DECLARE_METATYPE(Qt::AlignmentFlag)
257 void tst_QGraphicsLinearLayout::alignment_data()
258 {
259     QTest::addColumn<Qt::Orientation>("orientation");
260     QTest::addColumn<QSize>("newSize");
261     QTest::newRow("h-defaultsize") << Qt::Horizontal << QSize();
262     QTest::newRow("v-defaultsize") << Qt::Vertical << QSize();
263     QTest::newRow("h-300") << Qt::Horizontal << QSize(300,100);
264     QTest::newRow("v-300") << Qt::Vertical << QSize(100, 300);
265 }
266 
alignment()267 void tst_QGraphicsLinearLayout::alignment()
268 {
269     QFETCH(Qt::Orientation, orientation);
270     QFETCH(QSize, newSize);
271 
272     //if (alignment == Qt::AlignAbsolute)
273     //    QApplication::setLayoutDirection(Qt::RightToLeft);
274     QGraphicsScene scene;
275     QGraphicsView view(&scene);
276     view.setSceneRect(0, 0, 320, 240);
277     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
278     SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout(orientation));
279     scene.addItem(widget);
280     widget->setLayout(&layout);
281 
282     static const Qt::Alignment alignmentsToTest[] = {
283         (Qt::Alignment)0,
284         Qt::AlignLeft,
285         Qt::AlignRight,
286         Qt::AlignHCenter,
287         Qt::AlignTop,
288         Qt::AlignBottom,
289         Qt::AlignVCenter,
290         Qt::AlignCenter,
291         (Qt::Alignment)0,
292         Qt::AlignLeft,
293         Qt::AlignRight,
294         Qt::AlignHCenter,
295         Qt::AlignTop,
296         Qt::AlignBottom,
297         Qt::AlignVCenter,
298         Qt::AlignCenter
299     };
300 
301     int i;
302     bool addWidget = true;
303     for (i = 0; i < sizeof(alignmentsToTest)/sizeof(Qt::Alignment); ++i) {
304         QGraphicsLayoutItem *loutItem;
305         Qt::Alignment align = alignmentsToTest[i];
306         if (!align && i > 0)
307             addWidget = false;
308         if (addWidget)
309             loutItem = new RectWidget(widget, QBrush(Qt::blue));
310         else {
311             SubQGraphicsLinearLayout *lay = new SubQGraphicsLinearLayout(Qt::Vertical);
312             lay->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::DefaultType);
313             lay->setContentsMargins(0,0,0,0);
314             QGraphicsWidget *w = new RectWidget(widget, QBrush(Qt::red));
315             if (align) {
316                 w->setMinimumSize(QSizeF(10,10));
317                 w->setMaximumSize(QSizeF(10,10));
318             } else {
319                 w->setMinimumSize(QSizeF(50,50));
320                 w->setMaximumSize(QSizeF(50,50));
321             }
322             lay->addItem(w);
323             loutItem = lay;
324         }
325         if (align) {
326             loutItem->setMinimumSize(QSizeF(10,10));
327             loutItem->setMaximumSize(QSizeF(10,10));
328         } else {
329             loutItem->setMinimumSize(QSizeF(50,50));
330             loutItem->setMaximumSize(QSizeF(50,50));
331         }
332         layout.addItem(loutItem);
333         layout.setAlignment(loutItem, align);
334 
335     }
336     layout.setContentsMargins(0,0,0,0);
337     int spacing = 1;
338     layout.setSpacing(spacing);
339     if (newSize.isValid())
340         widget->resize(newSize);
341     view.show();
342     widget->show();
343     QTest::qWaitForWindowShown(&view);
344     QApplication::processEvents();
345 
346     int x = 0;
347     int y = 0;
348     for (i = 0; i < layout.count(); ++i) {
349         QGraphicsLayoutItem *item = layout.itemAt(i);
350         Qt::Alignment align = layout.alignment(item);
351 
352         int w = 10;
353         int h = 10;
354         switch(align) {
355             case Qt::AlignLeft:
356                 break;
357             case Qt::AlignRight:
358                 if (orientation == Qt::Vertical)
359                     x += 40;
360                 break;
361             case Qt::AlignHCenter:
362                 if (orientation == Qt::Vertical)
363                     x += 20;
364                 break;
365             case Qt::AlignTop:
366                 break;
367             case Qt::AlignBottom:
368                 if (orientation == Qt::Horizontal)
369                     y += 40;
370                 break;
371             case Qt::AlignVCenter:
372                 if (orientation == Qt::Horizontal)
373                     y += 20;
374                 break;
375             case Qt::AlignCenter:
376                 if (orientation == Qt::Horizontal)
377                     y += 20;
378                 else
379                     x += 20;
380                 break;
381             case 0:
382                 w = 50;
383                 h = 50;
384                 break;
385             default:
386                 break;
387         }
388         QRectF expectedGeometry(x, y, w, h);
389         QCOMPARE(item->geometry(), expectedGeometry);
390         if (orientation == Qt::Horizontal) {
391             x += w;
392             y = 0;
393             x += spacing;
394         } else {
395             x = 0;
396             y += h;
397             y += spacing;
398         }
399     }
400 }
401 
count_data()402 void tst_QGraphicsLinearLayout::count_data()
403 {
404     QTest::addColumn<int>("itemCount");
405     QTest::addColumn<int>("layoutCount");
406     QTest::newRow("0, 0") << 0 << 0;
407     QTest::newRow("0, 5") << 0 << 5;
408     QTest::newRow("5, 0") << 5 << 0;
409     QTest::newRow("5, 5") << 5 << 5;
410 }
411 
412 // int count() const public
count()413 void tst_QGraphicsLinearLayout::count()
414 {
415     QFETCH(int, itemCount);
416     QFETCH(int, layoutCount);
417 
418     SubQGraphicsLinearLayout layout;
419     QCOMPARE(layout.count(), 0);
420 
421     for (int i = 0; i < itemCount; ++i)
422         layout.addItem(new QGraphicsWidget);
423     QCOMPARE(layout.count(), itemCount);
424 
425     for (int i = 0; i < layoutCount; ++i)
426         layout.addItem(new SubQGraphicsLinearLayout);
427     QCOMPARE(layout.count(), itemCount + layoutCount);
428 
429     // see also removeAt()
430 }
431 
dump_data()432 void tst_QGraphicsLinearLayout::dump_data()
433 {
434     QTest::addColumn<int>("itemCount");
435     QTest::addColumn<int>("layoutCount");
436     for (int i = -1; i < 3; ++i) {
437         QTest::newRow(QString("%1, 0, 0").arg(i).toLatin1()) << 0 << 0;
438         QTest::newRow(QString("%1, 0, 5").arg(i).toLatin1()) << 5 << 5;
439         QTest::newRow(QString("%1, 5, 0").arg(i).toLatin1()) << 5 << 5;
440         QTest::newRow(QString("%1, 5, 5").arg(i).toLatin1()) << 5 << 5;
441     }
442 }
443 
444 // void dump(int indent = 0) const public
dump()445 void tst_QGraphicsLinearLayout::dump()
446 {
447     QFETCH(int, itemCount);
448     QFETCH(int, layoutCount);
449     SubQGraphicsLinearLayout layout;
450     for (int i = 0; i < itemCount; ++i)
451         layout.addItem(new QGraphicsWidget);
452     for (int i = 0; i < layoutCount; ++i)
453         layout.addItem(new SubQGraphicsLinearLayout);
454 }
455 
geometry_data()456 void tst_QGraphicsLinearLayout::geometry_data()
457 {
458     QTest::addColumn<int>("itemCount");
459     QTest::addColumn<int>("layoutCount");
460     QTest::addColumn<int>("itemSpacing");
461     QTest::addColumn<int>("spacing");
462     QTest::addColumn<Qt::Orientation>("orientation");
463     QTest::addColumn<QRectF>("rect");
464 
465     QTest::newRow("null") << 0 << 0 << 0 << 0 << Qt::Horizontal << QRectF();
466 
467     QTest::newRow("one item") << 1 << 0 << 0 << 0 << Qt::Horizontal << QRectF(0, 0, 10, 10);
468     QTest::newRow("one layout") << 0 << 1 << 0 << 0 << Qt::Horizontal << QRectF(0, 0, 10, 10);
469     QTest::newRow("two h") << 1 << 1 << 0 << 0 << Qt::Horizontal << QRectF(0, 0, 20, 10);
470     QTest::newRow("two v") << 1 << 1 << 0 << 0 << Qt::Vertical << QRectF(0, 0, 10, 20);
471 
472     QTest::newRow("two w/itemspacing") << 1 << 1 << 5 << 0 << Qt::Horizontal << QRectF(0, 0, 25, 10);
473     QTest::newRow("two w/spacing") << 1 << 1 << 8 << 0 << Qt::Horizontal << QRectF(0, 0, 28, 10);
474 
475     QTest::newRow("two w/itemspacing v") << 1 << 1 << 5 << 0 << Qt::Vertical << QRectF(0, 0, 10, 25);
476     QTest::newRow("two w/spacing v") << 1 << 1 << 8 << 0 << Qt::Vertical << QRectF(0, 0, 10, 28);
477 }
478 
479 // QRectF geometry() const public
geometry()480 void tst_QGraphicsLinearLayout::geometry()
481 {
482     QFETCH(int, itemCount);
483     QFETCH(int, layoutCount);
484     QFETCH(int, itemSpacing);
485     QFETCH(int, spacing);
486     QFETCH(Qt::Orientation, orientation);
487     QFETCH(QRectF, rect);
488     QGraphicsScene scene;
489     QGraphicsView view(&scene);
490     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
491     SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout(orientation));
492     scene.addItem(widget);
493     widget->setLayout(&layout);
494     widget->setContentsMargins(0, 0, 0, 0);
495     for (int i = 0; i < itemCount; ++i)
496         layout.addItem(new QGraphicsWidget);
497     for (int i = 0; i < layoutCount; ++i)
498         layout.addItem(new SubQGraphicsLinearLayout);
499 
500     for (int i = 0; i < layout.count(); ++i) {
501         QGraphicsLayoutItem *item = layout.itemAt(i);
502         item->setMaximumSize(10, 10);
503         item->setMinimumSize(10, 10);
504     }
505     layout.setItemSpacing(0, itemSpacing);
506     layout.setSpacing(spacing);
507     layout.setContentsMargins(0, 0, 0, 0);
508 
509     widget->show();
510     view.show();
511     QApplication::processEvents();
512     QCOMPARE(layout.geometry(), rect);
513     delete widget;
514 }
515 
insertItem_data()516 void tst_QGraphicsLinearLayout::insertItem_data()
517 {
518     QTest::addColumn<int>("itemCount");
519     QTest::addColumn<int>("layoutCount");
520     QTest::addColumn<int>("insertItemAt");
521     QTest::addColumn<bool>("isWidget");
522     for (int i = -1; i < 4; ++i) {
523         for (int j = 0; j < 2; ++j) {
524             QTest::newRow(QString("0, 0, %1 %2").arg(i).arg(j).toLatin1()) << 0 << 0 << i << (bool)j;
525             QTest::newRow(QString("1, 0, %1 %2").arg(i).arg(j).toLatin1()) << 1 << 0 << i << (bool)j;
526             QTest::newRow(QString("0, 1, %1 %2").arg(i).arg(j).toLatin1()) << 0 << 1 << i << (bool)j;
527             QTest::newRow(QString("2, 2, %1 %2").arg(i).arg(j).toLatin1()) << 2 << 2 << i << (bool)j;
528         }
529     }
530 }
531 
532 // void insertItem(int index, QGraphicsLayoutItem* item) public
insertItem()533 void tst_QGraphicsLinearLayout::insertItem()
534 {
535     QFETCH(int, itemCount);
536     QFETCH(int, layoutCount);
537     QFETCH(int, insertItemAt);
538     QFETCH(bool, isWidget);
539     if (insertItemAt > layoutCount + itemCount)
540         return;
541 
542     SubQGraphicsLinearLayout layout;
543     for (int i = 0; i < itemCount; ++i)
544         layout.addItem(new QGraphicsWidget);
545     for (int i = 0; i < layoutCount; ++i)
546         layout.addItem(new SubQGraphicsLinearLayout);
547 
548     QGraphicsLayoutItem *item = 0;
549     if (isWidget)
550         item = new QGraphicsWidget;
551     else
552         item = new SubQGraphicsLinearLayout;
553 
554     QSizeF oldSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
555     layout.insertItem(insertItemAt, item);
556     QCOMPARE(layout.count(), itemCount + layoutCount + 1);
557 
558     if (insertItemAt >= 0 && (itemCount + layoutCount >= 0)) {
559         QCOMPARE(layout.itemAt(insertItemAt), item);
560     }
561 
562     layout.activate();
563     QSizeF newSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
564     if (!isWidget && layout.count() == 1)
565         QCOMPARE(oldSizeHint.width(), newSizeHint.width());
566     else if (itemCount + layoutCount > 0)
567         QVERIFY(oldSizeHint.width() < newSizeHint.width());
568 }
569 
insertStretch_data()570 void tst_QGraphicsLinearLayout::insertStretch_data()
571 {
572     QTest::addColumn<int>("itemCount");
573     QTest::addColumn<int>("layoutCount");
574     QTest::addColumn<int>("insertItemAt");
575     QTest::addColumn<int>("stretch");
576     for (int i = -1; i < 4; ++i) {
577         for (int j = 0; j < 2; ++j) {
578             QTest::newRow(QString("0, 0, %1 %2").arg(i).arg(j).toLatin1()) << 0 << 0 << i << j;
579             QTest::newRow(QString("1, 0, %1 %2").arg(i).arg(j).toLatin1()) << 1 << 0 << i << j;
580             QTest::newRow(QString("0, 1, %1 %2").arg(i).arg(j).toLatin1()) << 0 << 1 << i << j;
581             QTest::newRow(QString("2, 2, %1 %2").arg(i).arg(j).toLatin1()) << 2 << 2 << i << j;
582         }
583     }
584 }
585 
586 // void insertStretch(int index, int stretch = 1) public
insertStretch()587 void tst_QGraphicsLinearLayout::insertStretch()
588 {
589     QFETCH(int, itemCount);
590     QFETCH(int, layoutCount);
591     QFETCH(int, insertItemAt);
592     QFETCH(int, stretch);
593     if (insertItemAt > layoutCount + itemCount)
594         return;
595 
596     QGraphicsScene scene;
597     QGraphicsView view(&scene);
598     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
599     SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout;
600     scene.addItem(widget);
601 
602     QList<QGraphicsWidget *>items;
603     QGraphicsWidget *item = 0;
604     for (int i = 0; i < itemCount; ++i) {
605         item = new RectWidget;
606         item->setMinimumSize(10, 10);
607         item->setPreferredSize(25, 25);
608         item->setMaximumSize(50, 50);
609         layout->addItem(item);
610     }
611     for (int i = 0; i < layoutCount; ++i) {
612         item = new RectWidget;
613         item->setMinimumSize(10, 10);
614         item->setPreferredSize(25, 25);
615         item->setMaximumSize(50, 50);
616         SubQGraphicsLinearLayout *sublayout = new SubQGraphicsLinearLayout;
617         sublayout->addItem(item);
618         layout->addItem(sublayout);
619     }
620     widget->setLayout(layout);
621     layout->insertStretch(insertItemAt, stretch);
622     QCOMPARE(layout->count(), itemCount + layoutCount);
623 
624     layout->activate();
625     view.show();
626     widget->show();
627 
628     int prevStretch = -2;
629     int prevWidth = -2;
630     widget->resize((layoutCount + itemCount) * 25 + 25, 25);
631     for (int i = 0; i < layout->count(); ++i) {
632         if (QGraphicsLayoutItem *item = layout->itemAt(i)) {
633             if (prevStretch != -2) {
634                 if (layout->stretchFactor(item) >= prevStretch) {
635                     QVERIFY(item->geometry().width() >= prevWidth);
636                 } else {
637                     QVERIFY(item->geometry().width() < prevWidth);
638                 }
639             }
640             prevStretch = layout->stretchFactor(item);
641             prevWidth = (int)(item->geometry().width());
642         }
643     }
644 
645     //QTest::qWait(1000);
646     delete widget;
647 }
648 
invalidate_data()649 void tst_QGraphicsLinearLayout::invalidate_data()
650 {
651     QTest::addColumn<int>("count");
652     QTest::newRow("0") << 0;
653     QTest::newRow("1") << 1;
654     QTest::newRow("2") << 2;
655     QTest::newRow("3") << 3;
656 }
657 
658 // void invalidate() public
invalidate()659 void tst_QGraphicsLinearLayout::invalidate()
660 {
661     QFETCH(int, count);
662     QGraphicsScene scene;
663     QGraphicsView view(&scene);
664     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
665     SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
666     scene.addItem(widget);
667     widget->setLayout(&layout);
668     widget->setContentsMargins(0, 0, 0, 0);
669     layout.setContentsMargins(0, 0, 0, 0);
670     view.show();
671     widget->show();
672     //QTest::qWait(1000);
673     QTest::qWaitForWindowShown(&view);
674     qApp->processEvents();
675     layout.layoutRequest = 0;
676 
677     layout.setContentsMargins(1, 2, 3, 4);
678     QApplication::sendPostedEvents(0, 0);
679     QCOMPARE(layout.layoutRequest, 1);
680 
681     layout.setOrientation(Qt::Vertical);
682     QApplication::sendPostedEvents(0, 0);
683     QCOMPARE(layout.layoutRequest, 2);
684 
685     for (int i = 0; i < count; ++i)
686         layout.invalidate();        // Event is compressed, should only get one layoutrequest
687     QApplication::sendPostedEvents(0, 0);
688     QCOMPARE(layout.layoutRequest, count ? 3 : 2);
689     delete widget;
690 }
691 
itemAt_data()692 void tst_QGraphicsLinearLayout::itemAt_data()
693 {
694     QTest::addColumn<int>("index");
695     QTest::newRow("0") << 0;
696     QTest::newRow("1") << 1;
697     QTest::newRow("2") << 2;
698 }
699 
700 // QGraphicsLayoutItem* itemAt(int index) const public
itemAt()701 void tst_QGraphicsLinearLayout::itemAt()
702 {
703     // see also the insertItem() etc tests
704     QFETCH(int, index);
705     SubQGraphicsLinearLayout layout;
706     for (int i = 0; i < 3; ++i)
707         layout.addItem(new QGraphicsWidget);
708 
709     QVERIFY(layout.itemAt(index) != 0);
710 }
711 
itemAt_visualOrder()712 void tst_QGraphicsLinearLayout::itemAt_visualOrder()
713 {
714     QGraphicsLinearLayout *l = new QGraphicsLinearLayout;
715 
716     QGraphicsWidget *w1 = new QGraphicsWidget;
717     l->addItem(w1);
718 
719     QGraphicsWidget *w3 = new QGraphicsWidget;
720     l->addItem(w3);
721 
722     QGraphicsWidget *w0 = new QGraphicsWidget;
723     l->insertItem(0, w0);
724 
725     QGraphicsWidget *w2 = new QGraphicsWidget;
726     l->insertItem(2, w2);
727 
728     QCOMPARE(l->itemAt(0), static_cast<QGraphicsLayoutItem*>(w0));
729     QCOMPARE(l->itemAt(1), static_cast<QGraphicsLayoutItem*>(w1));
730     QCOMPARE(l->itemAt(2), static_cast<QGraphicsLayoutItem*>(w2));
731     QCOMPARE(l->itemAt(3), static_cast<QGraphicsLayoutItem*>(w3));
732 }
733 
orientation_data()734 void tst_QGraphicsLinearLayout::orientation_data()
735 {
736     QTest::addColumn<Qt::Orientation>("orientation");
737     QTest::newRow("vertical") << Qt::Vertical;
738     QTest::newRow("horizontal") << Qt::Horizontal;
739 }
740 
741 // Qt::Orientation orientation() const public
orientation()742 void tst_QGraphicsLinearLayout::orientation()
743 {
744     QFETCH(Qt::Orientation, orientation);
745 
746     QGraphicsScene scene;
747     QGraphicsView view(&scene);
748     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
749     Qt::Orientation initialOrientation = (orientation == Qt::Vertical ? Qt::Horizontal : Qt::Vertical);
750     SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout(initialOrientation));
751     scene.addItem(widget);
752     widget->setLayout(&layout);
753     widget->setContentsMargins(0, 0, 0, 0);
754     layout.setContentsMargins(0, 0, 0, 0);
755     int i;
756     int itemCount = 3;
757     for (i = 0; i < itemCount; ++i)
758         layout.addItem(new RectWidget);
759     QCOMPARE(layout.orientation(), initialOrientation);
760     QList<qreal> positions;
761 
762     view.show();
763     widget->show();
764     qApp->processEvents();
765 
766     for (i = 0; i < itemCount; ++i) {
767         QGraphicsWidget *item = static_cast<QGraphicsWidget*>(layout.itemAt(i));
768         qreal pos;
769         if (initialOrientation == Qt::Horizontal)
770             pos = item->pos().x();
771         else
772             pos = item->pos().y();
773         positions.append(pos);
774 
775     }
776 
777     layout.setOrientation(orientation);
778     QCOMPARE(layout.orientation(), orientation);
779 	// important to resize to preferredsize when orientation is switched
780     widget->resize(widget->effectiveSizeHint(Qt::PreferredSize));
781     qApp->processEvents();
782     for (i = 0; i < positions.count(); ++i) {
783         QGraphicsWidget *item = static_cast<QGraphicsWidget*>(layout.itemAt(i));
784         if (initialOrientation == Qt::Horizontal)
785             QCOMPARE(item->pos().y(), positions.at(i));
786         else
787             QCOMPARE(item->pos().x(), positions.at(i));
788     }
789 
790     //QSKIP("LayoutdirectionChange should only posted when QGraphicsWidget::setLayoutDirection() is called, right?", SkipAll);
791 
792     //QCOMPARE(layout.layoutDirectionChange, 1);
793 }
794 
removeAt_data()795 void tst_QGraphicsLinearLayout::removeAt_data()
796 {
797     QTest::addColumn<int>("itemCount");
798     QTest::addColumn<int>("layoutCount");
799     QTest::addColumn<int>("removeItemAt");
800     QTest::addColumn<Qt::Orientation>("orientation");
801     for (int i = -1; i < 4; ++i) {
802         for (int k = 0; k < 2; ++k) {
803             Qt::Orientation orientation = (k == 0) ? Qt::Vertical : Qt::Horizontal;
804             QTest::newRow(QString("0, 0, %1").arg(i).toLatin1()) << 0 << 0 << i << orientation;
805             QTest::newRow(QString("1, 0, %1").arg(i).toLatin1()) << 1 << 0 << i << orientation;
806             QTest::newRow(QString("0, 1, %1").arg(i).toLatin1()) << 0 << 1 << i << orientation;
807             QTest::newRow(QString("2, 2, %1").arg(i).toLatin1()) << 2 << 2 << i << orientation;
808         }
809     }
810 }
811 
812 // void removeAt(int index) public
removeAt()813 void tst_QGraphicsLinearLayout::removeAt()
814 {
815     QFETCH(int, itemCount);
816     QFETCH(int, layoutCount);
817     QFETCH(int, removeItemAt);
818     QFETCH(Qt::Orientation, orientation);
819     if (removeItemAt >= layoutCount + itemCount)
820         return;
821 
822     SubQGraphicsLinearLayout layout(orientation);
823     for (int i = 0; i < itemCount; ++i)
824         layout.addItem(new QGraphicsWidget);
825     for (int i = 0; i < layoutCount; ++i)
826         layout.addItem(new SubQGraphicsLinearLayout);
827     QSizeF oldSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
828 
829     QGraphicsLayoutItem *w = 0;
830     if (removeItemAt >= 0 && removeItemAt < layout.count())
831         w = layout.itemAt(removeItemAt);
832     if (w) {
833         QGraphicsLayoutItem *wParent = w->parentLayoutItem();
834         QCOMPARE(wParent, static_cast<QGraphicsLayoutItem *>(&layout));
835         layout.removeAt(removeItemAt);
836         wParent = w->parentLayoutItem();
837         QCOMPARE(wParent, static_cast<QGraphicsLayoutItem *>(0));
838         delete w;
839     }
840     QCOMPARE(layout.count(), itemCount + layoutCount - (w ? 1 : 0));
841 
842     layout.activate();
843     QSizeF newSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
844     if (orientation == Qt::Horizontal)
845         QVERIFY(oldSizeHint.width() >= newSizeHint.width());
846     else
847         QVERIFY(oldSizeHint.height() >= newSizeHint.height());
848 }
849 
removeItem_data()850 void tst_QGraphicsLinearLayout::removeItem_data()
851 {
852     QTest::addColumn<int>("itemCount");
853     QTest::addColumn<int>("layoutCount");
854     QTest::addColumn<int>("removeItemAt");
855     for (int i = -1; i < 4; ++i) {
856         QTest::newRow(QString("0, 0, %1").arg(i).toLatin1()) << 0 << 0 << i;
857         QTest::newRow(QString("1, 0, %1").arg(i).toLatin1()) << 1 << 0 << i;
858         QTest::newRow(QString("0, 1, %1").arg(i).toLatin1()) << 0 << 1 << i;
859         QTest::newRow(QString("2, 2, %1").arg(i).toLatin1()) << 2 << 2 << i;
860     }
861 }
862 
863 // void removeItem(QGraphicsLayoutItem* item) public
removeItem()864 void tst_QGraphicsLinearLayout::removeItem()
865 {
866     QFETCH(int, itemCount);
867     QFETCH(int, layoutCount);
868     QFETCH(int, removeItemAt);
869     if (removeItemAt >= layoutCount + itemCount)
870         return;
871 
872     SubQGraphicsLinearLayout layout;
873     for (int i = 0; i < itemCount; ++i)
874         layout.addItem(new QGraphicsWidget);
875     for (int i = 0; i < layoutCount; ++i)
876         layout.addItem(new SubQGraphicsLinearLayout);
877 
878     QGraphicsLayoutItem *w = 0;
879     if (removeItemAt >= 0 && removeItemAt < layout.count())
880         w = layout.itemAt(removeItemAt);
881     QSizeF oldSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
882     if (w) {
883         layout.removeItem(w);
884         delete w;
885     }
886     QCOMPARE(layout.count(), itemCount + layoutCount - (w ? 1 : 0));
887 
888     layout.activate();
889     QSizeF newSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
890     QVERIFY(oldSizeHint.width() >= newSizeHint.width());
891 }
892 
setGeometry_data()893 void tst_QGraphicsLinearLayout::setGeometry_data()
894 {
895     QTest::addColumn<QRectF>("rect");
896     QTest::newRow("null") << QRectF();
897     QTest::newRow("small") << QRectF(0, 0, 10, 10);
898 }
899 
900 // void setGeometry(QRectF const& rect) public
setGeometry()901 void tst_QGraphicsLinearLayout::setGeometry()
902 {
903     QFETCH(QRectF, rect);
904     QGraphicsScene scene;
905     QGraphicsView view(&scene);
906     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
907     SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
908     scene.addItem(widget);
909     widget->setLayout(&layout);
910     widget->setContentsMargins(0, 0, 0, 0);
911     layout.setContentsMargins(0, 0, 0, 0);
912     layout.setMaximumSize(100, 100);
913     view.show();
914     widget->show();
915     QApplication::processEvents();
916     widget->setGeometry(rect);
917     QCOMPARE(layout.geometry(), rect);
918     // see also geometry()
919     delete widget;
920 }
921 
setSpacing_data()922 void tst_QGraphicsLinearLayout::setSpacing_data()
923 {
924     QTest::addColumn<qreal>("spacing");
925     QTest::newRow("0") << (qreal)0;
926     QTest::newRow("5") << (qreal)5;
927     QTest::newRow("3.3") << (qreal)3.3;
928     QTest::newRow("-4.3") << (qreal)4.3;
929 }
930 
931 // void setSpacing(qreal spacing) public
setSpacing()932 void tst_QGraphicsLinearLayout::setSpacing()
933 {
934     QFETCH(qreal, spacing);
935 
936     QGraphicsScene scene;
937     QGraphicsView view(&scene);
938     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
939     SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
940     scene.addItem(widget);
941     widget->setLayout(&layout);
942     layout.setContentsMargins(0, 0, 0, 0);
943 
944     qreal oldSpacing = layout.spacing();
945     if (oldSpacing != -1) {
946         for (int i = 0; i < 3; ++i)
947             layout.addItem(new QGraphicsWidget);
948         QSizeF oldSizeHint = layout.sizeHint(Qt::PreferredSize);
949 
950         layout.setSpacing(spacing);
951         QCOMPARE(layout.spacing(), spacing);
952 
953         view.show();
954         widget->show();
955         QApplication::processEvents();
956         QSizeF newSizeHint = layout.sizeHint(Qt::PreferredSize);
957 
958         QCOMPARE(oldSizeHint.width() - oldSpacing * 2, newSizeHint.width() - spacing * 2);
959     } else {
960         QSKIP("This style uses non-uniform spacings (layoutSpacingImplementation() is reimplemented)", SkipAll);
961     }
962     delete widget;
963 }
964 
setItemSpacing_data()965 void tst_QGraphicsLinearLayout::setItemSpacing_data()
966 {
967     QTest::addColumn<int>("index");
968     QTest::addColumn<int>("spacing");
969 
970     QTest::newRow("0 at 0") << 0 << 0;
971     QTest::newRow("10 at 0") << 0 << 10;
972     QTest::newRow("10 at 1") << 1 << 10;
973     QTest::newRow("10 at the end") << 4 << 10;
974 }
975 
setItemSpacing()976 void tst_QGraphicsLinearLayout::setItemSpacing()
977 {
978     QFETCH(int, index);
979     QFETCH(int, spacing);
980 
981     QGraphicsScene scene;
982     QGraphicsView view(&scene);
983     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
984     SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout;
985     scene.addItem(widget);
986     widget->setLayout(layout);
987     layout->setContentsMargins(0, 0, 0, 0);
988     for (int i = 0; i < 5; ++i) {
989         QGraphicsWidget *w = new QGraphicsWidget;
990         layout->addItem(w);
991     }
992     QSizeF oldSizeHint = layout->sizeHint(Qt::PreferredSize);
993     qreal oldSpacing = 0;
994     if (index < layout->count() - 1)
995         oldSpacing = layout->spacing();
996     else
997         spacing = 0;
998 
999     layout->setItemSpacing(index, spacing);
1000     view.show();
1001     QApplication::processEvents();
1002     QSizeF newSizeHint = layout->sizeHint(Qt::PreferredSize);
1003     if (oldSpacing >= 0) {
1004         QCOMPARE(newSizeHint.width() - spacing, oldSizeHint.width() - oldSpacing);
1005     } else {
1006         QSKIP("This style uses non-uniform spacings (layoutSpacingImplementation() is reimplemented)", SkipAll);
1007     }
1008     delete widget;
1009 }
1010 
itemSpacing()1011 void tst_QGraphicsLinearLayout::itemSpacing()
1012 {
1013     QGraphicsScene scene;
1014     QGraphicsView view(&scene);
1015     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
1016     SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout;
1017     scene.addItem(widget);
1018     widget->setLayout(layout);
1019     layout->setContentsMargins(0, 0, 0, 0);
1020     for (int i = 0; i < 5; ++i) {
1021         QGraphicsWidget *w = new QGraphicsWidget;
1022         layout->addItem(w);
1023     }
1024 
1025     // Check defaults
1026     qreal defaultSpacing = layout->spacing();
1027     if (defaultSpacing >= 0) {
1028         QCOMPARE(layout->itemSpacing(0), defaultSpacing);
1029     } else {
1030         // all widgets are the same, so the spacing should be uniform
1031         QCOMPARE(layout->itemSpacing(0), layout->itemSpacing(1));
1032     }
1033 
1034     layout->setItemSpacing(1, 42);
1035     QCOMPARE(layout->itemSpacing(1), qreal(42));
1036 
1037     // try to unset
1038     layout->setItemSpacing(1, -1);
1039     QCOMPARE(layout->itemSpacing(1), defaultSpacing);
1040 
1041     delete widget;
1042 }
1043 
1044 /**
1045  * The stretch factors are not applied linearly, but they are used together with both the preferred size, maximum size to form the
1046  * internal effective stretch factor.
1047  * There is only need to apply stretch factors if the size of the layout is different than the layouts preferred size.
1048  * (If the size of the layout is the preferred size, then all items should get their preferred sizes.
1049  * However, imagine this use case:
1050  * Layout
1051  *          +----------+----------+----------+
1052  * name     |    A     |    B     |    C     |
1053  * stretch  |    1     |    2     |    3     |
1054  * sizehints|[5,10,50] |[5,10,50] |[5,10,50] |
1055  *          +----------+----------+----------+
1056  *
1057  * layout->resize(120, h)
1058  *
1059  * In QLayout, C would become 50, B would become 50 and A would get 20. When scaling a layout this would give a jerky feeling, since
1060  * the item with the highest stretch factor will first resize. When that has reached its maximum the next candidate for stretch will
1061  * resize, and finally, item with the lowest stretch factor will resize.
1062  * In QGraphicsLinearLayout we try to scale all items so that they all reach their maximum at the same time. This means that
1063  * their relative sizes are not proportional to their stretch factors.
1064  */
1065 
1066 typedef QList<int> IntList;
1067 Q_DECLARE_METATYPE(IntList)
Q_DECLARE_METATYPE(qreal)1068 Q_DECLARE_METATYPE(qreal)
1069 
1070 void tst_QGraphicsLinearLayout::setStretchFactor_data()
1071 {
1072     QTest::addColumn<qreal>("totalSize");
1073     QTest::addColumn<IntList>("stretches");
1074 
1075     QTest::newRow(QString("60 [1,2]").toLatin1()) << qreal(60.0) << (IntList() << 1 << 2);
1076     QTest::newRow(QString("60 [1,2,3]").toLatin1()) << qreal(60.0) << (IntList() << 1 << 2 << 3);
1077     QTest::newRow(QString("120 [1,2,3,6]").toLatin1()) << qreal(120.0) << (IntList() << 1 << 2 << 3 << 6);
1078 }
1079 
1080 // void setStretchFactor(QGraphicsLayoutItem* item, int stretch) public
setStretchFactor()1081 void tst_QGraphicsLinearLayout::setStretchFactor()
1082 {
1083     QFETCH(qreal, totalSize);
1084     QFETCH(IntList, stretches);
1085     //QSKIP("Seems to be some problems with stretch factors. Talk with Jasmin", SkipAll);
1086     QGraphicsScene scene;
1087     QGraphicsView view(&scene);
1088     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
1089     SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
1090     scene.addItem(widget);
1091     widget->setLayout(&layout);
1092     layout.setContentsMargins(0, 0, 0, 0);
1093     layout.setSpacing(0.0);
1094     widget->setContentsMargins(0, 0, 0, 0);
1095 
1096 
1097     int i;
1098     for (i = 0; i < stretches.count(); ++i) {
1099         QGraphicsWidget *item = new RectWidget(widget);
1100         item->setMinimumSize(5,5);
1101         item->setPreferredSize(10,5);
1102         item->setMaximumSize(50,5);
1103         layout.addItem(item);
1104         layout.setStretchFactor(item, stretches.at(i));
1105     }
1106 
1107     widget->resize(totalSize, 10);
1108     QApplication::processEvents();
1109 
1110     view.show();
1111     widget->show();
1112 
1113     qreal firstStretch = -1;
1114     qreal firstExtent = -1.;
1115     qreal sumExtent = 0;
1116     for (i = 0; i < stretches.count(); ++i) {
1117         QGraphicsWidget *item = static_cast<QGraphicsWidget*>(layout.itemAt(i));
1118         qreal extent = item->size().width();
1119         qreal stretch = (qreal)stretches.at(i);
1120         if (firstStretch != -1 && firstExtent != -1) {
1121             // The resulting widths does not correspond linearly to the stretch factors.
1122             if (stretch == firstStretch)
1123                 QCOMPARE(extent, firstExtent);
1124             else if (stretch > firstStretch)
1125                 QVERIFY(extent > firstExtent);
1126             else
1127                 QVERIFY(extent < firstExtent);
1128         } else {
1129             firstStretch = (qreal)stretch;
1130             firstExtent = extent;
1131         }
1132         sumExtent+= extent;
1133     }
1134     QCOMPARE(sumExtent, totalSize);
1135 
1136     delete widget;
1137 }
1138 
testStretch()1139 void tst_QGraphicsLinearLayout::testStretch()
1140 {
1141     QGraphicsScene scene;
1142     QGraphicsView *view = new QGraphicsView(&scene);
1143     QGraphicsWidget *form = new QGraphicsWidget(0, Qt::Window);
1144 
1145     scene.addItem(form);
1146     form->setMinimumSize(600, 600);
1147     form->setMaximumSize(600, 600);
1148     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal, form);
1149     QGraphicsWidget *w1 = new RectWidget;
1150     w1->setPreferredSize(100,100);
1151     w1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
1152     QGraphicsWidget *w2 = new RectWidget;
1153     w2->setPreferredSize(200,200);
1154     w2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
1155     layout->setSpacing(0);
1156     layout->setContentsMargins(0, 0, 0, 0);
1157     layout->addItem(w1);
1158     layout->addStretch(2);
1159     layout->addItem(w2);
1160     QCOMPARE(layout->count(), 2);
1161     QVERIFY(layout->itemAt(0) == w1);
1162     QVERIFY(layout->itemAt(1) == w2);
1163     layout->activate();
1164 
1165     //view->setSceneRect(-50, -50, 800, 800);
1166     //view->show();
1167     //QTest::qWaitForWindowShown(view);
1168     //QTest::qWait(5000);
1169     QCOMPARE(form->geometry().size(), QSizeF(600,600));
1170     QCOMPARE(w1->geometry(), QRectF(0, 0, 100, 100));
1171     QCOMPARE(w2->geometry(), QRectF(400, 0, 200, 200));
1172 }
1173 
defaultStretchFactors_data()1174 void tst_QGraphicsLinearLayout::defaultStretchFactors_data()
1175 {
1176     QTest::addColumn<Qt::Orientation>("orientation");
1177     QTest::addColumn<int>("count");
1178     QTest::addColumn<IntList>("preferredSizeHints");
1179     QTest::addColumn<IntList>("stretches");
1180     QTest::addColumn<IntList>("ignoreFlag");
1181     QTest::addColumn<QSizeF>("newSize");
1182     QTest::addColumn<IntList>("expectedSizes");
1183 
1184     QTest::newRow("hor") << Qt::Horizontal << 3
1185                             << (IntList() << 20 << 40 << 60)
1186                             << (IntList())
1187                             << (IntList())
1188                             << QSizeF()
1189                             << (IntList() << 20 << 40 << 60);
1190 
1191     QTest::newRow("ver") << Qt::Vertical << 3
1192                             << (IntList() << 20 << 40 << 60)
1193                             << (IntList())
1194                             << (IntList())
1195                             << QSizeF()
1196                             << (IntList() << 20 << 40 << 60);
1197 
1198     QTest::newRow("hor,ignore123") << Qt::Horizontal << 3
1199                             << (IntList() << 20 << 40 << 60)
1200                             << (IntList())
1201                             << (IntList() << 1 << 1 << 1)
1202                             << QSizeF()
1203                             << (IntList() << 0 << 0 << 0);
1204 
1205     QTest::newRow("hor,ignore23") << Qt::Horizontal << 3
1206                             << (IntList() << 10 << 10 << 10)
1207                             << (IntList())
1208                             << (IntList() << 0 << 1 << 1)
1209                             << QSizeF(200, 50)
1210                             << (IntList());     //### stretches are not linear.
1211 
1212     QTest::newRow("hor,ignore2") << Qt::Horizontal << 3
1213                             << (IntList() << 10 << 10 << 10)
1214                             << (IntList())
1215                             << (IntList() << 0 << 1 << 0)
1216                             << QSizeF()
1217                             << (IntList() << 10 << 0 << 10);
1218 
1219 }
1220 
defaultStretchFactors()1221 void tst_QGraphicsLinearLayout::defaultStretchFactors()
1222 {
1223     QFETCH(Qt::Orientation, orientation);
1224     QFETCH(int, count);
1225     QFETCH(IntList, preferredSizeHints);
1226     QFETCH(IntList, stretches);
1227     QFETCH(IntList, ignoreFlag);
1228     QFETCH(QSizeF, newSize);
1229     QFETCH(IntList, expectedSizes);
1230 
1231     QGraphicsScene scene;
1232     QGraphicsView view(&scene);
1233     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
1234     SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout(orientation);
1235     scene.addItem(widget);
1236     widget->setLayout(layout);
1237     layout->setContentsMargins(0, 0, 0, 0);
1238     layout->setSpacing(0.0);
1239     widget->setContentsMargins(0, 0, 0, 0);
1240 
1241     int i;
1242     for (i = 0; i < count; ++i) {
1243         RectWidget *item = new RectWidget(widget);
1244         layout->addItem(item);
1245         if (preferredSizeHints.value(i, -1) >= 0) {
1246             item->setSizeHint(Qt::PreferredSize, QSizeF(preferredSizeHints.at(i), preferredSizeHints.at(i)));
1247         }
1248         if (stretches.value(i, -1) >= 0) {
1249             layout->setStretchFactor(item, stretches.at(i));
1250         }
1251         if (ignoreFlag.value(i, 0) != 0) {
1252             QSizePolicy sp = item->sizePolicy();
1253             if (orientation == Qt::Horizontal)
1254                 sp.setHorizontalPolicy(QSizePolicy::Policy(sp.horizontalPolicy() | QSizePolicy::IgnoreFlag));
1255             else
1256                 sp.setVerticalPolicy(QSizePolicy::Policy(sp.verticalPolicy() | QSizePolicy::IgnoreFlag));
1257             item->setSizePolicy(sp);
1258         }
1259     }
1260 
1261     QApplication::processEvents();
1262 
1263     widget->show();
1264     view.show();
1265     view.resize(400,300);
1266     if (newSize.isValid())
1267         widget->resize(newSize);
1268 
1269     QApplication::processEvents();
1270     for (i = 0; i < count; ++i) {
1271         QSizeF itemSize = layout->itemAt(i)->geometry().size();
1272         if (orientation == Qt::Vertical)
1273             itemSize.transpose();
1274         if (i < expectedSizes.count())
1275             QCOMPARE(itemSize.width(), qreal(expectedSizes.at(i)));
1276     }
1277 
1278     delete widget;
1279 }
1280 
Q_DECLARE_METATYPE(Qt::SizeHint)1281 Q_DECLARE_METATYPE(Qt::SizeHint)
1282 void tst_QGraphicsLinearLayout::sizeHint_data()
1283 {
1284     QTest::addColumn<Qt::SizeHint>("which");
1285     QTest::addColumn<QSizeF>("constraint");
1286     QTest::addColumn<qreal>("spacing");
1287     QTest::addColumn<qreal>("layoutMargin");
1288     QTest::addColumn<QSizeF>("sizeHint");
1289 
1290     QTest::newRow("minimumSize") << Qt::MinimumSize << QSizeF() << qreal(0.0) << qreal(0.0) << QSizeF(30, 10);
1291     QTest::newRow("preferredSize") << Qt::PreferredSize << QSizeF() << qreal(0.0) << qreal(0.0) << QSizeF(75, 25);
1292     QTest::newRow("maximumSize") << Qt::MaximumSize << QSizeF() << qreal(0.0) << qreal(0.0) << QSizeF(150, 50);
1293     QTest::newRow("minimumSize, spacing=3") << Qt::MinimumSize << QSizeF() << qreal(3.0) << qreal(0.0) << QSizeF(30 + 2*3, 10);
1294     QTest::newRow("minimumSize, spacing=3, layoutMargin=10") << Qt::MinimumSize << QSizeF() << qreal(3.0) << qreal(10.0) << QSizeF(30 + 2*3 + 2*10, 10 + 2*10);
1295     QTest::newRow("minimumSize, spacing=0, layoutMargin=7") << Qt::MinimumSize << QSizeF() << qreal(0.0) << qreal(7.0) << QSizeF(30 + 0 + 2*7, 10 + 2*7);
1296 }
1297 
1298 // QSizeF sizeHint(Qt::SizeHint which, QSizeF const& constraint) const public
sizeHint()1299 void tst_QGraphicsLinearLayout::sizeHint()
1300 {
1301     QFETCH(Qt::SizeHint, which);
1302     QFETCH(QSizeF, constraint);
1303     QFETCH(qreal, spacing);
1304     QFETCH(qreal, layoutMargin);
1305     QFETCH(QSizeF, sizeHint);
1306 
1307     QGraphicsScene scene;
1308     QGraphicsView view(&scene);
1309     QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
1310     SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
1311     scene.addItem(widget);
1312     widget->setLayout(&layout);
1313     layout.setContentsMargins(layoutMargin, layoutMargin, layoutMargin, layoutMargin);
1314     layout.setSpacing(spacing);
1315     for (int i = 0; i < 3; ++i) {
1316         QGraphicsWidget *item = new QGraphicsWidget(widget);
1317         item->setMinimumSize(10, 10);
1318         item->setPreferredSize(25, 25);
1319         item->setMaximumSize(50, 50);
1320         layout.addItem(item);
1321     }
1322     QApplication::processEvents();
1323     QCOMPARE(layout.sizeHint(which, constraint), sizeHint);
1324     delete widget;
1325 }
1326 
updateGeometry()1327 void tst_QGraphicsLinearLayout::updateGeometry()
1328 {
1329     QGraphicsScene scene;
1330     QGraphicsView view(&scene);
1331 
1332     QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window);
1333     QGraphicsWidget *w1 = new QGraphicsWidget(window);
1334     w1->setMinimumSize(100, 40);
1335     SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout;
1336     layout->addItem(w1);
1337     scene.addItem(window);
1338     window->setLayout(layout);
1339     layout->setContentsMargins(0, 0, 0, 0);
1340     QCOMPARE(w1->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(layout));
1341     QCOMPARE(layout->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(window));
1342 
1343     view.show();
1344     QApplication::processEvents();
1345     QCOMPARE(window->size().toSize(), QSize(100, 50));
1346     w1->setMinimumSize(110, 60);
1347     QApplication::processEvents();
1348     QCOMPARE(window->size().toSize(), QSize(110, 60));
1349     QApplication::processEvents();
1350 
1351     {
1352         delete window;
1353         window = new QGraphicsWidget(0, Qt::Window);
1354         SubQGraphicsLinearLayout *layout2a = new SubQGraphicsLinearLayout;
1355         QGraphicsWidget *w1 = new QGraphicsWidget(window);
1356         w1->setMinimumSize(110, 50);
1357         layout2a->addItem(w1);
1358         SubQGraphicsLinearLayout *layout2 = new SubQGraphicsLinearLayout;
1359         layout2->addItem(layout2a);
1360         layout2->setContentsMargins(1, 1, 1, 1);
1361         layout2a->setContentsMargins(1, 1, 1, 1);
1362         window->setLayout(layout2);
1363         QApplication::processEvents();
1364         QCOMPARE(w1->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(layout2a));
1365         QCOMPARE(layout2a->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(layout2));
1366         QCOMPARE(layout2->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(window));
1367         QCOMPARE(window->size().toSize(), QSize(114, 54));
1368         QApplication::processEvents();
1369         w1->setMinimumSize(120, 60);
1370         QApplication::processEvents();
1371         QCOMPARE(window->size().toSize(), QSize(124, 64));
1372     }
1373 
1374     {
1375         delete window;
1376         window = new QGraphicsWidget(0, Qt::Window);
1377         scene.addItem(window);
1378         window->show();
1379         QGraphicsWidget *w1 = new QGraphicsWidget(window);
1380         w1->setMinimumSize(100, 50);
1381         SubQGraphicsLinearLayout *layout2a = new SubQGraphicsLinearLayout;
1382         layout2a->addItem(w1);
1383         SubQGraphicsLinearLayout *layout2 = new SubQGraphicsLinearLayout;
1384         layout2->addItem(layout2a);
1385         layout2a->setContentsMargins(1, 1, 1, 1);
1386         window->setLayout(layout2);
1387         QApplication::processEvents();
1388         qreal left, top, right, bottom;
1389         layout2->getContentsMargins(&left, &top, &right, &bottom);
1390         QCOMPARE(window->size().toSize(), QSize(102 +left + right, 52 + top + bottom));
1391     }
1392 
1393     {
1394         delete window;
1395         window = new QGraphicsWidget(0, Qt::Window);
1396         scene.addItem(window);
1397         QGraphicsWidget *w1 = new QGraphicsWidget(window);
1398         w1->setMinimumSize(100, 50);
1399         window->setLayout(0);
1400         SubQGraphicsLinearLayout *layout2a = new SubQGraphicsLinearLayout;
1401         layout2a->addItem(w1);
1402         SubQGraphicsLinearLayout *layout2 = new SubQGraphicsLinearLayout;
1403         layout2->addItem(layout2a);
1404         window->resize(200, 80);
1405         window->setLayout(layout2);
1406         window->show();
1407         QApplication::processEvents();
1408         QCOMPARE(window->size().toSize(), QSize(200, 80));
1409     }
1410 
1411 }
1412 
layoutDirection()1413 void tst_QGraphicsLinearLayout::layoutDirection()
1414 {
1415     QGraphicsScene scene;
1416     QGraphicsView view(&scene);
1417 
1418     QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window);
1419     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
1420     layout->setContentsMargins(1, 2, 3, 4);
1421     layout->setSpacing(6);
1422 
1423     RectWidget *w1 = new RectWidget;
1424     w1->setPreferredSize(20, 20);
1425     w1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
1426     layout->addItem(w1);
1427     RectWidget *w2 = new RectWidget;
1428     w2->setPreferredSize(20, 20);
1429     w2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
1430     layout->addItem(w2);
1431 
1432     scene.addItem(window);
1433     window->setLayout(layout);
1434     view.show();
1435     window->resize(50, 20);
1436     window->setLayoutDirection(Qt::LeftToRight);
1437     QApplication::processEvents();
1438     QCOMPARE(w1->geometry().left(), 1.0);
1439     QCOMPARE(w1->geometry().right(), 21.0);
1440     QCOMPARE(w2->geometry().left(), 27.0);
1441     QCOMPARE(w2->geometry().right(), 47.0);
1442 
1443     window->setLayoutDirection(Qt::RightToLeft);
1444     QApplication::processEvents();
1445     QCOMPARE(w1->geometry().right(), 49.0);
1446     QCOMPARE(w1->geometry().left(), 29.0);
1447     QCOMPARE(w2->geometry().right(), 23.0);
1448     QCOMPARE(w2->geometry().left(),  3.0);
1449 
1450     delete window;
1451 }
1452 
removeLayout()1453 void tst_QGraphicsLinearLayout::removeLayout()
1454 {
1455     QGraphicsScene scene;
1456     RectWidget *textEdit = new RectWidget;
1457     RectWidget *pushButton = new RectWidget;
1458     scene.addItem(textEdit);
1459     scene.addItem(pushButton);
1460 
1461     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
1462     layout->addItem(textEdit);
1463     layout->addItem(pushButton);
1464 
1465     QGraphicsWidget *form = new QGraphicsWidget;
1466     form->setLayout(layout);
1467     scene.addItem(form);
1468 
1469     QGraphicsView view(&scene);
1470     view.show();
1471     QTest::qWait(20);
1472 
1473     QRectF r1 = textEdit->geometry();
1474     QRectF r2 = pushButton->geometry();
1475     form->setLayout(0);
1476     //documentation of QGraphicsWidget::setLayout:
1477     //If layout is 0, the widget is left without a layout. Existing subwidgets' geometries will remain unaffected.
1478     QCOMPARE(textEdit->geometry(), r1);
1479     QCOMPARE(pushButton->geometry(), r2);
1480 }
1481 
avoidRecursionInInsertItem()1482 void tst_QGraphicsLinearLayout::avoidRecursionInInsertItem()
1483 {
1484     QGraphicsWidget window(0, Qt::Window);
1485 	QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(&window);
1486     QCOMPARE(layout->count(), 0);
1487     QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::insertItem: cannot insert itself");
1488     layout->insertItem(0, layout);
1489     QCOMPARE(layout->count(), 0);
1490 }
1491 
styleInfoLeak()1492 void tst_QGraphicsLinearLayout::styleInfoLeak()
1493 {
1494     QGraphicsLinearLayout layout;
1495     layout.spacing();
1496 }
1497 
task218400_insertStretchCrash()1498 void tst_QGraphicsLinearLayout::task218400_insertStretchCrash()
1499 {
1500     QGraphicsScene *scene = new QGraphicsScene;
1501     QGraphicsWidget *a = scene->addWidget(new QWidget);
1502     QGraphicsWidget *b = scene->addWidget(new QWidget);
1503 
1504     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
1505     layout->addItem(a);
1506     layout->addItem(b);
1507     layout->insertStretch(0); // inserts gap in item grid in the layout engine
1508 
1509     QGraphicsWidget *form  = new QGraphicsWidget;
1510     form->setLayout(layout); // crash
1511 }
1512 
testAlignmentInLargerLayout()1513 void tst_QGraphicsLinearLayout::testAlignmentInLargerLayout()
1514 {
1515     QGraphicsScene *scene = new QGraphicsScene;
1516     QGraphicsWidget *form = new QGraphicsWidget;
1517     scene->addItem(form);
1518     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, form);
1519     layout->setSpacing(0);
1520     layout->setContentsMargins(0,0,0,0);
1521 
1522     QGraphicsWidget *a = new QGraphicsWidget;
1523     a->setMaximumSize(100,100);
1524     layout->addItem(a);
1525 
1526     QCOMPARE(form->maximumSize(), QSizeF(100,100));
1527     QCOMPARE(layout->maximumSize(), QSizeF(100,100));
1528     layout->setMinimumSize(QSizeF(200,200));
1529     layout->setMaximumSize(QSizeF(200,200));
1530 
1531     layout->setAlignment(a, Qt::AlignCenter);
1532     layout->activate();
1533     QCOMPARE(a->geometry(), QRectF(50,50,100,100));
1534 
1535     layout->setAlignment(a, Qt::AlignRight | Qt::AlignBottom);
1536     layout->activate();
1537     QCOMPARE(a->geometry(), QRectF(100,100,100,100));
1538 
1539     layout->setAlignment(a, Qt::AlignHCenter | Qt::AlignTop);
1540     layout->activate();
1541     QCOMPARE(a->geometry(), QRectF(50,0,100,100));
1542 
1543     QGraphicsWidget *b = new QGraphicsWidget;
1544     b->setMaximumSize(100,100);
1545     layout->addItem(b);
1546 
1547     layout->setAlignment(a, Qt::AlignCenter);
1548     layout->setAlignment(b, Qt::AlignCenter);
1549     layout->activate();
1550     QCOMPARE(a->geometry(), QRectF(50,0,100,100));
1551     QCOMPARE(b->geometry(), QRectF(50,100,100,100));
1552 
1553     layout->setAlignment(a, Qt::AlignRight | Qt::AlignBottom);
1554     layout->setAlignment(b, Qt::AlignLeft | Qt::AlignTop);
1555     layout->activate();
1556     QCOMPARE(a->geometry(), QRectF(100,0,100,100));
1557     QCOMPARE(b->geometry(), QRectF(0,100,100,100));
1558 }
1559 
testOffByOneInLargerLayout()1560 void tst_QGraphicsLinearLayout::testOffByOneInLargerLayout() {
1561     QGraphicsScene *scene = new QGraphicsScene;
1562     QGraphicsWidget *form = new QGraphicsWidget;
1563     scene->addItem(form);
1564     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, form);
1565     layout->setSpacing(0);
1566     layout->setContentsMargins(0,0,0,0);
1567 
1568     QGraphicsWidget *a = new QGraphicsWidget;
1569     QGraphicsWidget *b = new QGraphicsWidget;
1570     a->setMaximumSize(100,100);
1571     b->setMaximumSize(100,100);
1572     layout->addItem(a);
1573     layout->addItem(b);
1574 
1575     layout->setAlignment(a, Qt::AlignRight | Qt::AlignBottom);
1576     layout->setAlignment(b, Qt::AlignLeft | Qt::AlignTop);
1577     layout->setMinimumSize(QSizeF(101,201));
1578     layout->setMaximumSize(QSizeF(101,201));
1579     layout->activate();
1580     QCOMPARE(a->geometry(), QRectF(1,0.5,100,100));
1581     QCOMPARE(b->geometry(), QRectF(0,100.5,100,100));
1582 
1583     layout->setMinimumSize(QSizeF(100,200));
1584     layout->setMaximumSize(QSizeF(100,200));
1585     layout->activate();
1586     QCOMPARE(a->geometry(), QRectF(0,0,100,100));
1587     QCOMPARE(b->geometry(), QRectF(0,100,100,100));
1588 
1589     layout->setMinimumSize(QSizeF(99,199));
1590     layout->setMaximumSize(QSizeF(99,199));
1591     layout->activate();
1592     QCOMPARE(a->geometry(), QRectF(0,0,99,99.5));
1593     QCOMPARE(b->geometry(), QRectF(0,99.5,99,99.5));
1594 }
testDefaultAlignment()1595 void tst_QGraphicsLinearLayout::testDefaultAlignment()
1596 {
1597     QGraphicsWidget *widget = new QGraphicsWidget;
1598     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, widget);
1599     layout->setContentsMargins(0, 0, 0, 0);
1600     layout->setSpacing(0);
1601 
1602     QGraphicsWidget *w = new QGraphicsWidget;
1603     w->setMinimumSize(50,50);
1604     w->setMaximumSize(50,50);
1605     layout->addItem(w);
1606 
1607     //Default alignment should be to the top-left
1608     QCOMPARE(layout->alignment(w), 0);
1609 
1610     //First, check by forcing the layout to be bigger
1611     layout->setMinimumSize(100,100);
1612     layout->activate();
1613     QCOMPARE(layout->geometry(), QRectF(0,0,100,100));
1614     QCOMPARE(w->geometry(), QRectF(0,0,50,50));
1615     layout->setMinimumSize(-1,-1);
1616 
1617     //Second, check by adding a larger item in the column
1618     QGraphicsWidget *w2 = new QGraphicsWidget;
1619     w2->setMinimumSize(100,100);
1620     w2->setMaximumSize(100,100);
1621     layout->addItem(w2);
1622     layout->activate();
1623     QCOMPARE(layout->geometry(), QRectF(0,0,100,150));
1624     QCOMPARE(w->geometry(), QRectF(0,0,50,50));
1625     QCOMPARE(w2->geometry(), QRectF(0,50,100,100));
1626 }
1627 
combineSizePolicies()1628 void tst_QGraphicsLinearLayout::combineSizePolicies()
1629 {
1630     QGraphicsWidget *widget = new QGraphicsWidget;
1631     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal, widget);
1632     layout->setContentsMargins(0, 0, 0, 0);
1633     layout->setSpacing(0);
1634 
1635     QGraphicsWidget *w1 = new QGraphicsWidget;
1636     w1->setMaximumSize(200,200);
1637     w1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
1638     layout->addItem(w1);
1639 
1640     QGraphicsWidget *w2 = new QGraphicsWidget;
1641     w2->setPreferredSize(50,50);
1642     w2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
1643     layout->addItem(w2);
1644     QCOMPARE(layout->maximumHeight(), qreal(200));
1645 
1646     // now remove the fixed vertical size policy, and set instead the maximum height to 50
1647     // this should in effect give the same maximumHeight
1648     w2->setMaximumHeight(50);
1649     w2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
1650     QCOMPARE(layout->maximumHeight(), qreal(200));
1651 }
1652 
hiddenItems()1653 void tst_QGraphicsLinearLayout::hiddenItems()
1654 {
1655     QGraphicsWidget *widget = new QGraphicsWidget;
1656     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal, widget);
1657     layout->setContentsMargins(0, 0, 0, 0);
1658     layout->setSpacing(2);
1659 
1660     RectWidget *w1 = new RectWidget;
1661     w1->setPreferredSize(QSizeF(20, 20));
1662     layout->addItem(w1);
1663 
1664     RectWidget *w2 = new RectWidget;
1665     w2->setPreferredSize(QSizeF(20, 20));
1666     layout->addItem(w2);
1667 
1668     RectWidget *w3 = new RectWidget;
1669     w3->setPreferredSize(QSizeF(20, 20));
1670     layout->addItem(w3);
1671 
1672     QCOMPARE(layout->preferredWidth(), qreal(64));
1673     w2->hide();
1674     QCOMPARE(layout->preferredWidth(), qreal(42));
1675     w2->show();
1676     QCOMPARE(layout->preferredWidth(), qreal(64));
1677 }
1678 
1679 
1680 QTEST_MAIN(tst_QGraphicsLinearLayout)
1681 #include "tst_qgraphicslinearlayout.moc"
1682 
1683