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 #include <QtGui>
43 #include <QtTest/QtTest>
44 #include <QTest>
45 #include <QMetaType>
46 #include <QtGui/qgraphicsanchorlayout.h>
47 #include <private/qgraphicsanchorlayout_p.h>
48 
49 #define TEST_COMPLEX_CASES
50 
51 
52 //---------------------- AnchorLayout helper class ----------------------------
53 class TheAnchorLayout : public QGraphicsAnchorLayout
54 {
55 public:
TheAnchorLayout()56     TheAnchorLayout() : QGraphicsAnchorLayout()
57     {
58         setContentsMargins( 0,0,0,0 );
59         setSpacing( 0 );
60     }
61 
isValid()62     bool isValid()
63     {
64         return !QGraphicsAnchorLayoutPrivate::get(this)->hasConflicts();
65     }
66 
setAnchor(QGraphicsLayoutItem * startItem,Qt::AnchorPoint startEdge,QGraphicsLayoutItem * endItem,Qt::AnchorPoint endEdge,qreal value)67     void setAnchor(
68         QGraphicsLayoutItem *startItem,
69         Qt::AnchorPoint startEdge,
70         QGraphicsLayoutItem *endItem,
71         Qt::AnchorPoint endEdge,
72         qreal value)
73         {
74             QGraphicsAnchor *anchor = addAnchor( startItem, startEdge, endItem, endEdge);
75             if (anchor)
76                 anchor->setSpacing(value);
77         }
78 
indexOf(const QGraphicsLayoutItem * item) const79     int indexOf(const QGraphicsLayoutItem* item) const
80     {
81         for ( int i=0; i< count(); i++) {
82             if ( itemAt(i) == item ) {
83                 return i;
84             }
85         }
86         return -1;
87     }
88 
removeItem(QGraphicsLayoutItem * item)89     void removeItem(QGraphicsLayoutItem* item)
90     {
91         removeAt(indexOf(item));
92     }
93 
removeAnchor(QGraphicsLayoutItem * startItem,Qt::AnchorPoint startEdge,QGraphicsLayoutItem * endItem,Qt::AnchorPoint endEdge)94     void removeAnchor(
95         QGraphicsLayoutItem *startItem,
96         Qt::AnchorPoint startEdge,
97         QGraphicsLayoutItem *endItem,
98         Qt::AnchorPoint endEdge)
99         {
100             delete QGraphicsAnchorLayout::anchor(startItem, startEdge, endItem, endEdge);
101         }
102 };
103 //-----------------------------------------------------------------------------
104 
105 
106 struct BasicLayoutTestData
107 {
BasicLayoutTestDataBasicLayoutTestData108     inline BasicLayoutTestData(
109         int index1, Qt::AnchorPoint edge1,
110         int index2, Qt::AnchorPoint edge2,
111         qreal distance)
112         : firstIndex(index1), firstEdge(edge1),
113           secondIndex(index2), secondEdge(edge2),
114           spacing(distance)
115         {
116         }
117 
118     int firstIndex;
119     Qt::AnchorPoint firstEdge;
120     int secondIndex;
121     Qt::AnchorPoint secondEdge;
122     qreal spacing;
123 };
124 
125 struct AnchorItemSizeHint
126 {
AnchorItemSizeHintAnchorItemSizeHint127     inline AnchorItemSizeHint(
128         qreal hmin, qreal hpref, qreal hmax,
129         qreal vmin, qreal vpref, qreal vmax )
130         : hmin(hmin), hpref(hpref), hmax(hmax), vmin(vmin), vpref(vpref), vmax(vmax)
131         {
132         }
133     qreal hmin, hpref, hmax;
134     qreal vmin, vpref, vmax;
135 };
136 
137 // some test results
138 
139 struct BasicLayoutTestResult
140 {
BasicLayoutTestResultBasicLayoutTestResult141     inline BasicLayoutTestResult(
142         int resultIndex, const QRectF& resultRect )
143         : index(resultIndex), rect(resultRect)
144         {
145         }
146 
147     int index;
148     QRectF rect;
149 };
150 
151 typedef QList<BasicLayoutTestData> BasicLayoutTestDataList;
152 Q_DECLARE_METATYPE(BasicLayoutTestDataList)
153 
154 typedef QList<BasicLayoutTestResult> BasicLayoutTestResultList;
155 Q_DECLARE_METATYPE(BasicLayoutTestResultList)
156 
157 typedef QList<AnchorItemSizeHint> AnchorItemSizeHintList;
158 Q_DECLARE_METATYPE(AnchorItemSizeHintList)
159 
160 
161 //---------------------- Test Widget used on all tests ------------------------
162 class TestWidget : public QGraphicsWidget
163 {
164 public:
TestWidget(QGraphicsItem * parent=0,const QString & name=QString ())165     inline TestWidget(QGraphicsItem *parent = 0, const QString &name = QString())
166         : QGraphicsWidget(parent)
167         {
168             setContentsMargins( 0,0,0,0 );
169             if (name.isEmpty())
170                 setData(0, QString::fromAscii("w%1").arg(quintptr(this)));
171             else
172                 setData(0, name);
173         }
~TestWidget()174     ~TestWidget()
175         {
176         }
177 
178 protected:
179     QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const;
180 };
181 
sizeHint(Qt::SizeHint which,const QSizeF & constraint) const182 QSizeF TestWidget::sizeHint(Qt::SizeHint which, const QSizeF &constraint) const
183 {
184     Q_UNUSED( constraint );
185     if (which == Qt::MinimumSize) {
186         return QSizeF(5,5);
187     }
188 
189     if (which == Qt::PreferredSize) {
190         return QSizeF(50,50);
191     }
192 
193     return QSizeF(500,500);
194 }
195 //-----------------------------------------------------------------------------
196 
197 
198 
199 //----------------------------- Test class ------------------------------------
200 class tst_QGraphicsAnchorLayout1 : public QObject
201 {
202     Q_OBJECT
203 
204 private slots:
205     void testCount();
206 
207     void testRemoveAt();
208     void testRemoveItem();
209 
210     void testItemAt();
211     void testIndexOf();
212 
213     void testAddAndRemoveAnchor();
214     void testIsValid();
215     void testSpecialCases();
216 
217     void testBasicLayout_data();
218     void testBasicLayout();
219 
220     void testNegativeSpacing_data();
221     void testNegativeSpacing();
222 
223     void testMixedSpacing_data();
224     void testMixedSpacing();
225 
226     void testMulti_data();
227     void testMulti();
228 
229     void testCenterAnchors_data();
230     void testCenterAnchors();
231 
232     void testRemoveCenterAnchor_data();
233     void testRemoveCenterAnchor();
234 
235     void testSingleSizePolicy_data();
236     void testSingleSizePolicy();
237 
238     void testDoubleSizePolicy_data();
239     void testDoubleSizePolicy();
240 
241     void testSizeDistribution_data();
242     void testSizeDistribution();
243 
244     void testSizeHint();
245 
246 #ifdef TEST_COMPLEX_CASES
247     void testComplexCases_data();
248     void testComplexCases();
249 #endif
250 };
251 
252 
testCount()253 void tst_QGraphicsAnchorLayout1::testCount()
254 {
255     QGraphicsWidget *widget = new QGraphicsWidget;
256 
257     TheAnchorLayout *layout = new TheAnchorLayout();
258     QVERIFY( layout->count() == 0 );
259 
260     TestWidget *widget1 = new TestWidget();
261     layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
262     QCOMPARE( layout->count(), 1 );
263 
264     // adding one more anchor for already added widget should not increase the count
265     layout->setAnchor(layout, Qt::AnchorRight, widget1, Qt::AnchorRight, 1);
266     QCOMPARE( layout->count(), 1 );
267 
268     // create one more widget and attach with anchor layout
269     TestWidget *widget2 = new TestWidget();
270     layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 1);
271     QCOMPARE( layout->count(), 2 );
272 
273     widget->setLayout(layout);
274     delete widget;
275 }
276 
testRemoveAt()277 void tst_QGraphicsAnchorLayout1::testRemoveAt()
278 {
279     TheAnchorLayout *layout = new TheAnchorLayout();
280     QVERIFY( layout->count() == 0 );
281 
282     TestWidget *widget1 = new TestWidget();
283     layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 2);
284     QVERIFY( layout->count() == 1 );
285 
286     TestWidget *widget2 = new TestWidget();
287     layout->setAnchor(widget2, Qt::AnchorLeft, layout, Qt::AnchorLeft, 0.1);
288     QVERIFY( layout->count() == 2 );
289 
290     layout->removeAt(0);
291     QVERIFY( layout->count() == 1 );
292 
293     layout->removeAt(-55);
294     layout->removeAt(55);
295     QVERIFY( layout->count() == 1 );
296 
297     layout->removeAt(0);
298     QVERIFY( layout->count() == 0 );
299 
300     delete layout;
301     delete widget1;
302     delete widget2;
303 }
304 
testRemoveItem()305 void tst_QGraphicsAnchorLayout1::testRemoveItem()
306 {
307     TheAnchorLayout *layout = new TheAnchorLayout();
308     QCOMPARE( layout->count(), 0 );
309 
310     TestWidget *widget1 = new TestWidget();
311     layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 2);
312     QCOMPARE( layout->count(), 1 );
313 
314     TestWidget *widget2 = new TestWidget();
315     layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1);
316     QCOMPARE( layout->count(), 2 );
317 
318     layout->removeItem(0);
319     QCOMPARE( layout->count(), 2 );
320 
321     layout->removeItem(widget1);
322     QCOMPARE( layout->count(), 1 );
323     QCOMPARE( layout->indexOf(widget1), -1 );
324     QCOMPARE( layout->indexOf(widget2), 0 );
325 
326     layout->removeItem(widget1);
327     QCOMPARE( layout->count(), 1 );
328 
329     layout->removeItem(widget2);
330     QVERIFY( layout->count() == 0 );
331 
332     delete layout;
333     delete widget1;
334     delete widget2;
335 }
336 
testItemAt()337 void tst_QGraphicsAnchorLayout1::testItemAt()
338 {
339     QGraphicsWidget *widget = new QGraphicsWidget;
340 
341     TheAnchorLayout *layout = new TheAnchorLayout();
342 
343     TestWidget *widget1 = new TestWidget();
344     TestWidget *widget2 = new TestWidget();
345     TestWidget *widget3 = new TestWidget();
346     TestWidget *widget4 = new TestWidget();
347 
348     layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
349     layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1);
350     layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 0.1);
351     layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1);
352 
353     QVERIFY( layout->itemAt(0) == widget1 );
354 
355     layout->removeAt(0);
356 
357     QVERIFY( layout->itemAt(0) == widget2 );
358 
359     delete widget1;
360 
361     widget->setLayout(layout);
362     delete widget;
363 }
364 
testIndexOf()365 void tst_QGraphicsAnchorLayout1::testIndexOf()
366 {
367     QGraphicsWidget *widget = new QGraphicsWidget;
368 
369     TheAnchorLayout *layout = new TheAnchorLayout();
370 
371     TestWidget *widget1 = new TestWidget();
372     TestWidget *widget2 = new TestWidget();
373     TestWidget *widget3 = new TestWidget();
374     TestWidget *widget4 = new TestWidget();
375 
376     QCOMPARE( layout->indexOf(widget1), -1 );
377 
378     layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
379     layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.1);
380     layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 0.1);
381 
382     QCOMPARE( layout->indexOf(widget4), -1 );
383     layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1);
384 
385     QCOMPARE( layout->count(), 4 );
386     for (int i = 0; i < layout->count(); ++i) {
387         QCOMPARE(layout->indexOf(layout->itemAt(i)), i);
388     }
389 
390     QCOMPARE( layout->indexOf(0), -1 );
391     widget->setLayout(layout);
392     delete widget;
393 }
394 
testAddAndRemoveAnchor()395 void tst_QGraphicsAnchorLayout1::testAddAndRemoveAnchor()
396 {
397     QGraphicsWidget *widget = new QGraphicsWidget;
398 
399     TheAnchorLayout *layout = new TheAnchorLayout();
400 
401     TestWidget *widget1 = new TestWidget();
402     TestWidget *widget2 = new TestWidget();
403     TestWidget *widget3 = new TestWidget();
404     TestWidget *widget4 = new TestWidget();
405     TestWidget *widget5 = new TestWidget();
406 
407     layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
408     layout->setAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 0.5);
409     layout->setAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft, 10);
410     layout->setAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 0.1);
411     QCOMPARE( layout->count(), 4 );
412 
413     // test setting invalid anchors
414     QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor NULL items");
415     layout->setAnchor(0, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
416     QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor NULL items");
417     layout->setAnchor(layout, Qt::AnchorLeft, 0, Qt::AnchorLeft, 1);
418     QCOMPARE( layout->count(), 4 );
419 
420     // test removing invalid anchors
421     layout->removeAnchor(widget4, Qt::AnchorRight, widget1, Qt::AnchorRight);
422 
423     // anchor one horizontal edge with vertical edge. it should not add this widget as a child
424     QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations");
425     layout->setAnchor(layout, Qt::AnchorLeft, widget5, Qt::AnchorTop, 10);
426     QCOMPARE( layout->count(), 4 );
427 
428     // anchor two edges of a widget (to define width / height)
429     QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
430     layout->setAnchor(widget5, Qt::AnchorLeft, widget5, Qt::AnchorRight, 10);
431     // QCOMPARE( layout->count(), 5 );
432     QCOMPARE( layout->count(), 4 );
433 
434     // anchor yet new widget properly
435     layout->setAnchor(layout, Qt::AnchorRight, widget5, Qt::AnchorRight, 20 );
436     QCOMPARE( layout->count(), 5 );
437 
438     // remove anchor for widget1. widget1 should be removed from layout since the
439     // last anchor was removed.
440     layout->removeAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft);
441 
442     QCOMPARE( layout->count(), 4 );
443     QVERIFY( !widget1->parentLayoutItem() );
444 
445     // test that item is not removed from layout if other anchors remain set
446     layout->setAnchor(widget2, Qt::AnchorLeft, widget3, Qt::AnchorRight, 10);
447     layout->removeAnchor(layout, Qt::AnchorLeft, widget2, Qt::AnchorLeft);
448     QCOMPARE( layout->count(), 4 );
449 
450     // remove all the anchors
451     layout->removeAnchor(widget2, Qt::AnchorLeft, widget3, Qt::AnchorRight);
452     layout->removeAnchor(layout, Qt::AnchorLeft, widget3, Qt::AnchorLeft);
453     layout->removeAnchor(layout, Qt::AnchorLeft, widget4, Qt::AnchorLeft);
454     layout->removeAnchor(widget5, Qt::AnchorLeft, widget5, Qt::AnchorRight);
455     layout->removeAnchor(layout, Qt::AnchorRight, widget5, Qt::AnchorRight);
456 
457     QCOMPARE( layout->count(), 0 );
458 
459     // set one anchor "another way round" to get full coverage for "removeAnchor"
460     layout->setAnchor(widget1, Qt::AnchorLeft, layout, Qt::AnchorLeft, 0.1);
461     layout->removeAnchor(widget1, Qt::AnchorLeft, layout, Qt::AnchorLeft);
462 
463     QCOMPARE( layout->count(), 0 );
464 
465     delete widget1;
466     delete widget2;
467     delete widget3;
468     delete widget4;
469     delete widget5;
470 
471     widget->setLayout(layout);
472     delete widget;
473 }
474 
testIsValid()475 void tst_QGraphicsAnchorLayout1::testIsValid()
476 {
477     // Empty, valid
478     {
479     QGraphicsWidget *widget = new QGraphicsWidget;
480     TheAnchorLayout *layout = new TheAnchorLayout();
481     widget->setLayout(layout);
482     widget->setGeometry(QRectF(0,0,100,100));
483 
484     QCOMPARE(layout->isValid(), true);
485     delete widget;
486     }
487 
488     // One widget, valid
489     {
490     QGraphicsWidget *widget = new QGraphicsWidget;
491     TheAnchorLayout *layout = new TheAnchorLayout();
492 
493     TestWidget *widget1 = new TestWidget();
494 
495     layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
496     layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 0.1);
497     layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 0.1);
498     layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 0.1);
499 
500     widget->setLayout(layout);
501 
502     widget->setGeometry(QRectF(0,0,100,100));
503     QCOMPARE(layout->isValid(), true);
504     delete widget;
505     }
506 
507     // Overconstrained one widget, invalid
508     // ### Our understanding is that this case is valid. What happens though,
509     //     is that the layout minimum and maximum vertical size hints become
510     //     the same, 10.1. That means its height is fixed.
511     //     What will "fail" then is the "setGeometry(0, 0, 100, 100)" call,
512     //     after which the layout geometry will be (0, 0, 100, 10.1).
513 
514     {
515     QGraphicsWidget *widget = new QGraphicsWidget;
516     TheAnchorLayout *layout = new TheAnchorLayout();
517 
518     TestWidget *widget1 = new TestWidget();
519 
520     layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
521     layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 0.1);
522     layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 0.1);
523     layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 0.1);
524 
525     layout->setAnchor(widget1, Qt::AnchorTop, layout, Qt::AnchorBottom, 10);
526 
527     widget->setLayout(layout);
528 
529     widget->setGeometry(QRectF(0,0,100,100));
530     QCOMPARE(layout->isValid(), true);
531     delete widget;
532     }
533 
534     // Underconstrained two widgets, valid
535     {
536     QGraphicsWidget *widget = new QGraphicsWidget;
537     TheAnchorLayout *layout = new TheAnchorLayout();
538 
539     TestWidget *widget1 = new TestWidget();
540     TestWidget *widget2 = new TestWidget();
541 
542     // Vertically the layout has floating items. Therefore, we have a conflict
543     layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 0.1);
544     layout->setAnchor(layout, Qt::AnchorRight, widget1, Qt::AnchorRight, -0.1);
545 
546     // Horizontally the layout has floating items. Therefore, we have a conflict
547     layout->setAnchor(layout, Qt::AnchorTop, widget2, Qt::AnchorTop, 0.1);
548     layout->setAnchor(layout, Qt::AnchorBottom, widget2, Qt::AnchorBottom, -0.1);
549 
550     widget->setLayout(layout);
551 
552     widget->setGeometry(QRectF(0,0,100,100));
553     QCOMPARE(layout->isValid(), false);
554     delete widget;
555     }
556 }
557 
testSpecialCases()558 void tst_QGraphicsAnchorLayout1::testSpecialCases()
559 {
560     // One widget, setLayout before defining layouts
561     {
562 #ifdef QT_DEBUG
563     QTest::ignoreMessage(QtWarningMsg, "QGraphicsLayout::addChildLayoutItem: QGraphicsWidget \"\""
564                                        " in wrong parent; moved to correct parent");
565 #endif
566     QGraphicsWidget *widget = new QGraphicsWidget;
567     TheAnchorLayout *layout = new TheAnchorLayout();
568     widget->setLayout(layout);
569 
570     TestWidget *widget1 = new TestWidget();
571 
572     layout->setAnchor(layout, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
573     layout->setAnchor(layout, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
574     layout->setAnchor(widget1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
575     layout->setAnchor(widget1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
576     widget->setGeometry(QRectF(0,0,100,100));
577     QCOMPARE(widget1->geometry(), QRectF(1,1,98,98));
578     delete widget1;
579     delete widget;
580     }
581 
582     // One widget, layout inside layout, layout inside layout inside layout
583     {
584 #ifdef QT_DEBUG
585     QTest::ignoreMessage(QtWarningMsg, "QGraphicsLayout::addChildLayoutItem: QGraphicsWidget \"\""
586                                        " in wrong parent; moved to correct parent");
587 #endif
588     QGraphicsWidget *widget = new QGraphicsWidget;
589     TheAnchorLayout *layout = new TheAnchorLayout();
590     widget->setLayout(layout);
591 
592     TheAnchorLayout *layout1 = new TheAnchorLayout();
593     TestWidget *widget1 = new TestWidget();
594     layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
595     layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
596     layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
597     layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
598 
599     TheAnchorLayout *layout2 = new TheAnchorLayout();
600     TestWidget *widget2 = new TestWidget();
601     layout2->setAnchor(layout2, Qt::AnchorLeft, widget2, Qt::AnchorLeft, 1);
602     layout2->setAnchor(layout2, Qt::AnchorTop, widget2, Qt::AnchorTop, 1);
603     layout2->setAnchor(widget2, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
604     layout2->setAnchor(widget2, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
605 
606     layout1->setAnchor(layout1, Qt::AnchorLeft, layout2, Qt::AnchorLeft, 1);
607     layout1->setAnchor(layout1, Qt::AnchorTop, layout2, Qt::AnchorTop, 1);
608     layout1->setAnchor(layout2, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
609     layout1->setAnchor(layout2, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
610 
611     layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
612     layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
613     layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
614     layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
615 
616     // remove and add again to improve test coverage.
617     layout->removeItem(layout1);
618 
619     layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
620     layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
621     layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
622     layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
623 
624     widget->setGeometry(QRectF(0,0,100,100));
625     QCOMPARE(widget1->geometry(), QRectF(2,2,96,96));
626     QCOMPARE(widget2->geometry(), QRectF(3,3,94,94));
627     delete widget;
628     }
629 
630     // One widget, layout inside layout, setLayout after layout definition
631     {
632     QGraphicsWidget *widget = new QGraphicsWidget;
633     TheAnchorLayout *layout = new TheAnchorLayout();
634 
635     TheAnchorLayout *layout1 = new TheAnchorLayout();
636 
637     TestWidget *widget1 = new TestWidget();
638     layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
639     layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
640     layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
641     layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
642 
643     layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
644     layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
645     layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
646     layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
647 
648     widget->setLayout(layout);
649     widget->setGeometry(QRectF(0,0,100,100));
650     QCOMPARE(widget1->geometry(), QRectF(2,2,96,96));
651     delete widget;
652     }
653 
654     // One widget, layout inside layout, setLayout after layout definition, widget transferred from
655     // one layout to another
656     {
657     QGraphicsWidget *widget = new QGraphicsWidget;
658     TheAnchorLayout *layout = new TheAnchorLayout();
659     widget->setLayout(layout);
660 
661     TheAnchorLayout *layout1 = new TheAnchorLayout();
662     TestWidget *widget1 = new TestWidget();
663 
664     // Additional layout + widget to improve coverage.
665     TheAnchorLayout *layout0 = new TheAnchorLayout();
666     TestWidget *widget0 = new TestWidget();
667 
668     // widget0 to layout0
669     layout0->setAnchor(layout0, Qt::AnchorLeft, widget0, Qt::AnchorLeft, 1);
670     layout0->setAnchor(layout0, Qt::AnchorTop, widget0, Qt::AnchorTop, 1);
671     layout0->setAnchor(widget0, Qt::AnchorRight, layout0, Qt::AnchorRight, 1);
672     layout0->setAnchor(widget0, Qt::AnchorBottom, layout0, Qt::AnchorBottom, 1);
673 
674     // layout0 to layout
675     layout->setAnchor(layout, Qt::AnchorLeft, layout0, Qt::AnchorLeft, 1);
676     layout->setAnchor(layout, Qt::AnchorTop, layout0, Qt::AnchorTop, 1);
677     layout->setAnchor(layout0, Qt::AnchorRight, layout, Qt::AnchorRight, 50);
678     layout->setAnchor(layout0, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
679 
680     // widget1 to layout1
681     layout1->setAnchor(layout1, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
682     layout1->setAnchor(layout1, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
683     layout1->setAnchor(widget1, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
684     layout1->setAnchor(widget1, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
685 
686     // layout1 to layout
687     layout->setAnchor(layout, Qt::AnchorLeft, layout1, Qt::AnchorLeft, 1);
688     layout->setAnchor(layout, Qt::AnchorTop, layout1, Qt::AnchorTop, 1);
689     layout->setAnchor(layout1, Qt::AnchorRight, layout, Qt::AnchorRight, 50);
690     layout->setAnchor(layout1, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
691 
692     TheAnchorLayout *layout2 = new TheAnchorLayout();
693 
694     // layout2 to layout
695     layout->setAnchor(layout, Qt::AnchorLeft, layout2, Qt::AnchorLeft, 50);
696     layout->setAnchor(layout, Qt::AnchorTop, layout2, Qt::AnchorTop, 1);
697     layout->setAnchor(layout2, Qt::AnchorRight, layout, Qt::AnchorRight, 1);
698     layout->setAnchor(layout2, Qt::AnchorBottom, layout, Qt::AnchorBottom, 1);
699 
700     // transfer widget1 to layout2
701     layout2->setAnchor(layout2, Qt::AnchorLeft, widget1, Qt::AnchorLeft, 1);
702     layout2->setAnchor(layout2, Qt::AnchorTop, widget1, Qt::AnchorTop, 1);
703     layout2->setAnchor(widget1, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
704     layout2->setAnchor(widget1, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
705 
706     widget->setGeometry(QRectF(0,0,100,100));
707     QCOMPARE(widget1->geometry(), QRectF(51,2,47,96));
708     delete widget;
709     }
710 
711     // One widget, set first to one layout then to another. Child reparented.
712     // In addition widget as a direct child of another widget. Child reparented.
713     {
714     QGraphicsWidget *widget1 = new QGraphicsWidget;
715     TheAnchorLayout *layout1 = new TheAnchorLayout();
716     widget1->setLayout(layout1);
717 
718     TestWidget *childWidget = new TestWidget();
719 
720     // childWidget to layout1
721     layout1->setAnchor(layout1, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 1);
722     layout1->setAnchor(layout1, Qt::AnchorTop, childWidget, Qt::AnchorTop, 1);
723     layout1->setAnchor(childWidget, Qt::AnchorRight, layout1, Qt::AnchorRight, 1);
724     layout1->setAnchor(childWidget, Qt::AnchorBottom, layout1, Qt::AnchorBottom, 1);
725 
726     widget1->setGeometry(QRectF(0,0,100,100));
727     QCOMPARE(childWidget->geometry(), QRectF(1,1,98,98));
728     QVERIFY(childWidget->parentLayoutItem() == layout1);
729     QGraphicsWidget *widget2 = new QGraphicsWidget;
730     TheAnchorLayout *layout2 = new TheAnchorLayout();
731     widget2->setLayout(layout2);
732 
733     // childWidget to layout2
734     layout2->setAnchor(layout2, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 1);
735     layout2->setAnchor(layout2, Qt::AnchorTop, childWidget, Qt::AnchorTop, 1);
736     layout2->setAnchor(childWidget, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
737     layout2->setAnchor(childWidget, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
738 
739     QGraphicsWidget *widget3 = new QGraphicsWidget;
740     QGraphicsWidget *widget4 = new QGraphicsWidget;
741     // widget4 is a direct child of widget3 (i.e. not in any layout)
742     widget4->setParentItem(widget3);
743 
744     // widget4 to layout2
745     layout2->setAnchor(layout2, Qt::AnchorLeft, widget4, Qt::AnchorLeft, 1);
746     layout2->setAnchor(layout2, Qt::AnchorTop, widget4, Qt::AnchorTop, 1);
747     layout2->setAnchor(widget4, Qt::AnchorRight, layout2, Qt::AnchorRight, 1);
748     layout2->setAnchor(widget4, Qt::AnchorBottom, layout2, Qt::AnchorBottom, 1);
749 
750     widget2->setGeometry(QRectF(0,0,100,100));
751     QCOMPARE(childWidget->geometry(), QRectF(1,1,98,98));
752     QVERIFY(childWidget->parentLayoutItem() == layout2);
753     QCOMPARE(widget4->geometry(), QRectF(1,1,98,98));
754     QVERIFY(widget4->parentLayoutItem() == layout2);
755     QVERIFY(widget4->parentItem() == widget2);
756 
757     delete widget4;
758     delete widget3;
759     delete widget1;
760     delete childWidget;
761     delete widget2;
762     }
763 }
764 
testBasicLayout_data()765 void tst_QGraphicsAnchorLayout1::testBasicLayout_data()
766 {
767     QTest::addColumn<QSizeF>("size");
768     QTest::addColumn<BasicLayoutTestDataList>("data");
769     QTest::addColumn<BasicLayoutTestResultList>("result");
770 
771     typedef BasicLayoutTestData BasicData;
772     typedef BasicLayoutTestResult BasicResult;
773 
774     // One widget, basic
775     {
776         BasicLayoutTestDataList theData;
777         BasicLayoutTestResultList theResult;
778 
779         theData
780             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
781             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20)
782             << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 30)
783             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 40)
784             ;
785 
786         theResult
787             << BasicResult(0, QRectF(20, 10, 150, 50) )
788             ;
789 
790         QTest::newRow("One, simple") << QSizeF(200, 100) << theData << theResult;
791     }
792 
793     // One widget, duplicates
794     {
795         BasicLayoutTestDataList theData;
796         BasicLayoutTestResultList theResult;
797 
798         theData
799             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
800             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20)
801             << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 30)
802             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 40)
803 
804             << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
805             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 0)
806             << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, 0)
807             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0)
808             ;
809 
810         theResult
811             << BasicResult(0, QRectF(0, 0, 200, 100) )
812             ;
813 
814         QTest::newRow("One, duplicates") << QSizeF(200, 100) << theData << theResult;
815     }
816 
817     // One widget, mixed
818     {
819         BasicLayoutTestDataList theData;
820         BasicLayoutTestResultList theResult;
821 
822         theData
823             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorBottom, 80)
824             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 150)
825             << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorRight, 150)
826             << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorBottom, 80)
827             ;
828 
829         theResult
830             << BasicResult(0, QRectF(50, 20, 100, 60) )
831             ;
832 
833         QTest::newRow("One, mixed") << QSizeF(200, 100) << theData << theResult;
834     }
835 
836     // Basic case - two widgets (same layout), different ordering
837     {
838         BasicLayoutTestDataList theData;
839         BasicLayoutTestResultList theResult;
840 
841         theData
842             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
843             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
844             << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
845             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
846 
847             << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
848             << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 10)
849             << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
850             << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
851             ;
852 
853         theResult
854             << BasicResult(0, QRectF(10, 10, 180, 80) )
855             << BasicResult(1, QRectF(10, 10, 180, 80) )
856             ;
857 
858         QTest::newRow("Two, orderings") << QSizeF(200, 100) << theData << theResult;
859     }
860 
861     // Basic case - two widgets, duplicate anchors
862     {
863         BasicLayoutTestDataList theData;
864         BasicLayoutTestResultList theResult;
865 
866         theData
867             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
868             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
869             << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
870             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
871             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 30)
872             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
873 
874             << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
875             << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 10)
876             << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
877             << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
878             << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
879             << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, 0)
880             ;
881 
882         theResult
883             << BasicResult(0, QRectF(30, 10, 160, 70) )
884             << BasicResult(1, QRectF(10, 0, 190, 90) )
885             ;
886 
887         QTest::newRow("Two, duplicates") << QSizeF(200, 100) << theData << theResult;
888     }
889 
890     // Basic case - two widgets, mixed
891     {
892         BasicLayoutTestDataList theData;
893         BasicLayoutTestResultList theResult;
894 
895         theData
896             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorBottom, 90)
897             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 190)
898             << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorRight, 190)
899             << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorBottom, 90)
900 
901             << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorBottom, 20)
902             << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
903             << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 10)
904             << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorRight, 20)
905             ;
906 
907         theResult
908             << BasicResult(0, QRectF(10, 10, 180, 80) )
909             << BasicResult(1, QRectF(10, 80, 10, 10) )
910             ;
911 
912         QTest::newRow("Two, mixed") << QSizeF(200, 100) << theData << theResult;
913     }
914 
915     // Basic case - two widgets, 1 horizontal connection, first completely defined
916     {
917         BasicLayoutTestDataList theData;
918         BasicLayoutTestResultList theResult;
919 
920         theData
921             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
922             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
923             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
924             << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
925 
926             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
927             << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
928             << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
929             << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
930             ;
931 
932         theResult
933             << BasicResult(0, QRectF(10, 10, 10, 80) )
934             << BasicResult(1, QRectF(30, 10, 160, 70) )
935             ;
936 
937         QTest::newRow("Two, 1h connected") << QSizeF(200, 100) << theData << theResult;
938     }
939 
940     // Basic case - two widgets, 2 horizontal connections, first completely defined
941     {
942         BasicLayoutTestDataList theData;
943         BasicLayoutTestResultList theResult;
944 
945         theData
946             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
947             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
948             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
949             << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
950 
951             // ### QGAL is not sensible to the argument order in this case
952             //     To achieve the desired result we must explicitly set a negative
953             //     spacing.
954             // << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, 100)
955             << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, -100)
956 
957             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 30)
958             << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
959             << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
960             ;
961 
962         theResult
963             << BasicResult(0, QRectF(10, 10, 10, 80) )
964             << BasicResult(1, QRectF(50, 10, 60, 70) )
965             ;
966 
967         QTest::newRow("Two, 2h connected") << QSizeF(200, 100) << theData << theResult;
968     }
969 
970     // Basic case - two widgets, 1 vertical connection, first completely defined
971     {
972         BasicLayoutTestDataList theData;
973         BasicLayoutTestResultList theResult;
974 
975         theData
976             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
977             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
978             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
979             << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
980 
981             << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 30)
982             << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
983             << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
984             << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
985             ;
986 
987         theResult
988             << BasicResult(0, QRectF(10, 10, 10, 80) )
989             << BasicResult(1, QRectF(30, 20, 160, 60) )
990             ;
991 
992         QTest::newRow("Two, 1v connected") << QSizeF(200, 100) << theData << theResult;
993     }
994 
995     // Basic case - two widgets, 2 vertical connections, first completely defined
996     {
997         BasicLayoutTestDataList theData;
998         BasicLayoutTestResultList theResult;
999 
1000         theData
1001             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
1002             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
1003             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
1004             << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
1005 
1006             << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 30)
1007             << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
1008             << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
1009             << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 20)
1010             ;
1011 
1012         theResult
1013             << BasicResult(0, QRectF(10, 10, 10, 80) )
1014             << BasicResult(1, QRectF(30, 20, 160, 50) )
1015             ;
1016 
1017         QTest::newRow("Two, 2v connected") << QSizeF(200, 100) << theData << theResult;
1018     }
1019 
1020     // Basic case - two widgets, 1 horizontal and 1 vertical connection, first completely defined
1021     {
1022         BasicLayoutTestDataList theData;
1023         BasicLayoutTestResultList theResult;
1024 
1025         theData
1026             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
1027             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
1028             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
1029             << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
1030 
1031             << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 80)
1032             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 100)
1033             << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
1034             << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 10)
1035             ;
1036 
1037         theResult
1038             << BasicResult(0, QRectF(10, 10, 10, 80) )
1039             << BasicResult(1, QRectF(80, 10, 40, 70) )
1040             ;
1041 
1042         QTest::newRow("Two, 1h+1v connected") << QSizeF(200, 100) << theData << theResult;
1043     }
1044 
1045     // Basic case - two widgets, 2 horizontal and 2 vertical connections, first completely defined
1046     {
1047         BasicLayoutTestDataList theData;
1048         BasicLayoutTestResultList theResult;
1049 
1050         theData
1051             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
1052             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
1053             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
1054             << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 180)
1055 
1056             << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 80)
1057             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 100)
1058             << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
1059             << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 10)
1060             ;
1061 
1062         theResult
1063             << BasicResult(0, QRectF(10, 10, 10, 80) )
1064             << BasicResult(1, QRectF(90, 20, 30, 60) )
1065             ;
1066 
1067         QTest::newRow("Two, 2h+2v connected") << QSizeF(200, 100) << theData << theResult;
1068     }
1069 
1070     // Basic case - two widgets, 2 horizontal and 2 vertical connections, dependent on each other.
1071     {
1072         BasicLayoutTestDataList theData;
1073         BasicLayoutTestResultList theResult;
1074 
1075         theData
1076             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
1077             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 150)
1078             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
1079             << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 10)
1080 
1081             << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 90)
1082             << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
1083             << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 10)
1084             << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 20)
1085             ;
1086 
1087         theResult
1088             << BasicResult(0, QRectF(10, 10, 30, 60) )
1089             << BasicResult(1, QRectF(100, 20, 90, 60) )
1090             ;
1091 
1092         QTest::newRow("Two, 2h+2v connected2") << QSizeF(200, 100) << theData << theResult;
1093     }
1094 
1095     // Basic case - two widgets, connected, overlapping
1096     {
1097         BasicLayoutTestDataList theData;
1098         BasicLayoutTestResultList theResult;
1099 
1100         theData
1101             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
1102             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
1103             // << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, 30)
1104             // ### QGAL has different semantics and assumes right edges are always
1105             //     to the left of left edges. Thus we need the minus sign here.
1106             << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, -30)
1107             << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 40)
1108 
1109             << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 40)
1110             << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 20)
1111             << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
1112             << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
1113             ;
1114 
1115         theResult
1116             << BasicResult(0, QRectF(10, 10, 60, 40) )
1117             << BasicResult(1, QRectF(40, 20, 150, 70) )
1118             ;
1119 
1120         QTest::newRow("Two, connected overlapping") << QSizeF(200, 100) << theData << theResult;
1121     }
1122 }
1123 
testNegativeSpacing_data()1124 void tst_QGraphicsAnchorLayout1::testNegativeSpacing_data()
1125 {
1126     QTest::addColumn<QSizeF>("size");
1127     QTest::addColumn<BasicLayoutTestDataList>("data");
1128     QTest::addColumn<BasicLayoutTestResultList>("result");
1129 
1130     typedef BasicLayoutTestData BasicData;
1131     typedef BasicLayoutTestResult BasicResult;
1132 
1133     // One widget, negative spacing
1134     {
1135         BasicLayoutTestDataList theData;
1136         BasicLayoutTestResultList theResult;
1137 
1138         /// ### QGAL assumes items are always inside the layout.
1139         //      In this case, the negative spacing would make the item
1140         //      grow beyond the layout edges, which is OK, but gives a
1141         //      different result.
1142         //      Changing the direction of anchors (-1 to 0 or vice-versa)
1143         //      has no effect in this case.
1144 
1145         theData
1146             // << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1147             // << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -20)
1148             // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -30)
1149             // << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -40)
1150 
1151             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, -10)
1152             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, -20)
1153             << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, -30)
1154             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, -40)
1155 
1156             ;
1157 
1158         theResult
1159             // << BasicResult(0, QRectF(20, 10, 150, 50) )
1160             << BasicResult(0, QRectF(-20, -10, 250, 150) )
1161             ;
1162 
1163         QTest::newRow("One, simple (n)") << QSizeF(200, 100) << theData << theResult;
1164     }
1165 
1166     // One widget, duplicates, negative spacing
1167     {
1168         BasicLayoutTestDataList theData;
1169         BasicLayoutTestResultList theResult;
1170 
1171         theData
1172             << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -20)
1173             << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -20)
1174             << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -30)
1175             << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -40)
1176 
1177             << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1178             << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10)
1179             << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -10)
1180             << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10)
1181             ;
1182 
1183         theResult
1184             // ### Same as above...
1185             // << BasicResult(0, QRectF(10, 10, 180, 80) )
1186             << BasicResult(0, QRectF(-10, -10, 220, 120) )
1187             ;
1188 
1189         QTest::newRow("One, duplicates (n)") << QSizeF(200, 100) << theData << theResult;
1190     }
1191 
1192     // One widget, mixed, negative spacing
1193     {
1194         BasicLayoutTestDataList theData;
1195         BasicLayoutTestResultList theResult;
1196 
1197         theData
1198             // ### All anchors of negative spacing between the layout and an
1199             //     item are handled as to make sure the item is _outside_ the
1200             //     layout.
1201             //     To keep it inside, one _must_ use positive spacings.
1202             // << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorTop, -80)
1203             // << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorLeft, -150)
1204             // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorLeft, -150)
1205             // << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorTop, -80)
1206 
1207             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorTop, 80)
1208             << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorLeft, 150)
1209             << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorLeft, 150)
1210             << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorTop, 80)
1211             ;
1212 
1213         theResult
1214             << BasicResult(0, QRectF(50, 20, 100, 60) )
1215             ;
1216 
1217         QTest::newRow("One, mixed (n)") << QSizeF(200, 100) << theData << theResult;
1218     }
1219 
1220     // Basic case - two widgets, 1 horizontal connection, first completely defined, negative spacing
1221     {
1222         BasicLayoutTestDataList theData;
1223         BasicLayoutTestResultList theResult;
1224 
1225         theData
1226             // << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1227             // << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10)
1228             // << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10)
1229             // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, -180)
1230 
1231             // << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, -10)
1232             // << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10)
1233             // << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1234             // << BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -20)
1235 
1236             << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1237             << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10)
1238             << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10)
1239             << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, 180)
1240 
1241             << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorRight, -10)
1242             << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10)
1243             << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1244             << BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -20)
1245 
1246             ;
1247 
1248         theResult
1249             // << BasicResult(0, QRectF(10, 10, 10, 80) )
1250             // << BasicResult(1, QRectF(30, 10, 160, 70) )
1251 
1252             << BasicResult(0, QRectF(-10, -10, 30, 120) )
1253             << BasicResult(1, QRectF(10, -10, 200, 130) )
1254             ;
1255 
1256         QTest::newRow("Two, 1h connected (n)") << QSizeF(200, 100) << theData << theResult;
1257     }
1258 
1259     // Basic case - two widgets, 2 horizontal and 2 vertical connections, dependent on each other, negative spacing
1260     {
1261         BasicLayoutTestDataList theData;
1262         BasicLayoutTestResultList theResult;
1263 
1264         theData
1265             << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -10)
1266             << BasicData(1, Qt::AnchorRight, 0, Qt::AnchorRight, -150)
1267             << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, -10)
1268             << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, -10)
1269 
1270             << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorLeft, -90)
1271             << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10)
1272             << BasicData(1, Qt::AnchorTop, 0, Qt::AnchorTop, -10)
1273             << BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -20)
1274             ;
1275 
1276         theResult
1277             // << BasicResult(0, QRectF(10, 10, 30, 60) )
1278             // << BasicResult(1, QRectF(100, 20, 90, 60) )
1279             << BasicResult(0, QRectF(-10, -10, 70, 120) )
1280             << BasicResult(1, QRectF(80, 0, 130, 120) )
1281             ;
1282 
1283         QTest::newRow("Two, 2h+2v connected2 (n)") << QSizeF(200, 100) << theData << theResult;
1284     }
1285 }
1286 
testMixedSpacing_data()1287 void tst_QGraphicsAnchorLayout1::testMixedSpacing_data()
1288 {
1289     QTest::addColumn<QSizeF>("size");
1290     QTest::addColumn<BasicLayoutTestDataList>("data");
1291     QTest::addColumn<BasicLayoutTestResultList>("result");
1292 
1293     typedef BasicLayoutTestData BasicData;
1294     typedef BasicLayoutTestResult BasicResult;
1295 
1296     // Two widgets, partial overlapping
1297     {
1298         BasicLayoutTestDataList theData;
1299         BasicLayoutTestResultList theResult;
1300 
1301         theData
1302             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
1303             << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, -50)
1304             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 50)
1305             << BasicData(1, Qt::AnchorRight, 0, Qt::AnchorRight, 15)
1306 
1307             // << BasicData(1, Qt::AnchorTop, 0, Qt::AnchorBottom, 5)
1308             << BasicData(1, Qt::AnchorTop, 0, Qt::AnchorBottom, -5)
1309             << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, -10)
1310             << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 20)
1311             << BasicData(-1, Qt::AnchorBottom, 1, Qt::AnchorBottom, -5)
1312             ;
1313 
1314         theResult
1315             // << BasicResult(0, QRectF(50, 10, 45, 40) )
1316             // << BasicResult(1, QRectF(40, 45, 40, 50) )
1317             << BasicResult(0, QRectF(-50, 10, 145, 40) )
1318             << BasicResult(1, QRectF(-60, 45, 140, 60) )
1319             ;
1320 
1321         QTest::newRow("Two, partial overlap") << QSizeF(100, 100) << theData << theResult;
1322     }
1323 
1324     // Two widgets, complete overlapping
1325     {
1326         BasicLayoutTestDataList theData;
1327         BasicLayoutTestResultList theResult;
1328 
1329         theData
1330             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 5)
1331             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 0)
1332             << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
1333             << BasicData(1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 25)
1334 
1335             << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 0)
1336             << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
1337             << BasicData(1, Qt::AnchorLeft, -1, Qt::AnchorRight, 50)
1338             << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, -10)
1339             ;
1340 
1341         theResult
1342             << BasicResult(0, QRectF(65, 5, 35, 35) )
1343             << BasicResult(1, QRectF(40, 5, 60, 35) )
1344             ;
1345 
1346         QTest::newRow("Two, complete overlap") << QSizeF(90, 45) << theData << theResult;
1347     }
1348 
1349     // Five widgets, v shaped, edges shared
1350     {
1351         BasicLayoutTestDataList theData;
1352         BasicLayoutTestResultList theResult;
1353 
1354         theData
1355             // edges shared
1356             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 0)
1357             << BasicData(1, Qt::AnchorRight, 2, Qt::AnchorLeft, 0)
1358             << BasicData(2, Qt::AnchorRight, 3, Qt::AnchorLeft, 0)
1359             << BasicData(3, Qt::AnchorRight, 4, Qt::AnchorLeft, 0)
1360             << BasicData(1, Qt::AnchorBottom, 2, Qt::AnchorTop, 0)
1361             << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorTop, 0)
1362             << BasicData(3, Qt::AnchorBottom, 2, Qt::AnchorTop, 0)
1363             << BasicData(4, Qt::AnchorBottom, 3, Qt::AnchorTop, 0)
1364             << BasicData(0, Qt::AnchorBottom, 4, Qt::AnchorBottom, 0)
1365             << BasicData(1, Qt::AnchorBottom, 3, Qt::AnchorBottom, 0)
1366             << BasicData(0, Qt::AnchorTop, 4, Qt::AnchorTop, 0)
1367             << BasicData(1, Qt::AnchorTop, 3, Qt::AnchorTop, 0)
1368 
1369             // margins
1370             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 5)
1371             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 5)
1372             << BasicData(2, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
1373             // << BasicData(-1, Qt::AnchorRight, 4, Qt::AnchorRight, -5)
1374             << BasicData(-1, Qt::AnchorRight, 4, Qt::AnchorRight, 5)
1375 
1376             // additional details for exact size determination easily
1377             << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 25)
1378             << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorRight, 50)
1379             // << BasicData(-1, Qt::AnchorRight, 3, Qt::AnchorRight, -25)
1380             // << BasicData(-1, Qt::AnchorRight, 2, Qt::AnchorRight, -50)
1381             << BasicData(-1, Qt::AnchorRight, 3, Qt::AnchorRight, 25)
1382             << BasicData(-1, Qt::AnchorRight, 2, Qt::AnchorRight, 50)
1383             << BasicData(-1, Qt::AnchorTop, 3, Qt::AnchorBottom, 50)
1384             // << BasicData(-1, Qt::AnchorBottom, 3, Qt::AnchorTop, -50)
1385             << BasicData(-1, Qt::AnchorBottom, 3, Qt::AnchorTop, 50)
1386 
1387             ;
1388 
1389         theResult
1390             << BasicResult(0, QRectF(5,5,20,20))
1391             << BasicResult(1, QRectF(25,25,25,25))
1392             << BasicResult(2, QRectF(50,50,25,20))
1393             << BasicResult(3, QRectF(75,25,25,25))
1394             << BasicResult(4, QRectF(100,5,20,20))
1395             ;
1396 
1397         QTest::newRow("Five, V shape") << QSizeF(125, 75) << theData << theResult;
1398     }
1399 
1400     // ### The behavior is different in QGraphicsAnchorLayout. What happens here is
1401     //     that when the above anchors are set, the layout size hints are changed.
1402     //     In the example, the minimum item width is 5, thus the minimum layout width
1403     //     becomes 105 (50 + 5 + 50). Once that size hint is set, trying to set
1404     //     the widget size to (10, 10) is not possible because
1405     //     QGraphicsWidget::setGeometry() will enforce the minimum is respected.
1406     if (0)
1407     // One widget, unsolvable
1408     {
1409         BasicLayoutTestDataList theData;
1410         BasicLayoutTestResultList theResult;
1411 
1412         theData
1413                 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 50)
1414                 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 50)
1415                 ;
1416         theResult
1417                 << BasicResult(0, QRectF(0,0,0,0))
1418                 ;
1419 
1420         QTest::newRow("One widget, unsolvable") << QSizeF(10, 10) << theData << theResult;
1421     }
1422 
1423     // Two widgets, one has fixed size
1424     {
1425         BasicLayoutTestDataList theData;
1426         BasicLayoutTestResultList theResult;
1427 
1428         theData
1429                 << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 50)
1430                 << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 50)
1431             // not supported, use sizePolicy instead
1432             // << BasicData(0, Qt::AnchorLeft, 0, Qt::AnchorRight, 50)
1433 
1434                 << BasicData(-1, Qt::AnchorLeft, 1, Qt::AnchorLeft, 50)
1435                 << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 50)
1436                 ;
1437         theResult
1438                 << BasicResult(0, QRectF(50,0,50,50))
1439                 << BasicResult(1, QRectF(50,0,50,50))
1440                 ;
1441 
1442         QTest::newRow("Two widgets, one has fixed size") << QSizeF(150, 150) << theData << theResult;
1443     }
1444 }
1445 
testMulti_data()1446 void tst_QGraphicsAnchorLayout1::testMulti_data()
1447 {
1448     QTest::addColumn<QSizeF>("size");
1449     QTest::addColumn<BasicLayoutTestDataList>("data");
1450     QTest::addColumn<BasicLayoutTestResultList>("result");
1451 
1452     typedef BasicLayoutTestData BasicData;
1453     typedef BasicLayoutTestResult BasicResult;
1454 
1455     // Multiple widgets, all overllapping
1456     {
1457         BasicLayoutTestDataList theData;
1458         BasicLayoutTestResultList theResult;
1459 
1460         const int n = 30;
1461         for ( int i = 0 ; i < n; i++ ) {
1462             theData
1463                 << BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, 20)
1464                 << BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, 10)
1465                 // << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -40)
1466                 // << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, -30);
1467                 << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, 40)
1468                 << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, 30);
1469 
1470             theResult
1471                 << BasicResult(i, QRectF(10, 20, 160, 40) );
1472         }
1473 
1474 
1475         QTest::newRow("Overlapping multi") << QSizeF(200, 100) << theData << theResult;
1476     }
1477 
1478     // Multiple widgets, linear order
1479     {
1480         BasicLayoutTestDataList theData;
1481         BasicLayoutTestResultList theResult;
1482 
1483         const qreal height = 1000.f;
1484         const qreal width = 2000.f;
1485 
1486         const int n = 30;
1487 
1488         const qreal verticalStep = height/qreal(n+2);
1489         const qreal horizontalStep = width/qreal(n+2);
1490 
1491         for ( int i = 0 ; i < n; i++ ) {
1492 
1493             if ( i == 0 ) {
1494                 // First item
1495                 theData
1496                     << BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1497                     << BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1498                     << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1499                     << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1500 
1501             } else if ( i == n-1 ) {
1502                 // Last item
1503                 theData
1504                     << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1505                     << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1506                     << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, verticalStep)
1507                     << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, horizontalStep);
1508                     // << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1509                     // << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1510 
1511             } else {
1512                 // items in the middle
1513                 theData
1514                     << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1515                     << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1516                     << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1517                     << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1518                     // << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1519                     // << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1520 
1521             }
1522 
1523             theResult
1524                 << BasicResult(i, QRectF((i+1)*horizontalStep, (i+1)*verticalStep, horizontalStep, verticalStep) );
1525         }
1526 
1527 
1528         if (sizeof(qreal) == 4) {
1529             qDebug("Linear multi: Skipping! (qreal has too little precision, result will be wrong)");
1530         } else {
1531             QTest::newRow("Linear multi") << QSizeF(width, height) << theData << theResult;
1532         }
1533     }
1534 
1535     // Multiple widgets, V shape
1536     {
1537         BasicLayoutTestDataList theData;
1538         BasicLayoutTestResultList theResult;
1539 
1540         const qreal height = 100.f;
1541         const qreal width = 200.f;
1542 
1543         const int n = 31; // odd number please (3,5,7... )
1544 
1545         const qreal verticalStep = height/(2.f+(n+1)/2.f);
1546         const qreal horizontalStep = width/(n+2.f);
1547 
1548         for ( int i = 0 ; i < n; i++ ) {
1549 
1550             if ( i == 0 ) {
1551                 // First item
1552                 theData
1553                     << BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1554                     << BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1555                     << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1556                     << BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep);
1557 
1558             } else if ( i == n-1 ) {
1559                 // Last item
1560                 theData
1561                     << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, -verticalStep)
1562                     << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1563                     << BasicData(i-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1564                     << BasicData(i, Qt::AnchorRight, -1, Qt::AnchorRight, horizontalStep);
1565             } else if ( i == ((n-1)/2) ) {
1566                 // midway
1567                 theData
1568                     << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1569                     << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1570                     // << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1571                     << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, verticalStep)
1572                     << BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep);
1573             } else if ( i < ((n-1)/2) ) {
1574                 // before midway - going down
1575                 theData
1576                     << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1577                     << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1578                     << BasicData(i+1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1579                     << BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep);
1580 
1581             } else {
1582                 // after midway - going up
1583                 theData
1584                     << BasicData(i-1, Qt::AnchorTop, i, Qt::AnchorTop, -verticalStep)
1585                     << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1586                     << BasicData(i-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1587                     << BasicData(i, Qt::AnchorRight, i+1, Qt::AnchorRight, horizontalStep);
1588 
1589             }
1590 
1591             if ( i <= ((n-1)/2) ) {
1592                 // until midway
1593                 theResult
1594                     << BasicResult(i, QRectF((i+1)*horizontalStep, (i+1)*verticalStep, horizontalStep, verticalStep) );
1595             } else {
1596                 // after midway
1597                 theResult
1598                     << BasicResult(i, QRectF((i+1)*horizontalStep, (n-i)*verticalStep, horizontalStep, verticalStep) );
1599             }
1600 
1601         }
1602         if (sizeof(qreal) == 4) {
1603             qDebug("V multi: Skipping! (qreal has too little precision, result will be wrong)");
1604         } else {
1605             QTest::newRow("V multi") << QSizeF(width, height) << theData << theResult;
1606         }
1607     }
1608 
1609     // Multiple widgets, grid
1610     {
1611         BasicLayoutTestDataList theData;
1612         BasicLayoutTestResultList theResult;
1613 
1614         const qreal height = 100.f;
1615         const qreal width = 200.f;
1616 
1617         const int d = 10; // items per dimension
1618         const int n = d*d;
1619 
1620         const qreal verticalStep = height/(d+2.f);
1621         const qreal horizontalStep = width/(d+2.f);
1622 
1623         for ( int i = 0 ; i < n; i++ ) {
1624             if ( i%d == 0 ) {
1625                 // left side item
1626                 theData
1627                     << BasicData(-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1628                     << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1629             } else if ( (i+1)%d == 0 ) {
1630                 // rigth side item
1631                 theData
1632                     << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1633                     // << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1634                     << BasicData(-1, Qt::AnchorRight, i, Qt::AnchorRight, horizontalStep);
1635             } else {
1636                 // horizontal middle
1637                 theData
1638                     << BasicData(i-1, Qt::AnchorLeft, i, Qt::AnchorLeft, horizontalStep)
1639                     << BasicData(i+1, Qt::AnchorRight, i, Qt::AnchorRight, -horizontalStep);
1640             }
1641 
1642             if ( i < d ) {
1643                 // top line
1644                 theData
1645                     << BasicData(-1, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1646                     << BasicData(i+d, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep);
1647             } else if ( i >= (d-1)*d ){
1648                 // bottom line
1649                 theData
1650                     << BasicData(i-d, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1651                     // << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep)
1652                     << BasicData(-1, Qt::AnchorBottom, i, Qt::AnchorBottom, verticalStep);
1653             } else {
1654                 // vertical middle
1655                 theData
1656                     << BasicData(i-d, Qt::AnchorTop, i, Qt::AnchorTop, verticalStep)
1657                     << BasicData(i+d, Qt::AnchorBottom, i, Qt::AnchorBottom, -verticalStep);
1658             }
1659 
1660             theResult
1661                 << BasicResult(i, QRectF(((i%d)+1)*horizontalStep, ((i/d)+1)*verticalStep, horizontalStep, verticalStep) );
1662         }
1663 
1664         if (sizeof(qreal) == 4) {
1665             qDebug("Grid multi: Skipping! (qreal has too little precision, result will be wrong)");
1666         } else {
1667             QTest::newRow("Grid multi") << QSizeF(200, 100) << theData << theResult;
1668         }
1669     }
1670 }
1671 
getItem(int index,const QList<QGraphicsWidget * > & widgets,QGraphicsLayoutItem * defaultItem)1672 inline QGraphicsLayoutItem *getItem(
1673         int index,
1674         const QList<QGraphicsWidget *>& widgets,
1675         QGraphicsLayoutItem *defaultItem)
1676 {
1677     if (index < 0) {
1678         return defaultItem;
1679     }
1680 
1681     return widgets[index];
1682 }
1683 
fuzzierCompare(qreal a,qreal b)1684 static bool fuzzierCompare(qreal a, qreal b)
1685 {
1686     return qAbs(a - b) <= qreal(0.0001);
1687 }
1688 
fuzzierCompare(const QRectF & r1,const QRectF & r2)1689 static bool fuzzierCompare(const QRectF &r1, const QRectF &r2)
1690 {
1691 
1692     return fuzzierCompare(r1.x(), r2.x()) && fuzzierCompare(r1.y(), r2.y())
1693         && fuzzierCompare(r1.width(), r2.width()) && fuzzierCompare(r1.height(), r2.height());
1694 }
1695 
testBasicLayout()1696 void tst_QGraphicsAnchorLayout1::testBasicLayout()
1697 {
1698     QFETCH(QSizeF, size);
1699     QFETCH(BasicLayoutTestDataList, data);
1700     QFETCH(BasicLayoutTestResultList, result);
1701 
1702     QGraphicsWidget *widget = new QGraphicsWidget;
1703 
1704     // Determine amount of widgets to add.
1705     int widgetCount = -1;
1706     for (int i = 0; i < data.count(); ++i) {
1707         const BasicLayoutTestData item = data[i];
1708         widgetCount = qMax(widgetCount, item.firstIndex);
1709         widgetCount = qMax(widgetCount, item.secondIndex);
1710     }
1711     ++widgetCount; // widgetCount is max of indices.
1712 
1713     // Create dummy widgets
1714     QList<QGraphicsWidget *> widgets;
1715     for (int i = 0; i < widgetCount; ++i) {
1716         TestWidget *w = new TestWidget(0, QString::fromAscii("W%1").arg(i));
1717         widgets << w;
1718     }
1719 
1720     // Setup anchor layout
1721     TheAnchorLayout *layout = new TheAnchorLayout;
1722 
1723     for (int i = 0; i < data.count(); ++i) {
1724         const BasicLayoutTestData item = data[i];
1725         layout->setAnchor(
1726             getItem(item.firstIndex, widgets, layout),
1727             item.firstEdge,
1728             getItem(item.secondIndex, widgets, layout),
1729             item.secondEdge,
1730             item.spacing );
1731     }
1732 
1733     widget->setLayout(layout);
1734     widget->setContentsMargins(0,0,0,0);
1735 
1736     widget->resize(size);
1737     QCOMPARE(widget->size(), size);
1738 
1739     // Validate
1740     for (int i = 0; i < result.count(); ++i) {
1741         const BasicLayoutTestResult item = result[i];
1742         QRectF expected = item.rect;
1743         QRectF actual = widgets[item.index]->geometry();
1744 
1745         QVERIFY(fuzzierCompare(actual, expected));
1746     }
1747 
1748     // Test mirrored mode
1749     widget->setLayoutDirection(Qt::RightToLeft);
1750     layout->activate();
1751     // Validate
1752     for (int j = 0; j < result.count(); ++j) {
1753         const BasicLayoutTestResult item = result[j];
1754         QRectF mirroredRect(item.rect);
1755         // only valid cases are mirrored
1756         if (mirroredRect.isValid()){
1757             mirroredRect.moveLeft(size.width()-item.rect.width()-item.rect.left());
1758         }
1759         QRectF expected = mirroredRect;
1760         QRectF actual = widgets[item.index]->geometry();
1761 
1762         QVERIFY(fuzzierCompare(actual, expected));
1763     }
1764 
1765     qDeleteAll(widgets);
1766     delete widget;
1767 }
1768 
testNegativeSpacing()1769 void tst_QGraphicsAnchorLayout1::testNegativeSpacing()
1770 {
1771     // use the same frame
1772     testBasicLayout();
1773 }
1774 
testMixedSpacing()1775 void tst_QGraphicsAnchorLayout1::testMixedSpacing()
1776 {
1777     // use the same frame
1778     testBasicLayout();
1779 }
1780 
testMulti()1781 void tst_QGraphicsAnchorLayout1::testMulti()
1782 {
1783     // use the same frame
1784     testBasicLayout();
1785 }
1786 
testCenterAnchors_data()1787 void tst_QGraphicsAnchorLayout1::testCenterAnchors_data()
1788 {
1789     QTest::addColumn<QSizeF>("size");
1790     QTest::addColumn<BasicLayoutTestDataList>("data");
1791     QTest::addColumn<BasicLayoutTestResultList>("result");
1792 
1793     typedef BasicLayoutTestData BasicData;
1794     typedef BasicLayoutTestResult BasicResult;
1795 
1796     // Basic center case
1797     {
1798         BasicLayoutTestDataList theData;
1799         BasicLayoutTestResultList theResult;
1800 
1801         theData
1802             // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10)
1803             << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10)
1804             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15)
1805             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10)
1806             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5);
1807 
1808         theResult
1809             << BasicResult(0, QRectF(5, 5, 10, 10) );
1810 
1811         QTest::newRow("center, basic") << QSizeF(20, 20) << theData << theResult;
1812     }
1813 
1814     // Basic center case, with invalid (shouldn't affect on result)
1815     {
1816         BasicLayoutTestDataList theData;
1817         BasicLayoutTestResultList theResult;
1818 
1819         theData
1820             // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10)
1821             << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10)
1822             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15)
1823             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10)
1824             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
1825 
1826             // bogus definitions
1827             << BasicData(0, Qt::AnchorHorizontalCenter, -1, Qt::AnchorBottom, 5)
1828             << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorVerticalCenter, 5)
1829             << BasicData(0, Qt::AnchorVerticalCenter, -1, Qt::AnchorRight, 5)
1830             << BasicData(0, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 666)
1831             << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 999)
1832             << BasicData(0, Qt::AnchorLeft, 0, Qt::AnchorLeft, 333)
1833             << BasicData(-1, Qt::AnchorRight, -1, Qt::AnchorRight, 222)
1834             << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorTop, 111)
1835             << BasicData(0, Qt::AnchorBottom, 0, Qt::AnchorBottom, 444);
1836 
1837         theResult
1838             << BasicResult(0, QRectF(5, 5, 10, 10) );
1839 
1840         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations");
1841         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations");
1842         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor edges of different orientations");
1843         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1844         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1845         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1846         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1847         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1848         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1849         QTest::newRow("center, basic with invalid") << QSizeF(20, 20) << theData << theResult;
1850     }
1851 
1852     // Basic center case 2
1853     {
1854         BasicLayoutTestDataList theData;
1855         BasicLayoutTestResultList theResult;
1856 
1857         theData
1858             << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 0)
1859             // Not supported << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5)
1860             << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5)
1861             << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 0)
1862             << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, -5);
1863 
1864         theResult
1865             << BasicResult(0, QRectF(5, 5, 10, 10) );
1866 
1867         QTest::newRow("center, basic 2") << QSizeF(20, 20) << theData << theResult;
1868     }
1869 
1870     // Basic center case, overrides
1871     {
1872         BasicLayoutTestDataList theData;
1873         BasicLayoutTestResultList theResult;
1874 
1875         theData
1876             << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 10)
1877             << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 20)
1878             << BasicData(0, Qt::AnchorHorizontalCenter, -1, Qt::AnchorHorizontalCenter, 30)
1879             << BasicData(0, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 40)
1880             // actual data:
1881             << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 0)
1882             << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 0)
1883             // << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5)
1884             << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 5)
1885             << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, -5);
1886 
1887         theResult
1888             << BasicResult(0, QRectF(5, 5, 10, 10) );
1889 
1890         QTest::newRow("center, overrides") << QSizeF(20, 20) << theData << theResult;
1891     }
1892 
1893     // Two nested
1894     {
1895         BasicLayoutTestDataList theData;
1896         BasicLayoutTestResultList theResult;
1897 
1898         theData
1899             << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorLeft, 0)
1900             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
1901             << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 0)
1902             << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorRight, 0)
1903             << BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorTop, 0)
1904             << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 0)
1905             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 0)
1906             << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 0);
1907 
1908         theResult
1909             << BasicResult(0, QRectF(20, 0, 20, 40))
1910             << BasicResult(1, QRectF(20, 20, 20, 20));
1911 
1912         QTest::newRow("center, two nested") << QSizeF(40, 40) << theData << theResult;
1913     }
1914 
1915     // Two overlap
1916     {
1917         BasicLayoutTestDataList theData;
1918         BasicLayoutTestResultList theResult;
1919 
1920         // theData
1921         //     // horizontal
1922         //     << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20)
1923         //     << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorLeft, 0)
1924         //     << BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, -5)
1925         //     << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
1926         //     << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, 10)
1927         //     // vertical is pretty much same as horizontal, just roles swapped
1928         //     << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 20)
1929         //     << BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, 0)
1930         //     << BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorBottom, -5)
1931         //     << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 10)
1932         //     << BasicData(1, Qt::AnchorVerticalCenter, 1, Qt::AnchorBottom, 10);
1933 
1934         theData
1935             // horizontal
1936             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 20)
1937             << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorLeft, 0)
1938             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorHorizontalCenter, 5)
1939             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorRight, 20)
1940             // vertical
1941             << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 20)
1942             << BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorTop, 0)
1943             << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorVerticalCenter, 5)
1944             << BasicData(1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 20);
1945 
1946         theResult
1947             << BasicResult(0, QRectF(20, 30, 20, 30))
1948             << BasicResult(1, QRectF(30, 20, 30, 20));
1949 
1950         QTest::newRow("center, two overlap") << QSizeF(70, 70) << theData << theResult;
1951     }
1952 
1953     // Three
1954     {
1955         BasicLayoutTestDataList theData;
1956         BasicLayoutTestResultList theResult;
1957 
1958         theData
1959             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 0)
1960             << BasicData(0, Qt::AnchorHorizontalCenter, 2, Qt::AnchorHorizontalCenter, 75)
1961             << BasicData(1, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
1962             << BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, -30)
1963             << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 0)
1964             << BasicData(1, Qt::AnchorLeft, 1, Qt::AnchorRight, 30)
1965             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
1966 
1967             << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
1968             << BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 35)
1969             << BasicData(1, Qt::AnchorVerticalCenter, 2, Qt::AnchorVerticalCenter, 15)
1970             << BasicData(1, Qt::AnchorBottom, 2, Qt::AnchorTop, 5)
1971             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0)
1972             << BasicData(2, Qt::AnchorBottom, 0, Qt::AnchorTop, 5)
1973             << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 20);
1974 
1975         theResult
1976             << BasicResult(0, QRectF(0, 30, 10, 20))
1977             << BasicResult(1, QRectF(20, 0, 30, 10))
1978             << BasicResult(2, QRectF(60, 15, 40, 10));
1979 
1980         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1981         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
1982 
1983         QTest::newRow("center, three") << QSizeF(100, 50) << theData << theResult;
1984     }
1985 
1986     // Two, parent center
1987     {
1988         BasicLayoutTestDataList theData;
1989         BasicLayoutTestResultList theResult;
1990 
1991         theData
1992             // vertical is pretty much same as horizontal, just roles swapped
1993             << BasicData(-1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, -15)
1994             << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 10)
1995             << BasicData(-1, Qt::AnchorBottom, 0, Qt::AnchorBottom, 0)
1996             << BasicData(1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
1997             // horizontal
1998             << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, -15)
1999             << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 10)
2000             << BasicData(-1, Qt::AnchorRight, 1, Qt::AnchorRight, 0)
2001             << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorLeft, 0);
2002 
2003         theResult
2004             << BasicResult(0, QRectF(20, 20, 30, 80))
2005             << BasicResult(1, QRectF(20, 20, 80, 30));
2006 
2007         QTest::newRow("center, parent") << QSizeF(100, 100) << theData << theResult;
2008     }
2009 
2010     // Two, parent center 2
2011     {
2012         BasicLayoutTestDataList theData;
2013         BasicLayoutTestResultList theResult;
2014 
2015         theData
2016             // << BasicData(1, Qt::AnchorLeft, -1, Qt::AnchorHorizontalCenter, 15)
2017             << BasicData(1, Qt::AnchorLeft, -1, Qt::AnchorHorizontalCenter, -15)
2018             << BasicData(1, Qt::AnchorRight, 0, Qt::AnchorLeft, 10)
2019             << BasicData(0, Qt::AnchorRight, -1, Qt::AnchorRight, 5)
2020             << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorRight, -5)
2021             // vertical
2022             << BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 20)
2023             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 10)
2024             << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorBottom, 20)
2025             << BasicData(0, Qt::AnchorTop, 1, Qt::AnchorTop, 20)
2026             << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorTop, 10);
2027 
2028         theResult
2029             << BasicResult(0, QRectF(30, 10, 15, 10))
2030             << BasicResult(1, QRectF(10, 30, 10, 10));
2031 
2032         QTest::newRow("center, parent 2") << QSizeF(50, 50) << theData << theResult;
2033     }
2034 
2035     // Two, parent center 3
2036     {
2037         BasicLayoutTestDataList theData;
2038         BasicLayoutTestResultList theResult;
2039 
2040         theData
2041             << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorRight, -5)
2042             << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorLeft, 5)
2043             // << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, 100)
2044             << BasicData(0, Qt::AnchorLeft, 1, Qt::AnchorRight, -100)
2045             << BasicData(0, Qt::AnchorLeft, -1, Qt::AnchorLeft, 0)
2046 
2047             // vertical
2048             << BasicData(0, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 55)
2049             << BasicData(0, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
2050             << BasicData(1, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0)
2051             << BasicData(0, Qt::AnchorBottom, 1, Qt::AnchorTop, 10)
2052             // << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 45)
2053             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorBottom, 45)
2054             ;
2055 
2056         theResult
2057             << BasicResult(0, QRectF(0, 0, 45, 45))
2058             << BasicResult(1, QRectF(55, 55, 45, 45));
2059 
2060         QTest::newRow("center, parent 3") << QSizeF(100, 100) << theData << theResult;
2061     }
2062 
2063 }
2064 
testCenterAnchors()2065 void tst_QGraphicsAnchorLayout1::testCenterAnchors()
2066 {
2067     // use the same frame
2068     testBasicLayout();
2069 }
2070 
testRemoveCenterAnchor_data()2071 void tst_QGraphicsAnchorLayout1::testRemoveCenterAnchor_data()
2072 {
2073     QTest::addColumn<QSizeF>("size");
2074     QTest::addColumn<BasicLayoutTestDataList>("data");
2075     QTest::addColumn<BasicLayoutTestDataList>("removeData");
2076     QTest::addColumn<BasicLayoutTestResultList>("result");
2077 
2078     typedef BasicLayoutTestData BasicData;
2079     typedef BasicLayoutTestResult BasicResult;
2080 
2081     {
2082         BasicLayoutTestDataList theData;
2083         BasicLayoutTestDataList theRemoveData;
2084         BasicLayoutTestResultList theResult;
2085 
2086         theData
2087             // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10)
2088             << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10)
2089             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15)
2090             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10)
2091             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
2092 
2093             << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 66)
2094             << BasicData(1, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 99)
2095             << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 33)
2096             ;
2097 
2098         theRemoveData
2099             << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 0)
2100             << BasicData(1, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 0)
2101             << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 0);
2102 
2103         theResult
2104             << BasicResult(0, QRectF(5, 5, 10, 10) );
2105 
2106         QTest::newRow("remove, center, basic") << QSizeF(20, 20) << theData
2107             << theRemoveData << theResult;
2108     }
2109 
2110     {
2111         BasicLayoutTestDataList theData;
2112         BasicLayoutTestDataList theRemoveData;
2113         BasicLayoutTestResultList theResult;
2114 
2115         theData
2116             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 0)
2117             << BasicData(0, Qt::AnchorHorizontalCenter, 2, Qt::AnchorHorizontalCenter, 75)
2118             << BasicData(1, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
2119             << BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, -30)
2120             << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 0)
2121             << BasicData(1, Qt::AnchorLeft, 1, Qt::AnchorRight, 30)
2122             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
2123 
2124             // extra:
2125             << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 66)
2126             << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 33)
2127             << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 55)
2128             << BasicData(1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 55)
2129 
2130             << BasicData(1, Qt::AnchorTop, -1, Qt::AnchorTop, 0)
2131             << BasicData(1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 35)
2132             << BasicData(1, Qt::AnchorVerticalCenter, 2, Qt::AnchorVerticalCenter, 15)
2133             << BasicData(1, Qt::AnchorBottom, 2, Qt::AnchorTop, 5)
2134             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 0)
2135             << BasicData(2, Qt::AnchorBottom, 0, Qt::AnchorTop, 5)
2136             << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 20);
2137 
2138         theRemoveData
2139             << BasicData(-1, Qt::AnchorVerticalCenter, 0, Qt::AnchorVerticalCenter, 66)
2140             << BasicData(-1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 33)
2141             << BasicData(0, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 55)
2142             << BasicData(1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 55);
2143 
2144         theResult
2145             << BasicResult(0, QRectF(0, 30, 10, 20))
2146             << BasicResult(1, QRectF(20, 0, 30, 10))
2147             << BasicResult(2, QRectF(60, 15, 40, 10));
2148 
2149         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
2150         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
2151         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
2152         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
2153 
2154         QTest::newRow("remove, center, three") << QSizeF(100, 50) << theData << theRemoveData << theResult;
2155     }
2156 
2157     // add edge (item0,edge0,item1,edge1), remove (item1,edge1,item0,edge0)
2158     {
2159         BasicLayoutTestDataList theData;
2160         BasicLayoutTestDataList theRemoveData;
2161         BasicLayoutTestResultList theResult;
2162 
2163         theData
2164             // << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, -10)
2165             << BasicData(-1, Qt::AnchorRight, 0, Qt::AnchorHorizontalCenter, 10)
2166             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorRight, 15)
2167             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorVerticalCenter, 10)
2168             << BasicData(0, Qt::AnchorBottom, -1, Qt::AnchorBottom, 5)
2169 
2170             << BasicData(-1, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 66)
2171             << BasicData(1, Qt::AnchorVerticalCenter, -1, Qt::AnchorVerticalCenter, 99)
2172             << BasicData(0, Qt::AnchorHorizontalCenter, 1, Qt::AnchorHorizontalCenter, 33)
2173             << BasicData(0, Qt::AnchorLeft, 0, Qt::AnchorRight, 22)
2174             << BasicData(0, Qt::AnchorTop, 0, Qt::AnchorBottom, 11)
2175             ;
2176 
2177         theRemoveData
2178             << BasicData(1, Qt::AnchorHorizontalCenter, -1, Qt::AnchorHorizontalCenter, 0)
2179             << BasicData(-1, Qt::AnchorVerticalCenter, 1, Qt::AnchorVerticalCenter, 0)
2180             << BasicData(1, Qt::AnchorHorizontalCenter, 0, Qt::AnchorHorizontalCenter, 0)
2181             << BasicData(0, Qt::AnchorRight, 0, Qt::AnchorLeft, 0)
2182             << BasicData(0, Qt::AnchorBottom, 0, Qt::AnchorTop, 0)
2183             ;
2184 
2185         theResult
2186             << BasicResult(0, QRectF(5, 5, 10, 10) );
2187 
2188         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
2189         QTest::ignoreMessage(QtWarningMsg, "QGraphicsAnchorLayout::addAnchor(): Cannot anchor the item to itself");
2190         QTest::newRow("remove, center, basic 2") << QSizeF(20, 20) << theData
2191             << theRemoveData << theResult;
2192     }
2193 
2194 }
2195 
testRemoveCenterAnchor()2196 void tst_QGraphicsAnchorLayout1::testRemoveCenterAnchor()
2197 {
2198     QFETCH(QSizeF, size);
2199     QFETCH(BasicLayoutTestDataList, data);
2200     QFETCH(BasicLayoutTestDataList, removeData);
2201     QFETCH(BasicLayoutTestResultList, result);
2202 
2203     QGraphicsWidget *widget = new QGraphicsWidget;
2204 
2205     // Determine amount of widgets to add.
2206     int widgetCount = -1;
2207     for (int i = 0; i < data.count(); ++i) {
2208         const BasicLayoutTestData item = data[i];
2209         widgetCount = qMax(widgetCount, item.firstIndex);
2210         widgetCount = qMax(widgetCount, item.secondIndex);
2211     }
2212     ++widgetCount; // widgetCount is max of indices.
2213 
2214     // Create dummy widgets
2215     QList<QGraphicsWidget *> widgets;
2216     for (int i = 0; i < widgetCount; ++i) {
2217         TestWidget *w = new TestWidget;
2218         widgets << w;
2219     }
2220 
2221     // Setup anchor layout
2222     TheAnchorLayout *layout = new TheAnchorLayout;
2223 
2224     for (int i = 0; i < data.count(); ++i) {
2225         const BasicLayoutTestData item = data[i];
2226         layout->setAnchor(
2227             getItem(item.firstIndex, widgets, layout),
2228             item.firstEdge,
2229             getItem(item.secondIndex, widgets, layout),
2230             item.secondEdge,
2231             item.spacing );
2232     }
2233 
2234     for (int i = 0; i < removeData.count(); ++i) {
2235         const BasicLayoutTestData item = removeData[i];
2236         layout->removeAnchor(
2237             getItem(item.firstIndex, widgets, layout),
2238             item.firstEdge,
2239             getItem(item.secondIndex, widgets, layout),
2240             item.secondEdge);
2241     }
2242 
2243     widget->setLayout(layout);
2244     widget->setContentsMargins(0,0,0,0);
2245 
2246     widget->resize(size);
2247     QCOMPARE(widget->size(), size);
2248 
2249     // Validate
2250     for (int i = 0; i < result.count(); ++i) {
2251         const BasicLayoutTestResult item = result[i];
2252 
2253         QCOMPARE(widgets[item.index]->geometry(), item.rect);
2254     }
2255 
2256     qDeleteAll(widgets);
2257     delete widget;
2258 }
2259 
testSingleSizePolicy_data()2260 void tst_QGraphicsAnchorLayout1::testSingleSizePolicy_data()
2261 {
2262     QTest::addColumn<QSizeF>("size");
2263     QTest::addColumn<QSizePolicy>("policy");
2264     QTest::addColumn<bool>("valid");
2265 
2266 // FIXED
2267     {
2268         QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
2269         QTest::newRow("single size policy: fixed ok") << QSizeF(70, 70) << sizePolicy << true;
2270     }
2271 /*
2272     {
2273         QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
2274         QTest::newRow("single size policy: fixed too big") << QSizeF(100, 100) << sizePolicy << false;
2275     }
2276 
2277     {
2278         QSizePolicy sizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
2279         QTest::newRow("single size policy: fixed too small") << QSizeF(50, 50) << sizePolicy << false;
2280     }
2281 */
2282 // MINIMUM
2283     {
2284         QSizePolicy sizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
2285         QTest::newRow("single size policy: minimum bigger ok") << QSizeF(100, 100) << sizePolicy << true;
2286     }
2287 
2288     {
2289         QSizePolicy sizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
2290         QTest::newRow("single size policy: minimum limit ok") << QSizeF(70, 70) << sizePolicy << true;
2291     }
2292 /*
2293     {
2294         QSizePolicy sizePolicy( QSizePolicy::Minimum, QSizePolicy::Minimum );
2295         QTest::newRow("single size policy: minimum too small") << QSizeF(50, 50) << sizePolicy << false;
2296     }
2297 */
2298 // MAXIMUM
2299     {
2300         QSizePolicy sizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
2301         QTest::newRow("single size policy: maximum small ok") << QSizeF(50, 50) << sizePolicy << true;
2302     }
2303 
2304     {
2305         QSizePolicy sizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
2306         QTest::newRow("single size policy: maximum limit ok") << QSizeF(70, 70) << sizePolicy << true;
2307     }
2308 /*
2309     {
2310         QSizePolicy sizePolicy( QSizePolicy::Maximum, QSizePolicy::Maximum );
2311         QTest::newRow("single size policy: maximum bigger fail") << QSizeF(100, 100) << sizePolicy << false;
2312     }
2313 */
2314 // PREFERRED
2315     {
2316         QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
2317         QTest::newRow("single size policy: preferred bigger ok") << QSizeF(100, 100) << sizePolicy << true;
2318     }
2319 
2320     {
2321         QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
2322         QTest::newRow("single size policy: preferred smaller ok") << QSizeF(50, 50)  << sizePolicy << true;
2323     }
2324 /*
2325     {
2326         QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
2327         QTest::newRow("single size policy: preferred too big") << QSizeF(700, 700) << sizePolicy << false;
2328     }
2329 
2330     {
2331         QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Preferred );
2332         QTest::newRow("single size policy: preferred too small") << QSizeF(21, 21) << sizePolicy << false;
2333     }
2334 */
2335 // MINIMUMEXPANDING
2336 
2337     {
2338         QSizePolicy sizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
2339         QTest::newRow("single size policy: min.expanding bigger ok") << QSizeF(100, 100) << sizePolicy << true;
2340     }
2341 
2342     {
2343         QSizePolicy sizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
2344         QTest::newRow("single size policy: min.expanding limit ok") << QSizeF(70, 70) << sizePolicy << true;
2345     }
2346 
2347     /*{
2348         QSizePolicy sizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
2349         QTest::newRow("single size policy: min.expanding too small") << QSizeF(50, 50) << sizePolicy << false;
2350     }*/
2351 
2352 // EXPANDING
2353 
2354     {
2355         QSizePolicy sizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
2356         QTest::newRow("single size policy: expanding bigger ok") << QSizeF(100, 100) << sizePolicy << true;
2357     }
2358 
2359     {
2360         QSizePolicy sizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
2361         QTest::newRow("single size policy: expanding smaller ok") << QSizeF(50, 50)  << sizePolicy << true;
2362     }
2363 
2364  // IGNORED
2365 
2366     {
2367         QSizePolicy sizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored );
2368         QTest::newRow("single size policy: ignored bigger ok") << QSizeF(100, 100) << sizePolicy << true;
2369     }
2370 
2371     {
2372         QSizePolicy sizePolicy( QSizePolicy::Ignored, QSizePolicy::Ignored );
2373         QTest::newRow("single size policy: ignored smaller ok") << QSizeF(50, 50)  << sizePolicy << true;
2374     }
2375 }
2376 
testSingleSizePolicy()2377 void tst_QGraphicsAnchorLayout1::testSingleSizePolicy()
2378 {
2379     QFETCH(QSizeF, size);
2380     QFETCH(QSizePolicy, policy);
2381     QFETCH(bool, valid);
2382 
2383     // create objects
2384     QGraphicsWidget widget;
2385     TheAnchorLayout *layout = new TheAnchorLayout;
2386     TestWidget *childWidget = new TestWidget;
2387 
2388     // set anchors
2389     layout->setAnchor( layout, Qt::AnchorLeft, childWidget, Qt::AnchorLeft, 10 );
2390     layout->setAnchor( childWidget, Qt::AnchorRight, layout, Qt::AnchorRight, 10 );
2391     layout->setAnchor( layout, Qt::AnchorTop, childWidget, Qt::AnchorTop, 10 );
2392     layout->setAnchor( childWidget, Qt::AnchorBottom, layout, Qt::AnchorBottom, 10 );
2393 
2394     widget.setLayout( layout );
2395 
2396     // set test case specific: policy and size
2397     childWidget->setSizePolicy( policy );
2398     widget.setGeometry( QRectF( QPoint(0,0), size ) );
2399 
2400     QCOMPARE( layout->isValid() , valid );
2401 
2402     const QRectF childRect = childWidget->geometry();
2403     Q_UNUSED( childRect );
2404 }
2405 
testDoubleSizePolicy_data()2406 void tst_QGraphicsAnchorLayout1::testDoubleSizePolicy_data()
2407 {
2408     // tests only horizontal direction
2409     QTest::addColumn<QSizePolicy>("policy1");
2410     QTest::addColumn<QSizePolicy>("policy2");
2411     QTest::addColumn<qreal>("width1");
2412     QTest::addColumn<qreal>("width2");
2413 
2414     // layout size always 100x100 and size hints for items are 5<50<500
2415     // gabs: 10-item1-10-item2-10
2416 
2417     {
2418         QSizePolicy sizePolicy1( QSizePolicy::Fixed, QSizePolicy::Fixed );
2419         QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2420         const qreal width1 = 50;
2421         const qreal width2 = 100-10-10-10-width1;
2422         QTest::newRow("double size policy: fixed-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2423     }
2424 
2425     {
2426         QSizePolicy sizePolicy1( QSizePolicy::Minimum, QSizePolicy::Minimum );
2427         QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2428         const qreal width1 = 50;
2429         const qreal width2 = 100-10-10-10-width1;
2430         QTest::newRow("double size policy: minimum-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2431     }
2432 
2433     {
2434         QSizePolicy sizePolicy1( QSizePolicy::Maximum, QSizePolicy::Maximum );
2435         QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2436         const qreal width1 = 35;
2437         const qreal width2 = 100-10-10-10-width1;
2438         QTest::newRow("double size policy: maximum-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2439     }
2440 
2441     {
2442         QSizePolicy sizePolicy1( QSizePolicy::Preferred, QSizePolicy::Preferred );
2443         QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2444         const qreal width1 = 35;
2445         const qreal width2 = 100-10-10-10-width1;
2446         QTest::newRow("double size policy: preferred-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2447     }
2448 
2449     {
2450         QSizePolicy sizePolicy1( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
2451         QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2452         const qreal width1 = 50;
2453         const qreal width2 = 100-10-10-10-width1;
2454         QTest::newRow("double size policy: min.expanding-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2455     }
2456 
2457     {
2458         QSizePolicy sizePolicy1( QSizePolicy::Expanding, QSizePolicy::Expanding );
2459         QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2460         const qreal width1 = 35;
2461         const qreal width2 = 100-10-10-10-width1;
2462         QTest::newRow("double size policy: expanding-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2463     }
2464 
2465     // QGAL handling of ignored flag is different
2466     if (0)
2467     {
2468         QSizePolicy sizePolicy1( QSizePolicy::Ignored, QSizePolicy::Ignored );
2469         QSizePolicy sizePolicy2( QSizePolicy::Preferred, QSizePolicy::Preferred );
2470         const qreal width1 = 35;
2471         const qreal width2 = 100-10-10-10-width1;
2472         QTest::newRow("double size policy: ignored-preferred") << sizePolicy1 << sizePolicy2 << width1 << width2;
2473     }
2474 
2475     /*{
2476         QSizePolicy sizePolicy1( QSizePolicy::Fixed, QSizePolicy::Fixed );
2477         QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2478         const qreal width1 = -1;
2479         const qreal width2 = 100-10-10-10-width1;
2480         QTest::newRow("double size policy: fixed-fixed invalid") << sizePolicy1 << sizePolicy2 << width1 << width2;
2481     }*/
2482 
2483     /*{
2484         QSizePolicy sizePolicy1( QSizePolicy::Minimum, QSizePolicy::Minimum );
2485         QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2486         const qreal width1 = -1;
2487         const qreal width2 = 100-10-10-10-width1;
2488         QTest::newRow("double size policy: minimum-fixed invalid") << sizePolicy1 << sizePolicy2 << width1 << width2;
2489     }*/
2490 
2491     {
2492         QSizePolicy sizePolicy1( QSizePolicy::Maximum, QSizePolicy::Maximum );
2493         QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2494         const qreal width1 = 20;
2495         const qreal width2 = 100-10-10-10-width1;
2496         QTest::newRow("double size policy: maximum-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2;
2497     }
2498 
2499     {
2500         QSizePolicy sizePolicy1( QSizePolicy::Preferred, QSizePolicy::Preferred );
2501         QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2502         const qreal width1 = 20;
2503         const qreal width2 = 100-10-10-10-width1;
2504         QTest::newRow("double size policy: preferred-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2;
2505     }
2506 
2507     /*{
2508         QSizePolicy sizePolicy1( QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding );
2509         QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2510         const qreal width1 = -1;
2511         const qreal width2 = 100-10-10-10-width1;
2512         QTest::newRow("double size policy: min.expanding-fixed invalid") << sizePolicy1 << sizePolicy2 << width1 << width2;
2513     }*/
2514 
2515     {
2516         QSizePolicy sizePolicy1( QSizePolicy::Expanding, QSizePolicy::Expanding );
2517         QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2518         const qreal width1 = 20;
2519         const qreal width2 = 100-10-10-10-width1;
2520         QTest::newRow("double size policy: expanding-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2;
2521     }
2522 
2523     {
2524         QSizePolicy sizePolicy1( QSizePolicy::Ignored, QSizePolicy::Ignored );
2525         QSizePolicy sizePolicy2( QSizePolicy::Fixed, QSizePolicy::Fixed );
2526         const qreal width1 = 20;
2527         const qreal width2 = 100-10-10-10-width1;
2528         QTest::newRow("double size policy: ignored-fixed") << sizePolicy1 << sizePolicy2 << width1 << width2;
2529     }
2530 }
2531 
testDoubleSizePolicy()2532 void tst_QGraphicsAnchorLayout1::testDoubleSizePolicy()
2533 {
2534     QFETCH(QSizePolicy, policy1);
2535     QFETCH(QSizePolicy, policy2);
2536     QFETCH(qreal, width1);
2537     QFETCH(qreal, width2);
2538 
2539     // create objects
2540     QGraphicsWidget widget;
2541     TheAnchorLayout *layout = new TheAnchorLayout;
2542     TestWidget *childWidget1 = new TestWidget;
2543     TestWidget *childWidget2 = new TestWidget;
2544 
2545     // set anchors
2546     layout->setAnchor( layout, Qt::AnchorLeft, childWidget1, Qt::AnchorLeft, 10 );
2547     layout->setAnchor( childWidget1, Qt::AnchorRight, childWidget2, Qt::AnchorLeft, 10 );
2548     layout->setAnchor( childWidget2, Qt::AnchorRight, layout, Qt::AnchorRight, 10 );
2549 
2550     widget.setLayout( layout );
2551 
2552     // set test case specific: policy
2553     childWidget1->setSizePolicy( policy1 );
2554     childWidget2->setSizePolicy( policy2 );
2555 
2556     widget.setGeometry( QRectF( QPoint(0,0), QSize( 100,100 ) ) );
2557 
2558     // check results:
2559     if ( width1 == -1.0f ) {
2560         // invalid
2561         QCOMPARE( layout->isValid() , false );
2562     } else {
2563         // valid
2564         QCOMPARE( childWidget1->geometry().width(), width1 );
2565         QCOMPARE( childWidget2->geometry().width(), width2 );
2566     }
2567 }
2568 
2569 typedef QMap<int,qreal> SizeHintArray;
Q_DECLARE_METATYPE(SizeHintArray)2570 Q_DECLARE_METATYPE(SizeHintArray)
2571 
2572 void tst_QGraphicsAnchorLayout1::testSizeDistribution_data()
2573 {
2574     // tests only horizontal direction
2575     QTest::addColumn<SizeHintArray>("sizeHints1");
2576     QTest::addColumn<SizeHintArray>("sizeHints2");
2577     QTest::addColumn<qreal>("width1");
2578     QTest::addColumn<qreal>("width2");
2579 
2580     // layout size always 100x100 and size policy for items is preferred-preferred
2581     // gabs: 10-item1-10-item2-10
2582 
2583     {
2584         SizeHintArray sizeHints1;
2585         sizeHints1.insert( Qt::MinimumSize, 30 );
2586         sizeHints1.insert( Qt::PreferredSize, 35 );
2587         sizeHints1.insert( Qt::MaximumSize, 40 );
2588 
2589         SizeHintArray sizeHints2;
2590         sizeHints2.insert( Qt::MinimumSize, 5 );
2591         sizeHints2.insert( Qt::PreferredSize, 35 );
2592         sizeHints2.insert( Qt::MaximumSize, 300 );
2593 
2594         const qreal width1 = 35;
2595         const qreal width2 = 100-10-10-10-width1;
2596         QTest::newRow("size distribution: preferred equal") << sizeHints1 << sizeHints2 << width1 << width2;
2597     }
2598 
2599     {
2600         SizeHintArray sizeHints1;
2601         sizeHints1.insert( Qt::MinimumSize, 0 );
2602         sizeHints1.insert( Qt::PreferredSize, 20 );
2603         sizeHints1.insert( Qt::MaximumSize, 100 );
2604 
2605         SizeHintArray sizeHints2;
2606         sizeHints2.insert( Qt::MinimumSize, 0 );
2607         sizeHints2.insert( Qt::PreferredSize, 50 );
2608         sizeHints2.insert( Qt::MaximumSize, 100 );
2609 
2610         const qreal width1 = 20;
2611         const qreal width2 = 100-10-10-10-width1;
2612         QTest::newRow("size distribution: preferred non-equal") << sizeHints1 << sizeHints2 << width1 << width2;
2613     }
2614 
2615     {
2616         SizeHintArray sizeHints1;
2617         sizeHints1.insert( Qt::MinimumSize, 0 );
2618         sizeHints1.insert( Qt::PreferredSize, 40 );
2619         sizeHints1.insert( Qt::MaximumSize, 100 );
2620 
2621         SizeHintArray sizeHints2;
2622         sizeHints2.insert( Qt::MinimumSize, 0 );
2623         sizeHints2.insert( Qt::PreferredSize, 60 );
2624         sizeHints2.insert( Qt::MaximumSize, 100 );
2625 
2626         const qreal width1 = 28; // got from manual calculation
2627         const qreal width2 = 100-10-10-10-width1;
2628         QTest::newRow("size distribution: below preferred") << sizeHints1 << sizeHints2 << width1 << width2;
2629     }
2630 
2631     {
2632         SizeHintArray sizeHints1;
2633         sizeHints1.insert( Qt::MinimumSize, 0 );
2634         sizeHints1.insert( Qt::PreferredSize, 10 );
2635         sizeHints1.insert( Qt::MaximumSize, 100 );
2636 
2637         SizeHintArray sizeHints2;
2638         sizeHints2.insert( Qt::MinimumSize, 0 );
2639         sizeHints2.insert( Qt::PreferredSize, 40 );
2640         sizeHints2.insert( Qt::MaximumSize, 100 );
2641 
2642         const qreal width1 = 22; // got from manual calculation
2643         const qreal width2 = 100-10-10-10-width1;
2644         QTest::newRow("size distribution: above preferred") << sizeHints1 << sizeHints2 << width1 << width2;
2645     }
2646 
2647 }
2648 
testSizeDistribution()2649 void tst_QGraphicsAnchorLayout1::testSizeDistribution()
2650 {
2651     QFETCH(SizeHintArray, sizeHints1);
2652     QFETCH(SizeHintArray, sizeHints2);
2653     QFETCH(qreal, width1);
2654     QFETCH(qreal, width2);
2655 
2656     // sanity-check the test data - MinimumSize <= PreferredSize <= MaximumSize
2657     QVERIFY( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) );
2658     QVERIFY( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) );
2659     QVERIFY( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) );
2660     QVERIFY( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) );
2661 
2662     // create objects
2663     QGraphicsWidget widget;
2664     TheAnchorLayout *layout = new TheAnchorLayout;
2665     TestWidget *childWidget1 = new TestWidget;
2666     TestWidget *childWidget2 = new TestWidget;
2667 
2668     // set anchors
2669     layout->setAnchor( layout, Qt::AnchorLeft, childWidget1, Qt::AnchorLeft, 10 );
2670     layout->setAnchor( childWidget1, Qt::AnchorRight, childWidget2, Qt::AnchorLeft, 10 );
2671     layout->setAnchor( childWidget2, Qt::AnchorRight, layout, Qt::AnchorRight, 10 );
2672 
2673     widget.setLayout( layout );
2674 
2675     // set test case specific: size hints
2676     childWidget1->setMinimumWidth( sizeHints1.value( Qt::MinimumSize ) );
2677     childWidget1->setPreferredWidth( sizeHints1.value( Qt::PreferredSize ) );
2678     childWidget1->setMaximumWidth( sizeHints1.value( Qt::MaximumSize ) );
2679 
2680     childWidget2->setMinimumWidth( sizeHints2.value( Qt::MinimumSize ) );
2681     childWidget2->setPreferredWidth( sizeHints2.value( Qt::PreferredSize ) );
2682     childWidget2->setMaximumWidth( sizeHints2.value( Qt::MaximumSize ) );
2683 
2684     widget.setGeometry( QRectF( QPoint(0,0), QSize( 100,100 ) ) );
2685 
2686     // check results:
2687     if ( width1 == -1.0f ) {
2688         // invalid
2689         QCOMPARE( layout->isValid() , false );
2690     } else {
2691         // valid
2692         QCOMPARE( float(childWidget1->geometry().width()), float(width1) );
2693         QCOMPARE( float(childWidget2->geometry().width()), float(width2) );
2694     }
2695 }
2696 
testSizeHint()2697 void tst_QGraphicsAnchorLayout1::testSizeHint()
2698 {
2699     QGraphicsWidget *widget[5];
2700 
2701     for( int i = 0; i < 5; i++ ) {
2702         widget[i] = new QGraphicsWidget;
2703         widget[i]->setMinimumSize( 10, 10 );
2704         widget[i]->setPreferredSize( 20, 20 );
2705         widget[i]->setMaximumSize( 40, 40 );
2706     }
2707 
2708     // one, basic
2709     {
2710         TheAnchorLayout *layout = new TheAnchorLayout();
2711 
2712 
2713         layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 );
2714         layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, 0 );
2715 
2716         layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 );
2717         layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 );
2718 
2719         QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() );
2720         QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() );
2721         QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() );
2722 
2723 
2724         delete layout;
2725     }
2726 
2727     // one, basic again
2728     {
2729         TheAnchorLayout *layout = new TheAnchorLayout();
2730 
2731 
2732         layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 10 );
2733         // layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, -10 );
2734         layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, 10 );
2735 
2736         layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 10 );
2737         // layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, -10 );
2738         layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 10 );
2739 
2740         QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() + QSizeF( 20, 20 ) );
2741         QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() + QSizeF( 20, 20 ) );
2742         QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() + QSizeF( 20, 20 ) );
2743 
2744         delete layout;
2745     }
2746 
2747     // two, serial
2748     {
2749         TheAnchorLayout *layout = new TheAnchorLayout();
2750 
2751 
2752         layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 );
2753         layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 );
2754         layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 );
2755 
2756         layout->setAnchor(widget[0], Qt::AnchorRight, widget[1], Qt::AnchorLeft, 0 );
2757         layout->setAnchor(widget[1], Qt::AnchorRight, layout, Qt::AnchorRight, 0 );
2758 
2759 
2760         QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() + QSizeF( widget[1]->minimumWidth(), 0 ) );
2761         QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() + QSizeF( widget[1]->preferredWidth(), 0 ) );
2762         QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() + QSizeF( widget[1]->maximumWidth(), 0 ) );
2763 
2764         delete layout;
2765     }
2766 
2767     // two, parallel
2768     {
2769         TheAnchorLayout *layout = new TheAnchorLayout();
2770 
2771 
2772         layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 );
2773         layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 );
2774         layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 );
2775         layout->setAnchor(layout, Qt::AnchorRight, widget[0], Qt::AnchorRight, 0 );
2776 
2777         layout->setAnchor(layout, Qt::AnchorLeft, widget[1], Qt::AnchorLeft, 0 );
2778         layout->setAnchor(layout, Qt::AnchorTop, widget[1], Qt::AnchorTop, 0 );
2779         layout->setAnchor(layout, Qt::AnchorBottom, widget[1], Qt::AnchorBottom, 0 );
2780         layout->setAnchor(layout, Qt::AnchorRight, widget[1], Qt::AnchorRight, 0 );
2781 
2782         QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() );
2783         QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() );
2784         QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() );
2785 
2786         delete layout;
2787     }
2788 
2789     // five, serial
2790     {
2791         TheAnchorLayout *layout = new TheAnchorLayout();
2792 
2793 
2794         layout->setAnchor(layout, Qt::AnchorLeft, widget[0], Qt::AnchorLeft, 0 );
2795         layout->setAnchor(layout, Qt::AnchorTop, widget[0], Qt::AnchorTop, 0 );
2796         layout->setAnchor(layout, Qt::AnchorBottom, widget[0], Qt::AnchorBottom, 0 );
2797 
2798         layout->setAnchor(widget[0], Qt::AnchorRight, widget[1], Qt::AnchorLeft, 0 );
2799         layout->setAnchor(widget[1], Qt::AnchorRight, widget[2], Qt::AnchorLeft, 0 );
2800         layout->setAnchor(widget[2], Qt::AnchorRight, widget[3], Qt::AnchorLeft, 0 );
2801         layout->setAnchor(widget[3], Qt::AnchorRight, widget[4], Qt::AnchorLeft, 0 );
2802         layout->setAnchor(widget[4], Qt::AnchorRight, layout, Qt::AnchorRight, 0 );
2803 
2804 
2805         QCOMPARE( layout->minimumSize(), widget[0]->minimumSize() +
2806         QSizeF( widget[1]->minimumWidth() +
2807         widget[2]->minimumWidth() +
2808         widget[3]->minimumWidth() +
2809         widget[4]->minimumWidth(), 0 ) );
2810 
2811         QCOMPARE( layout->preferredSize(), widget[0]->preferredSize() +
2812         QSizeF( widget[1]->preferredWidth() +
2813         widget[2]->preferredWidth() +
2814         widget[3]->preferredWidth() +
2815         widget[4]->preferredWidth(), 0 ) );
2816 
2817         QCOMPARE( layout->maximumSize(), widget[0]->maximumSize() +
2818         QSizeF( widget[1]->maximumWidth() +
2819         widget[2]->maximumWidth() +
2820         widget[3]->maximumWidth() +
2821         widget[4]->maximumWidth(), 0 ) );
2822 
2823         delete layout;
2824     }
2825 
2826 
2827     for( int i = 0; i < 5; i++ ) {
2828         delete widget[i];
2829     }
2830 }
2831 
2832 #ifdef TEST_COMPLEX_CASES
2833 
testComplexCases_data()2834 void tst_QGraphicsAnchorLayout1::testComplexCases_data()
2835 {
2836     QTest::addColumn<QSizeF>("size");
2837     QTest::addColumn<BasicLayoutTestDataList>("data");
2838     QTest::addColumn<AnchorItemSizeHintList>("sizehint");
2839     QTest::addColumn<BasicLayoutTestResultList>("result");
2840 
2841     typedef BasicLayoutTestData BasicData;
2842     typedef BasicLayoutTestResult BasicResult;
2843 
2844     // Three widgets, the same sizehint
2845     {
2846         BasicLayoutTestDataList theData;
2847         AnchorItemSizeHintList theSizeHint;
2848         BasicLayoutTestResultList theResult1;
2849         BasicLayoutTestResultList theResult2;
2850 
2851         theData
2852             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
2853             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
2854             << BasicData(0, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
2855 
2856             << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
2857             << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
2858 
2859             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
2860             << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
2861             << BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0)
2862          ;
2863 
2864         theSizeHint
2865             << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2866             << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2867             << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2868          ;
2869         theResult1
2870             << BasicResult(0, QRectF(10, 0, 30, 50) )
2871             << BasicResult(1, QRectF(50, 0, 30, 50) )
2872             << BasicResult(2, QRectF(50, 0, 30, 50) )
2873             ;
2874 
2875         theResult2
2876             << BasicResult(0, QRectF(10, 0, 60, 50) )
2877             << BasicResult(1, QRectF(80, 0, 60, 50) )
2878             << BasicResult(2, QRectF(80, 0, 60, 50) )
2879             ;
2880 
2881         QTest::newRow("Three, the same sizehint(1)") << QSizeF(90, 50) << theData << theSizeHint << theResult1;
2882         QTest::newRow("Three, the same sizehint(2)") << QSizeF(150, 50) << theData << theSizeHint << theResult2;
2883     }
2884 
2885     // Three widgets, serial is bigger
2886     {
2887         BasicLayoutTestDataList theData;
2888         AnchorItemSizeHintList theSizeHint;
2889         BasicLayoutTestResultList theResult;
2890 
2891         theData
2892             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
2893             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
2894             << BasicData(0, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
2895 
2896             << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
2897             << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
2898 
2899             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
2900             << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
2901             << BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0)
2902          ;
2903 
2904         theSizeHint
2905             << AnchorItemSizeHint( 0, 100, 200, 0, 50, 100 )
2906             << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2907             << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2908          ;
2909 
2910         theResult
2911             << BasicResult(0, QRectF(10, 0, 70, 50) )
2912             << BasicResult(1, QRectF(90, 0, 35, 50) )
2913             << BasicResult(2, QRectF(90, 0, 35, 50) );
2914 
2915         QTest::newRow("Three, serial is bigger") << QSizeF(135, 50) << theData << theSizeHint << theResult;
2916 
2917         // theResult
2918         //     << BasicResult(0, QRectF(10, 0, 80, 50) )
2919         //     << BasicResult(1, QRectF(100, 0, 60, 50) )
2920         //     << BasicResult(2, QRectF(100, 0, 60, 50) )
2921         // ;
2922 
2923         // QTest::newRow("Three, serial is bigger") << QSizeF(170, 50) << theData << theSizeHint << theResult;
2924     }
2925 
2926 
2927     // Three widgets, parallel is bigger
2928     {
2929         BasicLayoutTestDataList theData;
2930         AnchorItemSizeHintList theSizeHint;
2931         BasicLayoutTestResultList theResult;
2932 
2933         theData
2934             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
2935             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
2936             << BasicData(0, Qt::AnchorRight, 2, Qt::AnchorLeft, 10)
2937 
2938             << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
2939             << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
2940 
2941             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
2942             << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
2943             << BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0)
2944          ;
2945 
2946         theSizeHint
2947             << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2948             << AnchorItemSizeHint( 0, 100, 200, 0, 50, 100 )
2949             << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
2950          ;
2951 
2952         // ### QGAL uses a different preferred size calculation algorithm.
2953         //     This algorithm was discussed with Jan-Arve and tries to grow
2954         //     items instead of shrinking them.
2955         //     In this case, the preferred size of each item becomes:
2956         //     Item 0: 50
2957         //     Item 1: 100 (grows to avoid shrinking item 2)
2958         //     Item 2: 100
2959         //     Therefore, the preferred size of the parent widget becomes
2960         //     180 == (10 + 50 + 10 + 100 + 10)
2961         //     As we set its size to 150, each widget is shrinked in the same
2962         //     ratio, in order to achieve the width of 150 == (10 + 40 + 10 + 80 + 10)
2963 
2964         theResult
2965             << BasicResult(0, QRectF(10, 0, 40, 50) )
2966             << BasicResult(1, QRectF(60, 0, 80, 50) )
2967             << BasicResult(2, QRectF(60, 0, 80, 50) )
2968             ;
2969 
2970         QTest::newRow("Three, parallel is bigger") << QSizeF(150, 50) << theData << theSizeHint << theResult;
2971 
2972         // #ifdef PREFERRED_IS_AVERAGE
2973         //         theResult
2974         //             << BasicResult(0, QRectF(10, 0, 50, 50) )
2975         //             << BasicResult(1, QRectF(70, 0, 75, 50) )
2976         //             << BasicResult(2, QRectF(70, 0, 75, 50) )
2977         //             ;
2978 
2979         //         QTest::newRow("Three, parallel is bigger") << QSizeF(155, 50) << theData << theSizeHint << theResult;
2980         // #else
2981         //         theResult
2982         //             << BasicResult(0, QRectF(10, 0, 50, 50) )
2983         //             << BasicResult(1, QRectF(70, 0, 66.66666666666666, 50) )
2984         //             << BasicResult(2, QRectF(70, 0, 60.66666666666666, 50) )
2985         //             ;
2986 
2987         //         QTest::newRow("Three, parallel is bigger") << QSizeF(146.66666666666666, 50) << theData << theSizeHint << theResult;
2988         // #endif
2989     }
2990 
2991     // Three widgets, the same sizehint, one center anchor
2992     {
2993         BasicLayoutTestDataList theData;
2994         AnchorItemSizeHintList theSizeHint;
2995         BasicLayoutTestResultList theResult;
2996 
2997         theData
2998             << BasicData(-1, Qt::AnchorLeft, 0, Qt::AnchorLeft, 10)
2999             << BasicData(0, Qt::AnchorRight, 1, Qt::AnchorLeft, 10)
3000             << BasicData(0, Qt::AnchorHorizontalCenter, 2, Qt::AnchorLeft, 10)
3001 
3002             << BasicData(1, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
3003             << BasicData(2, Qt::AnchorRight, -1, Qt::AnchorRight, 10)
3004 
3005             << BasicData(-1, Qt::AnchorTop, 0, Qt::AnchorTop, 0)
3006             << BasicData(-1, Qt::AnchorTop, 1, Qt::AnchorTop, 0)
3007             << BasicData(-1, Qt::AnchorTop, 2, Qt::AnchorTop, 0)
3008          ;
3009 
3010         theSizeHint
3011             << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
3012             << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
3013             << AnchorItemSizeHint( 0, 50, 100, 0, 50, 100 )
3014          ;
3015         theResult
3016             << BasicResult(0, QRectF(10, 0, 40, 50) )
3017             << BasicResult(1, QRectF(60, 0, 40, 50) )
3018             << BasicResult(2, QRectF(40, 0, 60, 50) )
3019             ;
3020 
3021             ;
3022 
3023         QTest::newRow("Three, the same sizehint, one center anchor") << QSizeF(110, 50) << theData << theSizeHint << theResult;
3024     }
3025 }
3026 
testComplexCases()3027 void tst_QGraphicsAnchorLayout1::testComplexCases()
3028 {
3029     QFETCH(QSizeF, size);
3030     QFETCH(BasicLayoutTestDataList, data);
3031     QFETCH(AnchorItemSizeHintList, sizehint);
3032     QFETCH(BasicLayoutTestResultList, result);
3033 
3034     QGraphicsWidget *widget = new QGraphicsWidget;
3035 
3036     // Determine amount of widgets to add.
3037     int widgetCount = -1;
3038     for (int i = 0; i < data.count(); ++i) {
3039         const BasicLayoutTestData item = data[i];
3040         widgetCount = qMax(widgetCount, item.firstIndex);
3041         widgetCount = qMax(widgetCount, item.secondIndex);
3042     }
3043     ++widgetCount; // widgetCount is max of indices.
3044 
3045     // Create dummy widgets
3046     QList<QGraphicsWidget *> widgets;
3047     for (int i = 0; i < widgetCount; ++i) {
3048         TestWidget *w = new TestWidget;
3049 
3050         w->setMinimumWidth( sizehint[i].hmin );
3051         w->setPreferredWidth( sizehint[i].hpref );
3052         w->setMaximumWidth( sizehint[i].hmax );
3053 
3054         w->setMinimumHeight( sizehint[i].vmin );
3055         w->setPreferredHeight( sizehint[i].vpref );
3056         w->setMaximumHeight( sizehint[i].vmax );
3057 
3058         widgets << w;
3059     }
3060 
3061     // Setup anchor layout
3062     TheAnchorLayout *layout = new TheAnchorLayout;
3063 
3064     for (int i = 0; i < data.count(); ++i) {
3065         const BasicLayoutTestData item = data[i];
3066         layout->setAnchor(
3067             getItem(item.firstIndex, widgets, layout),
3068             item.firstEdge,
3069             getItem(item.secondIndex, widgets, layout),
3070             item.secondEdge,
3071             item.spacing );
3072     }
3073 
3074     widget->setLayout(layout);
3075     widget->setContentsMargins(0,0,0,0);
3076 
3077     widget->resize(size);
3078     QCOMPARE(widget->size(), size);
3079 
3080 //    QTest::qWait(500); // layouting is asynchronous..
3081 
3082     // Validate
3083     for (int i = 0; i < result.count(); ++i) {
3084         const BasicLayoutTestResult item = result[i];
3085         QCOMPARE(widgets[item.index]->geometry(), item.rect);
3086     }
3087 
3088     // Test mirrored mode
3089     widget->setLayoutDirection(Qt::RightToLeft);
3090     layout->activate();
3091     // Validate
3092     for (int j = 0; j < result.count(); ++j) {
3093         const BasicLayoutTestResult item = result[j];
3094         QRectF mirroredRect(item.rect);
3095         // only valid cases are mirrored
3096         if (mirroredRect.isValid()){
3097             mirroredRect.moveLeft(size.width()-item.rect.width()-item.rect.left());
3098         }
3099         QCOMPARE(widgets[item.index]->geometry(), mirroredRect);
3100         delete widgets[item.index];
3101     }
3102 
3103     delete widget;
3104 }
3105 #endif //TEST_COMPLEX_CASES
3106 
3107 
3108 QTEST_MAIN(tst_QGraphicsAnchorLayout1)
3109 #include "tst_qgraphicsanchorlayout1.moc"
3110 //-----------------------------------------------------------------------------
3111 
3112