qt5base-lts/tests/auto/widgets/graphicsview/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp
Jason McDonald 5635823e17 Remove "All rights reserved" line from license headers.
As in the past, to avoid rewriting various autotests that contain
line-number information, an extra blank line has been inserted at the
end of the license text to ensure that this commit does not change the
total number of lines in the license header.

Change-Id: I311e001373776812699d6efc045b5f742890c689
Reviewed-by: Rohan McGovern <rohan.mcgovern@nokia.com>
2012-01-30 03:54:59 +01:00

1650 lines
55 KiB
C++

/****************************************************************************
**
** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest/QtTest>
#include <qgraphicslinearlayout.h>
#include <qgraphicsproxywidget.h>
#include <qgraphicswidget.h>
#include <qgraphicsscene.h>
#include <qgraphicsview.h>
#include <qapplication.h>
#include <qplastiquestyle.h>
class tst_QGraphicsLinearLayout : public QObject {
Q_OBJECT
public slots:
void initTestCase();
void cleanupTestCase();
void init();
void cleanup();
private slots:
void qgraphicslinearlayout_data();
void qgraphicslinearlayout();
void alignment_data();
void alignment();
void count_data();
void count();
void dump_data();
void dump();
void geometry_data();
void geometry();
void insertItem_data();
void insertItem();
void insertStretch_data();
void insertStretch();
void invalidate_data();
void invalidate();
void itemAt_data();
void itemAt();
void itemAt_visualOrder();
void orientation_data();
void orientation();
void removeAt_data();
void removeAt();
void removeItem_data();
void removeItem();
void setGeometry_data();
void setGeometry();
void setSpacing_data();
void setSpacing();
void setItemSpacing_data();
void setItemSpacing();
void itemSpacing();
void setStretchFactor_data();
void setStretchFactor();
void testStretch();
void defaultStretchFactors_data();
void defaultStretchFactors();
void sizeHint_data();
void sizeHint();
void updateGeometry();
void layoutDirection();
void removeLayout();
void avoidRecursionInInsertItem();
void styleInfoLeak();
void testAlignmentInLargerLayout();
void testOffByOneInLargerLayout();
void testDefaultAlignment();
void combineSizePolicies();
// Task specific tests
void task218400_insertStretchCrash();
};
// Subclass that exposes the protected functions.
class SubQGraphicsLinearLayout : public QGraphicsLinearLayout {
public:
SubQGraphicsLinearLayout(Qt::Orientation orientation = Qt::Horizontal) : QGraphicsLinearLayout(orientation),
graphicsSceneResize(0),
layoutRequest(0),
layoutDirectionChange(0)
{ }
void widgetEvent(QEvent *e)
{
switch (e->type()) {
case QEvent::GraphicsSceneResize:
graphicsSceneResize++;
break;
case QEvent::LayoutRequest:
layoutRequest++;
break;
case QEvent::LayoutDirectionChange:
layoutDirectionChange++;
break;
default:
break;
}
QGraphicsLinearLayout::widgetEvent(e);
}
int graphicsSceneResize;
int layoutRequest;
int layoutDirectionChange;
};
// This will be called before the first test function is executed.
// It is only called once.
void tst_QGraphicsLinearLayout::initTestCase()
{
// since the style will influence the results, we have to ensure
// that the tests are run using the same style on all platforms
#if defined (Q_WS_WINCE)
QApplication::setStyle(new QWindowsStyle);
#else
QApplication::setStyle(new QPlastiqueStyle);
#endif
}
// This will be called after the last test function is executed.
// It is only called once.
void tst_QGraphicsLinearLayout::cleanupTestCase()
{
}
// This will be called before each test function is executed.
void tst_QGraphicsLinearLayout::init()
{
}
// This will be called after every test function.
void tst_QGraphicsLinearLayout::cleanup()
{
}
class RectWidget : public QGraphicsWidget
{
public:
RectWidget(QGraphicsItem *parent = 0, const QBrush &brush = QBrush()) : QGraphicsWidget(parent){ m_brush = brush;}
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
Q_UNUSED(widget);
painter->setBrush(m_brush);
painter->drawRoundRect(rect());
}
void setSizeHint(Qt::SizeHint which, const QSizeF &size) {
m_sizeHints[which] = size;
updateGeometry();
}
virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const {
if (m_sizeHints[which].isValid()) {
return m_sizeHints[which];
}
return QGraphicsWidget::sizeHint(which, constraint);
}
QSizeF m_sizeHints[Qt::NSizeHints];
QBrush m_brush;
};
Q_DECLARE_METATYPE(Qt::Orientation)
void tst_QGraphicsLinearLayout::qgraphicslinearlayout_data()
{
QTest::addColumn<Qt::Orientation>("orientation");
QTest::newRow("vertical") << Qt::Vertical;
QTest::newRow("horizontal") << Qt::Horizontal;
}
void tst_QGraphicsLinearLayout::qgraphicslinearlayout()
{
QFETCH(Qt::Orientation, orientation);
SubQGraphicsLinearLayout layout(orientation);
QVERIFY(layout.isLayout());
qApp->processEvents();
QCOMPARE(layout.graphicsSceneResize, 0);
QCOMPARE(layout.layoutRequest, 0);
QCOMPARE(layout.layoutDirectionChange, 0);
layout.setOrientation(Qt::Vertical);
layout.orientation();
QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::insertItem: cannot insert null item");
QCOMPARE(layout.count(), 0);
layout.addItem(0);
QCOMPARE(layout.count(), 0);
layout.addStretch(0);
QCOMPARE(layout.count(), 0);
QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::insertItem: cannot insert null item");
layout.insertItem(0, 0);
layout.insertStretch(0, 0);
layout.removeItem(0);
QCOMPARE(layout.count(), 0);
layout.setSpacing(0);
layout.spacing();
QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::setStretchFactor: cannot assign a stretch factor to a null item");
layout.setStretchFactor(0, 0);
QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::setStretchFactor: cannot return a stretch factor for a null item");
layout.stretchFactor(0);
layout.setAlignment(0, Qt::AlignHCenter);
QCOMPARE(layout.alignment(0), 0);
layout.setGeometry(QRectF());
layout.geometry();
QCOMPARE(layout.count(), 0);
layout.invalidate();
layout.sizeHint(Qt::MinimumSize, QSizeF());
}
Q_DECLARE_METATYPE(Qt::AlignmentFlag)
void tst_QGraphicsLinearLayout::alignment_data()
{
QTest::addColumn<Qt::Orientation>("orientation");
QTest::addColumn<QSize>("newSize");
QTest::newRow("h-defaultsize") << Qt::Horizontal << QSize();
QTest::newRow("v-defaultsize") << Qt::Vertical << QSize();
QTest::newRow("h-300") << Qt::Horizontal << QSize(300,100);
QTest::newRow("v-300") << Qt::Vertical << QSize(100, 300);
}
void tst_QGraphicsLinearLayout::alignment()
{
QFETCH(Qt::Orientation, orientation);
QFETCH(QSize, newSize);
//if (alignment == Qt::AlignAbsolute)
// QApplication::setLayoutDirection(Qt::RightToLeft);
QGraphicsScene scene;
QGraphicsView view(&scene);
view.setSceneRect(0, 0, 320, 240);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout(orientation));
scene.addItem(widget);
widget->setLayout(&layout);
static const Qt::Alignment alignmentsToTest[] = {
(Qt::Alignment)0,
Qt::AlignLeft,
Qt::AlignRight,
Qt::AlignHCenter,
Qt::AlignTop,
Qt::AlignBottom,
Qt::AlignVCenter,
Qt::AlignCenter,
(Qt::Alignment)0,
Qt::AlignLeft,
Qt::AlignRight,
Qt::AlignHCenter,
Qt::AlignTop,
Qt::AlignBottom,
Qt::AlignVCenter,
Qt::AlignCenter
};
int i;
bool addWidget = true;
for (size_t i = 0; i < sizeof(alignmentsToTest)/sizeof(Qt::Alignment); ++i) {
QGraphicsLayoutItem *loutItem;
Qt::Alignment align = alignmentsToTest[i];
if (!align && i > 0)
addWidget = false;
if (addWidget)
loutItem = new RectWidget(widget, QBrush(Qt::blue));
else {
SubQGraphicsLinearLayout *lay = new SubQGraphicsLinearLayout(Qt::Vertical);
lay->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::DefaultType);
lay->setContentsMargins(0,0,0,0);
QGraphicsWidget *w = new RectWidget(widget, QBrush(Qt::red));
if (align) {
w->setMinimumSize(QSizeF(10,10));
w->setMaximumSize(QSizeF(10,10));
} else {
w->setMinimumSize(QSizeF(50,50));
w->setMaximumSize(QSizeF(50,50));
}
lay->addItem(w);
loutItem = lay;
}
if (align) {
loutItem->setMinimumSize(QSizeF(10,10));
loutItem->setMaximumSize(QSizeF(10,10));
} else {
loutItem->setMinimumSize(QSizeF(50,50));
loutItem->setMaximumSize(QSizeF(50,50));
}
layout.addItem(loutItem);
layout.setAlignment(loutItem, align);
}
layout.setContentsMargins(0,0,0,0);
int spacing = 1;
layout.setSpacing(spacing);
if (newSize.isValid())
widget->resize(newSize);
view.show();
widget->show();
QTest::qWaitForWindowShown(&view);
QApplication::processEvents();
int x = 0;
int y = 0;
for (i = 0; i < layout.count(); ++i) {
QGraphicsLayoutItem *item = layout.itemAt(i);
Qt::Alignment align = layout.alignment(item);
int w = 10;
int h = 10;
switch(align) {
case Qt::AlignLeft:
break;
case Qt::AlignRight:
if (orientation == Qt::Vertical)
x += 40;
break;
case Qt::AlignHCenter:
if (orientation == Qt::Vertical)
x += 20;
break;
case Qt::AlignTop:
break;
case Qt::AlignBottom:
if (orientation == Qt::Horizontal)
y += 40;
break;
case Qt::AlignVCenter:
if (orientation == Qt::Horizontal)
y += 20;
break;
case Qt::AlignCenter:
if (orientation == Qt::Horizontal)
y += 20;
else
x += 20;
break;
case 0:
w = 50;
h = 50;
break;
default:
break;
}
QRectF expectedGeometry(x, y, w, h);
QCOMPARE(item->geometry(), expectedGeometry);
if (orientation == Qt::Horizontal) {
x += w;
y = 0;
x += spacing;
} else {
x = 0;
y += h;
y += spacing;
}
}
}
void tst_QGraphicsLinearLayout::count_data()
{
QTest::addColumn<int>("itemCount");
QTest::addColumn<int>("layoutCount");
QTest::newRow("0, 0") << 0 << 0;
QTest::newRow("0, 5") << 0 << 5;
QTest::newRow("5, 0") << 5 << 0;
QTest::newRow("5, 5") << 5 << 5;
}
// int count() const public
void tst_QGraphicsLinearLayout::count()
{
QFETCH(int, itemCount);
QFETCH(int, layoutCount);
SubQGraphicsLinearLayout layout;
QCOMPARE(layout.count(), 0);
for (int i = 0; i < itemCount; ++i)
layout.addItem(new QGraphicsWidget);
QCOMPARE(layout.count(), itemCount);
for (int i = 0; i < layoutCount; ++i)
layout.addItem(new SubQGraphicsLinearLayout);
QCOMPARE(layout.count(), itemCount + layoutCount);
// see also removeAt()
}
void tst_QGraphicsLinearLayout::dump_data()
{
QTest::addColumn<int>("itemCount");
QTest::addColumn<int>("layoutCount");
for (int i = -1; i < 3; ++i) {
QTest::newRow(QString("%1, 0, 0").arg(i).toLatin1()) << 0 << 0;
QTest::newRow(QString("%1, 0, 5").arg(i).toLatin1()) << 5 << 5;
QTest::newRow(QString("%1, 5, 0").arg(i).toLatin1()) << 5 << 5;
QTest::newRow(QString("%1, 5, 5").arg(i).toLatin1()) << 5 << 5;
}
}
// void dump(int indent = 0) const public
void tst_QGraphicsLinearLayout::dump()
{
QFETCH(int, itemCount);
QFETCH(int, layoutCount);
SubQGraphicsLinearLayout layout;
for (int i = 0; i < itemCount; ++i)
layout.addItem(new QGraphicsWidget);
for (int i = 0; i < layoutCount; ++i)
layout.addItem(new SubQGraphicsLinearLayout);
}
void tst_QGraphicsLinearLayout::geometry_data()
{
QTest::addColumn<int>("itemCount");
QTest::addColumn<int>("layoutCount");
QTest::addColumn<int>("itemSpacing");
QTest::addColumn<int>("spacing");
QTest::addColumn<Qt::Orientation>("orientation");
QTest::addColumn<QRectF>("rect");
QTest::newRow("null") << 0 << 0 << 0 << 0 << Qt::Horizontal << QRectF();
QTest::newRow("one item") << 1 << 0 << 0 << 0 << Qt::Horizontal << QRectF(0, 0, 10, 10);
QTest::newRow("one layout") << 0 << 1 << 0 << 0 << Qt::Horizontal << QRectF(0, 0, 10, 10);
QTest::newRow("two h") << 1 << 1 << 0 << 0 << Qt::Horizontal << QRectF(0, 0, 20, 10);
QTest::newRow("two v") << 1 << 1 << 0 << 0 << Qt::Vertical << QRectF(0, 0, 10, 20);
QTest::newRow("two w/itemspacing") << 1 << 1 << 5 << 0 << Qt::Horizontal << QRectF(0, 0, 25, 10);
QTest::newRow("two w/spacing") << 1 << 1 << 8 << 0 << Qt::Horizontal << QRectF(0, 0, 28, 10);
QTest::newRow("two w/itemspacing v") << 1 << 1 << 5 << 0 << Qt::Vertical << QRectF(0, 0, 10, 25);
QTest::newRow("two w/spacing v") << 1 << 1 << 8 << 0 << Qt::Vertical << QRectF(0, 0, 10, 28);
}
// QRectF geometry() const public
void tst_QGraphicsLinearLayout::geometry()
{
QFETCH(int, itemCount);
QFETCH(int, layoutCount);
QFETCH(int, itemSpacing);
QFETCH(int, spacing);
QFETCH(Qt::Orientation, orientation);
QFETCH(QRectF, rect);
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout(orientation));
scene.addItem(widget);
widget->setLayout(&layout);
widget->setContentsMargins(0, 0, 0, 0);
for (int i = 0; i < itemCount; ++i)
layout.addItem(new QGraphicsWidget);
for (int i = 0; i < layoutCount; ++i)
layout.addItem(new SubQGraphicsLinearLayout);
for (int i = 0; i < layout.count(); ++i) {
QGraphicsLayoutItem *item = layout.itemAt(i);
item->setMaximumSize(10, 10);
item->setMinimumSize(10, 10);
}
layout.setItemSpacing(0, itemSpacing);
layout.setSpacing(spacing);
layout.setContentsMargins(0, 0, 0, 0);
widget->show();
view.show();
QApplication::processEvents();
QCOMPARE(layout.geometry(), rect);
delete widget;
}
void tst_QGraphicsLinearLayout::insertItem_data()
{
QTest::addColumn<int>("itemCount");
QTest::addColumn<int>("layoutCount");
QTest::addColumn<int>("insertItemAt");
QTest::addColumn<bool>("isWidget");
for (int i = -1; i < 4; ++i) {
for (int j = 0; j < 2; ++j) {
QTest::newRow(QString("0, 0, %1 %2").arg(i).arg(j).toLatin1()) << 0 << 0 << i << (bool)j;
QTest::newRow(QString("1, 0, %1 %2").arg(i).arg(j).toLatin1()) << 1 << 0 << i << (bool)j;
QTest::newRow(QString("0, 1, %1 %2").arg(i).arg(j).toLatin1()) << 0 << 1 << i << (bool)j;
QTest::newRow(QString("2, 2, %1 %2").arg(i).arg(j).toLatin1()) << 2 << 2 << i << (bool)j;
}
}
}
// void insertItem(int index, QGraphicsLayoutItem* item) public
void tst_QGraphicsLinearLayout::insertItem()
{
QFETCH(int, itemCount);
QFETCH(int, layoutCount);
QFETCH(int, insertItemAt);
QFETCH(bool, isWidget);
if (insertItemAt > layoutCount + itemCount)
return;
SubQGraphicsLinearLayout layout;
for (int i = 0; i < itemCount; ++i)
layout.addItem(new QGraphicsWidget);
for (int i = 0; i < layoutCount; ++i)
layout.addItem(new SubQGraphicsLinearLayout);
QGraphicsLayoutItem *item = 0;
if (isWidget)
item = new QGraphicsWidget;
else
item = new SubQGraphicsLinearLayout;
QSizeF oldSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
layout.insertItem(insertItemAt, item);
QCOMPARE(layout.count(), itemCount + layoutCount + 1);
if (insertItemAt >= 0 && (itemCount + layoutCount >= 0)) {
QCOMPARE(layout.itemAt(insertItemAt), item);
}
layout.activate();
QSizeF newSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
if (!isWidget && layout.count() == 1)
QCOMPARE(oldSizeHint.width(), newSizeHint.width());
else if (itemCount + layoutCount > 0)
QVERIFY(oldSizeHint.width() < newSizeHint.width());
}
void tst_QGraphicsLinearLayout::insertStretch_data()
{
QTest::addColumn<int>("itemCount");
QTest::addColumn<int>("layoutCount");
QTest::addColumn<int>("insertItemAt");
QTest::addColumn<int>("stretch");
for (int i = -1; i < 4; ++i) {
for (int j = 0; j < 2; ++j) {
QTest::newRow(QString("0, 0, %1 %2").arg(i).arg(j).toLatin1()) << 0 << 0 << i << j;
QTest::newRow(QString("1, 0, %1 %2").arg(i).arg(j).toLatin1()) << 1 << 0 << i << j;
QTest::newRow(QString("0, 1, %1 %2").arg(i).arg(j).toLatin1()) << 0 << 1 << i << j;
QTest::newRow(QString("2, 2, %1 %2").arg(i).arg(j).toLatin1()) << 2 << 2 << i << j;
}
}
}
// void insertStretch(int index, int stretch = 1) public
void tst_QGraphicsLinearLayout::insertStretch()
{
QFETCH(int, itemCount);
QFETCH(int, layoutCount);
QFETCH(int, insertItemAt);
QFETCH(int, stretch);
if (insertItemAt > layoutCount + itemCount)
return;
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout;
scene.addItem(widget);
QList<QGraphicsWidget *>items;
QGraphicsWidget *item = 0;
for (int i = 0; i < itemCount; ++i) {
item = new RectWidget;
item->setMinimumSize(10, 10);
item->setPreferredSize(25, 25);
item->setMaximumSize(50, 50);
layout->addItem(item);
}
for (int i = 0; i < layoutCount; ++i) {
item = new RectWidget;
item->setMinimumSize(10, 10);
item->setPreferredSize(25, 25);
item->setMaximumSize(50, 50);
SubQGraphicsLinearLayout *sublayout = new SubQGraphicsLinearLayout;
sublayout->addItem(item);
layout->addItem(sublayout);
}
widget->setLayout(layout);
layout->insertStretch(insertItemAt, stretch);
QCOMPARE(layout->count(), itemCount + layoutCount);
layout->activate();
view.show();
widget->show();
int prevStretch = -2;
int prevWidth = -2;
widget->resize((layoutCount + itemCount) * 25 + 25, 25);
for (int i = 0; i < layout->count(); ++i) {
if (QGraphicsLayoutItem *item = layout->itemAt(i)) {
if (prevStretch != -2) {
if (layout->stretchFactor(item) >= prevStretch) {
QVERIFY(item->geometry().width() >= prevWidth);
} else {
QVERIFY(item->geometry().width() < prevWidth);
}
}
prevStretch = layout->stretchFactor(item);
prevWidth = (int)(item->geometry().width());
}
}
//QTest::qWait(1000);
delete widget;
}
void tst_QGraphicsLinearLayout::invalidate_data()
{
QTest::addColumn<int>("count");
QTest::newRow("0") << 0;
QTest::newRow("1") << 1;
QTest::newRow("2") << 2;
QTest::newRow("3") << 3;
}
// void invalidate() public
void tst_QGraphicsLinearLayout::invalidate()
{
QFETCH(int, count);
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
scene.addItem(widget);
widget->setLayout(&layout);
widget->setContentsMargins(0, 0, 0, 0);
layout.setContentsMargins(0, 0, 0, 0);
view.show();
widget->show();
//QTest::qWait(1000);
QTest::qWaitForWindowShown(&view);
qApp->processEvents();
layout.layoutRequest = 0;
layout.setContentsMargins(1, 2, 3, 4);
QApplication::sendPostedEvents(0, 0);
QCOMPARE(layout.layoutRequest, 1);
layout.setOrientation(Qt::Vertical);
QApplication::sendPostedEvents(0, 0);
QCOMPARE(layout.layoutRequest, 2);
for (int i = 0; i < count; ++i)
layout.invalidate(); // Event is compressed, should only get one layoutrequest
QApplication::sendPostedEvents(0, 0);
QCOMPARE(layout.layoutRequest, count ? 3 : 2);
delete widget;
}
void tst_QGraphicsLinearLayout::itemAt_data()
{
QTest::addColumn<int>("index");
QTest::newRow("0") << 0;
QTest::newRow("1") << 1;
QTest::newRow("2") << 2;
}
// QGraphicsLayoutItem* itemAt(int index) const public
void tst_QGraphicsLinearLayout::itemAt()
{
// see also the insertItem() etc tests
QFETCH(int, index);
SubQGraphicsLinearLayout layout;
for (int i = 0; i < 3; ++i)
layout.addItem(new QGraphicsWidget);
QVERIFY(layout.itemAt(index) != 0);
}
void tst_QGraphicsLinearLayout::itemAt_visualOrder()
{
QGraphicsLinearLayout *l = new QGraphicsLinearLayout;
QGraphicsWidget *w1 = new QGraphicsWidget;
l->addItem(w1);
QGraphicsWidget *w3 = new QGraphicsWidget;
l->addItem(w3);
QGraphicsWidget *w0 = new QGraphicsWidget;
l->insertItem(0, w0);
QGraphicsWidget *w2 = new QGraphicsWidget;
l->insertItem(2, w2);
QCOMPARE(l->itemAt(0), static_cast<QGraphicsLayoutItem*>(w0));
QCOMPARE(l->itemAt(1), static_cast<QGraphicsLayoutItem*>(w1));
QCOMPARE(l->itemAt(2), static_cast<QGraphicsLayoutItem*>(w2));
QCOMPARE(l->itemAt(3), static_cast<QGraphicsLayoutItem*>(w3));
}
void tst_QGraphicsLinearLayout::orientation_data()
{
QTest::addColumn<Qt::Orientation>("orientation");
QTest::newRow("vertical") << Qt::Vertical;
QTest::newRow("horizontal") << Qt::Horizontal;
}
// Qt::Orientation orientation() const public
void tst_QGraphicsLinearLayout::orientation()
{
QFETCH(Qt::Orientation, orientation);
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
Qt::Orientation initialOrientation = (orientation == Qt::Vertical ? Qt::Horizontal : Qt::Vertical);
SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout(initialOrientation));
scene.addItem(widget);
widget->setLayout(&layout);
widget->setContentsMargins(0, 0, 0, 0);
layout.setContentsMargins(0, 0, 0, 0);
int i;
int itemCount = 3;
for (i = 0; i < itemCount; ++i)
layout.addItem(new RectWidget);
QCOMPARE(layout.orientation(), initialOrientation);
QList<qreal> positions;
view.show();
widget->show();
qApp->processEvents();
for (i = 0; i < itemCount; ++i) {
QGraphicsWidget *item = static_cast<QGraphicsWidget*>(layout.itemAt(i));
qreal pos;
if (initialOrientation == Qt::Horizontal)
pos = item->pos().x();
else
pos = item->pos().y();
positions.append(pos);
}
layout.setOrientation(orientation);
QCOMPARE(layout.orientation(), orientation);
// important to resize to preferredsize when orientation is switched
widget->resize(widget->effectiveSizeHint(Qt::PreferredSize));
qApp->processEvents();
for (i = 0; i < positions.count(); ++i) {
QGraphicsWidget *item = static_cast<QGraphicsWidget*>(layout.itemAt(i));
if (initialOrientation == Qt::Horizontal)
QCOMPARE(item->pos().y(), positions.at(i));
else
QCOMPARE(item->pos().x(), positions.at(i));
}
}
void tst_QGraphicsLinearLayout::removeAt_data()
{
QTest::addColumn<int>("itemCount");
QTest::addColumn<int>("layoutCount");
QTest::addColumn<int>("removeItemAt");
QTest::addColumn<Qt::Orientation>("orientation");
for (int i = -1; i < 4; ++i) {
for (int k = 0; k < 2; ++k) {
Qt::Orientation orientation = (k == 0) ? Qt::Vertical : Qt::Horizontal;
QTest::newRow(QString("0, 0, %1").arg(i).toLatin1()) << 0 << 0 << i << orientation;
QTest::newRow(QString("1, 0, %1").arg(i).toLatin1()) << 1 << 0 << i << orientation;
QTest::newRow(QString("0, 1, %1").arg(i).toLatin1()) << 0 << 1 << i << orientation;
QTest::newRow(QString("2, 2, %1").arg(i).toLatin1()) << 2 << 2 << i << orientation;
}
}
}
// void removeAt(int index) public
void tst_QGraphicsLinearLayout::removeAt()
{
QFETCH(int, itemCount);
QFETCH(int, layoutCount);
QFETCH(int, removeItemAt);
QFETCH(Qt::Orientation, orientation);
if (removeItemAt >= layoutCount + itemCount)
return;
SubQGraphicsLinearLayout layout(orientation);
for (int i = 0; i < itemCount; ++i)
layout.addItem(new QGraphicsWidget);
for (int i = 0; i < layoutCount; ++i)
layout.addItem(new SubQGraphicsLinearLayout);
QSizeF oldSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
QGraphicsLayoutItem *w = 0;
if (removeItemAt >= 0 && removeItemAt < layout.count())
w = layout.itemAt(removeItemAt);
if (w) {
QGraphicsLayoutItem *wParent = w->parentLayoutItem();
QCOMPARE(wParent, static_cast<QGraphicsLayoutItem *>(&layout));
layout.removeAt(removeItemAt);
wParent = w->parentLayoutItem();
QCOMPARE(wParent, static_cast<QGraphicsLayoutItem *>(0));
delete w;
}
QCOMPARE(layout.count(), itemCount + layoutCount - (w ? 1 : 0));
layout.activate();
QSizeF newSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
if (orientation == Qt::Horizontal)
QVERIFY(oldSizeHint.width() >= newSizeHint.width());
else
QVERIFY(oldSizeHint.height() >= newSizeHint.height());
}
void tst_QGraphicsLinearLayout::removeItem_data()
{
QTest::addColumn<int>("itemCount");
QTest::addColumn<int>("layoutCount");
QTest::addColumn<int>("removeItemAt");
for (int i = -1; i < 4; ++i) {
QTest::newRow(QString("0, 0, %1").arg(i).toLatin1()) << 0 << 0 << i;
QTest::newRow(QString("1, 0, %1").arg(i).toLatin1()) << 1 << 0 << i;
QTest::newRow(QString("0, 1, %1").arg(i).toLatin1()) << 0 << 1 << i;
QTest::newRow(QString("2, 2, %1").arg(i).toLatin1()) << 2 << 2 << i;
}
}
// void removeItem(QGraphicsLayoutItem* item) public
void tst_QGraphicsLinearLayout::removeItem()
{
QFETCH(int, itemCount);
QFETCH(int, layoutCount);
QFETCH(int, removeItemAt);
if (removeItemAt >= layoutCount + itemCount)
return;
SubQGraphicsLinearLayout layout;
for (int i = 0; i < itemCount; ++i)
layout.addItem(new QGraphicsWidget);
for (int i = 0; i < layoutCount; ++i)
layout.addItem(new SubQGraphicsLinearLayout);
QGraphicsLayoutItem *w = 0;
if (removeItemAt >= 0 && removeItemAt < layout.count())
w = layout.itemAt(removeItemAt);
QSizeF oldSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
if (w) {
layout.removeItem(w);
delete w;
}
QCOMPARE(layout.count(), itemCount + layoutCount - (w ? 1 : 0));
layout.activate();
QSizeF newSizeHint = layout.sizeHint(Qt::PreferredSize, QSizeF());
QVERIFY(oldSizeHint.width() >= newSizeHint.width());
}
void tst_QGraphicsLinearLayout::setGeometry_data()
{
QTest::addColumn<QRectF>("rect");
QTest::newRow("null") << QRectF();
QTest::newRow("small") << QRectF(0, 0, 10, 10);
}
// void setGeometry(QRectF const& rect) public
void tst_QGraphicsLinearLayout::setGeometry()
{
QFETCH(QRectF, rect);
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
scene.addItem(widget);
widget->setLayout(&layout);
widget->setContentsMargins(0, 0, 0, 0);
layout.setContentsMargins(0, 0, 0, 0);
layout.setMaximumSize(100, 100);
view.show();
widget->show();
QApplication::processEvents();
widget->setGeometry(rect);
QCOMPARE(layout.geometry(), rect);
// see also geometry()
delete widget;
}
void tst_QGraphicsLinearLayout::setSpacing_data()
{
QTest::addColumn<qreal>("spacing");
QTest::newRow("0") << (qreal)0;
QTest::newRow("5") << (qreal)5;
QTest::newRow("3.3") << (qreal)3.3;
QTest::newRow("-4.3") << (qreal)4.3;
}
// void setSpacing(qreal spacing) public
void tst_QGraphicsLinearLayout::setSpacing()
{
QFETCH(qreal, spacing);
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
scene.addItem(widget);
widget->setLayout(&layout);
layout.setContentsMargins(0, 0, 0, 0);
// The remainder of this test is only applicable if the style uses uniform spacing
qreal oldSpacing = layout.spacing();
if (oldSpacing != -1) {
for (int i = 0; i < 3; ++i)
layout.addItem(new QGraphicsWidget);
QSizeF oldSizeHint = layout.sizeHint(Qt::PreferredSize);
layout.setSpacing(spacing);
QCOMPARE(layout.spacing(), spacing);
view.show();
widget->show();
QApplication::processEvents();
QSizeF newSizeHint = layout.sizeHint(Qt::PreferredSize);
QCOMPARE(oldSizeHint.width() - oldSpacing * 2, newSizeHint.width() - spacing * 2);
}
delete widget;
}
void tst_QGraphicsLinearLayout::setItemSpacing_data()
{
QTest::addColumn<int>("index");
QTest::addColumn<int>("spacing");
QTest::newRow("0 at 0") << 0 << 0;
QTest::newRow("10 at 0") << 0 << 10;
QTest::newRow("10 at 1") << 1 << 10;
QTest::newRow("10 at the end") << 4 << 10;
}
void tst_QGraphicsLinearLayout::setItemSpacing()
{
QFETCH(int, index);
QFETCH(int, spacing);
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout;
scene.addItem(widget);
widget->setLayout(layout);
layout->setContentsMargins(0, 0, 0, 0);
for (int i = 0; i < 5; ++i) {
QGraphicsWidget *w = new QGraphicsWidget;
layout->addItem(w);
}
QSizeF oldSizeHint = layout->sizeHint(Qt::PreferredSize);
qreal oldSpacing = 0;
if (index < layout->count() - 1)
oldSpacing = layout->spacing();
else
spacing = 0;
layout->setItemSpacing(index, spacing);
view.show();
QApplication::processEvents();
QSizeF newSizeHint = layout->sizeHint(Qt::PreferredSize);
// The remainder of this test is only applicable if the style uses uniform spacing
if (oldSpacing >= 0) {
QCOMPARE(newSizeHint.width() - spacing, oldSizeHint.width() - oldSpacing);
}
delete widget;
}
void tst_QGraphicsLinearLayout::itemSpacing()
{
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout;
scene.addItem(widget);
widget->setLayout(layout);
layout->setContentsMargins(0, 0, 0, 0);
for (int i = 0; i < 5; ++i) {
QGraphicsWidget *w = new QGraphicsWidget;
layout->addItem(w);
}
// Check defaults
qreal defaultSpacing = layout->spacing();
if (defaultSpacing >= 0) {
QCOMPARE(layout->itemSpacing(0), defaultSpacing);
} else {
// all widgets are the same, so the spacing should be uniform
QCOMPARE(layout->itemSpacing(0), layout->itemSpacing(1));
}
layout->setItemSpacing(1, 42);
QCOMPARE(layout->itemSpacing(1), qreal(42));
// try to unset
layout->setItemSpacing(1, -1);
QCOMPARE(layout->itemSpacing(1), defaultSpacing);
delete widget;
}
/**
* The stretch factors are not applied linearly, but they are used together with both the preferred size, maximum size to form the
* internal effective stretch factor.
* There is only need to apply stretch factors if the size of the layout is different than the layouts preferred size.
* (If the size of the layout is the preferred size, then all items should get their preferred sizes.
* However, imagine this use case:
* Layout
* +----------+----------+----------+
* name | A | B | C |
* stretch | 1 | 2 | 3 |
* sizehints|[5,10,50] |[5,10,50] |[5,10,50] |
* +----------+----------+----------+
*
* layout->resize(120, h)
*
* 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
* the item with the highest stretch factor will first resize. When that has reached its maximum the next candidate for stretch will
* resize, and finally, item with the lowest stretch factor will resize.
* In QGraphicsLinearLayout we try to scale all items so that they all reach their maximum at the same time. This means that
* their relative sizes are not proportional to their stretch factors.
*/
typedef QList<int> IntList;
Q_DECLARE_METATYPE(IntList)
Q_DECLARE_METATYPE(qreal)
void tst_QGraphicsLinearLayout::setStretchFactor_data()
{
QTest::addColumn<qreal>("totalSize");
QTest::addColumn<IntList>("stretches");
QTest::newRow(QString("60 [1,2]").toLatin1()) << qreal(60.0) << (IntList() << 1 << 2);
QTest::newRow(QString("60 [1,2,3]").toLatin1()) << qreal(60.0) << (IntList() << 1 << 2 << 3);
QTest::newRow(QString("120 [1,2,3,6]").toLatin1()) << qreal(120.0) << (IntList() << 1 << 2 << 3 << 6);
}
// void setStretchFactor(QGraphicsLayoutItem* item, int stretch) public
void tst_QGraphicsLinearLayout::setStretchFactor()
{
QFETCH(qreal, totalSize);
QFETCH(IntList, stretches);
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
scene.addItem(widget);
widget->setLayout(&layout);
layout.setContentsMargins(0, 0, 0, 0);
layout.setSpacing(0.0);
widget->setContentsMargins(0, 0, 0, 0);
int i;
for (i = 0; i < stretches.count(); ++i) {
QGraphicsWidget *item = new RectWidget(widget);
item->setMinimumSize(5,5);
item->setPreferredSize(10,5);
item->setMaximumSize(50,5);
layout.addItem(item);
layout.setStretchFactor(item, stretches.at(i));
}
widget->resize(totalSize, 10);
QApplication::processEvents();
view.show();
widget->show();
qreal firstStretch = -1;
qreal firstExtent = -1.;
qreal sumExtent = 0;
for (i = 0; i < stretches.count(); ++i) {
QGraphicsWidget *item = static_cast<QGraphicsWidget*>(layout.itemAt(i));
qreal extent = item->size().width();
qreal stretch = (qreal)stretches.at(i);
if (firstStretch != -1 && firstExtent != -1) {
// The resulting widths does not correspond linearly to the stretch factors.
if (stretch == firstStretch)
QCOMPARE(extent, firstExtent);
else if (stretch > firstStretch)
QVERIFY(extent > firstExtent);
else
QVERIFY(extent < firstExtent);
} else {
firstStretch = (qreal)stretch;
firstExtent = extent;
}
sumExtent+= extent;
}
QCOMPARE(sumExtent, totalSize);
delete widget;
}
void tst_QGraphicsLinearLayout::testStretch()
{
QGraphicsScene scene;
QGraphicsView *view = new QGraphicsView(&scene);
Q_UNUSED(view);
QGraphicsWidget *form = new QGraphicsWidget(0, Qt::Window);
scene.addItem(form);
form->setMinimumSize(600, 600);
form->setMaximumSize(600, 600);
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal, form);
QGraphicsWidget *w1 = new RectWidget;
w1->setPreferredSize(100,100);
w1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
QGraphicsWidget *w2 = new RectWidget;
w2->setPreferredSize(200,200);
w2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
layout->setSpacing(0);
layout->setContentsMargins(0, 0, 0, 0);
layout->addItem(w1);
layout->addStretch(2);
layout->addItem(w2);
QCOMPARE(layout->count(), 2);
QVERIFY(layout->itemAt(0) == w1);
QVERIFY(layout->itemAt(1) == w2);
layout->activate();
//view->setSceneRect(-50, -50, 800, 800);
//view->show();
//QTest::qWaitForWindowShown(view);
//QTest::qWait(5000);
QCOMPARE(form->geometry().size(), QSizeF(600,600));
QCOMPARE(w1->geometry(), QRectF(0, 0, 100, 100));
QCOMPARE(w2->geometry(), QRectF(400, 0, 200, 200));
}
void tst_QGraphicsLinearLayout::defaultStretchFactors_data()
{
QTest::addColumn<Qt::Orientation>("orientation");
QTest::addColumn<int>("count");
QTest::addColumn<IntList>("preferredSizeHints");
QTest::addColumn<IntList>("stretches");
QTest::addColumn<IntList>("ignoreFlag");
QTest::addColumn<QSizeF>("newSize");
QTest::addColumn<IntList>("expectedSizes");
QTest::newRow("hor") << Qt::Horizontal << 3
<< (IntList() << 20 << 40 << 60)
<< (IntList())
<< (IntList())
<< QSizeF()
<< (IntList() << 20 << 40 << 60);
QTest::newRow("ver") << Qt::Vertical << 3
<< (IntList() << 20 << 40 << 60)
<< (IntList())
<< (IntList())
<< QSizeF()
<< (IntList() << 20 << 40 << 60);
QTest::newRow("hor,ignore123") << Qt::Horizontal << 3
<< (IntList() << 20 << 40 << 60)
<< (IntList())
<< (IntList() << 1 << 1 << 1)
<< QSizeF()
<< (IntList() << 0 << 0 << 0);
QTest::newRow("hor,ignore23") << Qt::Horizontal << 3
<< (IntList() << 10 << 10 << 10)
<< (IntList())
<< (IntList() << 0 << 1 << 1)
<< QSizeF(200, 50)
<< (IntList()); //### stretches are not linear.
QTest::newRow("hor,ignore2") << Qt::Horizontal << 3
<< (IntList() << 10 << 10 << 10)
<< (IntList())
<< (IntList() << 0 << 1 << 0)
<< QSizeF()
<< (IntList() << 10 << 0 << 10);
}
void tst_QGraphicsLinearLayout::defaultStretchFactors()
{
QFETCH(Qt::Orientation, orientation);
QFETCH(int, count);
QFETCH(IntList, preferredSizeHints);
QFETCH(IntList, stretches);
QFETCH(IntList, ignoreFlag);
QFETCH(QSizeF, newSize);
QFETCH(IntList, expectedSizes);
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout(orientation);
scene.addItem(widget);
widget->setLayout(layout);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0.0);
widget->setContentsMargins(0, 0, 0, 0);
int i;
for (i = 0; i < count; ++i) {
RectWidget *item = new RectWidget(widget);
layout->addItem(item);
if (preferredSizeHints.value(i, -1) >= 0) {
item->setSizeHint(Qt::PreferredSize, QSizeF(preferredSizeHints.at(i), preferredSizeHints.at(i)));
}
if (stretches.value(i, -1) >= 0) {
layout->setStretchFactor(item, stretches.at(i));
}
if (ignoreFlag.value(i, 0) != 0) {
QSizePolicy sp = item->sizePolicy();
if (orientation == Qt::Horizontal)
sp.setHorizontalPolicy(QSizePolicy::Policy(sp.horizontalPolicy() | QSizePolicy::IgnoreFlag));
else
sp.setVerticalPolicy(QSizePolicy::Policy(sp.verticalPolicy() | QSizePolicy::IgnoreFlag));
item->setSizePolicy(sp);
}
}
QApplication::processEvents();
widget->show();
view.show();
view.resize(400,300);
if (newSize.isValid())
widget->resize(newSize);
QApplication::processEvents();
for (i = 0; i < count; ++i) {
QSizeF itemSize = layout->itemAt(i)->geometry().size();
if (orientation == Qt::Vertical)
itemSize.transpose();
if (i < expectedSizes.count())
QCOMPARE(itemSize.width(), qreal(expectedSizes.at(i)));
}
delete widget;
}
Q_DECLARE_METATYPE(Qt::SizeHint)
void tst_QGraphicsLinearLayout::sizeHint_data()
{
QTest::addColumn<Qt::SizeHint>("which");
QTest::addColumn<QSizeF>("constraint");
QTest::addColumn<qreal>("spacing");
QTest::addColumn<qreal>("layoutMargin");
QTest::addColumn<QSizeF>("sizeHint");
QTest::newRow("minimumSize") << Qt::MinimumSize << QSizeF() << qreal(0.0) << qreal(0.0) << QSizeF(30, 10);
QTest::newRow("preferredSize") << Qt::PreferredSize << QSizeF() << qreal(0.0) << qreal(0.0) << QSizeF(75, 25);
QTest::newRow("maximumSize") << Qt::MaximumSize << QSizeF() << qreal(0.0) << qreal(0.0) << QSizeF(150, 50);
QTest::newRow("minimumSize, spacing=3") << Qt::MinimumSize << QSizeF() << qreal(3.0) << qreal(0.0) << QSizeF(30 + 2*3, 10);
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);
QTest::newRow("minimumSize, spacing=0, layoutMargin=7") << Qt::MinimumSize << QSizeF() << qreal(0.0) << qreal(7.0) << QSizeF(30 + 0 + 2*7, 10 + 2*7);
}
// QSizeF sizeHint(Qt::SizeHint which, QSizeF const& constraint) const public
void tst_QGraphicsLinearLayout::sizeHint()
{
QFETCH(Qt::SizeHint, which);
QFETCH(QSizeF, constraint);
QFETCH(qreal, spacing);
QFETCH(qreal, layoutMargin);
QFETCH(QSizeF, sizeHint);
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
SubQGraphicsLinearLayout &layout = *(new SubQGraphicsLinearLayout);
scene.addItem(widget);
widget->setLayout(&layout);
layout.setContentsMargins(layoutMargin, layoutMargin, layoutMargin, layoutMargin);
layout.setSpacing(spacing);
for (int i = 0; i < 3; ++i) {
QGraphicsWidget *item = new QGraphicsWidget(widget);
item->setMinimumSize(10, 10);
item->setPreferredSize(25, 25);
item->setMaximumSize(50, 50);
layout.addItem(item);
}
QApplication::processEvents();
QCOMPARE(layout.sizeHint(which, constraint), sizeHint);
delete widget;
}
void tst_QGraphicsLinearLayout::updateGeometry()
{
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window);
QGraphicsWidget *w1 = new QGraphicsWidget(window);
w1->setMinimumSize(100, 40);
SubQGraphicsLinearLayout *layout = new SubQGraphicsLinearLayout;
layout->addItem(w1);
scene.addItem(window);
window->setLayout(layout);
layout->setContentsMargins(0, 0, 0, 0);
QCOMPARE(w1->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(layout));
QCOMPARE(layout->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(window));
view.show();
QApplication::processEvents();
QCOMPARE(window->size().toSize(), QSize(100, 50));
w1->setMinimumSize(110, 60);
QApplication::processEvents();
QCOMPARE(window->size().toSize(), QSize(110, 60));
QApplication::processEvents();
{
delete window;
window = new QGraphicsWidget(0, Qt::Window);
SubQGraphicsLinearLayout *layout2a = new SubQGraphicsLinearLayout;
QGraphicsWidget *w1 = new QGraphicsWidget(window);
w1->setMinimumSize(110, 50);
layout2a->addItem(w1);
SubQGraphicsLinearLayout *layout2 = new SubQGraphicsLinearLayout;
layout2->addItem(layout2a);
layout2->setContentsMargins(1, 1, 1, 1);
layout2a->setContentsMargins(1, 1, 1, 1);
window->setLayout(layout2);
QApplication::processEvents();
QCOMPARE(w1->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(layout2a));
QCOMPARE(layout2a->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(layout2));
QCOMPARE(layout2->parentLayoutItem(), static_cast<QGraphicsLayoutItem*>(window));
QCOMPARE(window->size().toSize(), QSize(114, 54));
QApplication::processEvents();
w1->setMinimumSize(120, 60);
QApplication::processEvents();
QCOMPARE(window->size().toSize(), QSize(124, 64));
}
{
delete window;
window = new QGraphicsWidget(0, Qt::Window);
scene.addItem(window);
window->show();
QGraphicsWidget *w1 = new QGraphicsWidget(window);
w1->setMinimumSize(100, 50);
SubQGraphicsLinearLayout *layout2a = new SubQGraphicsLinearLayout;
layout2a->addItem(w1);
SubQGraphicsLinearLayout *layout2 = new SubQGraphicsLinearLayout;
layout2->addItem(layout2a);
layout2a->setContentsMargins(1, 1, 1, 1);
window->setLayout(layout2);
QApplication::processEvents();
qreal left, top, right, bottom;
layout2->getContentsMargins(&left, &top, &right, &bottom);
QCOMPARE(window->size().toSize(), QSize(102 +left + right, 52 + top + bottom));
}
{
delete window;
window = new QGraphicsWidget(0, Qt::Window);
scene.addItem(window);
QGraphicsWidget *w1 = new QGraphicsWidget(window);
w1->setMinimumSize(100, 50);
window->setLayout(0);
SubQGraphicsLinearLayout *layout2a = new SubQGraphicsLinearLayout;
layout2a->addItem(w1);
SubQGraphicsLinearLayout *layout2 = new SubQGraphicsLinearLayout;
layout2->addItem(layout2a);
window->resize(200, 80);
window->setLayout(layout2);
window->show();
QApplication::processEvents();
QCOMPARE(window->size().toSize(), QSize(200, 80));
}
}
void tst_QGraphicsLinearLayout::layoutDirection()
{
QGraphicsScene scene;
QGraphicsView view(&scene);
QGraphicsWidget *window = new QGraphicsWidget(0, Qt::Window);
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
layout->setContentsMargins(1, 2, 3, 4);
layout->setSpacing(6);
RectWidget *w1 = new RectWidget;
w1->setPreferredSize(20, 20);
w1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
layout->addItem(w1);
RectWidget *w2 = new RectWidget;
w2->setPreferredSize(20, 20);
w2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
layout->addItem(w2);
scene.addItem(window);
window->setLayout(layout);
view.show();
window->resize(50, 20);
window->setLayoutDirection(Qt::LeftToRight);
QApplication::processEvents();
QCOMPARE(w1->geometry().left(), 1.0);
QCOMPARE(w1->geometry().right(), 21.0);
QCOMPARE(w2->geometry().left(), 27.0);
QCOMPARE(w2->geometry().right(), 47.0);
window->setLayoutDirection(Qt::RightToLeft);
QApplication::processEvents();
QCOMPARE(w1->geometry().right(), 49.0);
QCOMPARE(w1->geometry().left(), 29.0);
QCOMPARE(w2->geometry().right(), 23.0);
QCOMPARE(w2->geometry().left(), 3.0);
delete window;
}
void tst_QGraphicsLinearLayout::removeLayout()
{
QGraphicsScene scene;
RectWidget *textEdit = new RectWidget;
RectWidget *pushButton = new RectWidget;
scene.addItem(textEdit);
scene.addItem(pushButton);
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
layout->addItem(textEdit);
layout->addItem(pushButton);
QGraphicsWidget *form = new QGraphicsWidget;
form->setLayout(layout);
scene.addItem(form);
QGraphicsView view(&scene);
view.show();
QTest::qWait(20);
QRectF r1 = textEdit->geometry();
QRectF r2 = pushButton->geometry();
form->setLayout(0);
//documentation of QGraphicsWidget::setLayout:
//If layout is 0, the widget is left without a layout. Existing subwidgets' geometries will remain unaffected.
QCOMPARE(textEdit->geometry(), r1);
QCOMPARE(pushButton->geometry(), r2);
}
void tst_QGraphicsLinearLayout::avoidRecursionInInsertItem()
{
QGraphicsWidget window(0, Qt::Window);
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(&window);
QCOMPARE(layout->count(), 0);
QTest::ignoreMessage(QtWarningMsg, "QGraphicsLinearLayout::insertItem: cannot insert itself");
layout->insertItem(0, layout);
QCOMPARE(layout->count(), 0);
}
void tst_QGraphicsLinearLayout::styleInfoLeak()
{
QGraphicsLinearLayout layout;
layout.spacing();
}
void tst_QGraphicsLinearLayout::task218400_insertStretchCrash()
{
QGraphicsScene *scene = new QGraphicsScene;
QGraphicsWidget *a = scene->addWidget(new QWidget);
QGraphicsWidget *b = scene->addWidget(new QWidget);
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout;
layout->addItem(a);
layout->addItem(b);
layout->insertStretch(0); // inserts gap in item grid in the layout engine
QGraphicsWidget *form = new QGraphicsWidget;
form->setLayout(layout); // crash
}
void tst_QGraphicsLinearLayout::testAlignmentInLargerLayout()
{
QGraphicsScene *scene = new QGraphicsScene;
QGraphicsWidget *form = new QGraphicsWidget;
scene->addItem(form);
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, form);
layout->setSpacing(0);
layout->setContentsMargins(0,0,0,0);
QGraphicsWidget *a = new QGraphicsWidget;
a->setMaximumSize(100,100);
layout->addItem(a);
QCOMPARE(form->maximumSize(), QSizeF(100,100));
QCOMPARE(layout->maximumSize(), QSizeF(100,100));
layout->setMinimumSize(QSizeF(200,200));
layout->setMaximumSize(QSizeF(200,200));
layout->setAlignment(a, Qt::AlignCenter);
layout->activate();
QCOMPARE(a->geometry(), QRectF(50,50,100,100));
layout->setAlignment(a, Qt::AlignRight | Qt::AlignBottom);
layout->activate();
QCOMPARE(a->geometry(), QRectF(100,100,100,100));
layout->setAlignment(a, Qt::AlignHCenter | Qt::AlignTop);
layout->activate();
QCOMPARE(a->geometry(), QRectF(50,0,100,100));
QGraphicsWidget *b = new QGraphicsWidget;
b->setMaximumSize(100,100);
layout->addItem(b);
layout->setAlignment(a, Qt::AlignCenter);
layout->setAlignment(b, Qt::AlignCenter);
layout->activate();
QCOMPARE(a->geometry(), QRectF(50,0,100,100));
QCOMPARE(b->geometry(), QRectF(50,100,100,100));
layout->setAlignment(a, Qt::AlignRight | Qt::AlignBottom);
layout->setAlignment(b, Qt::AlignLeft | Qt::AlignTop);
layout->activate();
QCOMPARE(a->geometry(), QRectF(100,0,100,100));
QCOMPARE(b->geometry(), QRectF(0,100,100,100));
}
void tst_QGraphicsLinearLayout::testOffByOneInLargerLayout() {
QGraphicsScene *scene = new QGraphicsScene;
QGraphicsWidget *form = new QGraphicsWidget;
scene->addItem(form);
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, form);
layout->setSpacing(0);
layout->setContentsMargins(0,0,0,0);
QGraphicsWidget *a = new QGraphicsWidget;
QGraphicsWidget *b = new QGraphicsWidget;
a->setMaximumSize(100,100);
b->setMaximumSize(100,100);
layout->addItem(a);
layout->addItem(b);
layout->setAlignment(a, Qt::AlignRight | Qt::AlignBottom);
layout->setAlignment(b, Qt::AlignLeft | Qt::AlignTop);
layout->setMinimumSize(QSizeF(101,201));
layout->setMaximumSize(QSizeF(101,201));
layout->activate();
QCOMPARE(a->geometry(), QRectF(1,0.5,100,100));
QCOMPARE(b->geometry(), QRectF(0,100.5,100,100));
layout->setMinimumSize(QSizeF(100,200));
layout->setMaximumSize(QSizeF(100,200));
layout->activate();
QCOMPARE(a->geometry(), QRectF(0,0,100,100));
QCOMPARE(b->geometry(), QRectF(0,100,100,100));
layout->setMinimumSize(QSizeF(99,199));
layout->setMaximumSize(QSizeF(99,199));
layout->activate();
QCOMPARE(a->geometry(), QRectF(0,0,99,99.5));
QCOMPARE(b->geometry(), QRectF(0,99.5,99,99.5));
}
void tst_QGraphicsLinearLayout::testDefaultAlignment()
{
QGraphicsWidget *widget = new QGraphicsWidget;
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, widget);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
QGraphicsWidget *w = new QGraphicsWidget;
w->setMinimumSize(50,50);
w->setMaximumSize(50,50);
layout->addItem(w);
//Default alignment should be to the top-left
QCOMPARE(layout->alignment(w), 0);
//First, check by forcing the layout to be bigger
layout->setMinimumSize(100,100);
layout->activate();
QCOMPARE(layout->geometry(), QRectF(0,0,100,100));
QCOMPARE(w->geometry(), QRectF(0,0,50,50));
layout->setMinimumSize(-1,-1);
//Second, check by adding a larger item in the column
QGraphicsWidget *w2 = new QGraphicsWidget;
w2->setMinimumSize(100,100);
w2->setMaximumSize(100,100);
layout->addItem(w2);
layout->activate();
QCOMPARE(layout->geometry(), QRectF(0,0,100,150));
QCOMPARE(w->geometry(), QRectF(0,0,50,50));
QCOMPARE(w2->geometry(), QRectF(0,50,100,100));
}
void tst_QGraphicsLinearLayout::combineSizePolicies()
{
QGraphicsWidget *widget = new QGraphicsWidget;
QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal, widget);
layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(0);
QGraphicsWidget *w1 = new QGraphicsWidget;
w1->setMaximumSize(200,200);
w1->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
layout->addItem(w1);
QGraphicsWidget *w2 = new QGraphicsWidget;
w2->setPreferredSize(50,50);
w2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
layout->addItem(w2);
QCOMPARE(layout->maximumHeight(), qreal(200));
// now remove the fixed vertical size policy, and set instead the maximum height to 50
// this should in effect give the same maximumHeight
w2->setMaximumHeight(50);
w2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
QCOMPARE(layout->maximumHeight(), qreal(200));
}
QTEST_MAIN(tst_QGraphicsLinearLayout)
#include "tst_qgraphicslinearlayout.moc"