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