aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quick')
-rw-r--r--tests/auto/quick/drawingmodes/tst_drawingmodes.cpp14
-rw-r--r--tests/auto/quick/nodes/tst_nodestest.cpp9
-rw-r--r--tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp4
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml5
-rw-r--r--tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp114
-rw-r--r--tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml12
-rw-r--r--tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp46
-rw-r--r--tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp60
-rw-r--r--tests/auto/quick/qquickanimatedsprite/data/finishBehavior.qml18
-rw-r--r--tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp63
-rw-r--r--tests/auto/quick/qquickanimations/data/signalorder.qml27
-rw-r--r--tests/auto/quick/qquickanimations/qquickanimations.pro1
-rw-r--r--tests/auto/quick/qquickanimations/tst_qquickanimations.cpp270
-rw-r--r--tests/auto/quick/qquickbehaviors/data/targetProperty.qml16
-rw-r--r--tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp22
-rw-r--r--tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp2
-rw-r--r--tests/auto/quick/qquickboundaryrule/data/dragHandler.qml1
-rw-r--r--tests/auto/quick/qquickboundaryrule/qquickboundaryrule.pro2
-rw-r--r--tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp24
-rw-r--r--tests/auto/quick/qquickflickable/data/resize.qml1
-rw-r--r--tests/auto/quick/qquickflickable/tst_qquickflickable.cpp7
-rw-r--r--tests/auto/quick/qquickimage/data/ProPhoto.jpgbin0 -> 30900 bytes
-rw-r--r--tests/auto/quick/qquickimage/data/image.qml5
-rw-r--r--tests/auto/quick/qquickimage/tst_qquickimage.cpp106
-rw-r--r--tests/auto/quick/qquickitem/data/hellotr_la.qmbin0 -> 237 bytes
-rw-r--r--tests/auto/quick/qquickitem/tst_qquickitem.cpp35
-rw-r--r--tests/auto/quick/qquickitem2/data/mapCoordinates.qml20
-rw-r--r--tests/auto/quick/qquickitem2/data/mapCoordinatesRect.qml10
-rw-r--r--tests/auto/quick/qquickitem2/tst_qquickitem.cpp32
-rw-r--r--tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp8
-rw-r--r--tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml6
-rw-r--r--tests/auto/quick/qquicklistview/data/delegatesWithRequiredProperties.qml47
-rw-r--r--tests/auto/quick/qquicklistview/data/listview-sections_delegate_required.qml77
-rw-r--r--tests/auto/quick/qquicklistview/data/requiredObjectListModel.qml15
-rw-r--r--tests/auto/quick/qquicklistview/data/reusedelegateitems.qml98
-rw-r--r--tests/auto/quick/qquicklistview/qquicklistview.pro3
-rw-r--r--tests/auto/quick/qquicklistview/reusemodel.h84
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp567
-rw-r--r--tests/auto/quick/qquickloader/data/RequiredPropertyValuesComponent.qml8
-rw-r--r--tests/auto/quick/qquickloader/data/initialPropertyValues.10.qml20
-rw-r--r--tests/auto/quick/qquickloader/data/initialPropertyValues.9.qml20
-rw-r--r--tests/auto/quick/qquickloader/tst_qquickloader.cpp10
-rw-r--r--tests/auto/quick/qquickmousearea/data/dragreset.qml1
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp56
-rw-r--r--tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.2.qml59
-rw-r--r--tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.3.qml64
-rw-r--r--tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.qml53
-rw-r--r--tests/auto/quick/qquickpathview/data/delegatewithUnrelatedRequiredPreventsAccessToModel.qml52
-rw-r--r--tests/auto/quick/qquickpathview/tst_qquickpathview.cpp37
-rw-r--r--tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp6
-rw-r--r--tests/auto/quick/qquickpositioners/data/transitions-padding.qml10
-rw-r--r--tests/auto/quick/qquickpositioners/data/transitions.qml10
-rw-r--r--tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp63
-rw-r--r--tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp2
-rw-r--r--tests/auto/quick/qquickrendercontrol/data/rect.qml47
-rw-r--r--tests/auto/quick/qquickrendercontrol/qquickrendercontrol.pro12
-rw-r--r--tests/auto/quick/qquickrendercontrol/tst_qquickrendercontrol.cpp202
-rw-r--r--tests/auto/quick/qquickrepeater/data/contextProperty.qml13
-rw-r--r--tests/auto/quick/qquickrepeater/data/objlist_required.qml23
-rw-r--r--tests/auto/quick/qquickrepeater/data/package2.qml36
-rw-r--r--tests/auto/quick/qquickrepeater/data/requiredProperty.qml16
-rw-r--r--tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp59
-rw-r--r--tests/auto/quick/qquickshape/tst_qquickshape.cpp18
-rw-r--r--tests/auto/quick/qquickstates/data/parentChangeCorrectReversal.qml72
-rw-r--r--tests/auto/quick/qquickstates/tst_qquickstates.cpp17
-rw-r--r--tests/auto/quick/qquicktableview/data/delegateWithRequired.qml70
-rw-r--r--tests/auto/quick/qquicktableview/data/delegatewithRequiredUnset.qml71
-rw-r--r--tests/auto/quick/qquicktableview/tst_qquicktableview.cpp45
-rw-r--r--tests/auto/quick/qquicktext/BLACKLIST2
-rw-r--r--tests/auto/quick/qquicktext/data/displaySuperscriptedTag.qml18
-rw-r--r--tests/auto/quick/qquicktext/data/lineLayout.qml9
-rw-r--r--tests/auto/quick/qquicktext/data/lineLayoutImplicitWidth.qml80
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp88
-rw-r--r--tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp30
-rw-r--r--tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp88
-rw-r--r--tests/auto/quick/qquickvisualdatamodel/data/readFromProxyObject.qml23
-rw-r--r--tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp16
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp18
-rw-r--r--tests/auto/quick/quick.pro5
-rw-r--r--tests/auto/quick/rendernode/tst_rendernode.cpp6
-rw-r--r--tests/auto/quick/scenegraph/tst_scenegraph.cpp2
-rw-r--r--tests/auto/quick/shared/viewtestutil.cpp22
82 files changed, 2993 insertions, 417 deletions
diff --git a/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp b/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp
index 9bcc21c77d..5d69bf3b21 100644
--- a/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp
+++ b/tests/auto/quick/drawingmodes/tst_drawingmodes.cpp
@@ -154,7 +154,7 @@ void tst_drawingmodes::points()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
#ifdef Q_OS_WIN
if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES)
@@ -197,7 +197,7 @@ void tst_drawingmodes::lines()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QImage fb = runTest("DrawingModes.qml");
@@ -228,7 +228,7 @@ void tst_drawingmodes::lineStrip()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QImage fb = runTest("DrawingModes.qml");
@@ -261,7 +261,7 @@ void tst_drawingmodes::lineLoop()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
if (isRunningOnRhi())
QSKIP("Line loops are not supported by some modern graphics APIs - skipping test");
@@ -297,7 +297,7 @@ void tst_drawingmodes::triangles()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QImage fb = runTest("DrawingModes.qml");
@@ -326,7 +326,7 @@ void tst_drawingmodes::triangleStrip()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QImage fb = runTest("DrawingModes.qml");
@@ -354,7 +354,7 @@ void tst_drawingmodes::triangleFan()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
if (isRunningOnRhi())
QSKIP("Triangle fans are not supported by some modern graphics APIs - skipping test");
diff --git a/tests/auto/quick/nodes/tst_nodestest.cpp b/tests/auto/quick/nodes/tst_nodestest.cpp
index bd5e6c6383..249ecd5aa5 100644
--- a/tests/auto/quick/nodes/tst_nodestest.cpp
+++ b/tests/auto/quick/nodes/tst_nodestest.cpp
@@ -121,9 +121,6 @@ class DummyRenderer : public QSGBatchRenderer::Renderer
public:
DummyRenderer(QSGRootNode *root, QSGDefaultRenderContext *renderContext)
: QSGBatchRenderer::Renderer(renderContext)
- , changedNode(nullptr)
- , changedState(nullptr)
- , renderCount(0)
{
setRootNode(root);
}
@@ -139,11 +136,11 @@ public:
QSGBatchRenderer::Renderer::nodeChanged(node, state);
}
- QSGNode *changedNode;
+ QSGNode *changedNode = nullptr;
QSGNode::DirtyState changedState;
- int renderCount;
- int renderingOrder;
+ int renderCount = 0;
+ int renderingOrder = 0;
static int globalRendereringOrder;
};
diff --git a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp
index 35fed99e8b..4a7a132be2 100644
--- a/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp
+++ b/tests/auto/quick/pointerhandlers/multipointtoucharea_interop/tst_multipointtoucharea_interop.cpp
@@ -295,10 +295,10 @@ void tst_MptaInterop::unloadHandlerWithPassiveGrab()
QVERIFY(mpta);
QPoint point(90, 90);
- QTest::mousePress(window, Qt::LeftButton, 0, point);
+ QTest::mousePress(window, Qt::LeftButton, {}, point);
QCOMPARE(window->mouseGrabberItem(), mpta);
QTRY_VERIFY(handler.isNull()); // it got unloaded
- QTest::mouseRelease(window, Qt::LeftButton, 0, point); // QTBUG-73819: don't crash
+ QTest::mouseRelease(window, Qt::LeftButton, {}, point); // QTBUG-73819: don't crash
}
void tst_MptaInterop::dragHandlerInParentStealingGrabFromItem() // QTBUG-75025
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml
index 7b3601bea0..81fa20f3bb 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/data/draggables.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the manual tests of the Qt Toolkit.
@@ -26,7 +26,7 @@
**
****************************************************************************/
-import QtQuick 2.12
+import QtQuick 2.15
Item {
id: root
@@ -47,6 +47,7 @@ Item {
DragHandler {
id: dragHandler
objectName: "DragHandler " + (index + 1)
+ cursorShape: Qt.ClosedHandCursor
}
Text {
diff --git a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
index 66314f88a2..47cfd27817 100644
--- a/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickdraghandler/tst_qquickdraghandler.cpp
@@ -53,9 +53,12 @@ private slots:
void initTestCase();
void defaultPropertyValues();
+ void touchDrag_data();
void touchDrag();
void mouseDrag_data();
void mouseDrag();
+ void mouseDragThreshold_data();
+ void mouseDragThreshold();
void dragFromMargin();
void snapMode_data();
void snapMode();
@@ -131,9 +134,18 @@ void tst_DragHandler::defaultPropertyValues()
QCOMPARE(dragHandler->centroid().sceneGrabPosition(), QPointF());
}
+void tst_DragHandler::touchDrag_data()
+{
+ QTest::addColumn<int>("dragThreshold");
+ QTest::newRow("threshold zero") << 0;
+ QTest::newRow("threshold one") << 1;
+ QTest::newRow("threshold 20") << 20;
+ QTest::newRow("threshold default") << -1;
+}
+
void tst_DragHandler::touchDrag()
{
- const int dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QFETCH(int, dragThreshold);
QScopedPointer<QQuickView> windowPtr;
createView(windowPtr, "draggables.qml");
QQuickView * window = windowPtr.data();
@@ -142,6 +154,12 @@ void tst_DragHandler::touchDrag()
QVERIFY(ball);
QQuickDragHandler *dragHandler = ball->findChild<QQuickDragHandler*>();
QVERIFY(dragHandler);
+ if (dragThreshold < 0) {
+ dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QCOMPARE(dragHandler->dragThreshold(), dragThreshold);
+ } else {
+ dragHandler->setDragThreshold(dragThreshold);
+ }
QSignalSpy translationChangedSpy(dragHandler, SIGNAL(translationChanged()));
QSignalSpy centroidChangedSpy(dragHandler, SIGNAL(centroidChanged()));
@@ -161,7 +179,9 @@ void tst_DragHandler::touchDrag()
p1 += QPoint(dragThreshold, 0);
QTest::touchEvent(window, touchDevice).move(1, p1, window);
QQuickTouchUtils::flush(window);
- QTRY_VERIFY(dragHandler->centroid().velocity().x() > 0);
+ qCDebug(lcPointerTests) << "velocity after drag" << dragHandler->centroid().velocity();
+ if (dragThreshold > 0)
+ QTRY_VERIFY(!qFuzzyIsNull(dragHandler->centroid().velocity().x()));
QCOMPARE(centroidChangedSpy.count(), 2);
QVERIFY(!dragHandler->active());
p1 += QPoint(1, 0);
@@ -229,8 +249,11 @@ void tst_DragHandler::mouseDrag()
QPointF ballCenter = ball->clipRect().center();
QPointF scenePressPos = ball->mapToScene(ballCenter);
QPoint p1 = scenePressPos.toPoint();
- QTest::mousePress(window, static_cast<Qt::MouseButton>(int(dragButton)), Qt::NoModifier, p1);
+ QTest::mousePress(window, static_cast<Qt::MouseButton>(int(dragButton)), Qt::NoModifier, p1, 500);
QVERIFY(!dragHandler->active());
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::ArrowCursor);
+#endif
if (shouldDrag) {
QCOMPARE(dragHandler->centroid().position(), ballCenter);
QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter);
@@ -245,6 +268,9 @@ void tst_DragHandler::mouseDrag()
QTRY_VERIFY(dragHandler->centroid().velocity().x() > 0);
QCOMPARE(centroidChangedSpy.count(), 2);
QVERIFY(!dragHandler->active());
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::ArrowCursor);
+#endif
}
p1 += QPoint(1, 0);
QTest::mouseMove(window, p1);
@@ -272,6 +298,9 @@ void tst_DragHandler::mouseDrag()
QCOMPARE(dragHandler->translation().y(), 0.0);
QVERIFY(dragHandler->centroid().velocity().x() > 0);
QCOMPARE(centroidChangedSpy.count(), 4);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::ClosedHandCursor);
+#endif
}
QTest::mouseRelease(window, static_cast<Qt::MouseButton>(int(dragButton)), Qt::NoModifier, p1);
QTRY_VERIFY(!dragHandler->active());
@@ -280,6 +309,85 @@ void tst_DragHandler::mouseDrag()
QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1);
QCOMPARE(translationChangedSpy.count(), shouldDrag ? 1 : 0);
QCOMPARE(centroidChangedSpy.count(), shouldDrag ? 5 : 0);
+#if QT_CONFIG(cursor)
+ QTest::mouseMove(window, p1 + QPoint(1, 0)); // TODO after fixing QTBUG-53987, don't send mouseMove
+ QCOMPARE(window->cursor().shape(), Qt::ArrowCursor);
+#endif
+}
+
+void tst_DragHandler::mouseDragThreshold_data()
+{
+ QTest::addColumn<int>("dragThreshold");
+ QTest::newRow("threshold zero") << 0;
+ QTest::newRow("threshold one") << 1;
+ QTest::newRow("threshold 20") << 20;
+ QTest::newRow("threshold default") << -1;
+}
+
+void tst_DragHandler::mouseDragThreshold()
+{
+ QFETCH(int, dragThreshold);
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "draggables.qml");
+ QQuickView * window = windowPtr.data();
+
+ QQuickItem *ball = window->rootObject()->childItems().first();
+ QVERIFY(ball);
+ QQuickDragHandler *dragHandler = ball->findChild<QQuickDragHandler*>();
+ QVERIFY(dragHandler);
+ if (dragThreshold < 0) {
+ dragThreshold = QGuiApplication::styleHints()->startDragDistance();
+ QCOMPARE(dragHandler->dragThreshold(), dragThreshold);
+ } else {
+ dragHandler->setDragThreshold(dragThreshold);
+ }
+
+ QSignalSpy translationChangedSpy(dragHandler, SIGNAL(translationChanged()));
+ QSignalSpy centroidChangedSpy(dragHandler, SIGNAL(centroidChanged()));
+
+ QPointF ballCenter = ball->clipRect().center();
+ QPointF scenePressPos = ball->mapToScene(ballCenter);
+ QPoint p1 = scenePressPos.toPoint();
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QVERIFY(!dragHandler->active());
+ QCOMPARE(dragHandler->centroid().position(), ballCenter);
+ QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter);
+ QCOMPARE(dragHandler->centroid().scenePosition(), scenePressPos);
+ QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos);
+ QCOMPARE(dragHandler->centroid().velocity(), QVector2D());
+ QCOMPARE(centroidChangedSpy.count(), 1);
+ p1 += QPoint(dragThreshold, 0);
+ QTest::mouseMove(window, p1);
+ if (dragThreshold > 0)
+ QTRY_VERIFY(dragHandler->centroid().velocity().x() > 0);
+ QCOMPARE(centroidChangedSpy.count(), 2);
+ QVERIFY(!dragHandler->active());
+ p1 += QPoint(1, 0);
+ QTest::mouseMove(window, p1);
+ QTRY_VERIFY(dragHandler->active());
+ QCOMPARE(translationChangedSpy.count(), 0);
+ QCOMPARE(centroidChangedSpy.count(), 3);
+ QCOMPARE(dragHandler->translation().x(), 0.0);
+ QPointF sceneGrabPos = p1;
+ QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos);
+ p1 += QPoint(19, 0);
+ QTest::mouseMove(window, p1);
+ QTRY_VERIFY(dragHandler->active());
+ QCOMPARE(dragHandler->centroid().position(), ballCenter);
+ QCOMPARE(dragHandler->centroid().pressPosition(), ballCenter);
+ QCOMPARE(dragHandler->centroid().scenePosition(), ball->mapToScene(ballCenter));
+ QCOMPARE(dragHandler->centroid().scenePressPosition(), scenePressPos);
+ QCOMPARE(dragHandler->centroid().sceneGrabPosition(), sceneGrabPos);
+ QCOMPARE(dragHandler->translation().x(), dragThreshold + 20.0);
+ QCOMPARE(dragHandler->translation().y(), 0.0);
+ QVERIFY(dragHandler->centroid().velocity().x() > 0);
+ QCOMPARE(centroidChangedSpy.count(), 4);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, p1);
+ QTRY_VERIFY(!dragHandler->active());
+ QCOMPARE(dragHandler->centroid().pressedButtons(), Qt::NoButton);
+ QCOMPARE(ball->mapToScene(ballCenter).toPoint(), p1);
+ QCOMPARE(translationChangedSpy.count(), 1);
+ QCOMPARE(centroidChangedSpy.count(), 5);
}
void tst_DragHandler::dragFromMargin() // QTBUG-74966
diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml
index 011dc4e75f..38a19c57c5 100644
--- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml
+++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/data/lesHoverables.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
@@ -26,7 +26,7 @@
**
****************************************************************************/
-import QtQuick 2.12
+import QtQuick 2.15
Rectangle {
id: root
@@ -52,6 +52,7 @@ Rectangle {
id: buttonMA
objectName: "buttonMA"
hoverEnabled: true
+ cursorShape: Qt.UpArrowCursor
anchors.fill: parent
onClicked: console.log("clicked MA")
}
@@ -74,9 +75,12 @@ Rectangle {
id: buttonHH
objectName: "buttonHH"
acceptedDevices: PointerDevice.AllDevices
+ cursorShape: tapHandler.pressed ? Qt.BusyCursor : Qt.PointingHandCursor
}
- TapHandler { }
+ TapHandler {
+ id: tapHandler
+ }
Text {
anchors.centerIn: parent
@@ -127,6 +131,7 @@ Rectangle {
HoverHandler {
id: topSidebarHH
objectName: "topSidebarHH"
+ cursorShape: Qt.OpenHandCursor
}
Loader {
@@ -152,6 +157,7 @@ Rectangle {
id: bottomSidebarMA
objectName: "bottomSidebarMA"
hoverEnabled: true
+ cursorShape: Qt.ClosedHandCursor
anchors.fill: parent
}
diff --git a/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp
index 575139f851..61f2752dd2 100644
--- a/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickhoverhandler/tst_qquickhoverhandler.cpp
@@ -104,30 +104,45 @@ void tst_HoverHandler::hoverHandlerAndUnderlyingHoverHandler()
QCOMPARE(sidebarHoveredSpy.count(), 0);
QCOMPARE(buttonHH->isHovered(), false);
QCOMPARE(buttonHoveredSpy.count(), 0);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::ArrowCursor);
+#endif
QTest::mouseMove(window, rightOfButton);
QCOMPARE(topSidebarHH->isHovered(), true);
QCOMPARE(sidebarHoveredSpy.count(), 1);
QCOMPARE(buttonHH->isHovered(), false);
QCOMPARE(buttonHoveredSpy.count(), 0);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::OpenHandCursor);
+#endif
QTest::mouseMove(window, buttonCenter);
QCOMPARE(topSidebarHH->isHovered(), true);
QCOMPARE(sidebarHoveredSpy.count(), 1);
QCOMPARE(buttonHH->isHovered(), true);
QCOMPARE(buttonHoveredSpy.count(), 1);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::PointingHandCursor);
+#endif
QTest::mouseMove(window, rightOfButton);
QCOMPARE(topSidebarHH->isHovered(), true);
QCOMPARE(sidebarHoveredSpy.count(), 1);
QCOMPARE(buttonHH->isHovered(), false);
QCOMPARE(buttonHoveredSpy.count(), 2);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::OpenHandCursor);
+#endif
QTest::mouseMove(window, outOfSidebar);
QCOMPARE(topSidebarHH->isHovered(), false);
QCOMPARE(sidebarHoveredSpy.count(), 2);
QCOMPARE(buttonHH->isHovered(), false);
QCOMPARE(buttonHoveredSpy.count(), 2);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::ArrowCursor);
+#endif
}
void tst_HoverHandler::mouseAreaAndUnderlyingHoverHandler()
@@ -153,30 +168,45 @@ void tst_HoverHandler::mouseAreaAndUnderlyingHoverHandler()
QCOMPARE(sidebarHoveredSpy.count(), 0);
QCOMPARE(buttonMA->hovered(), false);
QCOMPARE(buttonHoveredSpy.count(), 0);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::ArrowCursor);
+#endif
QTest::mouseMove(window, rightOfButton);
QCOMPARE(topSidebarHH->isHovered(), true);
QCOMPARE(sidebarHoveredSpy.count(), 1);
QCOMPARE(buttonMA->hovered(), false);
QCOMPARE(buttonHoveredSpy.count(), 0);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::OpenHandCursor);
+#endif
QTest::mouseMove(window, buttonCenter);
QCOMPARE(topSidebarHH->isHovered(), true);
QCOMPARE(sidebarHoveredSpy.count(), 1);
QCOMPARE(buttonMA->hovered(), true);
QCOMPARE(buttonHoveredSpy.count(), 1);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::UpArrowCursor);
+#endif
QTest::mouseMove(window, rightOfButton);
QCOMPARE(topSidebarHH->isHovered(), true);
QCOMPARE(sidebarHoveredSpy.count(), 1);
QCOMPARE(buttonMA->hovered(), false);
QCOMPARE(buttonHoveredSpy.count(), 2);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::OpenHandCursor);
+#endif
QTest::mouseMove(window, outOfSidebar);
QCOMPARE(topSidebarHH->isHovered(), false);
QCOMPARE(sidebarHoveredSpy.count(), 2);
QCOMPARE(buttonMA->hovered(), false);
QCOMPARE(buttonHoveredSpy.count(), 2);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::ArrowCursor);
+#endif
}
void tst_HoverHandler::hoverHandlerAndUnderlyingMouseArea()
@@ -204,30 +234,45 @@ void tst_HoverHandler::hoverHandlerAndUnderlyingMouseArea()
QCOMPARE(sidebarHoveredSpy.count(), 0);
QCOMPARE(buttonHH->isHovered(), false);
QCOMPARE(buttonHoveredSpy.count(), 0);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::ArrowCursor);
+#endif
QTest::mouseMove(window, rightOfButton);
QCOMPARE(bottomSidebarMA->hovered(), true);
QCOMPARE(sidebarHoveredSpy.count(), 1);
QCOMPARE(buttonHH->isHovered(), false);
QCOMPARE(buttonHoveredSpy.count(), 0);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::ClosedHandCursor);
+#endif
QTest::mouseMove(window, buttonCenter);
QCOMPARE(bottomSidebarMA->hovered(), false);
QCOMPARE(sidebarHoveredSpy.count(), 2);
QCOMPARE(buttonHH->isHovered(), true);
QCOMPARE(buttonHoveredSpy.count(), 1);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::PointingHandCursor);
+#endif
QTest::mouseMove(window, rightOfButton);
QCOMPARE(bottomSidebarMA->hovered(), true);
QCOMPARE(sidebarHoveredSpy.count(), 3);
QCOMPARE(buttonHH->isHovered(), false);
QCOMPARE(buttonHoveredSpy.count(), 2);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::ClosedHandCursor);
+#endif
QTest::mouseMove(window, outOfSidebar);
QCOMPARE(bottomSidebarMA->hovered(), false);
QCOMPARE(sidebarHoveredSpy.count(), 4);
QCOMPARE(buttonHH->isHovered(), false);
QCOMPARE(buttonHoveredSpy.count(), 2);
+#if QT_CONFIG(cursor)
+ QCOMPARE(window->cursor().shape(), Qt::ArrowCursor);
+#endif
}
void tst_HoverHandler::movingItemWithHoverHandler()
@@ -255,6 +300,7 @@ void tst_HoverHandler::movingItemWithHoverHandler()
QVERIFY(QTest::qWaitForWindowExposed(window));
QTRY_COMPARE(paddleHH->isHovered(), true);
+ // TODO check the cursor shape after fixing QTBUG-53987
paddle->setX(100);
QTRY_COMPARE(paddleHH->isHovered(), false);
diff --git a/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp b/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp
index d0b3bc3d36..ca6463f365 100644
--- a/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp
+++ b/tests/auto/quick/pointerhandlers/qquickpointhandler/tst_qquickpointhandler.cpp
@@ -55,6 +55,7 @@ private slots:
void initTestCase();
void singleTouch();
+ void tabletStylus();
void simultaneousMultiTouch();
void pressedMultipleButtons_data();
void pressedMultipleButtons();
@@ -136,6 +137,65 @@ void tst_PointHandler::singleTouch()
QCOMPARE(translationSpy.count(), 3);
}
+void tst_PointHandler::tabletStylus()
+{
+ qApp->setAttribute(Qt::AA_SynthesizeMouseForUnhandledTabletEvents, false);
+ QScopedPointer<QQuickView> windowPtr;
+ createView(windowPtr, "pointTracker.qml");
+ QQuickView * window = windowPtr.data();
+ QQuickPointHandler *handler = window->rootObject()->findChild<QQuickPointHandler *>("pointHandler");
+ QVERIFY(handler);
+ handler->setAcceptedDevices(QQuickPointerDevice::Stylus);
+
+ QSignalSpy activeSpy(handler, SIGNAL(activeChanged()));
+ QSignalSpy pointSpy(handler, SIGNAL(pointChanged()));
+ QSignalSpy translationSpy(handler, SIGNAL(translationChanged()));
+
+ QPoint point(100,100);
+ const qint64 stylusId = 1234567890;
+
+ QWindowSystemInterface::handleTabletEvent(window, point, window->mapToGlobal(point),
+ QTabletEvent::Stylus, QTabletEvent::Pen, Qt::LeftButton, 0.5, 25, 35, 0.6, 12.3, 3, stylusId, Qt::NoModifier);
+ QTRY_COMPARE(handler->active(), true);
+ QCOMPARE(activeSpy.count(), 1);
+ QCOMPARE(pointSpy.count(), 1);
+ QCOMPARE(handler->point().position().toPoint(), point);
+ QCOMPARE(handler->point().scenePosition().toPoint(), point);
+ QCOMPARE(handler->point().pressedButtons(), Qt::LeftButton);
+ QCOMPARE(handler->point().pressure(), 0.5);
+ QCOMPARE(handler->point().rotation(), 12.3);
+ QCOMPARE(handler->point().uniqueId().numericId(), stylusId);
+ QCOMPARE(handler->translation(), QVector2D());
+ QCOMPARE(translationSpy.count(), 1);
+
+ point += QPoint(10, 10);
+ QWindowSystemInterface::handleTabletEvent(window, point, window->mapToGlobal(point),
+ QTabletEvent::Stylus, QTabletEvent::Pen, Qt::LeftButton, 0.45, 23, 33, 0.57, 15.6, 3.4, stylusId, Qt::NoModifier);
+ QTRY_COMPARE(pointSpy.count(), 2);
+ QCOMPARE(handler->active(), true);
+ QCOMPARE(activeSpy.count(), 1);
+ QCOMPARE(handler->point().position().toPoint(), point);
+ QCOMPARE(handler->point().scenePosition().toPoint(), point);
+ QCOMPARE(handler->point().pressPosition().toPoint(), QPoint(100, 100));
+ QCOMPARE(handler->point().scenePressPosition().toPoint(), QPoint(100, 100));
+ QCOMPARE(handler->point().pressedButtons(), Qt::LeftButton);
+ QCOMPARE(handler->point().pressure(), 0.45);
+ QCOMPARE(handler->point().rotation(), 15.6);
+ QCOMPARE(handler->point().uniqueId().numericId(), stylusId);
+ QVERIFY(handler->point().velocity().x() > 0);
+ QVERIFY(handler->point().velocity().y() > 0);
+ QCOMPARE(handler->translation(), QVector2D(10, 10));
+ QCOMPARE(translationSpy.count(), 2);
+
+ QWindowSystemInterface::handleTabletEvent(window, point, window->mapToGlobal(point),
+ QTabletEvent::Stylus, QTabletEvent::Pen, Qt::NoButton, 0, 0, 0, 0, 0, 0, stylusId, Qt::NoModifier);
+ QTRY_COMPARE(handler->active(), false);
+ QCOMPARE(activeSpy.count(), 2);
+ QCOMPARE(pointSpy.count(), 3);
+ QCOMPARE(handler->translation(), QVector2D());
+ QCOMPARE(translationSpy.count(), 3);
+}
+
void tst_PointHandler::simultaneousMultiTouch()
{
QScopedPointer<QQuickView> windowPtr;
diff --git a/tests/auto/quick/qquickanimatedsprite/data/finishBehavior.qml b/tests/auto/quick/qquickanimatedsprite/data/finishBehavior.qml
new file mode 100644
index 0000000000..13a0ef4622
--- /dev/null
+++ b/tests/auto/quick/qquickanimatedsprite/data/finishBehavior.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.15
+
+Rectangle {
+ color: "black"
+ width: 320
+ height: 320
+
+ AnimatedSprite {
+ objectName: "sprite"
+ loops: 1
+ source: "squarefacesprite.png"
+ frameCount: 6
+ frameDuration: 64
+ width: 160
+ height: 160
+ finishBehavior: AnimatedSprite.FinishAtFinalFrame
+ }
+}
diff --git a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
index d2bbf9e6b1..9f616c56e2 100644
--- a/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
+++ b/tests/auto/quick/qquickanimatedsprite/tst_qquickanimatedsprite.cpp
@@ -49,6 +49,7 @@ private slots:
void initTestCase();
void test_properties();
void test_runningChangedSignal();
+ void test_startStop();
void test_frameChangedSignal();
void test_largeAnimation_data();
void test_largeAnimation();
@@ -56,6 +57,7 @@ private slots:
void test_changeSourceToSmallerImgKeepingBigFrameSize();
void test_infiniteLoops();
void test_implicitSize();
+ void test_finishBehavior();
};
void tst_qquickanimatedsprite::initTestCase()
@@ -118,6 +120,42 @@ void tst_qquickanimatedsprite::test_runningChangedSignal()
QCOMPARE(finishedSpy.count(), 1);
}
+void tst_qquickanimatedsprite::test_startStop()
+{
+ QScopedPointer<QQuickView> window(new QQuickView);
+
+ window->setSource(testFileUrl("runningChange.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QVERIFY(window->rootObject());
+ QQuickAnimatedSprite* sprite = window->rootObject()->findChild<QQuickAnimatedSprite*>("sprite");
+ QVERIFY(sprite);
+
+ QVERIFY(!sprite->running());
+
+ QSignalSpy runningChangedSpy(sprite, SIGNAL(runningChanged(bool)));
+ QSignalSpy finishedSpy(sprite, SIGNAL(finished()));
+ QVERIFY(finishedSpy.isValid());
+
+ sprite->start();
+ QVERIFY(sprite->running());
+ QTRY_COMPARE(runningChangedSpy.count(), 1);
+ QCOMPARE(finishedSpy.count(), 0);
+ sprite->stop();
+ QVERIFY(!sprite->running());
+ QTRY_COMPARE(runningChangedSpy.count(), 2);
+ QCOMPARE(finishedSpy.count(), 0);
+
+ sprite->setCurrentFrame(2);
+ sprite->start();
+ QVERIFY(sprite->running());
+ QCOMPARE(sprite->currentFrame(), 0);
+ QTRY_VERIFY(sprite->currentFrame() > 0);
+ sprite->stop();
+ QVERIFY(!sprite->running());
+}
+
template <typename T>
static bool isWithinRange(T min, T value, T max)
{
@@ -391,6 +429,31 @@ void tst_qquickanimatedsprite::test_infiniteLoops()
QCOMPARE(finishedSpy.count(), 0);
}
+void tst_qquickanimatedsprite::test_finishBehavior()
+{
+ QQuickView window;
+ window.setSource(testFileUrl("finishBehavior.qml"));
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+ QVERIFY(window.rootObject());
+
+ QQuickAnimatedSprite* sprite = window.rootObject()->findChild<QQuickAnimatedSprite*>("sprite");
+ QVERIFY(sprite);
+
+ QTRY_VERIFY(sprite->running());
+
+ // correctly stops at last frame
+ QSignalSpy finishedSpy(sprite, SIGNAL(finished()));
+ QVERIFY(finishedSpy.wait(2000));
+ QCOMPARE(sprite->running(), false);
+ QCOMPARE(sprite->currentFrame(), 5);
+
+ // correctly starts a second time
+ sprite->start();
+ QTRY_VERIFY(sprite->running());
+ QTRY_COMPARE(sprite->currentFrame(), 5);
+}
+
QTEST_MAIN(tst_qquickanimatedsprite)
#include "tst_qquickanimatedsprite.moc"
diff --git a/tests/auto/quick/qquickanimations/data/signalorder.qml b/tests/auto/quick/qquickanimations/data/signalorder.qml
new file mode 100644
index 0000000000..35029b0c84
--- /dev/null
+++ b/tests/auto/quick/qquickanimations/data/signalorder.qml
@@ -0,0 +1,27 @@
+import QtQuick 2.12
+
+
+Item {
+ id: wrapper
+ width: 400; height: 400
+
+ Rectangle {
+ id: greenRect
+ width: 50; height: 50
+ color: "red"
+
+ ColorAnimation on color {
+ id: colorAnimation
+ objectName: "ColorAnimation"
+ to: "green"
+ duration: 10
+ running: false
+ }
+
+ ParallelAnimation {
+ id: parallelAnimation
+ objectName: "ParallelAnimation"
+ running: false
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickanimations/qquickanimations.pro b/tests/auto/quick/qquickanimations/qquickanimations.pro
index 94f694181d..6998c023db 100644
--- a/tests/auto/quick/qquickanimations/qquickanimations.pro
+++ b/tests/auto/quick/qquickanimations/qquickanimations.pro
@@ -64,6 +64,7 @@ OTHER_FILES += \
data/scriptActionCrash.qml \
data/sequentialAnimationNullChildBug.qml \
data/signals.qml \
+ data/signalorder.qml \
data/transitionAssignmentBug.qml \
data/valuesource.qml \
data/valuesource2.qml
diff --git a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
index 9bd0cd777f..b4eb33eb7a 100644
--- a/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
+++ b/tests/auto/quick/qquickanimations/tst_qquickanimations.cpp
@@ -89,6 +89,8 @@ private slots:
void easingProperties();
void rotation();
void startStopSignals();
+ void signalOrder_data();
+ void signalOrder();
void runningTrueBug();
void nonTransitionBug();
void registrationBug();
@@ -266,7 +268,8 @@ void tst_qquickanimations::simplePath()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("pathAnimation.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
@@ -300,14 +303,13 @@ void tst_qquickanimations::simplePath()
pathAnim->start();
QTRY_VERIFY(redRect->rotation() != 0);
pathAnim->stop();
-
- delete rect;
}
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("pathAnimation2.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
@@ -335,8 +337,6 @@ void tst_qquickanimations::simplePath()
QCOMPARE(redRect->x(), qreal(300));
QCOMPARE(redRect->y(), qreal(300));
QCOMPARE(redRect->rotation(), qreal(0));
-
- delete rect;
}
}
@@ -344,7 +344,8 @@ void tst_qquickanimations::simpleAnchor()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("reanchor.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *greenRect = rect->findChild<QQuickRectangle*>();
@@ -412,15 +413,14 @@ void tst_qquickanimations::simpleAnchor()
QCOMPARE(greenRect->y(), qreal(50));
QCOMPARE(greenRect->width(), qreal(150));
QCOMPARE(greenRect->height(), qreal(125));
-
- delete rect;
}
void tst_qquickanimations::reparent()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("reparent.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *target = rect->findChild<QQuickRectangle*>("target");
@@ -461,15 +461,14 @@ void tst_qquickanimations::reparent()
QCOMPARE(target->height(), qreal(50));
QCOMPARE(target->rotation(), qreal(0));
QCOMPARE(target->scale(), qreal(1));
-
- delete rect;
}
void tst_qquickanimations::pathInterpolator()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("pathInterpolator.qml"));
- QQuickPathInterpolator *interpolator = qobject_cast<QQuickPathInterpolator*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *interpolator = qobject_cast<QQuickPathInterpolator*>(obj.data());
QVERIFY(interpolator);
QCOMPARE(interpolator->progress(), qreal(0));
@@ -505,7 +504,8 @@ void tst_qquickanimations::pathInterpolatorBackwardJump()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("pathInterpolatorBack.qml"));
- QQuickPathInterpolator *interpolator = qobject_cast<QQuickPathInterpolator*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *interpolator = qobject_cast<QQuickPathInterpolator*>(obj.data());
QVERIFY(interpolator);
QCOMPARE(interpolator->progress(), qreal(0));
@@ -536,7 +536,8 @@ void tst_qquickanimations::pathInterpolatorBackwardJump()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("pathInterpolatorBack2.qml"));
- QQuickPathInterpolator *interpolator = qobject_cast<QQuickPathInterpolator*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *interpolator = qobject_cast<QQuickPathInterpolator*>(obj.data());
QVERIFY(interpolator);
QCOMPARE(interpolator->progress(), qreal(0));
@@ -563,7 +564,8 @@ void tst_qquickanimations::pathWithNoStart()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("pathAnimationNoStart.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
@@ -729,12 +731,9 @@ void tst_qquickanimations::badTypes()
{
//don't crash
{
- QQuickView *view = new QQuickView;
+ QScopedPointer<QQuickView> view(new QQuickView);
view->setSource(testFileUrl("badtype1.qml"));
-
qApp->processEvents();
-
- delete view;
}
//make sure we get a compiler error
@@ -742,7 +741,8 @@ void tst_qquickanimations::badTypes()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("badtype2.qml"));
QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready");
- c.create();
+ QScopedPointer<QObject> obj(c.create());
+ QVERIFY(obj.isNull());
QCOMPARE(c.errors().count(), 1);
QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: number expected"));
@@ -753,7 +753,8 @@ void tst_qquickanimations::badTypes()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("badtype3.qml"));
QTest::ignoreMessage(QtWarningMsg, "QQmlComponent: Component is not ready");
- c.create();
+ QScopedPointer<QObject> obj(c.create());
+ QVERIFY(obj.isNull());
QCOMPARE(c.errors().count(), 1);
QCOMPARE(c.errors().at(0).description(), QLatin1String("Invalid property assignment: color expected"));
@@ -763,7 +764,8 @@ void tst_qquickanimations::badTypes()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("badtype4.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickItemPrivate::get(rect)->setState("state1");
@@ -783,13 +785,15 @@ void tst_qquickanimations::badProperties()
QQmlComponent c1(&engine, testFileUrl("badproperty1.qml"));
QByteArray message = testFileUrl("badproperty1.qml").toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate non-existent property \"border.colr\"";
QTest::ignoreMessage(QtWarningMsg, message);
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c1.create());
+ QScopedPointer<QObject> obj(c1.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQmlComponent c2(&engine, testFileUrl("badproperty2.qml"));
message = testFileUrl("badproperty2.qml").toString().toUtf8() + ":18:9: QML ColorAnimation: Cannot animate read-only property \"border\"";
QTest::ignoreMessage(QtWarningMsg, message);
- rect = qobject_cast<QQuickRectangle*>(c2.create());
+ QScopedPointer<QObject> obj2(c2.create());
+ rect = qobject_cast<QQuickRectangle*>(obj2.data());
QVERIFY(rect);
//### should we warn here are well?
@@ -805,7 +809,8 @@ void tst_qquickanimations::mixedTypes()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("mixedtype1.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickItemPrivate::get(rect)->setState("state1");
@@ -821,7 +826,8 @@ void tst_qquickanimations::mixedTypes()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("mixedtype2.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickItemPrivate::get(rect)->setState("state1");
@@ -841,7 +847,8 @@ void tst_qquickanimations::properties()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("properties.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
@@ -853,7 +860,8 @@ void tst_qquickanimations::properties()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("properties2.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
@@ -865,7 +873,8 @@ void tst_qquickanimations::properties()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("properties3.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
@@ -877,7 +886,8 @@ void tst_qquickanimations::properties()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("properties4.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
@@ -890,7 +900,8 @@ void tst_qquickanimations::properties()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("properties5.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
@@ -907,7 +918,8 @@ void tst_qquickanimations::propertiesTransition()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("propertiesTransition.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickItemPrivate::get(rect)->setState("moved");
@@ -920,7 +932,8 @@ void tst_qquickanimations::propertiesTransition()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("propertiesTransition2.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
@@ -935,7 +948,8 @@ void tst_qquickanimations::propertiesTransition()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("propertiesTransition3.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
@@ -948,7 +962,8 @@ void tst_qquickanimations::propertiesTransition()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("propertiesTransition4.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
@@ -962,7 +977,8 @@ void tst_qquickanimations::propertiesTransition()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("propertiesTransition5.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
@@ -976,7 +992,8 @@ void tst_qquickanimations::propertiesTransition()
/*{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("propertiesTransition6.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
@@ -990,7 +1007,8 @@ void tst_qquickanimations::propertiesTransition()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("propertiesTransition7.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickItemPrivate::get(rect)->setState("moved");
@@ -1006,7 +1024,8 @@ void tst_qquickanimations::pathTransition()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("pathTransition.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("redRect");
@@ -1026,7 +1045,8 @@ void tst_qquickanimations::disabledTransition()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("disabledTransition.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *myRect = rect->findChild<QQuickRectangle*>("TheRect");
@@ -1054,12 +1074,12 @@ void tst_qquickanimations::disabledTransition()
void tst_qquickanimations::invalidDuration()
{
- QQuickPropertyAnimation *animation = new QQuickPropertyAnimation;
+ QScopedPointer<QQuickPropertyAnimation> animation(new QQuickPropertyAnimation);
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML PropertyAnimation: Cannot set a duration of < 0");
animation->setDuration(-1);
QCOMPARE(animation->duration(), 250);
- QQuickPauseAnimation *pauseAnimation = new QQuickPauseAnimation;
+ QScopedPointer<QQuickPauseAnimation> pauseAnimation(new QQuickPauseAnimation);
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: QML PauseAnimation: Cannot set a duration of < 0");
pauseAnimation->setDuration(-1);
QCOMPARE(pauseAnimation->duration(), 250);
@@ -1072,7 +1092,8 @@ void tst_qquickanimations::attached()
QQmlComponent c(&engine, testFileUrl("attached.qml"));
QTest::ignoreMessage(QtDebugMsg, "off");
QTest::ignoreMessage(QtDebugMsg, "on");
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
}
@@ -1083,7 +1104,8 @@ void tst_qquickanimations::propertyValueSourceDefaultStart()
QQmlComponent c(&engine, testFileUrl("valuesource.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim");
@@ -1096,7 +1118,8 @@ void tst_qquickanimations::propertyValueSourceDefaultStart()
QQmlComponent c(&engine, testFileUrl("valuesource2.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim");
@@ -1109,7 +1132,8 @@ void tst_qquickanimations::propertyValueSourceDefaultStart()
QQmlComponent c(&engine, testFileUrl("dontAutoStart.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim");
@@ -1128,7 +1152,8 @@ void tst_qquickanimations::dontStart()
QString warning = c.url().toString() + ":14:13: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes.";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim");
@@ -1143,7 +1168,8 @@ void tst_qquickanimations::dontStart()
QString warning = c.url().toString() + ":15:17: QML NumberAnimation: setRunning() cannot be used on non-root animation nodes.";
QTest::ignoreMessage(QtWarningMsg, qPrintable(warning));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickAbstractAnimation *myAnim = rect->findChild<QQuickAbstractAnimation*>("MyAnim");
@@ -1159,7 +1185,8 @@ void tst_qquickanimations::easingProperties()
QString componentStr = "import QtQuick 2.0\nNumberAnimation { easing.type: \"InOutQuad\" }";
QQmlComponent animationComponent(&engine);
animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
- QQuickPropertyAnimation *animObject = qobject_cast<QQuickPropertyAnimation*>(animationComponent.create());
+ QScopedPointer<QObject> obj(animationComponent.create());
+ auto *animObject = qobject_cast<QQuickPropertyAnimation *>(obj.data());
QVERIFY(animObject != nullptr);
QCOMPARE(animObject->easing().type(), QEasingCurve::InOutQuad);
@@ -1170,7 +1197,8 @@ void tst_qquickanimations::easingProperties()
QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"OutBounce\"; easing.amplitude: 5.0 }";
QQmlComponent animationComponent(&engine);
animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
- QQuickPropertyAnimation *animObject = qobject_cast<QQuickPropertyAnimation*>(animationComponent.create());
+ QScopedPointer<QObject> obj(animationComponent.create());
+ auto *animObject = qobject_cast<QQuickPropertyAnimation *>(obj.data());
QVERIFY(animObject != nullptr);
QCOMPARE(animObject->easing().type(), QEasingCurve::OutBounce);
@@ -1182,7 +1210,8 @@ void tst_qquickanimations::easingProperties()
QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"OutElastic\"; easing.amplitude: 5.0; easing.period: 3.0}";
QQmlComponent animationComponent(&engine);
animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
- QQuickPropertyAnimation *animObject = qobject_cast<QQuickPropertyAnimation*>(animationComponent.create());
+ QScopedPointer<QObject> obj(animationComponent.create());
+ auto *animObject = qobject_cast<QQuickPropertyAnimation *>(obj.data());
QVERIFY(animObject != nullptr);
QCOMPARE(animObject->easing().type(), QEasingCurve::OutElastic);
@@ -1195,7 +1224,8 @@ void tst_qquickanimations::easingProperties()
QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"InOutBack\"; easing.overshoot: 2 }";
QQmlComponent animationComponent(&engine);
animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
- QQuickPropertyAnimation *animObject = qobject_cast<QQuickPropertyAnimation*>(animationComponent.create());
+ QScopedPointer<QObject> obj(animationComponent.create());
+ auto *animObject = qobject_cast<QQuickPropertyAnimation *>(obj.data());
QVERIFY(animObject != nullptr);
QCOMPARE(animObject->easing().type(), QEasingCurve::InOutBack);
@@ -1207,7 +1237,8 @@ void tst_qquickanimations::easingProperties()
QString componentStr = "import QtQuick 2.0\nPropertyAnimation { easing.type: \"Bezier\"; easing.bezierCurve: [0.5, 0.2, 0.13, 0.65, 1.0, 1.0] }";
QQmlComponent animationComponent(&engine);
animationComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
- QQuickPropertyAnimation *animObject = qobject_cast<QQuickPropertyAnimation*>(animationComponent.create());
+ QScopedPointer<QObject> obj(animationComponent.create());
+ auto *animObject = qobject_cast<QQuickPropertyAnimation *>(obj.data());
QVERIFY(animObject != nullptr);
QCOMPARE(animObject->easing().type(), QEasingCurve::BezierSpline);
@@ -1223,7 +1254,8 @@ void tst_qquickanimations::rotation()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("rotation.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *rr = rect->findChild<QQuickRectangle*>("rr");
@@ -1253,7 +1285,8 @@ void tst_qquickanimations::startStopSignals()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("signals.qml"));
- QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *root = qobject_cast<QQuickItem *>(obj.data());
QVERIFY(root);
QCOMPARE(root->property("startedCount").toInt(), 1); //autostart
@@ -1293,12 +1326,63 @@ void tst_qquickanimations::startStopSignals()
QVERIFY(timer.elapsed() >= 200);
}
+void tst_qquickanimations::signalOrder_data()
+{
+ QTest::addColumn<QByteArray>("animationType");
+ QTest::addColumn<int>("duration");
+
+ QTest::addRow("ColorAnimation, duration = 10") << QByteArray("ColorAnimation") << 10;
+ QTest::addRow("ColorAnimation, duration = 0") << QByteArray("ColorAnimation") << 0;
+ QTest::addRow("ParallelAnimation, duration = 0") << QByteArray("ParallelAnimation") << 0;
+}
+
+void tst_qquickanimations::signalOrder()
+{
+ QFETCH(QByteArray, animationType);
+ QFETCH(int, duration);
+
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("signalorder.qml"));
+ QScopedPointer<QObject> obj(c.create());
+ auto *root = qobject_cast<QQuickItem *>(obj.data());
+ QVERIFY(root);
+ QQuickAbstractAnimation *animation = root->findChild<QQuickAbstractAnimation*>(animationType);
+
+ const QVector<void (QQuickAbstractAnimation::*)()> signalsToConnect = {
+ &QQuickAbstractAnimation::started,
+ &QQuickAbstractAnimation::stopped,
+ &QQuickAbstractAnimation::finished
+ };
+ const QVector<const char*> expectedSignalOrder = {
+ "started",
+ "stopped",
+ "finished"
+ };
+
+ QVector<const char*> actualSignalOrder;
+
+ for (int i = 0; i < signalsToConnect.size(); ++i) {
+ const char *str = expectedSignalOrder.at(i);
+ connect(animation, signalsToConnect.at(i) , [str, &actualSignalOrder] () {
+ actualSignalOrder.append(str);
+ });
+ }
+ QSignalSpy finishedSpy(animation, SIGNAL(finished()));
+ if (QQuickColorAnimation *colorAnimation = qobject_cast<QQuickColorAnimation*>(animation))
+ colorAnimation->setDuration(duration);
+
+ animation->start();
+ QTRY_VERIFY(finishedSpy.count());
+ QCOMPARE(actualSignalOrder, expectedSignalOrder);
+}
+
void tst_qquickanimations::runningTrueBug()
{
//ensure we start correctly when "running: true" is explicitly set
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("runningTrueBug.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *cloud = rect->findChild<QQuickRectangle*>("cloud");
@@ -1313,7 +1397,8 @@ void tst_qquickanimations::pathAnimationInOutBackBug()
//ensure we don't pass bad progress value (out of [0,1]) to QQuickPath::backwardsPointAt()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("pathAnimationInOutBackCrash.qml"));
- QQuickItem *item = qobject_cast<QQuickItem*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *item = qobject_cast<QQuickItem *>(obj.data());
QVERIFY(item);
QQuickRectangle *rect = item->findChild<QQuickRectangle *>("rect");
@@ -1331,7 +1416,8 @@ void tst_qquickanimations::nonTransitionBug()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("nonTransitionBug.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect != nullptr);
QQuickItemPrivate *rectPrivate = QQuickItemPrivate::get(rect);
QQuickRectangle *mover = rect->findChild<QQuickRectangle*>("mover");
@@ -1357,7 +1443,8 @@ void tst_qquickanimations::registrationBug()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("registrationBug.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect != nullptr);
QTRY_COMPARE(rect->property("value"), QVariant(int(100)));
}
@@ -1367,7 +1454,8 @@ void tst_qquickanimations::doubleRegistrationBug()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("doubleRegistrationBug.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect != nullptr);
QQuickAbstractAnimation *anim = rect->findChild<QQuickAbstractAnimation*>("animation");
@@ -1408,7 +1496,8 @@ void tst_qquickanimations::transitionAssignmentBug()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("transitionAssignmentBug.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect != nullptr);
QCOMPARE(rect->property("nullObject").toBool(), false);
@@ -1420,12 +1509,11 @@ void tst_qquickanimations::pauseBindingBug()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("pauseBindingBug.qml"));
- QQuickRectangle *rect = qobject_cast<QQuickRectangle*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect != nullptr);
QQuickAbstractAnimation *anim = rect->findChild<QQuickAbstractAnimation*>("animation");
QCOMPARE(anim->qtAnimation()->state(), QAbstractAnimationJob::Paused);
-
- delete rect;
}
//QTBUG-13598
@@ -1434,13 +1522,12 @@ void tst_qquickanimations::pauseBug()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("pauseBug.qml"));
- QQuickAbstractAnimation *anim = qobject_cast<QQuickAbstractAnimation*>(c.create());
+ QScopedPointer<QObject> obj(c.create());
+ auto *anim = qobject_cast<QQuickAbstractAnimation*>(obj.data());
QVERIFY(anim != nullptr);
QCOMPARE(anim->qtAnimation()->state(), QAbstractAnimationJob::Paused);
QCOMPARE(anim->isPaused(), true);
QCOMPARE(anim->isRunning(), true);
-
- delete anim;
}
//QTBUG-23092
@@ -1449,7 +1536,7 @@ void tst_qquickanimations::loopingBug()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("looping.qml"));
- QObject *obj = c.create();
+ QScopedPointer<QObject> obj(c.create());
QQuickAbstractAnimation *anim = obj->findChild<QQuickAbstractAnimation*>();
QVERIFY(anim != nullptr);
@@ -1461,8 +1548,6 @@ void tst_qquickanimations::loopingBug()
QQuickRectangle *rect = obj->findChild<QQuickRectangle*>();
QVERIFY(rect != nullptr);
QCOMPARE(rect->rotation(), qreal(90));
-
- delete obj;
}
//QTBUG-24532
@@ -1483,7 +1568,7 @@ void tst_qquickanimations::scriptActionBug()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("scriptActionBug.qml"));
- QObject *obj = c.create();
+ QScopedPointer<QObject> obj(c.create());
//Both the ScriptAction and StateChangeScript should be triggered
QCOMPARE(obj->property("actionTriggered").toBool(), true);
@@ -1497,20 +1582,16 @@ void tst_qquickanimations::groupAnimationNullChildBug()
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("sequentialAnimationNullChildBug.qml"));
- QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
+ QScopedPointer<QObject> root(c.create());
QVERIFY(root);
-
- delete root;
}
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("parallelAnimationNullChildBug.qml"));
- QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
+ QScopedPointer<QObject> root(c.create());
QVERIFY(root);
-
- delete root;
}
}
@@ -1519,12 +1600,10 @@ void tst_qquickanimations::scriptActionCrash()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("scriptActionCrash.qml"));
- QObject *obj = c.create();
+ QScopedPointer<QObject> obj(c.create());
//just testing that we don't crash
QTest::qWait(1000); //5x transition duration
-
- delete obj;
}
// QTBUG-49364
@@ -1535,12 +1614,10 @@ void tst_qquickanimations::animatorInvalidTargetCrash()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("animatorInvalidTargetCrash.qml"));
- QObject *obj = c.create();
+ QScopedPointer<QObject> obj(c.create());
//just testing that we don't crash
QTest::qWait(5000); //animator duration
-
- delete obj;
}
Q_DECLARE_METATYPE(QList<QQmlError>)
@@ -1556,7 +1633,8 @@ void tst_qquickanimations::defaultPropertyWarning()
QVERIFY(warnings.isValid());
QQmlComponent component(&engine, testFileUrl("defaultRotationAnimation.qml"));
- QScopedPointer<QQuickItem> root(qobject_cast<QQuickItem*>(component.create()));
+ QScopedPointer<QObject> obj(component.create());
+ auto *root = qobject_cast<QQuickItem *>(obj.data());
QVERIFY(root);
QVERIFY(warnings.isEmpty());
@@ -1567,7 +1645,8 @@ void tst_qquickanimations::pathSvgAnimation()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("pathSvgAnimation.qml"));
- QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(component.create()));
+ QScopedPointer<QObject> obj(component.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
@@ -1588,7 +1667,8 @@ void tst_qquickanimations::pathLineUnspecifiedXYBug()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("pathLineUnspecifiedXYBug.qml"));
- QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(component.create()));
+ QScopedPointer<QObject> obj(component.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
QVERIFY(rect);
QQuickRectangle *redRect = rect->findChild<QQuickRectangle*>();
@@ -1624,7 +1704,8 @@ void tst_qquickanimations::finished()
{
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("finished.qml"));
- QScopedPointer<QObject> root(component.create());
+ QScopedPointer<QObject> obj(component.create());
+ auto *root = qobject_cast<QQuickItem *>(obj.data());
QVERIFY(root);
// Test that finished() is emitted for a simple top-level animation.
@@ -1697,7 +1778,8 @@ void tst_qquickanimations::replacingTransitions()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("replacingTransitions.qml"));
- QScopedPointer<QQuickRectangle> rect(qobject_cast<QQuickRectangle*>(c.create()));
+ QScopedPointer<QObject> obj(c.create());
+ auto *rect = qobject_cast<QQuickRectangle*>(obj.data());
if (!c.errors().isEmpty())
qDebug() << c.errorString();
QVERIFY(rect);
@@ -1733,13 +1815,14 @@ void tst_qquickanimations::animationJobSelfDestruction()
QQmlEngine engine;
engine.clearComponentCache();
QQmlComponent c(&engine, testFileUrl("animationJobSelfDestructionBug.qml"));
- QScopedPointer<QQuickWindow> win(qobject_cast<QQuickWindow*>(c.create()));
+ QScopedPointer<QObject> obj(c.create());
+ auto *win = qobject_cast<QQuickWindow *>(obj.data());
if (!c.errors().isEmpty())
qDebug() << c.errorString();
QVERIFY(win);
win->setTitle(QTest::currentTestFunction());
win->show();
- QVERIFY(QTest::qWaitForWindowExposed(win.data()));
+ QVERIFY(QTest::qWaitForWindowExposed(win));
QQmlTimer *timer = win->property("timer").value<QQmlTimer*>();
QVERIFY(timer);
QCOMPARE(timer->isRunning(), false);
@@ -1753,13 +1836,14 @@ void tst_qquickanimations::fastFlickingBug()
QQmlEngine engine;
engine.clearComponentCache();
QQmlComponent c(&engine, testFileUrl("fastFlickingBug.qml"));
- QScopedPointer<QQuickWindow> win(qobject_cast<QQuickWindow*>(c.create()));
+ QScopedPointer<QObject> obj(c.create());
+ auto *win = qobject_cast<QQuickWindow *>(obj.data());
if (!c.errors().isEmpty())
qDebug() << c.errorString();
QVERIFY(win);
win->setTitle(QTest::currentTestFunction());
win->show();
- QVERIFY(QTest::qWaitForWindowExposed(win.data()));
+ QVERIFY(QTest::qWaitForWindowExposed(win));
auto timer = win->property("timer").value<QQmlTimer*>();
QVERIFY(timer);
QCOMPARE(timer->isRunning(), false);
diff --git a/tests/auto/quick/qquickbehaviors/data/targetProperty.qml b/tests/auto/quick/qquickbehaviors/data/targetProperty.qml
new file mode 100644
index 0000000000..18abd46010
--- /dev/null
+++ b/tests/auto/quick/qquickbehaviors/data/targetProperty.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.15
+
+Item {
+ readonly property QtObject xBehaviorObject: xBehavior.targetProperty.object
+ readonly property string xBehaviorName: xBehavior.targetProperty.name
+ readonly property QtObject emptyBehaviorObject: emptyBehavior.targetProperty.object
+ readonly property string emptyBehaviorName: emptyBehavior.targetProperty.name
+ Behavior on x {
+ id: xBehavior
+ objectName: "xBehavior"
+ }
+ Behavior {
+ id: emptyBehavior
+ objectName: "emptyBehavior"
+ }
+}
diff --git a/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp b/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp
index 64e32dcdfd..3b46019f64 100644
--- a/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp
+++ b/tests/auto/quick/qquickbehaviors/tst_qquickbehaviors.cpp
@@ -75,6 +75,7 @@ private slots:
void innerBehaviorOverwritten();
void oneWay();
void safeToDelete();
+ void targetProperty();
};
void tst_qquickbehaviors::simpleBehavior()
@@ -656,6 +657,27 @@ void tst_qquickbehaviors::safeToDelete()
QVERIFY(c.create());
}
+Q_DECLARE_METATYPE(QQmlProperty)
+void tst_qquickbehaviors::targetProperty()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("targetProperty.qml"));
+ QScopedPointer<QQuickItem> item(qobject_cast<QQuickItem*>(c.create()));
+ QVERIFY2(!item.isNull(), qPrintable(c.errorString()));
+
+ QQuickBehavior* xBehavior =
+ qobject_cast<QQuickBehavior*>(item->findChild<QQuickBehavior*>("xBehavior"));
+ QCOMPARE(xBehavior->property("targetProperty").value<QQmlProperty>(), QQmlProperty(item.data(), "x"));
+ QCOMPARE(item->property("xBehaviorObject").value<QObject*>(), item.data());
+ QCOMPARE(item->property("xBehaviorName").toString(), "x");
+
+ QQuickBehavior* emptyBehavior =
+ qobject_cast<QQuickBehavior*>(item->findChild<QQuickBehavior*>("emptyBehavior"));
+ QCOMPARE(emptyBehavior->property("targetProperty").value<QQmlProperty>().isValid(), false);
+ QCOMPARE(item->property("emptyBehaviorObject").value<QObject*>(), nullptr);
+ QCOMPARE(item->property("emptyBehaviorName").toString(), "");
+}
+
QTEST_MAIN(tst_qquickbehaviors)
diff --git a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp
index dc3a783600..858a685796 100644
--- a/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp
+++ b/tests/auto/quick/qquickborderimage/tst_qquickborderimage.cpp
@@ -619,7 +619,7 @@ void tst_qquickborderimage::multiFrame()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QFETCH(QString, qmlfile);
QFETCH(bool, asynchronous);
diff --git a/tests/auto/quick/qquickboundaryrule/data/dragHandler.qml b/tests/auto/quick/qquickboundaryrule/data/dragHandler.qml
index c66fd76ff1..769a5b2c7d 100644
--- a/tests/auto/quick/qquickboundaryrule/data/dragHandler.qml
+++ b/tests/auto/quick/qquickboundaryrule/data/dragHandler.qml
@@ -14,6 +14,7 @@ Rectangle {
}
BoundaryRule on x {
+ objectName: "boundaryRule"
id: xbr
minimum: -50
maximum: 100
diff --git a/tests/auto/quick/qquickboundaryrule/qquickboundaryrule.pro b/tests/auto/quick/qquickboundaryrule/qquickboundaryrule.pro
index ef43f4526a..c41f798d33 100644
--- a/tests/auto/quick/qquickboundaryrule/qquickboundaryrule.pro
+++ b/tests/auto/quick/qquickboundaryrule/qquickboundaryrule.pro
@@ -9,4 +9,4 @@ include (../shared/util.pri)
TESTDATA = data/*
-QT += core-private gui-private qml-private quick-private testlib
+QT += quick-private qml testlib
diff --git a/tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp b/tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp
index 44f1c9a2f9..75639dba49 100644
--- a/tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp
+++ b/tests/auto/quick/qquickboundaryrule/tst_qquickboundaryrule.cpp
@@ -30,7 +30,6 @@
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>
#include <QtQuick/qquickview.h>
-#include <QtQuick/private/qquickboundaryrule_p.h>
#include <QtQuick/private/qquickdraghandler_p.h>
#include "../../shared/util.h"
#include "../shared/viewtestutil.h"
@@ -57,7 +56,7 @@ void tst_qquickboundaryrule::dragHandler()
QVERIFY(target);
QQuickDragHandler *dragHandler = target->findChild<QQuickDragHandler*>();
QVERIFY(dragHandler);
- QQuickBoundaryRule *boundaryRule = target->findChild<QQuickBoundaryRule*>();
+ QObject *boundaryRule = target->findChild<QObject *>(QLatin1String("boundaryRule"));
QVERIFY(boundaryRule);
QSignalSpy overshootChangedSpy(boundaryRule, SIGNAL(currentOvershootChanged()));
@@ -68,29 +67,34 @@ void tst_qquickboundaryrule::dragHandler()
QTest::mouseMove(&window, p1);
QTRY_VERIFY(dragHandler->active());
QCOMPARE(target->position().x(), 100);
- QCOMPARE(boundaryRule->currentOvershoot(), 0);
- QCOMPARE(boundaryRule->peakOvershoot(), 0);
+ bool ok = false;
+ QCOMPARE(boundaryRule->property("currentOvershoot").toReal(&ok), 0);
+ QVERIFY(ok);
+ QCOMPARE(boundaryRule->property("peakOvershoot").toReal(&ok), 0);
+ QVERIFY(ok);
QCOMPARE(overshootChangedSpy.count(), 0);
// restricted drag: halfway into overshoot
p1 += QPoint(20, 0);
QTest::mouseMove(&window, p1);
QCOMPARE(target->position().x(), 117.5);
- QCOMPARE(boundaryRule->currentOvershoot(), 20);
- QCOMPARE(boundaryRule->peakOvershoot(), 20);
+ QCOMPARE(boundaryRule->property("currentOvershoot").toReal(), 20);
+ QCOMPARE(boundaryRule->property("peakOvershoot").toReal(), 20);
QCOMPARE(overshootChangedSpy.count(), 1);
// restricted drag: maximum overshoot
p1 += QPoint(80, 0);
QTest::mouseMove(&window, p1);
QCOMPARE(target->position().x(), 140);
- QCOMPARE(boundaryRule->currentOvershoot(), 100);
- QCOMPARE(boundaryRule->peakOvershoot(), 100);
+ QCOMPARE(boundaryRule->property("currentOvershoot").toReal(), 100);
+ QCOMPARE(boundaryRule->property("peakOvershoot").toReal(), 100);
QCOMPARE(overshootChangedSpy.count(), 2);
// release and let it return to bounds
QTest::mouseRelease(&window, Qt::LeftButton, Qt::NoModifier, p1);
QTRY_COMPARE(dragHandler->active(), false);
QTRY_COMPARE(overshootChangedSpy.count(), 3);
- QCOMPARE(boundaryRule->currentOvershoot(), 0);
- QCOMPARE(boundaryRule->peakOvershoot(), 0);
+ QCOMPARE(boundaryRule->property("currentOvershoot").toReal(&ok), 0);
+ QVERIFY(ok);
+ QCOMPARE(boundaryRule->property("peakOvershoot").toReal(&ok), 0);
+ QVERIFY(ok);
QCOMPARE(target->position().x(), 100);
}
diff --git a/tests/auto/quick/qquickflickable/data/resize.qml b/tests/auto/quick/qquickflickable/data/resize.qml
index 2f7ae7b8bb..131691d012 100644
--- a/tests/auto/quick/qquickflickable/data/resize.qml
+++ b/tests/auto/quick/qquickflickable/data/resize.qml
@@ -1,6 +1,7 @@
import QtQuick 2.0
Rectangle {
+ required property bool setRebound
function resizeContent() {
flick.resizeContent(600, 600, Qt.point(100, 100))
}
diff --git a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
index da4bf5dae3..f3659290eb 100644
--- a/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
+++ b/tests/auto/quick/qquickflickable/tst_qquickflickable.cpp
@@ -227,7 +227,7 @@ void tst_qquickflickable::create()
{
QQmlEngine engine;
QQmlComponent c(&engine, testFileUrl("flickable01.qml"));
- QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.create());
+ QQuickFlickable *obj = qobject_cast<QQuickFlickable*>(c.createWithInitialProperties({{"setRebound", false}}));
QVERIFY(obj != nullptr);
QCOMPARE(obj->isAtXBeginning(), true);
@@ -783,9 +783,8 @@ void tst_qquickflickable::flickableDirection()
void tst_qquickflickable::resizeContent()
{
QQmlEngine engine;
- engine.rootContext()->setContextProperty("setRebound", QVariant::fromValue(false));
QQmlComponent c(&engine, testFileUrl("resize.qml"));
- QQuickItem *root = qobject_cast<QQuickItem*>(c.create());
+ QQuickItem *root = qobject_cast<QQuickItem*>(c.createWithInitialProperties({{"setRebound", false}}));
QQuickFlickable *obj = findItem<QQuickFlickable>(root, "flick");
QVERIFY(obj != nullptr);
@@ -817,7 +816,7 @@ void tst_qquickflickable::returnToBounds()
QScopedPointer<QQuickView> window(new QQuickView);
- window->rootContext()->setContextProperty("setRebound", setRebound);
+ window->setInitialProperties({{"setRebound", setRebound}});
window->setSource(testFileUrl("resize.qml"));
window->show();
QVERIFY(QTest::qWaitForWindowActive(window.data()));
diff --git a/tests/auto/quick/qquickimage/data/ProPhoto.jpg b/tests/auto/quick/qquickimage/data/ProPhoto.jpg
new file mode 100644
index 0000000000..481d35ca8e
--- /dev/null
+++ b/tests/auto/quick/qquickimage/data/ProPhoto.jpg
Binary files differ
diff --git a/tests/auto/quick/qquickimage/data/image.qml b/tests/auto/quick/qquickimage/data/image.qml
new file mode 100644
index 0000000000..09a577cc6f
--- /dev/null
+++ b/tests/auto/quick/qquickimage/data/image.qml
@@ -0,0 +1,5 @@
+import QtQuick 2.15
+
+Image {
+ source: "heart.png"
+}
diff --git a/tests/auto/quick/qquickimage/tst_qquickimage.cpp b/tests/auto/quick/qquickimage/tst_qquickimage.cpp
index abc7cd86bd..cf54208d8c 100644
--- a/tests/auto/quick/qquickimage/tst_qquickimage.cpp
+++ b/tests/auto/quick/qquickimage/tst_qquickimage.cpp
@@ -51,6 +51,7 @@
#include "../../shared/testhttpserver.h"
#include "../shared/visualtestutil.h"
+// #define DEBUG_WRITE_OUTPUT
using namespace QQuickVisualTestUtil;
@@ -89,6 +90,8 @@ private slots:
void imageCrash_QTBUG_32513();
void sourceSize_data();
void sourceSize();
+ void sourceClipRect_data();
+ void sourceClipRect();
void progressAndStatusChanges();
void sourceSizeChanges();
void correctStatus();
@@ -99,6 +102,7 @@ private slots:
void urlInterceptor();
void multiFrame_data();
void multiFrame();
+ void colorSpace();
private:
QQmlEngine engine;
@@ -337,7 +341,7 @@ void tst_qquickimage::mirror()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QMap<QQuickImage::FillMode, QImage> screenshots;
QList<QQuickImage::FillMode> fillModes;
@@ -552,7 +556,7 @@ void tst_qquickimage::tiling_QTBUG_6716()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QFETCH(QString, source);
@@ -879,6 +883,72 @@ void tst_qquickimage::sourceSizeChanges()
delete img;
}
+void tst_qquickimage::sourceClipRect_data()
+{
+ QTest::addColumn<QRectF>("sourceClipRect");
+ QTest::addColumn<QSize>("sourceSize");
+ QTest::addColumn<QList<QPoint>>("redPixelLocations");
+ QTest::addColumn<QList<QPoint>>("bluePixelLocations");
+
+ QTest::newRow("unclipped") << QRectF() << QSize()
+ << (QList<QPoint>() << QPoint(80, 80) << QPoint(150, 256))
+ << (QList<QPoint>() << QPoint(28, 28) << QPoint(215, 215));
+ QTest::newRow("upperLeft") << QRectF(10, 10, 100, 100) << QSize()
+ << (QList<QPoint>() << QPoint(99, 99))
+ << (QList<QPoint>() << QPoint(100, 100) << QPoint(28, 28));
+ QTest::newRow("lowerRight") << QRectF(200, 200, 20, 20) << QSize()
+ << (QList<QPoint>() << QPoint(0, 0))
+ << (QList<QPoint>() << QPoint(14, 14));
+ QTest::newRow("miniMiddle") << QRectF(20, 20, 60, 60) << QSize(100, 100)
+ << (QList<QPoint>() << QPoint(59, 0) << QPoint(6, 12) << QPoint(42, 42))
+ << (QList<QPoint>() << QPoint(54, 54) << QPoint(15, 59));
+}
+
+void tst_qquickimage::sourceClipRect()
+{
+ QFETCH(QRectF, sourceClipRect);
+ QFETCH(QSize, sourceSize);
+ QFETCH(QList<QPoint>, redPixelLocations);
+ QFETCH(QList<QPoint>, bluePixelLocations);
+
+ QScopedPointer<QQuickView> window(new QQuickView(nullptr));
+
+ window->setColor(Qt::blue);
+ window->setSource(testFileUrl("image.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickImage *image = qobject_cast<QQuickImage*>(window->rootObject());
+ QVERIFY(image);
+
+ image->setSourceSize(sourceSize);
+ QCOMPARE(image->implicitWidth(), sourceSize.isValid() ? sourceSize.width() : 300);
+ QCOMPARE(image->implicitHeight(), sourceSize.isValid() ? sourceSize.height() : 300);
+ image->setSourceClipRect(sourceClipRect);
+ QCOMPARE(image->implicitWidth(), sourceClipRect.isNull() ? 300 : sourceClipRect.width());
+ QCOMPARE(image->implicitHeight(), sourceClipRect.isNull() ? 300 : sourceClipRect.height());
+
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
+ QImage contents = window->grabWindow();
+ if (contents.width() < sourceClipRect.width())
+ QSKIP("Skipping due to grabWindow not functional");
+#ifdef DEBUG_WRITE_OUTPUT
+ contents.save("/tmp/sourceClipRect_" + QLatin1String(QTest::currentDataTag()) + ".png");
+#endif
+ for (auto p : redPixelLocations) {
+ QRgb color = contents.pixel(p);
+ QVERIFY(qRed(color) > 0xc0);
+ QVERIFY(qBlue(color) < 0x0f);
+ }
+ for (auto p : bluePixelLocations){
+ QRgb color = contents.pixel(p);
+ QVERIFY(qBlue(color) > 0xc0);
+ QVERIFY(qRed(color) < 0x0f);
+ }
+}
+
void tst_qquickimage::progressAndStatusChanges()
{
TestHTTPServer server;
@@ -1089,7 +1159,7 @@ void tst_qquickimage::hugeImages()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QQuickView view;
view.setSource(testFileUrl("hugeImages.qml"));
@@ -1147,7 +1217,7 @@ void tst_qquickimage::multiFrame()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QFETCH(QString, qmlfile);
QFETCH(bool, asynchronous);
@@ -1190,6 +1260,34 @@ void tst_qquickimage::multiFrame()
QVERIFY(qBlue(color) < 0xc0);
}
+void tst_qquickimage::colorSpace()
+{
+ QString componentStr1 = "import QtQuick 2.15\n"
+ "Image { source: srcImage; }";
+ QQmlComponent component1(&engine);
+ component1.setData(componentStr1.toLatin1(), QUrl::fromLocalFile(""));
+ engine.rootContext()->setContextProperty("srcImage", testFileUrl("ProPhoto.jpg"));
+
+ QScopedPointer<QQuickImage> object1 { qobject_cast<QQuickImage*>(component1.create())};
+ QVERIFY(object1);
+ QTRY_COMPARE(object1->status(), QQuickImageBase::Ready);
+ QCOMPARE(object1->colorSpace(), QColorSpace(QColorSpace::ProPhotoRgb));
+
+ QString componentStr2 = "import QtQuick 2.15\n"
+ "Image {\n"
+ " source: srcImage;\n"
+ " colorSpace.namedColorSpace: ColorSpace.SRgb;\n"
+ "}";
+
+ QQmlComponent component2(&engine);
+ component2.setData(componentStr2.toLatin1(), QUrl::fromLocalFile(""));
+
+ QScopedPointer<QQuickImage> object2 { qobject_cast<QQuickImage*>(component2.create())};
+ QVERIFY(object2);
+ QTRY_COMPARE(object2->status(), QQuickImageBase::Ready);
+ QCOMPARE(object2->colorSpace(), QColorSpace(QColorSpace::SRgb));
+}
+
QTEST_MAIN(tst_qquickimage)
#include "tst_qquickimage.moc"
diff --git a/tests/auto/quick/qquickitem/data/hellotr_la.qm b/tests/auto/quick/qquickitem/data/hellotr_la.qm
new file mode 100644
index 0000000000..25c0aad583
--- /dev/null
+++ b/tests/auto/quick/qquickitem/data/hellotr_la.qm
Binary files differ
diff --git a/tests/auto/quick/qquickitem/tst_qquickitem.cpp b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
index 8aab13e095..b5e001a2b7 100644
--- a/tests/auto/quick/qquickitem/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem/tst_qquickitem.cpp
@@ -40,6 +40,7 @@
#include "../../shared/util.h"
#include "../shared/viewtestutil.h"
#include <QSignalSpy>
+#include <QTranslator>
#ifdef TEST_QTBUG_60123
#include <QWidget>
@@ -70,6 +71,7 @@ public:
ulong timestamp;
QPoint lastWheelEventPos;
QPoint lastWheelEventGlobalPos;
+ int languageChangeEventCount = 0;
protected:
virtual void focusInEvent(QFocusEvent *) { Q_ASSERT(!focused); focused = true; }
virtual void focusOutEvent(QFocusEvent *) { Q_ASSERT(focused); focused = false; }
@@ -86,6 +88,12 @@ protected:
lastWheelEventPos = event->position().toPoint();
lastWheelEventGlobalPos = event->globalPosition().toPoint();
}
+ bool event(QEvent *e) override
+ {
+ if (e->type() == QEvent::LanguageChange)
+ languageChangeEventCount++;
+ return QQuickItem::event(e);
+ }
};
class TestWindow: public QQuickWindow
@@ -198,6 +206,7 @@ private slots:
#endif
void setParentCalledInOnWindowChanged();
+ void receivesLanguageChangeEvent();
private:
@@ -2155,6 +2164,32 @@ void tst_qquickitem::setParentCalledInOnWindowChanged()
QVERIFY(ensureFocus(&view)); // should not crash
}
+void tst_qquickitem::receivesLanguageChangeEvent()
+{
+ QQuickWindow window;
+ window.setFramePosition(QPoint(100, 100));
+ window.resize(200, 200);
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+
+ QScopedPointer<TestItem> child1(new TestItem);
+ child1->setObjectName(QStringLiteral("child1"));
+ child1->setSize(QSizeF(200, 100));
+ child1->setParentItem(window.contentItem());
+
+ QScopedPointer<TestItem> child2(new TestItem);
+ child2->setObjectName(QStringLiteral("child2"));
+ child2->setSize(QSizeF(50, 50));
+ child2->setParentItem(child1.data());
+
+ QTranslator t;
+ QVERIFY(t.load("hellotr_la.qm", dataDirectory()));
+ QVERIFY(QCoreApplication::installTranslator(&t));
+
+ QTRY_COMPARE(child1->languageChangeEventCount, 1);
+ QCOMPARE(child2->languageChangeEventCount, 1);
+}
+
QTEST_MAIN(tst_qquickitem)
#include "tst_qquickitem.moc"
diff --git a/tests/auto/quick/qquickitem2/data/mapCoordinates.qml b/tests/auto/quick/qquickitem2/data/mapCoordinates.qml
index 596dedab90..3e34633338 100644
--- a/tests/auto/quick/qquickitem2/data/mapCoordinates.qml
+++ b/tests/auto/quick/qquickitem2/data/mapCoordinates.qml
@@ -49,11 +49,21 @@ Item {
return Qt.point(pos.x, pos.y)
}
+ function mapAToBPoint(x, y) {
+ var pos = itemA.mapToItem(itemB, Qt.point(x, y))
+ return Qt.point(pos.x, pos.y)
+ }
+
function mapAFromB(x, y) {
var pos = itemA.mapFromItem(itemB, x, y)
return Qt.point(pos.x, pos.y)
}
+ function mapAFromBPoint(x, y) {
+ var pos = itemA.mapFromItem(itemB, Qt.point(x, y))
+ return Qt.point(pos.x, pos.y)
+ }
+
function mapAToNull(x, y) {
var pos = itemA.mapToItem(null, x, y)
return Qt.point(pos.x, pos.y)
@@ -69,11 +79,21 @@ Item {
return Qt.point(pos.x, pos.y)
}
+ function mapAToGlobalPoint(x, y) {
+ var pos = itemA.mapToGlobal(Qt.point(x, y))
+ return Qt.point(pos.x, pos.y)
+ }
+
function mapAFromGlobal(x, y) {
var pos = itemA.mapFromGlobal(x, y)
return Qt.point(pos.x, pos.y)
}
+ function mapAFromGlobalPoint(x, y) {
+ var pos = itemA.mapFromGlobal(Qt.point(x, y))
+ return Qt.point(pos.x, pos.y)
+ }
+
function mapOrphanToGlobal(x, y) {
var obj = itemComponent.createObject(null);
var pos = obj.mapToGlobal(x, y)
diff --git a/tests/auto/quick/qquickitem2/data/mapCoordinatesRect.qml b/tests/auto/quick/qquickitem2/data/mapCoordinatesRect.qml
index 2b856a27fc..c66d1e89b6 100644
--- a/tests/auto/quick/qquickitem2/data/mapCoordinatesRect.qml
+++ b/tests/auto/quick/qquickitem2/data/mapCoordinatesRect.qml
@@ -45,11 +45,21 @@ Item {
return Qt.rect(pos.x, pos.y, pos.width, pos.height)
}
+ function mapAToBRect(x, y, w, h) {
+ var pos = itemA.mapToItem(itemB, Qt.rect(x, y, w, h))
+ return Qt.rect(pos.x, pos.y, pos.width, pos.height)
+ }
+
function mapAFromB(x, y, w, h) {
var pos = itemA.mapFromItem(itemB, x, y, w, h)
return Qt.rect(pos.x, pos.y, pos.width, pos.height)
}
+ function mapAFromBRect(x, y, w, h) {
+ var pos = itemA.mapFromItem(itemB, Qt.rect(x, y, w, h))
+ return Qt.rect(pos.x, pos.y, pos.width, pos.height)
+ }
+
function mapAToNull(x, y, w, h) {
var pos = itemA.mapToItem(null, x, y, w, h)
return Qt.rect(pos.x, pos.y, pos.width, pos.height)
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index 767994ec7d..f01b3e25f1 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -77,8 +77,10 @@ private slots:
void qtbug_50516_2();
void keys();
+#if QT_CONFIG(shortcut)
void standardKeys_data();
void standardKeys();
+#endif
void keysProcessingOrder();
void keysim();
void keysForward();
@@ -1440,6 +1442,8 @@ void tst_QQuickItem::keys()
delete testObject;
}
+#if QT_CONFIG(shortcut)
+
Q_DECLARE_METATYPE(QEvent::Type);
Q_DECLARE_METATYPE(QKeySequence::StandardKey);
@@ -1498,6 +1502,8 @@ void tst_QQuickItem::standardKeys()
QCOMPARE(item->property("released").toBool(), released);
}
+#endif // QT_CONFIG(shortcut)
+
void tst_QQuickItem::keysProcessingOrder()
{
QQuickView *window = new QQuickView(nullptr);
@@ -2396,10 +2402,18 @@ void tst_QQuickItem::mapCoordinates()
Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToItem(b, QPointF(x, y)));
+ QVERIFY(QMetaObject::invokeMethod(root, "mapAToBPoint",
+ Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
+ QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToItem(b, QPointF(x, y)));
+
QVERIFY(QMetaObject::invokeMethod(root, "mapAFromB",
Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapFromItem(b, QPointF(x, y)));
+ QVERIFY(QMetaObject::invokeMethod(root, "mapAFromBPoint",
+ Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
+ QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapFromItem(b, QPointF(x, y)));
+
QVERIFY(QMetaObject::invokeMethod(root, "mapAToNull",
Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToScene(QPointF(x, y)));
@@ -2412,10 +2426,18 @@ void tst_QQuickItem::mapCoordinates()
Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToGlobal(QPointF(x, y)));
+ QVERIFY(QMetaObject::invokeMethod(root, "mapAToGlobalPoint",
+ Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
+ QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapToGlobal(QPointF(x, y)));
+
QVERIFY(QMetaObject::invokeMethod(root, "mapAFromGlobal",
Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapFromGlobal(QPointF(x, y)));
+ QVERIFY(QMetaObject::invokeMethod(root, "mapAFromGlobalPoint",
+ Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y)));
+ QCOMPARE(result.value<QPointF>(), qobject_cast<QQuickItem*>(a)->mapFromGlobal(QPointF(x, y)));
+
// for orphans we are primarily testing that we don't crash.
// when orphaned the final position is the original position of the item translated by x,y
QVERIFY(QMetaObject::invokeMethod(root, "mapOrphanToGlobal",
@@ -2477,10 +2499,18 @@ void tst_QQuickItem::mapCoordinatesRect()
Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height)));
QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectToItem(b, QRectF(x, y, width, height)));
+ QVERIFY(QMetaObject::invokeMethod(root, "mapAToBRect",
+ Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height)));
+ QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectToItem(b, QRectF(x, y, width, height)));
+
QVERIFY(QMetaObject::invokeMethod(root, "mapAFromB",
Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height)));
QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectFromItem(b, QRectF(x, y, width, height)));
+ QVERIFY(QMetaObject::invokeMethod(root, "mapAFromBRect",
+ Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height)));
+ QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectFromItem(b, QRectF(x, y, width, height)));
+
QVERIFY(QMetaObject::invokeMethod(root, "mapAToNull",
Q_RETURN_ARG(QVariant, result), Q_ARG(QVariant, x), Q_ARG(QVariant, y), Q_ARG(QVariant, width), Q_ARG(QVariant, height)));
QCOMPARE(result.value<QRectF>(), qobject_cast<QQuickItem*>(a)->mapRectToScene(QRectF(x, y, width, height)));
@@ -3369,7 +3399,7 @@ void tst_QQuickItem::grab()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabToImage not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabToImage not functional on offscreen/minimal platforms");
QQuickView view;
view.setSource(testFileUrl("grabToImage.qml"));
diff --git a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
index 2f90632841..824db1b080 100644
--- a/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
+++ b/tests/auto/quick/qquickitemlayer/tst_qquickitemlayer.cpp
@@ -149,7 +149,7 @@ void tst_QQuickItemLayer::layerSmooth()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QImage fb = runTest("Smooth.qml");
QVERIFY(!fb.size().isEmpty());
@@ -174,7 +174,7 @@ void tst_QQuickItemLayer::layerEnabled()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QImage fb = runTest("Enabled.qml");
QVERIFY(!fb.size().isEmpty());
@@ -210,7 +210,7 @@ void tst_QQuickItemLayer::layerEffect()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QImage fb = runTest("Effect.qml");
QVERIFY(!fb.size().isEmpty());
@@ -475,7 +475,7 @@ void tst_QQuickItemLayer::rectangleEffect()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QImage fb = runTest("RectangleEffect.qml");
QVERIFY(!fb.size().isEmpty());
diff --git a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
index 0732884c97..f61e2e0f48 100644
--- a/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
+++ b/tests/auto/quick/qquicklayouts/data/tst_rowlayout.qml
@@ -118,10 +118,10 @@ Item {
function test_warnAboutLayoutItemsWithAnchors()
{
- var fullPath = Qt.resolvedUrl("tst_rowlayout.qml")
+ var regex = new RegExp("QML Item: Detected anchors on an item that is managed by a layout. "
+ + "This is undefined behavior; use Layout.alignment instead.")
for (var i = 0; i < 7; ++i) {
- ignoreWarning(fullPath + ":" + (75 + 5*i) +":17: QML Item: Detected anchors on an item that is managed by a layout. "
- + "This is undefined behavior; use Layout.alignment instead.")
+ ignoreWarning(regex)
}
var layout = itemsWithAnchorsLayout_Component.createObject(container)
waitForRendering(layout)
diff --git a/tests/auto/quick/qquicklistview/data/delegatesWithRequiredProperties.qml b/tests/auto/quick/qquicklistview/data/delegatesWithRequiredProperties.qml
new file mode 100644
index 0000000000..f354517678
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/delegatesWithRequiredProperties.qml
@@ -0,0 +1,47 @@
+import QtQuick 2.12
+import Qt.fruit 1.0
+
+Rectangle {
+ id: root
+ required property bool useCpp
+ width: 200; height: 200
+
+
+ ListModel {
+ id: fruitModel
+
+ ListElement {
+ name: "Apple"
+ cost: 2
+ }
+ ListElement {
+ name: "Orange"
+ cost: 3
+ }
+ ListElement {
+ name: "Banana"
+ cost: 1
+ }
+ }
+
+
+ Component {
+ id: fruitDelegate
+ Row {
+ id: row
+ spacing: 10
+ required property string name
+ required property int cost
+ Text { text: row.name }
+ Text { text: '$' + row.cost }
+ Component.onCompleted: () => { console.debug(row.name+row.cost) };
+ }
+ }
+
+ ListView {
+ anchors.fill: parent
+ model: root.useCpp ? FruitModelCpp : fruitModel
+ delegate: fruitDelegate
+ }
+
+}
diff --git a/tests/auto/quick/qquicklistview/data/listview-sections_delegate_required.qml b/tests/auto/quick/qquicklistview/data/listview-sections_delegate_required.qml
new file mode 100644
index 0000000000..18ce406e3f
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/listview-sections_delegate_required.qml
@@ -0,0 +1,77 @@
+import QtQuick 2.0
+
+Rectangle {
+ property string sectionProperty: "number"
+ property int sectionPositioning: ViewSection.InlineLabels
+ width: 240
+ height: 320
+ color: "#ffffff"
+ resources: [
+ Component {
+ id: myDelegate
+ Item {
+ id: wrapper
+ objectName: "wrapper"
+ property string section: ListView.section
+ property string nextSection: ListView.nextSection
+ property string prevSection: ListView.previousSection
+ height: 20;
+ width: 240
+ Rectangle {
+ height: 20
+ width: parent.width
+ color: wrapper.ListView.isCurrentItem ? "lightsteelblue" : "white"
+ Text {
+ text: index
+ }
+ Text {
+ x: 30
+ id: textName
+ objectName: "textName"
+ text: name
+ }
+ Text {
+ x: 100
+ id: textNumber
+ objectName: "textNumber"
+ text: number
+ }
+ Text {
+ objectName: "nextSection"
+ x: 150
+ text: wrapper.ListView.nextSection
+ }
+ Text {
+ x: 200
+ text: wrapper.y
+ }
+ }
+ ListView.onRemove: SequentialAnimation {
+ PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: true }
+ NumberAnimation { target: wrapper; property: "height"; to: 0; duration: 100; easing.type: Easing.InOutQuad }
+ PropertyAction { target: wrapper; property: "ListView.delayRemove"; value: false }
+ }
+ }
+ }
+ ]
+ ListView {
+ id: list
+ objectName: "list"
+ width: 240
+ height: 320
+ cacheBuffer: 60
+ model: testModel
+ delegate: myDelegate
+ section.property: sectionProperty
+ section.delegate: Rectangle {
+ id: myDelegate
+ required property string section
+ objectName: "sect_" + section
+ color: "#99bb99"
+ height: 20
+ width: list.width
+ Text { text: myDelegate.section + ", " + parent.y + ", " + parent.objectName }
+ }
+ section.labelPositioning: sectionPositioning
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/data/requiredObjectListModel.qml b/tests/auto/quick/qquicklistview/data/requiredObjectListModel.qml
new file mode 100644
index 0000000000..f6380ed5aa
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/requiredObjectListModel.qml
@@ -0,0 +1,15 @@
+import QtQuick 2.0
+
+ListView {
+ width: 100
+ height: 100
+ required model
+
+ delegate: Rectangle {
+ required color
+ required property string name
+
+ height: 25
+ width: 100
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/data/reusedelegateitems.qml b/tests/auto/quick/qquicklistview/data/reusedelegateitems.qml
new file mode 100644
index 0000000000..773fb50f81
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/reusedelegateitems.qml
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.15
+
+Rectangle {
+ id: root
+ width: 640
+ height: 480
+
+ property int rows: 500
+ property int columns: 20
+ property real delegateHeight: 30
+ property real delegateWidth: 50
+
+ ListView {
+ id: list
+ anchors.fill: parent
+ anchors.margins: 10
+ objectName: "list"
+
+ model: reuseModel
+ reuseItems: true
+
+ cacheBuffer: 0
+ contentWidth: columns * delegateWidth
+ contentHeight: rows * delegateHeight
+ clip: true
+
+ property int delegatesCreatedCount: 0
+
+ delegate: Item {
+ objectName: "delegate"
+ width: list.contentWidth
+ height: delegateHeight
+
+ property int modelIndex: index
+ property int reusedCount: 0
+ property int pooledCount: 0
+ property string displayBinding: display
+
+ ListView.onPooled: pooledCount++
+ ListView.onReused: reusedCount++
+ Component.onCompleted: list.delegatesCreatedCount++
+
+ Text {
+ id: text1
+ text: display + " (Model index: " + modelIndex + ", Reused count: " + reusedCount + ")"
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/qquicklistview.pro b/tests/auto/quick/qquicklistview/qquicklistview.pro
index b08fca2b1d..10edb06549 100644
--- a/tests/auto/quick/qquicklistview/qquicklistview.pro
+++ b/tests/auto/quick/qquicklistview/qquicklistview.pro
@@ -5,7 +5,8 @@ macx:CONFIG -= app_bundle
HEADERS += incrementalmodel.h \
proxytestinnermodel.h \
- randomsortmodel.h
+ randomsortmodel.h \
+ reusemodel.h
SOURCES += tst_qquicklistview.cpp \
incrementalmodel.cpp \
proxytestinnermodel.cpp \
diff --git a/tests/auto/quick/qquicklistview/reusemodel.h b/tests/auto/quick/qquicklistview/reusemodel.h
new file mode 100644
index 0000000000..21e6739384
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/reusemodel.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef REUSEMODEL_H
+#define REUSEMODEL_H
+
+#include <QAbstractListModel>
+#include <QList>
+#include <QStringList>
+
+class ReuseModel : public QAbstractListModel
+{
+ Q_OBJECT
+
+public:
+ ReuseModel(int rowCount, QObject *parent = nullptr)
+ : QAbstractListModel(parent)
+ , m_rowCount(rowCount)
+ {}
+
+ int rowCount(const QModelIndex & = QModelIndex()) const override
+ {
+ return m_rowCount;
+ }
+
+ QVariant data(const QModelIndex &index, int role) const override
+ {
+ if (!index.isValid())
+ return QVariant();
+
+ switch (role) {
+ case Qt::DisplayRole:
+ return displayStringForRow(index.row());
+ default:
+ break;
+ }
+
+ return QVariant();
+ }
+
+ QString displayStringForRow(int row) const
+ {
+ return row % 2 == 0 ?
+ QStringLiteral("Even%1").arg(row) :
+ QStringLiteral("Odd%1").arg(row);
+ }
+
+ QHash<int, QByteArray> roleNames() const override
+ {
+ return {
+ {Qt::DisplayRole, "display"},
+ };
+ }
+
+private:
+ int m_rowCount;
+};
+
+#endif
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index 20d71aa0d7..4e49344bc0 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -41,6 +41,7 @@
#include <QtQuick/private/qquicklistview_p.h>
#include <QtQuick/private/qquickmousearea_p.h>
#include <QtQuick/private/qquicktext_p.h>
+#include <QtQuick/private/qquickrectangle_p.h>
#include <QtQmlModels/private/qqmlobjectmodel_p.h>
#include <QtQmlModels/private/qqmllistmodel_p.h>
#include <QtQmlModels/private/qqmldelegatemodel_p.h>
@@ -50,6 +51,7 @@
#include "incrementalmodel.h"
#include "proxytestinnermodel.h"
#include "randomsortmodel.h"
+#include "reusemodel.h"
#include <math.h>
Q_DECLARE_METATYPE(Qt::LayoutDirection)
@@ -128,6 +130,7 @@ private slots:
void qAbstractItemModel_package_sections();
void qAbstractItemModel_sections();
void sectionsPositioning();
+ void sectionsDelegate_data();
void sectionsDelegate();
void sectionsDragOutsideBounds_data();
void sectionsDragOutsideBounds();
@@ -283,9 +286,17 @@ private slots:
void setPositionOnLayout();
void touchCancel();
void resizeAfterComponentComplete();
+ void dragOverFloatingHeaderOrFooter();
+
+ void delegateWithRequiredProperties();
+
+ void reuse_reuseIsOffByDefault();
+ void reuse_checkThatItemsAreReused();
void moveObjectModelItemToAnotherObjectModel();
void changeModelAndDestroyTheOldOne();
+ void requiredObjectListModel();
+
private:
template <class T> void items(const QUrl &source);
template <class T> void changed(const QUrl &source);
@@ -395,7 +406,7 @@ void tst_QQuickListView::init()
m_view = nullptr;
}
#endif
- qmlRegisterType<QAbstractItemModel>();
+ qmlRegisterAnonymousType<QAbstractItemModel>("Proxy", 1);
qmlRegisterType<ProxyTestInnerModel>("Proxy", 1, 0, "ProxyTestInnerModel");
qmlRegisterType<QSortFilterProxyModel>("Proxy", 1, 0, "QSortFilterProxyModel");
}
@@ -422,8 +433,8 @@ void tst_QQuickListView::items(const QUrl &source)
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(source);
qApp->processEvents();
@@ -487,8 +498,6 @@ void tst_QQuickListView::items(const QUrl &source)
QTRY_COMPARE(listview->highlightResizeVelocity(), 1000.0);
QTRY_COMPARE(listview->highlightMoveVelocity(), 100000.0);
-
- delete testObject;
}
@@ -505,8 +514,8 @@ void tst_QQuickListView::changed(const QUrl &source)
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(source);
qApp->processEvents();
@@ -528,8 +537,6 @@ void tst_QQuickListView::changed(const QUrl &source)
QQuickText *number = findItem<QQuickText>(contentItem, "textNumber", 1);
QTRY_VERIFY(number != nullptr);
QTRY_COMPARE(number->text(), model.number(1));
-
- delete testObject;
}
template <class T>
@@ -547,8 +554,8 @@ void tst_QQuickListView::inserted(const QUrl &source)
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(source);
qApp->processEvents();
@@ -625,8 +632,6 @@ void tst_QQuickListView::inserted(const QUrl &source)
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", 0);
QVERIFY(item);
QTRY_COMPARE(item->y() - listview->contentY(), 0.);
-
- delete testObject;
}
template <class T>
@@ -645,8 +650,8 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("listviewtest.qml"));
window->show();
@@ -704,7 +709,7 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v
break;
}
}
- QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
+ QVERIFY2(firstVisibleIndex >= 0, QByteArray::number(firstVisibleIndex));
// Confirm items positioned correctly and indexes correct
QQuickText *name;
@@ -713,14 +718,14 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v
const qreal visibleToPos = listview->contentY() + listview->height() + listview->displayMarginEnd() + listview->cacheBuffer();
for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
qreal pos = i*20.0 + itemsOffsetAfterMove;
if (verticalLayoutDirection == QQuickItemView::BottomToTop)
pos = -item->height() - pos;
// Items outside the visible area (including cache buffer) should be skipped
if (pos > visibleToPos || pos < visibleFromPos) {
QTRY_VERIFY2(QQuickItemPrivate::get(item)->culled || item->y() < visibleFromPos || item->y() > visibleToPos,
- QTest::toString(QString("index %5, y %1, from %2, to %3, expected pos %4, culled %6").
+ qPrintable(QString("index %5, y %1, from %2, to %3, expected pos %4, culled %6").
arg(item->y()).arg(visibleFromPos).arg(visibleToPos).arg(pos).arg(i).arg(bool(QQuickItemPrivate::get(item)->culled))));
continue;
}
@@ -734,7 +739,6 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v
}
releaseView(window);
- delete testObject;
}
void tst_QQuickListView::inserted_more_data()
@@ -840,8 +844,8 @@ void tst_QQuickListView::insertBeforeVisible()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("listviewtest.qml"));
window->show();
@@ -889,7 +893,7 @@ void tst_QQuickListView::insertBeforeVisible()
int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
for (int i = 0; i < model.count() && i < itemCount; ++i) {
item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove);
name = findItem<QQuickText>(contentItem, "textName", i);
QVERIFY(name != nullptr);
@@ -897,7 +901,6 @@ void tst_QQuickListView::insertBeforeVisible()
}
releaseView(window);
- delete testObject;
}
void tst_QQuickListView::insertBeforeVisible_data()
@@ -953,8 +956,8 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */)
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(source);
window->show();
@@ -1116,8 +1119,6 @@ void tst_QQuickListView::removed(const QUrl &source, bool /* animated */)
for (int i = 0; i < 18; ++i)
model.removeItems(model.count() - 1, 1);
QTRY_VERIFY(findItems<QQuickItem>(contentItem, "wrapper").count() > 16);
-
- delete testObject;
}
template <class T>
@@ -1137,8 +1138,8 @@ void tst_QQuickListView::removed_more(const QUrl &source, QQuickItemView::Vertic
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(source);
window->show();
@@ -1180,14 +1181,14 @@ void tst_QQuickListView::removed_more(const QUrl &source, QQuickItemView::Vertic
break;
}
}
- QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
+ QVERIFY2(firstVisibleIndex >= 0, QByteArray::number(firstVisibleIndex));
// Confirm items positioned correctly and indexes correct
QQuickText *name;
QQuickText *number;
for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
qreal pos = i*20.0 + itemsOffsetAfterMove;
if (verticalLayoutDirection == QQuickItemView::BottomToTop)
pos = -item0->height() - pos;
@@ -1201,7 +1202,6 @@ void tst_QQuickListView::removed_more(const QUrl &source, QQuickItemView::Vertic
}
releaseView(window);
- delete testObject;
}
void tst_QQuickListView::removed_more_data()
@@ -1319,8 +1319,8 @@ void tst_QQuickListView::clear(const QUrl &source, QQuickItemView::VerticalLayou
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(source);
window->show();
@@ -1353,8 +1353,6 @@ void tst_QQuickListView::clear(const QUrl &source, QQuickItemView::VerticalLayou
QTRY_COMPARE(listview->count(), 1);
QVERIFY(listview->currentItem() != nullptr);
QCOMPARE(listview->currentIndex(), 0);
-
- delete testObject;
}
template <class T>
@@ -1377,8 +1375,8 @@ void tst_QQuickListView::moved(const QUrl &source, QQuickItemView::VerticalLayou
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(source);
window->show();
@@ -1414,12 +1412,12 @@ void tst_QQuickListView::moved(const QUrl &source, QQuickItemView::VerticalLayou
break;
}
}
- QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
+ QVERIFY2(firstVisibleIndex >= 0, QByteArray::number(firstVisibleIndex));
// Confirm items positioned correctly and indexes correct
for (int i = firstVisibleIndex; i < model.count() && i < items.count(); ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
qreal pos = i*20.0 + itemsOffsetAfterMove;
if (verticalLayoutDirection == QQuickItemView::BottomToTop)
pos = -item->height() - pos;
@@ -1437,7 +1435,6 @@ void tst_QQuickListView::moved(const QUrl &source, QQuickItemView::VerticalLayou
}
releaseView(window);
- delete testObject;
}
void tst_QQuickListView::moved_data()
@@ -1607,8 +1604,8 @@ void tst_QQuickListView::multipleChanges(bool condensed)
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("listviewtest.qml"));
window->show();
@@ -1660,7 +1657,7 @@ void tst_QQuickListView::multipleChanges(bool condensed)
int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
for (int i=0; i < model.count() && i < itemCount; ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
name = findItem<QQuickText>(contentItem, "textName", i);
QVERIFY(name != nullptr);
QTRY_COMPARE(name->text(), model.name(i));
@@ -1669,7 +1666,6 @@ void tst_QQuickListView::multipleChanges(bool condensed)
QTRY_COMPARE(number->text(), model.number(i));
}
- delete testObject;
releaseView(window);
}
@@ -1855,8 +1851,8 @@ void tst_QQuickListView::swapWithFirstItem()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("listviewtest.qml"));
window->show();
@@ -1870,8 +1866,6 @@ void tst_QQuickListView::swapWithFirstItem()
listview->setContentY(0);
model.moveItem(1, 0);
QTRY_COMPARE(listview->contentY(), qreal(0));
-
- delete testObject;
}
void tst_QQuickListView::checkCountForMultiColumnModels()
@@ -2039,8 +2033,8 @@ void tst_QQuickListView::spacing()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("listviewtest.qml"));
window->show();
@@ -2084,8 +2078,6 @@ void tst_QQuickListView::spacing()
QTRY_VERIFY(item);
QTRY_COMPARE(item->y(), i*20.0);
}
-
- delete testObject;
}
template <typename T>
@@ -2189,8 +2181,17 @@ void tst_QQuickListView::sections(const QUrl &source)
QTRY_COMPARE(item->height(), 40.0);
}
+void tst_QQuickListView::sectionsDelegate_data()
+{
+ QTest::addColumn<QUrl>("path");
+ QTest::addRow("implicit") << testFileUrl("listview-sections_delegate.qml");
+ QTest::addRow("required") << testFileUrl("listview-sections_delegate_required.qml");
+}
+
void tst_QQuickListView::sectionsDelegate()
{
+ QFETCH(QUrl, path);
+
QScopedPointer<QQuickView> window(createView());
QaimModel model;
@@ -2200,7 +2201,7 @@ void tst_QQuickListView::sectionsDelegate()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- window->setSource(testFileUrl("listview-sections_delegate.qml"));
+ window->setSource(path);
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window.data()));
@@ -2803,7 +2804,7 @@ void tst_QQuickListView::currentIndex()
for (int i = 0; i < 30; i++)
initModel.addItem("Item" + QString::number(i), QString::number(i));
- QQuickView *window = new QQuickView(nullptr);
+ QScopedPointer<QQuickView> window(new QQuickView(nullptr));
window->setGeometry(0,0,240,320);
QQmlContext *ctxt = window->rootContext();
@@ -2813,7 +2814,7 @@ void tst_QQuickListView::currentIndex()
QString filename(testFile("listview-initCurrent.qml"));
window->setSource(QUrl::fromLocalFile(filename));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list");
QTRY_VERIFY(listview != nullptr);
@@ -2901,8 +2902,6 @@ void tst_QQuickListView::currentIndex()
QCOMPARE(QQmlProperty(window->rootObject(), "s").read().toString(), "-1");
QCOMPARE(window->rootObject()->property("currentItemChangedCount").toInt(), 1);
QCOMPARE(listview->currentIndex(), -1);
-
- delete window;
}
void tst_QQuickListView::noCurrentIndex()
@@ -2911,7 +2910,7 @@ void tst_QQuickListView::noCurrentIndex()
for (int i = 0; i < 30; i++)
model.addItem("Item" + QString::number(i), QString::number(i));
- QQuickView *window = new QQuickView(nullptr);
+ QScopedPointer<QQuickView> window(new QQuickView(nullptr));
window->setGeometry(0,0,240,320);
QQmlContext *ctxt = window->rootContext();
@@ -2920,7 +2919,7 @@ void tst_QQuickListView::noCurrentIndex()
QString filename(testFile("listview-noCurrent.qml"));
window->setSource(QUrl::fromLocalFile(filename));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list");
QTRY_VERIFY(listview != nullptr);
@@ -2939,8 +2938,6 @@ void tst_QQuickListView::noCurrentIndex()
QCOMPARE(listview->currentIndex(), 2);
QVERIFY(listview->highlightItem());
QVERIFY(listview->currentItem());
-
- delete window;
}
void tst_QQuickListView::keyNavigation()
@@ -2958,9 +2955,9 @@ void tst_QQuickListView::keyNavigation()
model.addItem("Item" + QString::number(i), "");
QQuickView *window = getView();
- TestObject *testObject = new TestObject;
+ QScopedPointer<TestObject> testObject(new TestObject);
window->rootContext()->setContextProperty("testModel", &model);
- window->rootContext()->setContextProperty("testObject", testObject);
+ window->rootContext()->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("listviewtest.qml"));
window->show();
QVERIFY(QTest::qWaitForWindowActive(window));
@@ -3030,7 +3027,6 @@ void tst_QQuickListView::keyNavigation()
QTRY_COMPARE(listview->contentY(), contentPosAtFirstItem.y());
releaseView(window);
- delete testObject;
}
void tst_QQuickListView::keyNavigation_data()
@@ -3172,8 +3168,8 @@ void tst_QQuickListView::cacheBuffer()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("listviewtest.qml"));
window->show();
@@ -3261,8 +3257,6 @@ void tst_QQuickListView::cacheBuffer()
// negative cache buffer is ignored
listview->setCacheBuffer(-1);
QCOMPARE(listview->cacheBuffer(), 200);
-
- delete testObject;
}
void tst_QQuickListView::positionViewAtBeginningEnd()
@@ -3276,8 +3270,8 @@ void tst_QQuickListView::positionViewAtBeginningEnd()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->show();
window->setSource(testFileUrl("listviewtest.qml"));
QVERIFY(QTest::qWaitForWindowExposed(window.data()));
@@ -3315,8 +3309,6 @@ void tst_QQuickListView::positionViewAtBeginningEnd()
QTRY_COMPARE(listview->contentY(), -30.);
QVERIFY(listview->highlightItem());
QCOMPARE(listview->highlightItem()->y(), 20.);
-
- delete testObject;
}
void tst_QQuickListView::positionViewAtIndex()
@@ -3336,8 +3328,8 @@ void tst_QQuickListView::positionViewAtIndex()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->show();
window->setSource(testFileUrl("listviewtest.qml"));
QVERIFY(QTest::qWaitForWindowExposed(window));
@@ -3642,7 +3634,7 @@ void tst_QQuickListView::QTBUG_33568()
void tst_QQuickListView::manualHighlight()
{
- QQuickView *window = new QQuickView(nullptr);
+ QScopedPointer<QQuickView> window(new QQuickView(nullptr));
window->setGeometry(0,0,240,320);
QString filename(testFile("manual-highlight.qml"));
@@ -3672,8 +3664,6 @@ void tst_QQuickListView::manualHighlight()
QTRY_COMPARE(listview->currentIndex(), 2);
QTRY_COMPARE(listview->currentItem(), findItem<QQuickItem>(contentItem, "wrapper", 2));
QTRY_COMPARE(listview->highlightItem()->y() - 5, listview->currentItem()->y());
-
- delete window;
}
void tst_QQuickListView::QTBUG_11105()
@@ -3686,8 +3676,8 @@ void tst_QQuickListView::QTBUG_11105()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("listviewtest.qml"));
window->show();
@@ -3719,8 +3709,6 @@ void tst_QQuickListView::QTBUG_11105()
itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
QCOMPARE(itemCount, 5);
-
- delete testObject;
}
void tst_QQuickListView::initialZValues()
@@ -4358,8 +4346,8 @@ void tst_QQuickListView::resizeView()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("listviewtest.qml"));
window->show();
@@ -4422,8 +4410,6 @@ void tst_QQuickListView::resizeView()
QTRY_COMPARE(item->y(), i*20.);
QCOMPARE(delegateVisible(item), i < 6); // inside view visible, outside not visible
}
-
- delete testObject;
}
void tst_QQuickListView::resizeViewAndRepaint()
@@ -4470,8 +4456,8 @@ void tst_QQuickListView::sizeLessThan1()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("sizelessthan1.qml"));
window->show();
@@ -4491,8 +4477,6 @@ void tst_QQuickListView::sizeLessThan1()
QTRY_VERIFY(item);
QTRY_COMPARE(item->y(), i*0.5);
}
-
- delete testObject;
}
void tst_QQuickListView::QTBUG_14821()
@@ -4603,8 +4587,8 @@ void tst_QQuickListView::resizeFirstDelegate()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("listviewtest.qml"));
window->show();
@@ -4659,8 +4643,6 @@ void tst_QQuickListView::resizeFirstDelegate()
for (int i=0; i<3; i++) {
QTRY_VERIFY(!findItem<QQuickItem>(contentItem, "wrapper", i));
}
-
- delete testObject;
}
void tst_QQuickListView::repositionResizedDelegate()
@@ -4812,8 +4794,8 @@ void tst_QQuickListView::indexAt_itemAt()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testModel", &model);
- TestObject *testObject = new TestObject;
- ctxt->setContextProperty("testObject", testObject);
+ QScopedPointer<TestObject> testObject(new TestObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("listviewtest.qml"));
window->show();
@@ -4835,7 +4817,6 @@ void tst_QQuickListView::indexAt_itemAt()
QCOMPARE(listview->itemAt(x,y), item);
releaseView(window);
- delete testObject;
}
void tst_QQuickListView::itemAtIndex()
@@ -6466,7 +6447,7 @@ void tst_QQuickListView::unrequestedVisibility()
for (int i = 0; i < 30; i++)
model.addItem("Item" + QString::number(i), QString::number(i));
- QQuickView *window = new QQuickView(nullptr);
+ QScopedPointer<QQuickView> window(new QQuickView(nullptr));
window->setGeometry(0,0,240,320);
QQmlContext *ctxt = window->rootContext();
@@ -6475,7 +6456,7 @@ void tst_QQuickListView::unrequestedVisibility()
window->setSource(testFileUrl("unrequestedItems.qml"));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
QQuickListView *leftview;
@@ -6662,8 +6643,6 @@ void tst_QQuickListView::unrequestedVisibility()
item = findItem<QQuickItem>(rightContent, wrapperObjectName, 17);
QVERIFY(item);
QCOMPARE(delegateVisible(item), false);
-
- delete window;
}
void tst_QQuickListView::populateTransitions()
@@ -6684,8 +6663,9 @@ void tst_QQuickListView::populateTransitions()
}
QQuickView *window = getView();
+ QScopedPointer<TestObject> testObject(new TestObject(window->rootContext()));
window->rootContext()->setContextProperty("testModel", &model);
- window->rootContext()->setContextProperty("testObject", new TestObject(window->rootContext()));
+ window->rootContext()->setContextProperty("testObject", testObject.data());
window->rootContext()->setContextProperty("usePopulateTransition", usePopulateTransition);
window->rootContext()->setContextProperty("dynamicallyPopulate", dynamicallyPopulate);
window->rootContext()->setContextProperty("transitionFrom", transitionFrom);
@@ -6716,7 +6696,7 @@ void tst_QQuickListView::populateTransitions()
int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
for (int i=0; i < model.count() && i < itemCount; ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
QTRY_COMPARE(item->x(), 0.0);
QTRY_COMPARE(item->y(), i*20.0);
QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
@@ -6751,7 +6731,7 @@ void tst_QQuickListView::populateTransitions()
itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
for (int i=0; i < model.count() && i < itemCount; ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
QTRY_COMPARE(item->x(), 0.0);
QTRY_COMPARE(item->y(), i*20.0);
QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
@@ -6769,7 +6749,7 @@ void tst_QQuickListView::populateTransitions()
itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
for (int i=0; i < model.count() && i < itemCount; ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
QTRY_COMPARE(item->x(), 0.0);
QTRY_COMPARE(item->y(), i*20.0);
QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
@@ -6811,7 +6791,7 @@ void tst_QQuickListView::sizeTransitions()
QaimModel model;
ctxt->setContextProperty("testModel", &model);
ctxt->setContextProperty("topToBottom", topToBottom);
- TestObject *testObject = new TestObject;
+ QScopedPointer<TestObject> testObject(new TestObject);
ctxt->setContextProperty("testObject", &model);
window->setSource(testFileUrl("sizeTransitions.qml"));
window->show();
@@ -6832,7 +6812,6 @@ void tst_QQuickListView::sizeTransitions()
QCOMPARE(listview->property("transitionFinished").toBool(), true);
releaseView(window);
- delete testObject;
}
void tst_QQuickListView::sizeTransitions_data()
@@ -6869,13 +6848,13 @@ void tst_QQuickListView::addTransitions()
QQuickView *window = getView();
QQmlContext *ctxt = window->rootContext();
- TestObject *testObject = new TestObject;
+ QScopedPointer<TestObject> testObject(new TestObject);
ctxt->setContextProperty("testModel", &model);
ctxt->setContextProperty("model_targetItems_transitionFrom", &model_targetItems_transitionFrom);
ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia);
ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom);
ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia);
- ctxt->setContextProperty("testObject", testObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("addTransitions.qml"));
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window));
@@ -6954,12 +6933,12 @@ void tst_QQuickListView::addTransitions()
break;
}
}
- QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
+ QVERIFY2(firstVisibleIndex >= 0, QByteArray::number(firstVisibleIndex));
// verify all items moved to the correct final positions
for (int i=firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
QTRY_COMPARE(item->y(), i*20.0);
QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
QVERIFY(name != nullptr);
@@ -6967,7 +6946,6 @@ void tst_QQuickListView::addTransitions()
}
releaseView(window);
- delete testObject;
}
void tst_QQuickListView::addTransitions_data()
@@ -7065,13 +7043,13 @@ void tst_QQuickListView::moveTransitions()
QQuickView *window = getView();
QQmlContext *ctxt = window->rootContext();
- TestObject *testObject = new TestObject;
+ QScopedPointer<TestObject> testObject(new TestObject);
ctxt->setContextProperty("testModel", &model);
ctxt->setContextProperty("model_targetItems_transitionVia", &model_targetItems_transitionVia);
ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia);
ctxt->setContextProperty("targetItems_transitionVia", targetItems_transitionVia);
ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia);
- ctxt->setContextProperty("testObject", testObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("moveTransitions.qml"));
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window));
@@ -7138,13 +7116,13 @@ void tst_QQuickListView::moveTransitions()
break;
}
}
- QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
+ QVERIFY2(firstVisibleIndex >= 0, QByteArray::number(firstVisibleIndex));
// verify all items moved to the correct final positions
int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
for (int i=firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
QTRY_COMPARE(item->y(), i*20.0 + itemsOffsetAfterMove);
name = findItem<QQuickText>(contentItem, "textName", i);
QVERIFY(name != nullptr);
@@ -7152,7 +7130,6 @@ void tst_QQuickListView::moveTransitions()
}
releaseView(window);
- delete testObject;
}
void tst_QQuickListView::moveTransitions_data()
@@ -7268,13 +7245,13 @@ void tst_QQuickListView::removeTransitions()
QQuickView *window = getView();
QQmlContext *ctxt = window->rootContext();
- TestObject *testObject = new TestObject;
+ QScopedPointer<TestObject> testObject(new TestObject);
ctxt->setContextProperty("testModel", &model);
ctxt->setContextProperty("model_targetItems_transitionTo", &model_targetItems_transitionTo);
ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia);
ctxt->setContextProperty("targetItems_transitionTo", targetItems_transitionTo);
ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia);
- ctxt->setContextProperty("testObject", testObject);
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("removeTransitions.qml"));
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window));
@@ -7352,12 +7329,12 @@ void tst_QQuickListView::removeTransitions()
if (index < 0)
itemCount--; // exclude deleted items
}
- QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
+ QVERIFY2(firstVisibleIndex >= 0, QByteArray::number(firstVisibleIndex));
// verify all items moved to the correct final positions
for (int i=firstVisibleIndex; i < model.count() && i < itemCount; ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
QCOMPARE(item->x(), 0.0);
QCOMPARE(item->y(), contentY + (i-firstVisibleIndex) * 20.0);
QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
@@ -7366,7 +7343,6 @@ void tst_QQuickListView::removeTransitions()
}
releaseView(window);
- delete testObject;
}
void tst_QQuickListView::removeTransitions_data()
@@ -7467,9 +7443,9 @@ void tst_QQuickListView::displacedTransitions()
QQuickView *window = getView();
QQmlContext *ctxt = window->rootContext();
- TestObject *testObject = new TestObject(window);
+ QScopedPointer<TestObject> testObject(new TestObject(window));
ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testObject", testObject);
+ ctxt->setContextProperty("testObject", testObject.data());
ctxt->setContextProperty("model_displaced_transitionVia", &model_displaced_transitionVia);
ctxt->setContextProperty("model_addDisplaced_transitionVia", &model_addDisplaced_transitionVia);
ctxt->setContextProperty("model_moveDisplaced_transitionVia", &model_moveDisplaced_transitionVia);
@@ -7490,7 +7466,6 @@ void tst_QQuickListView::displacedTransitions()
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window));
-
QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list");
QTRY_VERIFY(listview != nullptr);
QQuickItem *contentItem = listview->contentItem();
@@ -7572,7 +7547,7 @@ void tst_QQuickListView::displacedTransitions()
QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
for (int i=0; i < model.count() && i < items.count(); ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
QCOMPARE(item->x(), 0.0);
QCOMPARE(item->y(), i * 20.0);
QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
@@ -7694,9 +7669,9 @@ void tst_QQuickListView::multipleTransitions()
QQuickView *window = getView();
QQmlContext *ctxt = window->rootContext();
- TestObject *testObject = new TestObject;
+ QScopedPointer<TestObject> testObject(new TestObject);
ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testObject", testObject);
+ ctxt->setContextProperty("testObject", testObject.data());
ctxt->setContextProperty("addTargets_transitionFrom", addTargets_transitionFrom);
ctxt->setContextProperty("addDisplaced_transitionFrom", addDisplaced_transitionFrom);
ctxt->setContextProperty("moveTargets_transitionFrom", moveTargets_transitionFrom);
@@ -7780,7 +7755,7 @@ void tst_QQuickListView::multipleTransitions()
QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
for (int i=0; i < model.count() && i < items.count(); ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
QTRY_COMPARE(item->x(), 0.0);
QTRY_COMPARE(item->y(), i*20.0);
QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
@@ -7789,7 +7764,6 @@ void tst_QQuickListView::multipleTransitions()
}
releaseView(window);
- delete testObject;
}
void tst_QQuickListView::multipleTransitions_data()
@@ -7862,8 +7836,9 @@ void tst_QQuickListView::multipleDisplaced()
QQuickView *window = getView();
QQmlContext *ctxt = window->rootContext();
+ QScopedPointer<TestObject> testObject(new TestObject(window));
ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("testObject", new TestObject(window));
+ ctxt->setContextProperty("testObject", testObject.data());
window->setSource(testFileUrl("multipleDisplaced.qml"));
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window));
@@ -7882,14 +7857,14 @@ void tst_QQuickListView::multipleDisplaced()
QVariantMap transitionsStarted = listview->property("displaceTransitionsStarted").toMap();
foreach (const QString &name, transitionsStarted.keys()) {
QVERIFY2(transitionsStarted[name] == 1,
- QTest::toString(QString("%1 was displaced %2 times").arg(name).arg(transitionsStarted[name].toInt())));
+ qPrintable(QString("%1 was displaced %2 times").arg(name).arg(transitionsStarted[name].toInt())));
}
// verify all items moved to the correct final positions
QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
for (int i=0; i < model.count() && i < items.count(); ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem, "wrapper", i);
- QVERIFY2(item, QTest::toString(QString("Item %1 not found").arg(i)));
+ QVERIFY2(item, qPrintable(QString("Item %1 not found").arg(i)));
QTRY_COMPARE(item->x(), 0.0);
QTRY_COMPARE(item->y(), i*20.0);
QQuickText *name = findItem<QQuickText>(contentItem, "textName", i);
@@ -7931,7 +7906,7 @@ void tst_QQuickListView::matchItemsAndIndexes(const QVariantMap &items, const Qa
QCOMPARE(it.value().type(), QVariant::Int);
QString name = it.key();
int itemIndex = it.value().toInt();
- QVERIFY2(expectedIndexes.contains(itemIndex), QTest::toString(QString("Index %1 not found in expectedIndexes").arg(itemIndex)));
+ QVERIFY2(expectedIndexes.contains(itemIndex), qPrintable(QString("Index %1 not found in expectedIndexes").arg(itemIndex)));
if (model.name(itemIndex) != name)
qDebug() << itemIndex;
QCOMPARE(model.name(itemIndex), name);
@@ -7946,8 +7921,8 @@ void tst_QQuickListView::matchItemLists(const QVariantList &itemLists, const QLi
QVariantList current = itemLists[i].toList();
for (int j=0; j<current.count(); j++) {
QQuickItem *o = qobject_cast<QQuickItem*>(current[j].value<QObject*>());
- QVERIFY2(o, QTest::toString(QString("Invalid actual item at %1").arg(j)));
- QVERIFY2(expectedItems.contains(o), QTest::toString(QString("Cannot match item %1").arg(j)));
+ QVERIFY2(o, qPrintable(QString("Invalid actual item at %1").arg(j)));
+ QVERIFY2(expectedItems.contains(o), qPrintable(QString("Cannot match item %1").arg(j)));
}
QCOMPARE(current.count(), expectedItems.count());
}
@@ -8121,7 +8096,7 @@ void tst_QQuickListView::defaultHighlightMoveDuration()
QQmlComponent component(&engine);
component.setData("import QtQuick 2.0; ListView {}", QUrl::fromLocalFile(""));
- QObject *obj = component.create();
+ QScopedPointer<QObject> obj(component.create());
QVERIFY(obj);
QCOMPARE(obj->property("highlightMoveDuration").toInt(), -1);
@@ -8937,15 +8912,15 @@ void tst_QQuickListView::programmaticFlickAtBounds3()
void tst_QQuickListView::layoutChange()
{
- RandomSortModel *model = new RandomSortModel;
- QSortFilterProxyModel *sortModel = new QSortFilterProxyModel;
- sortModel->setSourceModel(model);
+ QScopedPointer<RandomSortModel> model(new RandomSortModel);
+ QScopedPointer<QSortFilterProxyModel> sortModel(new QSortFilterProxyModel);
+ sortModel->setSourceModel(model.data());
sortModel->setSortRole(Qt::UserRole);
sortModel->setDynamicSortFilter(true);
sortModel->sort(0);
QScopedPointer<QQuickView> window(createView());
- window->rootContext()->setContextProperty("testModel", QVariant::fromValue(sortModel));
+ window->rootContext()->setContextProperty("testModel", QVariant::fromValue(sortModel.data()));
window->setSource(testFileUrl("layoutChangeSort.qml"));
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window.data()));
@@ -9093,7 +9068,8 @@ void tst_QQuickListView::objectModel()
QQmlEngine engine;
QQmlComponent component(&engine, testFileUrl("objectmodel.qml"));
- QQuickListView *listview = qobject_cast<QQuickListView *>(component.create());
+ QScopedPointer<QObject> obj(component.create());
+ QQuickListView *listview = qobject_cast<QQuickListView *>(obj.data());
QVERIFY(listview);
QQmlObjectModel *model = listview->model().value<QQmlObjectModel *>();
@@ -9133,8 +9109,6 @@ void tst_QQuickListView::objectModel()
model->clear();
QCOMPARE(model->count(), 0);
QCOMPARE(listview->count(), 0);
-
- delete listview;
}
void tst_QQuickListView::contentHeightWithDelayRemove_data()
@@ -9552,13 +9526,13 @@ void tst_QQuickListView::releaseItems()
void tst_QQuickListView::QTBUG_34576_velocityZero()
{
- QQuickView *window = new QQuickView(nullptr);
+ QScopedPointer<QQuickView> window(new QQuickView(nullptr));
window->setGeometry(0,0,240,320);
QString filename(testFile("qtbug34576.qml"));
window->setSource(QUrl::fromLocalFile(filename));
window->show();
- QVERIFY(QTest::qWaitForWindowExposed(window));
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list");
QVERIFY(listview);
@@ -9581,8 +9555,8 @@ void tst_QQuickListView::QTBUG_34576_velocityZero()
QSignalSpy currentIndexChangedSpy(listview, SIGNAL(currentIndexChanged()));
// click button which increases currentIndex
- QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(295,215));
- QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(295,215));
+ QTest::mousePress(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(295,215));
+ QTest::mouseRelease(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(295,215));
// verify that currentIndexChanged is triggered
QTRY_VERIFY(currentIndexChangedSpy.count() > 0);
@@ -9593,8 +9567,6 @@ void tst_QQuickListView::QTBUG_34576_velocityZero()
// velocity should be always > 0.0
QTRY_COMPARE(window->rootObject()->property("horizontalVelocityZeroCount").toInt(), 0);
-
- delete window;
}
void tst_QQuickListView::QTBUG_61537_modelChangesAsync()
@@ -9726,6 +9698,247 @@ void tst_QQuickListView::resizeAfterComponentComplete() // QTBUG-76487
QTRY_COMPARE(lastItem->property("y").toInt(), 9 * lastItem->property("height").toInt());
}
+class Animal
+{
+public:
+ Animal(const int cost, const QString &name) {m_name = name; m_cost = cost;}
+
+ int cost() const {return m_cost;}
+ QString name() const {return m_name;}
+
+ QString m_name;
+ int m_cost;
+};
+
+class FruitModel : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ enum AnimalRoles {
+ NameRole = Qt::UserRole + 1,
+ CostRole
+ };
+
+ FruitModel(QObject* = nullptr) {
+ m_animals.push_back(Animal {4, QLatin1String("Melon")});
+ m_animals.push_back(Animal {5, QLatin1String("Cherry")});
+ }
+
+ int rowCount(const QModelIndex & = QModelIndex()) const override {return m_animals.count();}
+
+ QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const override {
+ if (!checkIndex(index))
+ return {};
+ const Animal &animal = m_animals[index.row()];
+ if (role == CostRole)
+ return animal.cost();
+ else if (role == NameRole)
+ return animal.name();
+ return QVariant();
+ }
+
+protected:
+ QHash<int, QByteArray> roleNames() const override {
+ QHash<int, QByteArray> roles;
+ roles[CostRole] = "cost";
+ roles[NameRole] = "name";
+ return roles;
+ }
+private:
+ QList<Animal> m_animals;
+};
+
+void tst_QQuickListView::delegateWithRequiredProperties()
+{
+ FruitModel myModel;
+ qmlRegisterSingletonInstance("Qt.fruit", 1, 0, "FruitModelCpp", &myModel);
+ {
+ // ListModel
+ QTest::ignoreMessage(QtMsgType::QtDebugMsg, "Apple2");
+ QTest::ignoreMessage(QtMsgType::QtDebugMsg, "Orange3");
+ QTest::ignoreMessage(QtMsgType::QtDebugMsg, "Banana1");
+ QScopedPointer<QQuickView> window(createView());
+ window->setInitialProperties({{QLatin1String("useCpp"), false}});
+ window->setSource(testFileUrl("delegatesWithRequiredProperties.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QObject *listView = window->rootObject();
+ QVERIFY(listView);
+ }
+ {
+ // C++ model
+ QTest::ignoreMessage(QtMsgType::QtDebugMsg, "Melon4");
+ QTest::ignoreMessage(QtMsgType::QtDebugMsg, "Cherry5");
+ QScopedPointer<QQuickView> window(createView());
+ window->setInitialProperties({{QLatin1String("useCpp"), true}});
+ window->setSource(testFileUrl("delegatesWithRequiredProperties.qml"));
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QObject *listView = window->rootObject();
+ QVERIFY(listView);
+ }
+}
+
+void tst_QQuickListView::reuse_reuseIsOffByDefault()
+{
+ // Check that delegate recycling is off by default. The reason is that
+ // ListView needs to be backwards compatible with legacy applications. And
+ // when using delegate recycling, there are certain differences, like that
+ // a delegates Component.onCompleted will just be called the first time the
+ // item is created, and not when it's reused.
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("listviewtest.qml"));
+ window->resize(640, 480);
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickListView *listView = findItem<QQuickListView>(window->rootObject(), "list");
+ QVERIFY(listView != nullptr);
+ QVERIFY(!listView->reuseItems());
+}
+
+void tst_QQuickListView::reuse_checkThatItemsAreReused()
+{
+ // Flick up and down one page of items. Check that this results in the
+ // delegate items being reused once.
+ // Note that this is slightly different from tableview, which will reuse the items
+ // twice during a similar down-then-up flick. The reason is that listview fills up
+ // free space in the view with items _before_ it release old items that have been
+ // flicked out. But changing this will break other auto tests (and perhaps legacy
+ // apps), so we have chosen to stick with this behavior for now.
+ QScopedPointer<QQuickView> window(createView());
+
+ ReuseModel model(100);
+ QQmlContext *ctxt = window->rootContext();
+ ctxt->setContextProperty("reuseModel", &model);
+
+ window->setSource(testFileUrl("reusedelegateitems.qml"));
+ window->resize(640, 480);
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+ QVERIFY(window->rootObject() != nullptr);
+
+ QQuickListView *listView = findItem<QQuickListView>(window->rootObject(), "list");
+ QTRY_VERIFY(listView != nullptr);
+ const auto itemView_d = QQuickItemViewPrivate::get(listView);
+
+ QVERIFY(listView->reuseItems());
+
+ auto items = findItems<QQuickItem>(listView, "delegate");
+ const int initialItemCount = items.count();
+ QVERIFY(initialItemCount > 0);
+
+ // Sanity check that the size of the initial list of items match the count we tracked from QML
+ QCOMPARE(listView->property("delegatesCreatedCount").toInt(), initialItemCount);
+
+ // Go through all the initial items and check that they have not been reused yet
+ for (const auto item : qAsConst(items))
+ QCOMPARE(item->property("reusedCount").toInt(), 0);
+
+ // Flick one page down and count how many items we have created thus
+ // far. We expect this number to be twice as high as the initial count
+ // since we flicked one whole page.
+ const qreal delegateHeight = items.at(0)->height();
+ const qreal flickDistance = (initialItemCount * delegateHeight) + 1;
+ listView->setContentY(flickDistance);
+ QVERIFY(QQuickTest::qWaitForItemPolished(listView));
+ const int countAfterDownFlick = listView->property("delegatesCreatedCount").toInt();
+ QCOMPARE(countAfterDownFlick, initialItemCount * 2);
+
+ // Check that the reuse pool is now populated. We expect all initial items to be pooled,
+ // except model index 0, which was never reused or released, since it's ListView.currentItem.
+ const int poolSizeAfterDownFlick = itemView_d->model->poolSize();
+ QCOMPARE(poolSizeAfterDownFlick, initialItemCount - 1);
+
+ // Go through all items and check that all model data inside the delegate
+ // have values updated according to their model index. Since model roles
+ // like 'display' are injected into the context in a special way by the
+ // QML model classes, we need to catch it through a binding instead (which is
+ // OK, since then we can also check that bindings are updated when reused).
+ items = findItems<QQuickItem>(listView, "delegate");
+ for (const auto item : qAsConst(items)) {
+ const QString display = item->property("displayBinding").toString();
+ const int modelIndex = item->property("modelIndex").toInt();
+ QVERIFY(modelIndex >= initialItemCount);
+ QCOMPARE(display, model.displayStringForRow(modelIndex));
+ }
+
+ // Flick one page up. This time there shouldn't be any new items created, so
+ // delegatesCreatedCount should remain unchanged. But while we reuse all the items
+ // in the pool during the flick, we also fill it up again with all the items that
+ // were inside the page that was flicked out.
+ listView->setContentY(0);
+ QVERIFY(QQuickTest::qWaitForItemPolished(listView));
+ const int countAfterUpFlick = listView->property("delegatesCreatedCount").toInt();
+ const int poolSizeAfterUpFlick = itemView_d->model->poolSize();
+ QCOMPARE(countAfterUpFlick, countAfterDownFlick);
+ QCOMPARE(poolSizeAfterUpFlick, initialItemCount);
+
+ // Go through all items and check that they have been reused exactly once
+ // (except for ListView.currentItem, which was never released).
+ const auto listViewCurrentItem = listView->currentItem();
+ items = findItems<QQuickItem>(listView, "delegate");
+ for (const auto item : qAsConst(items)) {
+ const int reusedCount = item->property("reusedCount").toInt();
+ if (item == listViewCurrentItem)
+ QCOMPARE(reusedCount, 0);
+ else
+ QCOMPARE(reusedCount, 1);
+ }
+
+ // Go through all items again and check that all model data inside the delegate
+ // have correct values now that they have been reused.
+ items = findItems<QQuickItem>(listView, "delegate");
+ for (const auto item : qAsConst(items)) {
+ const QString display = item->property("displayBinding").toString();
+ const int modelIndex = item->property("modelIndex").toInt();
+ QVERIFY(modelIndex < initialItemCount);
+ QCOMPARE(display, model.displayStringForRow(modelIndex));
+ }
+}
+
+void tst_QQuickListView::dragOverFloatingHeaderOrFooter() // QTBUG-74046
+{
+ QQuickView *window = getView();
+ QQuickViewTestUtil::moveMouseAway(window);
+ window->setSource(testFileUrl("qtbug63974.qml"));
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
+
+ QQuickListView *listview = qmlobject_cast<QQuickListView *>(window->rootObject());
+ QVERIFY(listview);
+ QCOMPARE(listview->contentY(), -20);
+
+ // Drag downwards from the header: the list shouldn't move
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(10,10));
+ for (int i = 0; i < 10; ++i)
+ QTest::mouseMove(window, QPoint(10, 10 + i * 10));
+ QCOMPARE(listview->isMoving(), false);
+ QCOMPARE(listview->contentY(), -20);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier);
+
+ // Drag upwards from the footer: the list shouldn't move
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(10,190));
+ for (int i = 0; i < 10; ++i)
+ QTest::mouseMove(window, QPoint(10, 190 - i * 10));
+ QCOMPARE(listview->isMoving(), false);
+ QCOMPARE(listview->contentY(), -20);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier);
+
+ // Drag upwards from the middle: the list should move
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(10,100));
+ for (int i = 0; i < 10 && listview->contentY() == -20; ++i)
+ QTest::mouseMove(window, QPoint(10, 100 - i * 10));
+ QVERIFY(listview->isMoving());
+ QVERIFY(listview->contentY() > -20);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier);
+
+ releaseView(window);
+}
+
void tst_QQuickListView::moveObjectModelItemToAnotherObjectModel()
{
QScopedPointer<QQuickView> window(createView());
@@ -9775,6 +9988,60 @@ void tst_QQuickListView::changeModelAndDestroyTheOldOne() // QTBUG-80203
// no crash
}
+class DataObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString name READ name CONSTANT)
+ Q_PROPERTY(QString color READ color CONSTANT)
+
+public:
+ DataObject(QObject *parent = nullptr) : QObject(parent) {}
+ DataObject(const QString &name, const QString &color, QObject *parent = nullptr)
+ : QObject(parent), m_name(name), m_color(color) {}
+
+ QString name() const { return m_name; }
+ QString color() const { return m_color; }
+
+private:
+ QString m_name;
+ QString m_color;
+};
+
+void tst_QQuickListView::requiredObjectListModel()
+{
+ QList<QObject *> dataList = {
+ new DataObject("Item 1", "red", this),
+ new DataObject("Item 2", "green", this),
+ new DataObject("Item 3", "blue", this),
+ new DataObject("Item 4", "yellow", this)
+ };
+
+ const auto deleter = qScopeGuard([&](){ qDeleteAll(dataList); });
+ Q_UNUSED(deleter);
+
+ QQuickView view;
+ view.setInitialProperties({{ "model", QVariant::fromValue(dataList) }});
+ view.setSource(testFileUrl("requiredObjectListModel.qml"));
+ view.show();
+
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ const auto *root = qobject_cast<QQuickListView *>(view.rootObject());
+ QVERIFY(root);
+
+ QCOMPARE(root->count(), dataList.count());
+
+ for (int i = 0, end = dataList.count(); i != end; ++i) {
+ const auto *rect = qobject_cast<QQuickRectangle *>(root->itemAtIndex(i));
+ QVERIFY(rect);
+ const auto *data = qobject_cast<DataObject *>(dataList.at(i));
+ QVERIFY(data);
+
+ QCOMPARE(rect->color(), QColor(data->color()));
+ QCOMPARE(rect->property("name").toString(), data->name());
+ }
+}
+
QTEST_MAIN(tst_QQuickListView)
#include "tst_qquicklistview.moc"
diff --git a/tests/auto/quick/qquickloader/data/RequiredPropertyValuesComponent.qml b/tests/auto/quick/qquickloader/data/RequiredPropertyValuesComponent.qml
new file mode 100644
index 0000000000..7bb21e8b93
--- /dev/null
+++ b/tests/auto/quick/qquickloader/data/RequiredPropertyValuesComponent.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.0
+
+Item {
+ id: behaviorCounter
+ required property int i
+ required property string s
+
+}
diff --git a/tests/auto/quick/qquickloader/data/initialPropertyValues.10.qml b/tests/auto/quick/qquickloader/data/initialPropertyValues.10.qml
new file mode 100644
index 0000000000..4728346ca1
--- /dev/null
+++ b/tests/auto/quick/qquickloader/data/initialPropertyValues.10.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ property int i: 0
+ property string s: ""
+
+ Loader {
+ id: loader
+ objectName: "loader"
+ onLoaded: {
+ root.i = loader.item.i; // should be 42
+ root.s = loader.item.s; // should be 11
+ }
+ }
+
+ Component.onCompleted: {
+ loader.setSource("RequiredPropertyValuesComponent.qml", {"i": 42});
+ }
+}
diff --git a/tests/auto/quick/qquickloader/data/initialPropertyValues.9.qml b/tests/auto/quick/qquickloader/data/initialPropertyValues.9.qml
new file mode 100644
index 0000000000..5d6e3171a0
--- /dev/null
+++ b/tests/auto/quick/qquickloader/data/initialPropertyValues.9.qml
@@ -0,0 +1,20 @@
+import QtQuick 2.0
+
+Item {
+ id: root
+ property int i: 0
+ property string s: ""
+
+ Loader {
+ id: loader
+ objectName: "loader"
+ onLoaded: {
+ root.i = loader.item.i; // should be 42
+ root.s = loader.item.s; // should be 11
+ }
+ }
+
+ Component.onCompleted: {
+ loader.setSource("RequiredPropertyValuesComponent.qml", {"i": 42, "s": "hello world"});
+ }
+}
diff --git a/tests/auto/quick/qquickloader/tst_qquickloader.cpp b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
index 7bd6f9466a..91d0bcab2e 100644
--- a/tests/auto/quick/qquickloader/tst_qquickloader.cpp
+++ b/tests/auto/quick/qquickloader/tst_qquickloader.cpp
@@ -684,6 +684,16 @@ void tst_QQuickLoader::initialPropertyValues_data()
<< (QStringList() << "initialValue")
<< (QVariantList() << 6);
+ QTest::newRow("ensure required properties are set correctly") << testFileUrl("initialPropertyValues.9.qml")
+ << QStringList()
+ << (QStringList() << "i" << "s")
+ << (QVariantList() << 42 << QLatin1String("hello world"));
+
+ QTest::newRow("required properties only partially set =") << testFileUrl("initialPropertyValues.10.qml")
+ << (QStringList() << QString(testFileUrl("RequiredPropertyValuesComponent.qml").toString() + QLatin1String(":6:5: Required property s was not initialized")))
+ << (QStringList() << "i" << "s")
+ << (QVariantList() << 0 << QLatin1String(""));
+
QTest::newRow("source url changed, previously initial properties are discared") << testFileUrl("initialPropertyValues.11.qml")
<< QStringList()
<< (QStringList() << "oldi" << "i")
diff --git a/tests/auto/quick/qquickmousearea/data/dragreset.qml b/tests/auto/quick/qquickmousearea/data/dragreset.qml
index 10039f1fcb..bbe0160080 100644
--- a/tests/auto/quick/qquickmousearea/data/dragreset.qml
+++ b/tests/auto/quick/qquickmousearea/data/dragreset.qml
@@ -1,6 +1,7 @@
import QtQuick 2.0
Rectangle {
id: whiteRect
+ required property bool haveTarget
width: 200
height: 200
color: "white"
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index 1a9182de57..5879fc6897 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -308,7 +308,7 @@ void tst_QQuickMouseArea::resetDrag()
{
QQuickView window;
QByteArray errorMessage;
- window.rootContext()->setContextProperty("haveTarget", QVariant(true));
+ window.setInitialProperties({{"haveTarget", true}});
QVERIFY2(QQuickTest::initView(window, testFileUrl("dragreset.qml"), true, &errorMessage), errorMessage.constData());
window.show();
QVERIFY(QTest::qWaitForWindowExposed(&window));
@@ -327,7 +327,9 @@ void tst_QQuickMouseArea::resetDrag()
QVERIFY(rootItem != nullptr);
QSignalSpy targetSpy(drag, SIGNAL(targetChanged()));
QVERIFY(drag->target() != nullptr);
- window.rootContext()->setContextProperty("haveTarget", QVariant(false));
+ auto root = window.rootObject();
+ QQmlProperty haveTarget {root, "haveTarget"};
+ haveTarget.write(false);
QCOMPARE(targetSpy.count(),1);
QVERIFY(!drag->target());
}
@@ -716,7 +718,7 @@ void tst_QQuickMouseArea::updateMouseAreaPosOnClick()
QCOMPARE(mouseRegion->mouseX(), rect->x());
QCOMPARE(mouseRegion->mouseY(), rect->y());
- QMouseEvent event(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, nullptr);
+ QMouseEvent event(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, {});
QGuiApplication::sendEvent(&window, &event);
QCOMPARE(mouseRegion->mouseX(), 100.0);
@@ -744,7 +746,7 @@ void tst_QQuickMouseArea::updateMouseAreaPosOnResize()
QCOMPARE(mouseRegion->mouseX(), 0.0);
QCOMPARE(mouseRegion->mouseY(), 0.0);
- QMouseEvent event(QEvent::MouseButtonPress, rect->position().toPoint(), Qt::LeftButton, Qt::LeftButton, nullptr);
+ QMouseEvent event(QEvent::MouseButtonPress, rect->position().toPoint(), Qt::LeftButton, Qt::LeftButton, {});
QGuiApplication::sendEvent(&window, &event);
QVERIFY(!mouseRegion->property("emitPositionChanged").toBool());
@@ -773,7 +775,7 @@ void tst_QQuickMouseArea::noOnClickedWithPressAndHold()
QQuickMouseArea *mouseArea = qobject_cast<QQuickMouseArea*>(window.rootObject()->children().first());
QVERIFY(mouseArea);
- QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, nullptr);
+ QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, {});
QGuiApplication::sendEvent(&window, &pressEvent);
QCOMPARE(mouseArea->pressedButtons(), Qt::LeftButton);
@@ -787,7 +789,7 @@ void tst_QQuickMouseArea::noOnClickedWithPressAndHold()
QVERIFY(!window.rootObject()->property("clicked").toBool());
QVERIFY(window.rootObject()->property("held").toBool());
- QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, nullptr);
+ QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, {});
QGuiApplication::sendEvent(&window, &releaseEvent);
QTRY_VERIFY(window.rootObject()->property("held").toBool());
@@ -803,14 +805,14 @@ void tst_QQuickMouseArea::noOnClickedWithPressAndHold()
QVERIFY(QTest::qWaitForWindowExposed(&window));
QVERIFY(window.rootObject() != nullptr);
- QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, nullptr);
+ QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, {});
QGuiApplication::sendEvent(&window, &pressEvent);
QVERIFY(!window.rootObject()->property("clicked").toBool());
QTest::qWait(1000);
- QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, nullptr);
+ QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, {});
QGuiApplication::sendEvent(&window, &releaseEvent);
QVERIFY(window.rootObject()->property("clicked").toBool());
@@ -834,7 +836,7 @@ void tst_QQuickMouseArea::onMousePressRejected()
QVERIFY(!window.rootObject()->property("mr2_released").toBool());
QVERIFY(!window.rootObject()->property("mr2_canceled").toBool());
- QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, nullptr);
+ QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, {});
QGuiApplication::sendEvent(&window, &pressEvent);
QVERIFY(window.rootObject()->property("mr1_pressed").toBool());
@@ -846,7 +848,7 @@ void tst_QQuickMouseArea::onMousePressRejected()
QTest::qWait(200);
- QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, nullptr);
+ QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, {});
QGuiApplication::sendEvent(&window, &releaseEvent);
QVERIFY(window.rootObject()->property("mr1_released").toBool());
@@ -881,8 +883,8 @@ void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
QCOMPARE(window.rootObject()->property("clicked").toInt(), expectedClicks);
- QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, nullptr);
- QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, nullptr);
+ QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, {});
+ QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, {});
QGuiApplication::sendEvent(&window, &pressEvent);
@@ -899,7 +901,7 @@ void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
QCOMPARE(window.rootObject()->property("clicked").toInt(), ++expectedClicks);
QGuiApplication::sendEvent(&window, &pressEvent);
- QMouseEvent pressEvent2(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, nullptr);
+ QMouseEvent pressEvent2(QEvent::MouseButtonDblClick, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, {});
QGuiApplication::sendEvent(&window, &pressEvent2);
QTRY_VERIFY(window.rootObject()->property("pressed").toBool());
@@ -952,16 +954,16 @@ void tst_QQuickMouseArea::doubleClick()
// The sequence for a double click is:
// press, release, (click), press, double click, release
- QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), button, button, nullptr);
+ QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), button, button, {});
QGuiApplication::sendEvent(&window, &pressEvent);
- QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), button, button, nullptr);
+ QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), button, button, {});
QGuiApplication::sendEvent(&window, &releaseEvent);
QCOMPARE(window.rootObject()->property("released").toInt(), 1);
QGuiApplication::sendEvent(&window, &pressEvent);
- pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), button, button, nullptr);
+ pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), button, button, {});
QGuiApplication::sendEvent(&window, &pressEvent);
QGuiApplication::sendEvent(&window, &releaseEvent);
@@ -987,10 +989,10 @@ void tst_QQuickMouseArea::clickTwice()
QVERIFY(mouseArea);
mouseArea->setAcceptedButtons(acceptedButtons);
- QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), button, button, nullptr);
+ QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), button, button, {});
QGuiApplication::sendEvent(&window, &pressEvent);
- QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), button, button, nullptr);
+ QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), button, button, {});
QGuiApplication::sendEvent(&window, &releaseEvent);
QCOMPARE(window.rootObject()->property("pressed").toInt(), 1);
@@ -998,7 +1000,7 @@ void tst_QQuickMouseArea::clickTwice()
QCOMPARE(window.rootObject()->property("clicked").toInt(), 1);
QGuiApplication::sendEvent(&window, &pressEvent);
- pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), button, button, nullptr);
+ pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), button, button, {});
QGuiApplication::sendEvent(&window, &pressEvent);
QGuiApplication::sendEvent(&window, &releaseEvent);
@@ -1025,16 +1027,16 @@ void tst_QQuickMouseArea::invalidClick()
// The sequence for a double click is:
// press, release, (click), press, double click, release
- QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), button, button, nullptr);
+ QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), button, button, {});
QGuiApplication::sendEvent(&window, &pressEvent);
- QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), button, button, nullptr);
+ QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), button, button, {});
QGuiApplication::sendEvent(&window, &releaseEvent);
QCOMPARE(window.rootObject()->property("released").toInt(), 0);
QGuiApplication::sendEvent(&window, &pressEvent);
- pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), button, button, nullptr);
+ pressEvent = QMouseEvent(QEvent::MouseButtonDblClick, QPoint(100, 100), button, button, {});
QGuiApplication::sendEvent(&window, &pressEvent);
QGuiApplication::sendEvent(&window, &releaseEvent);
@@ -1054,12 +1056,12 @@ void tst_QQuickMouseArea::pressedOrdering()
QCOMPARE(window.rootObject()->property("value").toString(), QLatin1String("base"));
- QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, nullptr);
+ QMouseEvent pressEvent(QEvent::MouseButtonPress, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, {});
QGuiApplication::sendEvent(&window, &pressEvent);
QCOMPARE(window.rootObject()->property("value").toString(), QLatin1String("pressed"));
- QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, nullptr);
+ QMouseEvent releaseEvent(QEvent::MouseButtonRelease, QPoint(100, 100), Qt::LeftButton, Qt::LeftButton, {});
QGuiApplication::sendEvent(&window, &releaseEvent);
QCOMPARE(window.rootObject()->property("value").toString(), QLatin1String("toggled"));
@@ -1318,13 +1320,13 @@ void tst_QQuickMouseArea::hoverPropagation()
QCOMPARE(root->property("point1").toBool(), false);
QCOMPARE(root->property("point2").toBool(), false);
- QMouseEvent moveEvent(QEvent::MouseMove, QPoint(32, 32), Qt::NoButton, Qt::NoButton, nullptr);
+ QMouseEvent moveEvent(QEvent::MouseMove, QPoint(32, 32), Qt::NoButton, Qt::NoButton, {});
QGuiApplication::sendEvent(&window, &moveEvent);
QCOMPARE(root->property("point1").toBool(), true);
QCOMPARE(root->property("point2").toBool(), false);
- QMouseEvent moveEvent2(QEvent::MouseMove, QPoint(232, 32), Qt::NoButton, Qt::NoButton, nullptr);
+ QMouseEvent moveEvent2(QEvent::MouseMove, QPoint(232, 32), Qt::NoButton, Qt::NoButton, {});
QGuiApplication::sendEvent(&window, &moveEvent2);
QCOMPARE(root->property("point1").toBool(), false);
QCOMPARE(root->property("point2").toBool(), true);
@@ -1334,7 +1336,7 @@ void tst_QQuickMouseArea::hoverVisible()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QQuickView window;
QByteArray errorMessage;
diff --git a/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.2.qml b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.2.qml
new file mode 100644
index 0000000000..ae8ca784bc
--- /dev/null
+++ b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.2.qml
@@ -0,0 +1,59 @@
+import QtQuick 2.14
+
+Item {
+ id: root
+ width: 800
+ height: 600
+ property bool working: false
+
+ ListModel {
+ id: myModel
+ ListElement {
+ name: "Bill Jones"
+ place: "Berlin"
+ }
+ ListElement {
+ name: "Jane Doe"
+ place: "Oslo"
+ }
+ ListElement {
+ name: "John Smith"
+ place: "Oulo"
+ }
+ }
+
+ Component {
+ id: delegateComponent
+ Rectangle {
+ id: myDelegate
+ height: 50
+ width: 50
+ required property string name
+ required property int index
+ onNameChanged: () => {if (myDelegate.name === "You-know-who") root.working = true}
+ Text {
+ text: myDelegate.name
+ font.pointSize: 10
+ anchors.fill: myDelegate
+ }
+ }
+ }
+
+ PathView {
+ anchors.fill: parent
+ model: myModel
+ delegate: delegateComponent
+ path: Path {
+ startX: 80; startY: 100
+ PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }
+ PathQuad { x: 140; y: 100; controlX: -20; controlY: 75 }
+ }
+ }
+ Timer {
+ interval: 1
+ running: true
+ repeat: false
+ onTriggered: () => { myModel.setProperty(1, "name", "You-know-who"); }
+ }
+
+}
diff --git a/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.3.qml b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.3.qml
new file mode 100644
index 0000000000..2996ba18fd
--- /dev/null
+++ b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.3.qml
@@ -0,0 +1,64 @@
+import QtQuick 2.14
+
+Item {
+ id: root
+ width: 800
+ height: 600
+ property bool working: false
+
+ ListModel {
+ id: myModel
+ ListElement {
+ name: "Bill Jones"
+ place: "Berlin"
+ }
+ ListElement {
+ name: "Jane Doe"
+ place: "Oslo"
+ }
+ ListElement {
+ name: "John Smith"
+ place: "Oulo"
+ }
+ }
+
+ Component {
+ id: delegateComponent
+ Rectangle {
+ id: myDelegate
+ height: 50
+ width: 50
+ required property string name
+ required property int index
+ onNameChanged: () => {if (myDelegate.name === "You-know-who") root.working = false}
+ Text {
+ text: myDelegate.name
+ font.pointSize: 10
+ anchors.fill: myDelegate
+ }
+ Component.onCompleted: () => {myDelegate.name = "break binding"}
+ }
+ }
+
+ PathView {
+ anchors.fill: parent
+ model: myModel
+ delegate: delegateComponent
+ path: Path {
+ startX: 80; startY: 100
+ PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }
+ PathQuad { x: 140; y: 100; controlX: -20; controlY: 75 }
+ }
+ }
+ Timer {
+ interval: 1
+ running: true
+ repeat: false
+ onTriggered: () => {
+ myModel.setProperty(1, "name", "You-know-who")
+ myModel.setProperty(2, "name", "You-know-who")
+ root.working = true
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.qml b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.qml
new file mode 100644
index 0000000000..5d721fd0c4
--- /dev/null
+++ b/tests/auto/quick/qquickpathview/data/delegateWithRequiredProperties.qml
@@ -0,0 +1,53 @@
+import QtQuick 2.14
+
+Item {
+ width: 400
+ height: 200
+
+ ListModel {
+ id: myModel
+ ListElement {
+ name: "Bill Jones"
+ place: "Berlin"
+ }
+ ListElement {
+ name: "Jane Doe"
+ place: "Oslo"
+ }
+ ListElement {
+ name: "John Smith"
+ place: "Oulo"
+ }
+ }
+
+ Component {
+ id: delegateComponent
+ Rectangle {
+ id: myDelegate
+ required property int index
+ required property string name
+ required property string place
+ height: 100
+ width: 100
+ Text {
+ text: myDelegate.name + " lives in " + myDelegate.place + myDelegate.index
+ font.pointSize: 16
+ anchors.fill: myDelegate
+
+ Component.onCompleted: () => {console.info(myDelegate.name+myDelegate.place+myDelegate.index)}
+ }
+ }
+ }
+
+ PathView {
+ anchors.fill: parent
+ model: myModel
+ delegate: delegateComponent
+ path: Path {
+ startX: 120; startY: 100
+ PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }
+ PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 }
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquickpathview/data/delegatewithUnrelatedRequiredPreventsAccessToModel.qml b/tests/auto/quick/qquickpathview/data/delegatewithUnrelatedRequiredPreventsAccessToModel.qml
new file mode 100644
index 0000000000..bf130a2d73
--- /dev/null
+++ b/tests/auto/quick/qquickpathview/data/delegatewithUnrelatedRequiredPreventsAccessToModel.qml
@@ -0,0 +1,52 @@
+import QtQuick 2.14
+
+Item {
+ width: 400
+ height: 200
+
+ ListModel {
+ id: myModel
+ ListElement {
+ name: "Bill Jones"
+ place: "Berlin"
+ }
+ ListElement {
+ name: "Jane Doe"
+ place: "Oslo"
+ }
+ ListElement {
+ name: "John Smith"
+ place: "Oulo"
+ }
+ }
+
+ Component {
+ id: delegateComponent
+ Rectangle {
+ id: myDelegate
+ required property int set
+ set: 42
+ height: 100
+ width: 100
+ Text {
+ text: "Test"
+ font.pointSize: 16
+ anchors.fill: myDelegate
+
+ Component.onCompleted: () => { try {index; console.log(index); console.log(name)} catch(ex) {console.info(ex.name)} }
+ }
+ }
+ }
+
+ PathView {
+ anchors.fill: parent
+ model: myModel
+ delegate: delegateComponent
+ path: Path {
+ startX: 120; startY: 100
+ PathQuad { x: 120; y: 25; controlX: 260; controlY: 75 }
+ PathQuad { x: 120; y: 100; controlX: -20; controlY: 75 }
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
index f3119dd0f3..8ba09fa509 100644
--- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
+++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp
@@ -151,6 +151,8 @@ private slots:
void movementDirection();
void removePath();
void objectModelMove();
+ void requiredPropertiesInDelegate();
+ void requiredPropertiesInDelegatePreventUnrelated();
};
class TestObject : public QObject
@@ -2759,6 +2761,41 @@ void tst_QQuickPathView::objectModelMove()
}
}
+void tst_QQuickPathView::requiredPropertiesInDelegate()
+{
+ {
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "Bill JonesBerlin0");
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "Jane DoeOslo1");
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "John SmithOulo2");
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("delegateWithRequiredProperties.qml"));
+ window->show();
+ }
+ {
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("delegateWithRequiredProperties.2.qml"));
+ window->show();
+ QTRY_VERIFY(window->rootObject()->property("working").toBool());
+ }
+ {
+ QScopedPointer<QQuickView> window(createView());
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression("Writing to \"name\" broke the binding to the underlying model"));
+ window->setSource(testFileUrl("delegateWithRequiredProperties.3.qml"));
+ window->show();
+ QTRY_VERIFY(window->rootObject()->property("working").toBool());
+ }
+}
+
+void tst_QQuickPathView::requiredPropertiesInDelegatePreventUnrelated()
+{
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "ReferenceError");
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "ReferenceError");
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "ReferenceError");
+ QScopedPointer<QQuickView> window(createView());
+ window->setSource(testFileUrl("delegatewithUnrelatedRequiredPreventsAccessToModel.qml"));
+ window->show();
+}
+
QTEST_MAIN(tst_QQuickPathView)
#include "tst_qquickpathview.moc"
diff --git a/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp b/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp
index 1e2e0a6078..88cf6ece96 100644
--- a/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp
+++ b/tests/auto/quick/qquickpixmapcache/tst_qquickpixmapcache.cpp
@@ -433,7 +433,7 @@ void tst_qquickpixmapcache::uncached()
QUrl url("image://mypixmaps/mypix");
{
QQuickPixmap p;
- p.load(&engine, url, nullptr);
+ p.load(&engine, url, QQuickPixmap::Options{});
QImage img = p.image();
QCOMPARE(img.pixel(0,0), qRgb(255, 0, 0));
}
@@ -442,7 +442,7 @@ void tst_qquickpixmapcache::uncached()
MyPixmapProvider::fillColor = qRgb(0, 255, 0);
{
QQuickPixmap p;
- p.load(&engine, url, nullptr);
+ p.load(&engine, url, QQuickPixmap::Options{});
QImage img = p.image();
QCOMPARE(img.pixel(0,0), qRgb(0, 255, 0));
}
@@ -460,7 +460,7 @@ void tst_qquickpixmapcache::uncached()
MyPixmapProvider::fillColor = qRgb(255, 0, 255);
{
QQuickPixmap p;
- p.load(&engine, url, nullptr);
+ p.load(&engine, url, QQuickPixmap::Options{});
QImage img = p.image();
QCOMPARE(img.pixel(0,0), qRgb(255, 0, 255));
}
diff --git a/tests/auto/quick/qquickpositioners/data/transitions-padding.qml b/tests/auto/quick/qquickpositioners/data/transitions-padding.qml
index e3175c480c..eda9ce628e 100644
--- a/tests/auto/quick/qquickpositioners/data/transitions-padding.qml
+++ b/tests/auto/quick/qquickpositioners/data/transitions-padding.qml
@@ -5,6 +5,16 @@ Rectangle {
width: 500
height: 500
+ required property bool usePopulateTransition
+ required property bool enableAddTransition
+ required property bool dynamicallyPopulate
+ required property var testModel
+ required property var model_targetItems_transitionFrom
+ required property var model_displacedItems_transitionVia
+ required property point targetItems_transitionFrom
+ required property point displacedItems_transitionVia
+ required property string testedPositioner
+
property int duration: 50
property real incrementalSize: 5
diff --git a/tests/auto/quick/qquickpositioners/data/transitions.qml b/tests/auto/quick/qquickpositioners/data/transitions.qml
index a1f27bb06e..988a01e373 100644
--- a/tests/auto/quick/qquickpositioners/data/transitions.qml
+++ b/tests/auto/quick/qquickpositioners/data/transitions.qml
@@ -5,6 +5,16 @@ Rectangle {
width: 500
height: 500
+ required property bool usePopulateTransition
+ required property bool enableAddTransition
+ required property bool dynamicallyPopulate
+ required property var testModel
+ required property var model_targetItems_transitionFrom
+ required property var model_displacedItems_transitionVia
+ required property point targetItems_transitionFrom
+ required property point displacedItems_transitionVia
+ required property string testedPositioner
+
property int duration: 50
property real incrementalSize: 5
diff --git a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
index d3c0f345b9..e6bbd8c215 100644
--- a/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
+++ b/tests/auto/quick/qquickpositioners/tst_qquickpositioners.cpp
@@ -1025,16 +1025,17 @@ void tst_qquickpositioners::populateTransitions(const QString &positionerObjectN
QScopedPointer<QQuickView> window(QQuickViewTestUtil::createView());
- QQmlContext *ctxt = window->rootContext();
- ctxt->setContextProperty("usePopulateTransition", usePopulateTransition);
- ctxt->setContextProperty("enableAddTransition", true);
- ctxt->setContextProperty("dynamicallyPopulate", dynamicallyPopulate);
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("model_targetItems_transitionFrom", &model_targetItems_transitionFrom);
- ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia);
- ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom);
- ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia);
- ctxt->setContextProperty("testedPositioner", positionerObjectName);
+ window->setInitialProperties({
+ {"usePopulateTransition", usePopulateTransition},
+ {"enableAddTransition", true},
+ {"dynamicallyPopulate", dynamicallyPopulate},
+ {"testModel", QVariant::fromValue(&model)},
+ {"model_targetItems_transitionFrom", QVariant::fromValue(&model_targetItems_transitionFrom)},
+ {"model_displacedItems_transitionVia", QVariant::fromValue(&model_displacedItems_transitionVia)},
+ {"targetItems_transitionFrom", targetItems_transitionFrom},
+ {"displacedItems_transitionVia", displacedItems_transitionVia},
+ {"testedPositioner", positionerObjectName}
+ });
window->setSource(testFileUrl(qmlFile));
QQuickItem *positioner = window->rootObject()->findChild<QQuickItem*>(positionerObjectName);
@@ -1111,16 +1112,17 @@ void tst_qquickpositioners::addTransitions(const QString &positionerObjectName)
QaimModel model_displacedItems_transitionVia;
QScopedPointer<QQuickView> window(QQuickViewTestUtil::createView());
- QQmlContext *ctxt = window->rootContext();
- ctxt->setContextProperty("usePopulateTransition", QVariant(false));
- ctxt->setContextProperty("enableAddTransition", QVariant(true));
- ctxt->setContextProperty("dynamicallyPopulate", QVariant(false));
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("model_targetItems_transitionFrom", &model_targetItems_transitionFrom);
- ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia);
- ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom);
- ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia);
- ctxt->setContextProperty("testedPositioner", QString());
+ window->setInitialProperties({
+ {"usePopulateTransition", QVariant(false)},
+ {"enableAddTransition", QVariant(true)},
+ {"dynamicallyPopulate", QVariant(false)},
+ {"testModel", QVariant::fromValue(&model)},
+ {"model_targetItems_transitionFrom", QVariant::fromValue(&model_targetItems_transitionFrom)},
+ {"model_displacedItems_transitionVia", QVariant::fromValue(&model_displacedItems_transitionVia)},
+ {"targetItems_transitionFrom", targetItems_transitionFrom},
+ {"displacedItems_transitionVia", displacedItems_transitionVia},
+ {"testedPositioner", QString()}
+ });
window->setSource(testFileUrl(qmlFile));
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window.data()));
@@ -1234,16 +1236,17 @@ void tst_qquickpositioners::moveTransitions(const QString &positionerObjectName)
QaimModel model_displacedItems_transitionVia;
QScopedPointer<QQuickView> window(QQuickViewTestUtil::createView());
- QQmlContext *ctxt = window->rootContext();
- ctxt->setContextProperty("usePopulateTransition", QVariant(false));
- ctxt->setContextProperty("enableAddTransition", QVariant(false));
- ctxt->setContextProperty("dynamicallyPopulate", QVariant(false));
- ctxt->setContextProperty("testModel", &model);
- ctxt->setContextProperty("model_targetItems_transitionFrom", &model_targetItems_transitionFrom);
- ctxt->setContextProperty("model_displacedItems_transitionVia", &model_displacedItems_transitionVia);
- ctxt->setContextProperty("targetItems_transitionFrom", targetItems_transitionFrom);
- ctxt->setContextProperty("displacedItems_transitionVia", displacedItems_transitionVia);
- ctxt->setContextProperty("testedPositioner", QString());
+ window->setInitialProperties({
+ {"usePopulateTransition", QVariant(false)},
+ {"enableAddTransition", QVariant(false)},
+ {"dynamicallyPopulate", QVariant(false)},
+ {"testModel", QVariant::fromValue(&model)},
+ {"model_targetItems_transitionFrom", QVariant::fromValue(&model_targetItems_transitionFrom)},
+ {"model_displacedItems_transitionVia", QVariant::fromValue(&model_displacedItems_transitionVia)},
+ {"targetItems_transitionFrom", targetItems_transitionFrom},
+ {"displacedItems_transitionVia", displacedItems_transitionVia},
+ {"testedPositioner", QString()}
+ });
window->setSource(testFileUrl(qmlFile));
window->show();
QVERIFY(QTest::qWaitForWindowExposed(window.data()));
diff --git a/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp b/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp
index e4d790f466..536280337a 100644
--- a/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp
+++ b/tests/auto/quick/qquickrectangle/tst_qquickrectangle.cpp
@@ -73,7 +73,7 @@ void tst_qquickrectangle::color()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimal platforms", Abort);
QImage image = view.grabWindow();
QVERIFY(image.pixel(0,0) == QColor("#020202").rgba());
diff --git a/tests/auto/quick/qquickrendercontrol/data/rect.qml b/tests/auto/quick/qquickrendercontrol/data/rect.qml
new file mode 100644
index 0000000000..5f58869fb5
--- /dev/null
+++ b/tests/auto/quick/qquickrendercontrol/data/rect.qml
@@ -0,0 +1,47 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.2
+
+Rectangle {
+ width: 200
+ height: 200
+ color: "steelblue"
+ Rectangle {
+ id: r
+ width: 150
+ height: 150
+ anchors.centerIn: parent
+ color: "palegreen"
+ NumberAnimation on rotation { from: 0; to: 360; duration: 5000; loops: -1 }
+ }
+ Text {
+ text: "Hello World\n\nrotation=" + Math.round(r.rotation)
+ anchors.centerIn: parent
+ }
+}
diff --git a/tests/auto/quick/qquickrendercontrol/qquickrendercontrol.pro b/tests/auto/quick/qquickrendercontrol/qquickrendercontrol.pro
new file mode 100644
index 0000000000..958abe316d
--- /dev/null
+++ b/tests/auto/quick/qquickrendercontrol/qquickrendercontrol.pro
@@ -0,0 +1,12 @@
+CONFIG += testcase
+TARGET = tst_qquickrendercontrol
+SOURCES += tst_qquickrendercontrol.cpp
+
+include (../../shared/util.pri)
+
+macos:CONFIG -= app_bundle
+
+QT += core-private gui-private qml-private quick-private testlib opengl
+
+OTHER_FILES += \
+ data/rect.qml
diff --git a/tests/auto/quick/qquickrendercontrol/tst_qquickrendercontrol.cpp b/tests/auto/quick/qquickrendercontrol/tst_qquickrendercontrol.cpp
new file mode 100644
index 0000000000..4bab4e345a
--- /dev/null
+++ b/tests/auto/quick/qquickrendercontrol/tst_qquickrendercontrol.cpp
@@ -0,0 +1,202 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <qtest.h>
+
+#if QT_CONFIG(opengl)
+#include <QOffscreenSurface>
+#include <QOpenGLContext>
+#include <QOpenGLFunctions>
+#include <QOpenGLFramebufferObject>
+#endif
+#include <QAnimationDriver>
+
+#include <QQuickWindow>
+#include <QQuickRenderControl>
+#include <QQuickItem>
+#include <QQmlEngine>
+#include <QQmlComponent>
+
+#include "../../shared/util.h"
+
+#include <QtGui/private/qguiapplication_p.h>
+#include <QtGui/qpa/qplatformintegration.h>
+
+class tst_RenderControl : public QQmlDataTest
+{
+ Q_OBJECT
+
+private slots:
+ void initTestCase();
+ void renderAndReadBack();
+};
+
+void tst_RenderControl::initTestCase()
+{
+ QQmlDataTest::initTestCase();
+}
+
+class AnimationDriver : public QAnimationDriver
+{
+public:
+ AnimationDriver(int msPerStep) : m_step(msPerStep) { }
+
+ void advance() override
+ {
+ m_elapsed += m_step;
+ advanceAnimation();
+ }
+
+ qint64 elapsed() const override
+ {
+ return m_elapsed;
+ }
+
+private:
+ int m_step;
+ qint64 m_elapsed = 0;
+};
+
+
+void tst_RenderControl::renderAndReadBack()
+{
+ static const int ANIM_ADVANCE_PER_FRAME = 16; // milliseconds
+ QScopedPointer<AnimationDriver> animDriver(new AnimationDriver(ANIM_ADVANCE_PER_FRAME));
+ animDriver->install();
+
+ // ### Qt 6: migrate this to OpenGL-on-RHI
+#if QT_CONFIG(opengl)
+ if (!QGuiApplicationPrivate::platformIntegration()->hasCapability(QPlatformIntegration::OpenGL))
+ QSKIP("Skipping due to platform not supporting OpenGL at run time");
+
+ QScopedPointer<QOpenGLContext> context(new QOpenGLContext);
+ QVERIFY(context->create());
+ QScopedPointer<QOffscreenSurface> offscreenSurface(new QOffscreenSurface);
+ offscreenSurface->setFormat(context->format());
+ offscreenSurface->create();
+ QVERIFY(context->makeCurrent(offscreenSurface.data()));
+
+ QScopedPointer<QQuickRenderControl> renderControl(new QQuickRenderControl);
+ QScopedPointer<QQuickWindow> quickWindow(new QQuickWindow(renderControl.data()));
+ QScopedPointer<QQmlEngine> qmlEngine(new QQmlEngine);
+
+ QScopedPointer<QQmlComponent> qmlComponent(new QQmlComponent(qmlEngine.data(), testFileUrl(QLatin1String("rect.qml"))));
+ QVERIFY(!qmlComponent->isLoading());
+ if (qmlComponent->isError()) {
+ for (const QQmlError &error : qmlComponent->errors())
+ qWarning() << error.url() << error.line() << error;
+ }
+ QVERIFY(!qmlComponent->isError());
+
+ QObject *rootObject = qmlComponent->create();
+ if (qmlComponent->isError()) {
+ for (const QQmlError &error : qmlComponent->errors())
+ qWarning() << error.url() << error.line() << error;
+ }
+ QVERIFY(!qmlComponent->isError());
+
+ QQuickItem *rootItem = qobject_cast<QQuickItem *>(rootObject);
+ QVERIFY(rootItem);
+ QCOMPARE(rootItem->size(), QSize(200, 200));
+
+ quickWindow->contentItem()->setSize(rootItem->size());
+ quickWindow->setGeometry(0, 0, rootItem->width(), rootItem->height());
+
+ rootItem->setParentItem(quickWindow->contentItem());
+
+ renderControl->initialize(context.data());
+
+ // cannot do this test with the 'software' backend of Qt Quick
+ QSGRendererInterface::GraphicsApi api = quickWindow->rendererInterface()->graphicsApi();
+ if (api != QSGRendererInterface::OpenGL)
+ QSKIP("Skipping due to Qt Quick not using the direct OpenGL rendering path");
+
+ QScopedPointer<QOpenGLFramebufferObject> fbo(new QOpenGLFramebufferObject(rootItem->size().toSize(),
+ QOpenGLFramebufferObject::CombinedDepthStencil));
+
+ quickWindow->setRenderTarget(fbo.data());
+
+ for (int frame = 0; frame < 100; ++frame) {
+ // have to process events, e.g. to get queued metacalls delivered
+ QCoreApplication::processEvents();
+
+ if (frame > 0) {
+ // Quick animations will now think that ANIM_ADVANCE_PER_FRAME milliseconds have passed,
+ // even though in reality we have a tight loop that generates frames unthrottled.
+ animDriver->advance();
+ }
+
+ renderControl->polishItems();
+ renderControl->sync();
+ renderControl->render();
+
+ context->functions()->glFlush();
+
+ QImage img = fbo->toImage();
+ QVERIFY(!img.isNull());
+ QCOMPARE(img.size(), rootItem->size());
+
+ const int maxFuzz = 2;
+
+ // The scene is: background, rectangle, text
+ // where rectangle rotates
+
+ QRgb background = img.pixel(5, 5);
+ QVERIFY(qAbs(qRed(background) - 70) < maxFuzz);
+ QVERIFY(qAbs(qGreen(background) - 130) < maxFuzz);
+ QVERIFY(qAbs(qBlue(background) - 180) < maxFuzz);
+
+ background = img.pixel(195, 195);
+ QVERIFY(qAbs(qRed(background) - 70) < maxFuzz);
+ QVERIFY(qAbs(qGreen(background) - 130) < maxFuzz);
+ QVERIFY(qAbs(qBlue(background) - 180) < maxFuzz);
+
+ // after about 1.25 seconds (animation time, one iteration is 16 ms
+ // thanks to our custom animation driver) the rectangle reaches a 90
+ // degree rotation, that should be frame 76
+ if (frame <= 2 || (frame >= 76 && frame <= 80)) {
+ QRgb c = img.pixel(28, 28); // rectangle
+ QVERIFY(qAbs(qRed(c) - 152) < maxFuzz);
+ QVERIFY(qAbs(qGreen(c) - 251) < maxFuzz);
+ QVERIFY(qAbs(qBlue(c) - 152) < maxFuzz);
+ } else {
+ QRgb c = img.pixel(28, 28); // background because rectangle got rotated so this pixel is not covered by it
+ QVERIFY(qAbs(qRed(c) - 70) < maxFuzz);
+ QVERIFY(qAbs(qGreen(c) - 130) < maxFuzz);
+ QVERIFY(qAbs(qBlue(c) - 180) < maxFuzz);
+ }
+ }
+
+#else
+ QSKIP("No OpenGL, skipping rendercontrol test");
+#endif
+}
+
+#include "tst_qquickrendercontrol.moc"
+
+QTEST_MAIN(tst_RenderControl)
diff --git a/tests/auto/quick/qquickrepeater/data/contextProperty.qml b/tests/auto/quick/qquickrepeater/data/contextProperty.qml
new file mode 100644
index 0000000000..44e76f474f
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/contextProperty.qml
@@ -0,0 +1,13 @@
+import QtQuick 2.14
+
+Item {
+ Column {
+ Repeater {
+ model: ["apples", "oranges", "pears"]
+ Text {
+ id: txt
+ text: modelData + index
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickrepeater/data/objlist_required.qml b/tests/auto/quick/qquickrepeater/data/objlist_required.qml
new file mode 100644
index 0000000000..cc9dd9566c
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/objlist_required.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+
+Rectangle {
+ id: container
+ objectName: "container"
+ width: 240
+ height: 320
+ color: "white"
+ Repeater {
+ id: repeater
+ objectName: "repeater"
+ model: testData
+ property int errors: 0
+ property int instantiated: 0
+ Component {
+ Item{
+ required property int index
+ required property int idx
+ Component.onCompleted: {if (index != idx) repeater.errors += 1; repeater.instantiated++}
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickrepeater/data/package2.qml b/tests/auto/quick/qquickrepeater/data/package2.qml
new file mode 100644
index 0000000000..0ceb34b362
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/package2.qml
@@ -0,0 +1,36 @@
+import QtQuick 2.0
+import QtQml.Models 2.2
+import QtQuick.Window 2.0
+
+Item {
+ width: 300
+ height: 300
+ visible: true
+ DelegateModel {
+ id: mdl
+
+ model: 1
+ delegate: Package {
+ Item {
+ id: first
+ Package.name: "first"
+ }
+ Item{
+ id: second
+ Package.name: "second"
+ }
+ }
+ }
+
+ Repeater {
+ model: mdl.parts.first
+ }
+ Repeater {
+ model: mdl.parts.second
+ }
+
+ function setup(): bool {
+ mdl.model = 2
+ return true;
+ }
+}
diff --git a/tests/auto/quick/qquickrepeater/data/requiredProperty.qml b/tests/auto/quick/qquickrepeater/data/requiredProperty.qml
new file mode 100644
index 0000000000..80eb3c28ee
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/requiredProperty.qml
@@ -0,0 +1,16 @@
+import QtQuick 2.14
+
+Item {
+ Column {
+ Repeater {
+ model: ["apples", "oranges", "pears"]
+ Text {
+ id: txt
+ required property string modelData
+ required property int index
+ text: modelData + index
+ Component.onCompleted: () => {console.info(txt.text)}
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
index 65e7d29595..35883339d7 100644
--- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
+++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
@@ -55,6 +55,7 @@ public:
private slots:
void numberModel();
+ void objectList_data();
void objectList();
void stringList();
void dataModel_adding();
@@ -79,6 +80,8 @@ private slots:
void QTBUG54859_asynchronousMove();
void package();
void ownership();
+ void requiredProperties();
+ void contextProperties();
};
class TestObject : public QObject
@@ -143,6 +146,14 @@ void tst_QQuickRepeater::numberModel()
delete window;
}
+void tst_QQuickRepeater::objectList_data()
+{
+ QTest::addColumn<QUrl>("filename");
+
+ QTest::newRow("normal") << testFileUrl("objlist.qml");
+ QTest::newRow("required") << testFileUrl("objlist_required.qml");
+}
+
class MyObject : public QObject
{
Q_OBJECT
@@ -157,6 +168,7 @@ public:
void tst_QQuickRepeater::objectList()
{
+ QFETCH(QUrl, filename);
QQuickView *window = createView();
QObjectList data;
for (int i=0; i<100; i++)
@@ -165,7 +177,7 @@ void tst_QQuickRepeater::objectList()
QQmlContext *ctxt = window->rootContext();
ctxt->setContextProperty("testData", QVariant::fromValue(data));
- window->setSource(testFileUrl("objlist.qml"));
+ window->setSource(filename);
qApp->processEvents();
QQuickRepeater *repeater = findItem<QQuickRepeater>(window->rootObject(), "repeater");
@@ -1044,6 +1056,16 @@ void tst_QQuickRepeater::package()
QCOMPARE(repeater2->count(), 1);
QCOMPARE(repeater2->itemAt(0)->objectName(), "secondItem");
}
+
+ {
+ QQmlComponent component(&engine, testFileUrl("package2.qml"));
+ QScopedPointer<QObject> root(component.create());
+ QVERIFY(root != nullptr);
+ bool returnedValue = false;
+ // calling setup should not crash
+ QMetaObject::invokeMethod(root.get(), "setup", Q_RETURN_ARG(bool, returnedValue));
+ QVERIFY(returnedValue);
+ }
}
void tst_QQuickRepeater::ownership()
@@ -1108,6 +1130,41 @@ void tst_QQuickRepeater::ownership()
QVERIFY(!modelGuard);
}
+void tst_QQuickRepeater::requiredProperties()
+{
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "apples0");
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "oranges1");
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "pears2");
+ QQmlEngine engine;
+
+ QQmlComponent component(&engine, testFileUrl("requiredProperty.qml"));
+ QScopedPointer<QObject> o {component.create()};
+ QVERIFY(o);
+}
+
+void tst_QQuickRepeater::contextProperties()
+{
+ QQmlEngine engine;
+
+ QQmlComponent component(&engine, testFileUrl("contextProperty.qml"));
+ QScopedPointer<QObject> o {component.create()};
+ QVERIFY(o);
+
+ auto *root = qobject_cast<QQuickItem *>(o.get());
+ QVERIFY(root);
+
+ QQueue<QQuickItem *> items;
+ items.append(root);
+
+ while (!items.isEmpty()) {
+ QQuickItem *item = items.dequeue();
+ QQmlContextData *data = QQmlContextData::get(qmlContext(item));
+ QVERIFY(!data->hasExtraObject);
+ for (QQuickItem *child : item->childItems())
+ items.enqueue(child);
+ }
+}
+
QTEST_MAIN(tst_QQuickRepeater)
#include "tst_qquickrepeater.moc"
diff --git a/tests/auto/quick/qquickshape/tst_qquickshape.cpp b/tests/auto/quick/qquickshape/tst_qquickshape.cpp
index 851475e2cd..578d8d4e3a 100644
--- a/tests/auto/quick/qquickshape/tst_qquickshape.cpp
+++ b/tests/auto/quick/qquickshape/tst_qquickshape.cpp
@@ -283,7 +283,7 @@ void tst_QQuickShape::render()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimal platforms", Abort);
QImage img = window->grabWindow();
QVERIFY(!img.isNull());
@@ -307,7 +307,7 @@ void tst_QQuickShape::renderWithMultipleSp()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimal platforms", Abort);
QImage img = window->grabWindow();
QVERIFY(!img.isNull());
@@ -331,7 +331,7 @@ void tst_QQuickShape::radialGrad()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimal platforms", Abort);
QImage img = window->grabWindow();
QVERIFY(!img.isNull());
@@ -355,7 +355,7 @@ void tst_QQuickShape::conicalGrad()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimal platforms", Abort);
QImage img = window->grabWindow();
QVERIFY(!img.isNull());
@@ -379,7 +379,7 @@ void tst_QQuickShape::renderPolyline()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimal platforms", Abort);
QImage img = window->grabWindow();
QVERIFY(!img.isNull());
@@ -408,7 +408,7 @@ void tst_QQuickShape::renderMultiline()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimal platforms", Abort);
QImage img = window->grabWindow();
QVERIFY(!img.isNull());
@@ -474,7 +474,7 @@ void tst_QQuickShape::polylineDataTypes()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimal platforms", Abort);
QImage img = window->grabWindow();
QVERIFY(!img.isNull());
@@ -625,7 +625,7 @@ void tst_QQuickShape::multilineDataTypes()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimal platforms", Abort);
QImage img = window->grabWindow();
QVERIFY(!img.isNull());
@@ -673,7 +673,7 @@ void tst_QQuickShape::multilineStronglyTyped()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimal platforms", Abort);
QImage img = window->grabWindow();
QVERIFY(!img.isNull());
diff --git a/tests/auto/quick/qquickstates/data/parentChangeCorrectReversal.qml b/tests/auto/quick/qquickstates/data/parentChangeCorrectReversal.qml
new file mode 100644
index 0000000000..3d38fa4046
--- /dev/null
+++ b/tests/auto/quick/qquickstates/data/parentChangeCorrectReversal.qml
@@ -0,0 +1,72 @@
+import QtQuick 2.10
+import QtQuick.Layouts 1.3
+
+Item {
+ id: root
+
+ visible: true
+
+ width: 400
+ height: 200
+ property bool switchToRight: false
+ property alias stayingRectX: stayingRect.x
+
+ RowLayout {
+ id: topLayout
+
+ anchors.fill: parent
+
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Rectangle {
+ id: leftRect
+
+ width: parent.width*(2/3)
+ height: width
+ anchors.centerIn: parent
+
+ color: "red"
+
+ Rectangle {
+ id: stayingRect
+
+ x: 70; y: 70
+ width: 50; height: 50
+
+ color: "yellow"
+ }
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+
+ Rectangle {
+ id: rightRect
+
+ width: parent.height*(2/3)
+ height: width
+ anchors.centerIn: parent
+
+ color: "green"
+ rotation: 45
+ }
+ }
+ }
+
+ states: State {
+ name: "switchToRight"
+
+ ParentChange {
+ target: stayingRect
+ parent: rightRect
+ width: 70
+ }
+
+ }
+
+ state: root.switchToRight ? "switchToRight" : ""
+}
diff --git a/tests/auto/quick/qquickstates/tst_qquickstates.cpp b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
index 1eb797f54f..d5fea3cb28 100644
--- a/tests/auto/quick/qquickstates/tst_qquickstates.cpp
+++ b/tests/auto/quick/qquickstates/tst_qquickstates.cpp
@@ -139,6 +139,7 @@ private slots:
void revertListMemoryLeak();
void duplicateStateName();
void trivialWhen();
+ void parentChangeCorrectReversal();
};
void tst_qquickstates::initTestCase()
@@ -1675,6 +1676,22 @@ void tst_qquickstates::trivialWhen()
QVERIFY(c.create());
}
+void tst_qquickstates::parentChangeCorrectReversal()
+{
+ QQmlEngine engine;
+ QQmlComponent c(&engine, testFileUrl("parentChangeCorrectReversal.qml"));
+ QScopedPointer<QObject> root {c.create()};
+ QVERIFY(root);
+ QQmlProperty stayingRectX(root.get(), "stayingRectX");
+ qreal oldX = stayingRectX.read().toDouble();
+ QQmlProperty switchToRight(root.get(), "switchToRight");
+ switchToRight.write(true);
+ qreal newX = stayingRectX.read().toDouble();
+ QVERIFY(newX != oldX);
+ switchToRight.write(false);
+ QCOMPARE(oldX, stayingRectX.read().toDouble());
+}
+
QTEST_MAIN(tst_qquickstates)
diff --git a/tests/auto/quick/qquicktableview/data/delegateWithRequired.qml b/tests/auto/quick/qquicktableview/data/delegateWithRequired.qml
new file mode 100644
index 0000000000..bebfd86931
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/delegateWithRequired.qml
@@ -0,0 +1,70 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Window 2.3
+
+Item {
+ width: 640
+ height: 450
+
+ property alias tableView: tableView
+
+ TableView {
+ id: tableView
+ width: 600
+ height: 400
+ delegate: tableViewDelegate
+ }
+
+ Component {
+ id: tableViewDelegate
+ Rectangle {
+ id: rect
+ required property string position
+ required property bool hasModelChildren
+ required property QtObject model
+ Text {text: rect.position}
+ implicitWidth: 100
+ implicitHeight: 100
+ Component.onCompleted: () => {if (rect.position === "R1:C1" && rect.model.hasModelChildren == rect.hasModelChildren) console.info("success")}
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquicktableview/data/delegatewithRequiredUnset.qml b/tests/auto/quick/qquicktableview/data/delegatewithRequiredUnset.qml
new file mode 100644
index 0000000000..0c685cd49e
--- /dev/null
+++ b/tests/auto/quick/qquicktableview/data/delegatewithRequiredUnset.qml
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtQuick module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.12
+import QtQuick.Window 2.3
+
+Item {
+ width: 640
+ height: 450
+
+ property alias tableView: tableView
+
+ TableView {
+ id: tableView
+ width: 600
+ height: 400
+ delegate: tableViewDelegate
+ }
+
+ Component {
+ id: tableViewDelegate
+ Rectangle {
+ id: rect
+ required property string position
+ required property bool unset
+ required property bool hasModelChildren
+ required property QtObject model
+ Text {text: rect.position}
+ implicitWidth: 100
+ implicitHeight: 100
+ Component.onCompleted: () => {if (rect.position === "R1:C1" && rect.model.hasModelChildren == rect.hasModelChildren) console.info("success")}
+ }
+ }
+
+}
diff --git a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
index 7c4a5ed65b..ef39a91a65 100644
--- a/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
+++ b/tests/auto/quick/qquicktableview/tst_qquicktableview.cpp
@@ -175,6 +175,7 @@ private slots:
void checkSyncView_differentSizedModels();
void checkSyncView_connect_late_data();
void checkSyncView_connect_late();
+ void delegateWithRequiredProperties();
void checkThatFetchMoreIsCalledWhenScrolledToTheEndOfTable();
void replaceModel();
};
@@ -2701,6 +2702,50 @@ void tst_QQuickTableView::checkThatFetchMoreIsCalledWhenScrolledToTheEndOfTable(
QCOMPARE(tableView->columns(), 5);
}
+void tst_QQuickTableView::delegateWithRequiredProperties()
+{
+ constexpr static int PositionRole = Qt::UserRole+1;
+ struct MyTable : QAbstractTableModel {
+
+
+ using QAbstractTableModel::QAbstractTableModel;
+
+ int rowCount(const QModelIndex& = QModelIndex()) const override {
+ return 3;
+ }
+
+ int columnCount(const QModelIndex& = QModelIndex()) const override {
+ return 3;
+ }
+
+ QVariant data(const QModelIndex &index, int = Qt::DisplayRole) const override {
+ return QVariant::fromValue(QString::asprintf("R%d:C%d", index.row(), index.column()));
+ }
+
+ QHash<int, QByteArray> roleNames() const override {
+ return QHash<int, QByteArray> { {PositionRole, "position"} };
+ }
+ };
+
+ auto model = QVariant::fromValue(QSharedPointer<MyTable>(new MyTable));
+ {
+ QTest::ignoreMessage(QtMsgType::QtInfoMsg, "success");
+ LOAD_TABLEVIEW("delegateWithRequired.qml");
+ QVERIFY(tableView);
+ tableView->setModel(model);
+ WAIT_UNTIL_POLISHED;
+ QVERIFY(view->errors().empty());
+ }
+ {
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, QRegularExpression(R"|(TableView: failed loading index: \d)|"));
+ LOAD_TABLEVIEW("delegatewithRequiredUnset.qml");
+ QVERIFY(tableView);
+ tableView->setModel(model);
+ WAIT_UNTIL_POLISHED;
+ QTRY_VERIFY(view->errors().empty());
+ }
+}
+
void tst_QQuickTableView::replaceModel()
{
LOAD_TABLEVIEW("replaceModelTableView.qml");
diff --git a/tests/auto/quick/qquicktext/BLACKLIST b/tests/auto/quick/qquicktext/BLACKLIST
index 08a5249e2e..f50276a4f1 100644
--- a/tests/auto/quick/qquicktext/BLACKLIST
+++ b/tests/auto/quick/qquicktext/BLACKLIST
@@ -4,3 +4,5 @@ qemu
macos
[fontSizeMode]
opensuse-42.1
+[hAlignVisual]
+sles
diff --git a/tests/auto/quick/qquicktext/data/displaySuperscriptedTag.qml b/tests/auto/quick/qquicktext/data/displaySuperscriptedTag.qml
new file mode 100644
index 0000000000..b0ed21a0c8
--- /dev/null
+++ b/tests/auto/quick/qquicktext/data/displaySuperscriptedTag.qml
@@ -0,0 +1,18 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 200
+ height: 200
+ color: "white"
+ Text {
+ objectName: "text"
+ textFormat: Text.RichText
+ anchors.fill: parent
+ color: "black"
+ // display a black rectangle at the top left of the text
+ text: "<span style=\"background-color:rgba(255,255,255,255);vertical-align:super;\">&#x2588;</span>This is a test"
+ verticalAlignment: Text.AlignTop
+ horizontalAlignment: Text.AlignLeft
+ font.pixelSize: 30
+ }
+}
diff --git a/tests/auto/quick/qquicktext/data/lineLayout.qml b/tests/auto/quick/qquicktext/data/lineLayout.qml
index cb2474791e..5a980de7da 100644
--- a/tests/auto/quick/qquicktext/data/lineLayout.qml
+++ b/tests/auto/quick/qquicktext/data/lineLayout.qml
@@ -14,6 +14,9 @@ Rectangle {
textFormat: Text.StyledText
focus: true
+ property int lastLineNumber: -1
+ property bool receivedMultipleLastLines
+
text: "<b>Lorem ipsum</b> dolor sit amet, consectetur adipiscing elit. Integer at ante dui. Sed eu egestas est.
<br/><p><i>Maecenas nec libero leo. Sed ac leo eget ipsum ultricies viverra sit amet eu orci. Praesent et tortor risus, viverra accumsan sapien. Sed faucibus eleifend lectus, sed euismod urna porta eu. Aenean ultricies lectus ut orci dictum quis convallis nisi ultrices. Nunc elit mi, iaculis a porttitor rutrum, venenatis malesuada nisi. Suspendisse turpis quam, euismod non imperdiet et, rutrum nec ligula. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper tristique metus eu sodales. Integer eget risus ipsum. Quisque ut risus ut nulla tristique volutpat at sit amet nisl. Aliquam pulvinar auctor diam nec bibendum.</i><br/><p>Quisque luctus sapien id arcu volutpat pharetra. Praesent pretium imperdiet euismod. Integer fringilla rhoncus condimentum. Quisque sit amet ornare nulla. Cras sapien augue, sagittis a dictum id, suscipit et nunc. Cras vitae augue in enim elementum venenatis sed nec risus. Sed nisi quam, mollis quis auctor ac, vestibulum in neque. Vivamus eu justo risus. Suspendisse vel mollis est. Vestibulum gravida interdum mi, in molestie neque gravida in. Donec nibh odio, mattis facilisis vulputate et, scelerisque ut felis. Sed ornare eros nec odio aliquam eu varius augue adipiscing. Vivamus sit amet massa dapibus sapien pulvinar consectetur a sit amet felis. Cras non mi id libero dictum iaculis id dignissim eros. Praesent eget enim dui, sed bibendum neque. Ut interdum nisl id leo malesuada ornare. Pellentesque id nisl eu odio volutpat posuere et at massa. Pellentesque nec lorem justo. Integer sem urna, pharetra sed sagittis vitae, condimentum ac felis. Ut vitae sapien ac tortor adipiscing pharetra. Cras tristique urna tempus ante volutpat eleifend non eu ligula. Mauris sodales nisl et lorem tristique sodales. Mauris arcu orci, vehicula semper cursus ac, dapibus ut mi."
@@ -30,6 +33,12 @@ Rectangle {
line.x = line.width * 2 + 60
line.height = 20
}
+
+ // Save last line number, it is important to do this after setting the width
+ if (line.isLast) {
+ receivedMultipleLastLines = (lastLineNumber !== -1) && (lastLineNumber !== line.number)
+ lastLineNumber = line.number
+ }
}
}
}
diff --git a/tests/auto/quick/qquicktext/data/lineLayoutImplicitWidth.qml b/tests/auto/quick/qquicktext/data/lineLayoutImplicitWidth.qml
new file mode 100644
index 0000000000..de5ca616b8
--- /dev/null
+++ b/tests/auto/quick/qquicktext/data/lineLayoutImplicitWidth.qml
@@ -0,0 +1,80 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Jolla Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Rectangle {
+ id: main
+ width: 800; height: 600
+
+ property real off: 0
+
+ Text {
+ id: myText
+ objectName: "myText"
+ wrapMode: Text.WordWrap
+ font.pixelSize: 14
+ textFormat: Text.PlainText
+ focus: true
+ anchors.fill: parent
+
+ // The autotest will retrieve these so that it can verify them
+ property var lineImplicitWidths: []
+
+ text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam quis ante tristique, fermentum magna at, varius lacus. Donec elementum orci sit amet ligula efficitur, eget sodales orci porttitor. Etiam laoreet tellus quis nisi mollis lacinia. Cras vitae nisl sed nunc semper blandit. Duis egestas commodo lacus non congue. Fusce quis rhoncus urna. And magna arcu, sodales vitae nunc vel, rutrum hendrerit magna. Nullam imperdiet porttitor sem at euismod. Morbi faucibus libero sit amet vestibulum aliquam. Duis consectetur lacinia malesuada. Sed quis ante dui. Name dignissim faucibus felis. Quisque dapibus aliquam ante, eu cursus elit dictum in. Mauris placerat efficitur rutrum."
+
+ onLineLaidOut: {
+ var n = line.number
+
+ // Save information about the line so the autotest can retrieve it
+ lineImplicitWidths[n] = line.implicitWidth
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index e62db81d27..42fdbea58d 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -30,6 +30,7 @@
#include <QTextDocument>
#include <QtQml/qqmlengine.h>
#include <QtQml/qqmlcomponent.h>
+#include <QtQml/qjsvalue.h>
#include <QtQuick/private/qquicktext_p.h>
#include <QtQuick/private/qquickmousearea_p.h>
#include <QtQuickTest/QtQuickTest>
@@ -119,6 +120,7 @@ private slots:
void lineLaidOut();
void lineLaidOutRelayout();
void lineLaidOutHAlign();
+ void lineLaidOutImplicitWidth();
void imgTagsBaseUrl_data();
void imgTagsBaseUrl();
@@ -166,6 +168,8 @@ private slots:
void transparentBackground();
+ void displaySuperscriptedTag();
+
private:
QStringList standard;
QStringList richText;
@@ -1035,7 +1039,7 @@ void tst_qquicktext::hAlignImplicitWidth()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimal platforms", Abort);
// Left Align
QImage image = view.grabWindow();
@@ -2871,6 +2875,13 @@ void tst_qquicktext::lineLaidOut()
QCOMPARE(r.height(), qreal(20));
}
}
+
+ // Ensure that isLast was correctly emitted
+ int lastLineNumber = myText->property("lastLineNumber").toInt();
+ QCOMPARE(lastLineNumber, myText->lineCount() - 1);
+ // Ensure that only one line was considered last (after changing its width)
+ bool receivedMultipleLastLines = myText->property("receivedMultipleLastLines").toBool();
+ QVERIFY(!receivedMultipleLastLines);
}
void tst_qquicktext::lineLaidOutRelayout()
@@ -2975,6 +2986,53 @@ void tst_qquicktext::imgTagsBaseUrl_data()
<< 181.;
}
+void tst_qquicktext::lineLaidOutImplicitWidth()
+{
+ QScopedPointer<QQuickView> window(createView(testFile("lineLayoutImplicitWidth.qml")));
+
+ QQuickText *myText = window->rootObject()->findChild<QQuickText*>("myText");
+ QVERIFY(myText != nullptr);
+
+ QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText);
+ QVERIFY(textPrivate != nullptr);
+
+ // Retrieve the saved implicitWidth values of each rendered line
+ QVariant widthsProperty = myText->property("lineImplicitWidths");
+ QVERIFY(!widthsProperty.isNull());
+ QVERIFY(widthsProperty.isValid());
+ QVERIFY(widthsProperty.canConvert<QJSValue>());
+ QJSValue widthsValue = widthsProperty.value<QJSValue>();
+ QVERIFY(widthsValue.isArray());
+ int lineCount = widthsValue.property("length").toInt();
+ QVERIFY(lineCount > 0);
+
+ // Create the same text layout by hand
+ // Note that this approach needs additional processing for styled text,
+ // so we only use it for plain text here.
+ QTextLayout layout;
+ layout.setCacheEnabled(true);
+ layout.setText(myText->text());
+ layout.setTextOption(textPrivate->layout.textOption());
+ layout.setFont(myText->font());
+ layout.beginLayout();
+ for (QTextLine line = layout.createLine(); line.isValid(); line = layout.createLine()) {
+ line.setLineWidth(myText->width());
+ }
+ layout.endLayout();
+
+ // Line count of the just created layout should match the rendered text
+ QCOMPARE(lineCount, layout.lineCount());
+
+ // Go through each line and verify that the values emitted by lineLaidOut are correct
+ for (int i = 0; i < layout.lineCount(); ++i) {
+ qreal implicitWidth = widthsValue.property(i).toNumber();
+ QVERIFY(implicitWidth > 0);
+
+ QTextLine line = layout.lineAt(i);
+ QCOMPARE(implicitWidth, line.naturalTextWidth());
+ }
+}
+
static QUrl substituteTestServerUrl(const QUrl &serverUrl, const QUrl &testUrl)
{
QUrl result = testUrl;
@@ -4435,7 +4493,7 @@ void tst_qquicktext::transparentBackground()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabToImage not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabToImage not functional on offscreen/minimal platforms");
QScopedPointer<QQuickView> window(new QQuickView);
window->setSource(testFileUrl("transparentBackground.qml"));
@@ -4451,6 +4509,32 @@ void tst_qquicktext::transparentBackground()
QCOMPARE(color.blue(), 255);
QCOMPARE(color.green(), 255);
}
+
+void tst_qquicktext::displaySuperscriptedTag()
+{
+ if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
+ || (QGuiApplication::platformName() == QLatin1String("minimal")))
+ QSKIP("Skipping due to grabToImage not functional on offscreen/minimal platforms");
+
+ QScopedPointer<QQuickView> window(new QQuickView);
+ window->setSource(testFileUrl("displaySuperscriptedTag.qml"));
+ QTRY_COMPARE(window->status(), QQuickView::Ready);
+
+ window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window.data()));
+
+ QQuickText *text = window->findChild<QQuickText *>("text");
+ QVERIFY(text);
+
+ QImage img = window->grabWindow();
+ QCOMPARE(img.isNull(), false);
+
+ QColor color = img.pixelColor(1, static_cast<int>(text->contentHeight()) / 4 * 3);
+ QCOMPARE(color.red(), 255);
+ QCOMPARE(color.blue(), 255);
+ QCOMPARE(color.green(), 255);
+}
+
QTEST_MAIN(tst_qquicktext)
#include "tst_qquicktext.moc"
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
index facd63027e..8ea2ce3bfb 100644
--- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
@@ -131,8 +131,10 @@ private slots:
void mouseSelectionMode_accessors();
void selectByMouse();
void selectByKeyboard();
+#if QT_CONFIG(shortcut)
void keyboardSelection_data();
void keyboardSelection();
+#endif
void renderType();
void inputMethodHints();
@@ -190,16 +192,19 @@ private slots:
void insert();
void remove_data();
void remove();
-
+#if QT_CONFIG(shortcut)
void keySequence_data();
void keySequence();
+#endif
void undo_data();
void undo();
void redo_data();
void redo();
+#if QT_CONFIG(shortcut)
void undo_keypressevents_data();
void undo_keypressevents();
+#endif
void clear();
void baseUrl();
@@ -217,9 +222,11 @@ private slots:
private:
void simulateKeys(QWindow *window, const QList<Key> &keys);
+#if QT_CONFIG(shortcut)
void simulateKeys(QWindow *window, const QKeySequence &sequence);
+#endif
- void simulateKey(QWindow *, int key, Qt::KeyboardModifiers modifiers = nullptr);
+ void simulateKey(QWindow *, int key, Qt::KeyboardModifiers modifiers = {});
QStringList standard;
QStringList richText;
@@ -260,6 +267,8 @@ void tst_qquicktextedit::simulateKeys(QWindow *window, const QList<Key> &keys)
}
}
+#if QT_CONFIG(shortcut)
+
void tst_qquicktextedit::simulateKeys(QWindow *window, const QKeySequence &sequence)
{
for (int i = 0; i < sequence.count(); ++i) {
@@ -277,6 +286,8 @@ QList<Key> &operator <<(QList<Key> &keys, const QKeySequence &sequence)
return keys;
}
+#endif // QT_CONFIG(shortcut)
+
template <int N> QList<Key> &operator <<(QList<Key> &keys, const char (&characters)[N])
{
for (int i = 0; i < N - 1; ++i) {
@@ -916,7 +927,7 @@ void tst_qquicktextedit::hAlignVisual()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimimal platforms", Abort);
+ QEXPECT_FAIL("", "Failure due to grabWindow not functional on offscreen/minimal platforms", Abort);
// Left Align
QImage image = view.grabWindow();
@@ -1378,7 +1389,7 @@ void tst_qquicktextedit::focusOnPress()
QCOMPARE(textEditObject->hasActiveFocus(), false);
QPoint centerPoint(window.width()/2, window.height()/2);
- Qt::KeyboardModifiers noModifiers = nullptr;
+ Qt::KeyboardModifiers noModifiers;
QTest::mousePress(&window, Qt::LeftButton, noModifiers, centerPoint);
QGuiApplication::processEvents();
QCOMPARE(textEditObject->hasFocus(), true);
@@ -2307,6 +2318,8 @@ void tst_qquicktextedit::selectByKeyboard()
QCOMPARE(spy.at(2).at(0).toBool(), false);
}
+#if QT_CONFIG(shortcut)
+
Q_DECLARE_METATYPE(QKeySequence::StandardKey)
void tst_qquicktextedit::keyboardSelection_data()
@@ -2391,6 +2404,8 @@ void tst_qquicktextedit::keyboardSelection()
QCOMPARE(edit->selectedText(), selectedText);
}
+#endif // QT_CONFIG(shortcut)
+
void tst_qquicktextedit::renderType()
{
QQmlComponent component(&engine);
@@ -4820,6 +4835,7 @@ void tst_qquicktextedit::remove()
QVERIFY(cursorPositionSpy.count() > 0);
}
+#if QT_CONFIG(shortcut)
void tst_qquicktextedit::keySequence_data()
{
@@ -4984,6 +5000,8 @@ void tst_qquicktextedit::keySequence()
QCOMPARE(textEdit->selectedText(), selectedText);
}
+#endif // QT_CONFIG(shortcut)
+
#define NORMAL 0
#define REPLACE_UNTIL_END 1
@@ -5257,6 +5275,8 @@ void tst_qquicktextedit::redo()
QCOMPARE(spy.count(), 2);
}
+#if QT_CONFIG(shortcut)
+
void tst_qquicktextedit::undo_keypressevents_data()
{
QTest::addColumn<KeyList>("keys");
@@ -5450,6 +5470,8 @@ void tst_qquicktextedit::undo_keypressevents()
QVERIFY(textEdit->text().isEmpty());
}
+#endif // QT_CONFIG(shortcut)
+
void tst_qquicktextedit::clear()
{
QString componentStr = "import QtQuick 2.0\nTextEdit { focus: true }";
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index 6f24ca8ded..2e64c80b85 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -146,7 +146,7 @@ private slots:
void cursorRectangle();
void navigation();
void navigation_RTL();
-#if QT_CONFIG(clipboard)
+#if QT_CONFIG(clipboard) && QT_CONFIG(shortcut)
void copyAndPaste();
void copyAndPasteKeySequence();
void canPasteEmpty();
@@ -181,15 +181,19 @@ private slots:
void remove_data();
void remove();
+#if QT_CONFIG(shortcut)
void keySequence_data();
void keySequence();
+#endif
void undo_data();
void undo();
void redo_data();
void redo();
+#if QT_CONFIG(shortcut)
void undo_keypressevents_data();
void undo_keypressevents();
+#endif
void clear();
void backspaceSurrogatePairs();
@@ -236,7 +240,9 @@ private:
void simulateKey(QWindow *, int key);
void simulateKeys(QWindow *window, const QList<Key> &keys);
+#if QT_CONFIG(shortcut)
void simulateKeys(QWindow *window, const QKeySequence &sequence);
+#endif
QQmlEngine engine;
QStringList standard;
@@ -264,6 +270,8 @@ void tst_qquicktextinput::simulateKeys(QWindow *window, const QList<Key> &keys)
}
}
+#if QT_CONFIG(shortcut)
+
void tst_qquicktextinput::simulateKeys(QWindow *window, const QKeySequence &sequence)
{
for (int i = 0; i < sequence.count(); ++i) {
@@ -281,6 +289,8 @@ QList<Key> &operator <<(QList<Key> &keys, const QKeySequence &sequence)
return keys;
}
+#endif // QT_CONFIG(shortcut)
+
template <int N> QList<Key> &operator <<(QList<Key> &keys, const char (&characters)[N])
{
for (int i = 0; i < N - 1; ++i) {
@@ -2063,11 +2073,15 @@ void tst_qquicktextinput::validators()
QTest::keyPress(&window, Qt::Key_Comma);
QTest::keyRelease(&window, Qt::Key_Comma, Qt::NoModifier);
QTRY_COMPARE(dblInput->text(), QLatin1String("12,"));
- QCOMPARE(dblInput->hasAcceptableInput(), true);
- QTest::keyPress(&window, Qt::Key_1);
- QTest::keyRelease(&window, Qt::Key_1, Qt::NoModifier);
- QTRY_COMPARE(dblInput->text(), QLatin1String("12,"));
- QCOMPARE(dblInput->hasAcceptableInput(), true);
+ int extraSignals = 2;
+ if (dblInput->hasAcceptableInput()) {
+ // TODO: old behavior of QDoubleValidator - remove when merged from qtbase
+ QTest::keyPress(&window, Qt::Key_1);
+ QTest::keyRelease(&window, Qt::Key_1, Qt::NoModifier);
+ QTRY_COMPARE(dblInput->text(), QLatin1String("12,"));
+ QCOMPARE(dblInput->hasAcceptableInput(), true);
+ extraSignals = 0;
+ }
dblValidator->setLocaleName(deLocale.name());
QCOMPARE(dblInput->hasAcceptableInput(), true);
QTest::keyPress(&window, Qt::Key_1);
@@ -2096,84 +2110,84 @@ void tst_qquicktextinput::validators()
QTRY_COMPARE(dblInput->text(), QLatin1String("12."));
QCOMPARE(dblInput->hasAcceptableInput(), true);
QCOMPARE(dblInput->property("acceptable").toBool(), true);
- QCOMPARE(dblSpy.count(), 1);
+ QCOMPARE(dblSpy.count(), 1 + extraSignals);
QTest::keyPress(&window, Qt::Key_1);
QTest::keyRelease(&window, Qt::Key_1, Qt::NoModifier);
QTRY_COMPARE(dblInput->text(), QLatin1String("12.1"));
QCOMPARE(dblInput->hasAcceptableInput(), true);
QCOMPARE(dblInput->property("acceptable").toBool(), true);
- QCOMPARE(dblSpy.count(), 1);
+ QCOMPARE(dblSpy.count(), 1 + extraSignals);
QTest::keyPress(&window, Qt::Key_1);
QTest::keyRelease(&window, Qt::Key_1, Qt::NoModifier);
QTRY_COMPARE(dblInput->text(), QLatin1String("12.11"));
QCOMPARE(dblInput->hasAcceptableInput(), true);
QCOMPARE(dblInput->property("acceptable").toBool(), true);
- QCOMPARE(dblSpy.count(), 1);
+ QCOMPARE(dblSpy.count(), 1 + extraSignals);
QTest::keyPress(&window, Qt::Key_1);
QTest::keyRelease(&window, Qt::Key_1, Qt::NoModifier);
QTRY_COMPARE(dblInput->text(), QLatin1String("12.11"));
QCOMPARE(dblInput->hasAcceptableInput(), true);
QCOMPARE(dblInput->property("acceptable").toBool(), true);
- QCOMPARE(dblSpy.count(), 1);
+ QCOMPARE(dblSpy.count(), 1 + extraSignals);
// Ensure the validator doesn't prevent characters being removed.
dblInput->setValidator(intInput->validator());
QCOMPARE(dblInput->text(), QLatin1String("12.11"));
QCOMPARE(dblInput->hasAcceptableInput(), false);
QCOMPARE(dblInput->property("acceptable").toBool(), false);
- QCOMPARE(dblSpy.count(), 2);
+ QCOMPARE(dblSpy.count(), 2 + extraSignals);
QTest::keyPress(&window, Qt::Key_Backspace);
QTest::keyRelease(&window, Qt::Key_Backspace, Qt::NoModifier);
QTRY_COMPARE(dblInput->text(), QLatin1String("12.1"));
QCOMPARE(dblInput->hasAcceptableInput(), false);
QCOMPARE(dblInput->property("acceptable").toBool(), false);
- QCOMPARE(dblSpy.count(), 2);
+ QCOMPARE(dblSpy.count(), 2 + extraSignals);
// Once unacceptable input is in anything goes until it reaches an acceptable state again.
QTest::keyPress(&window, Qt::Key_1);
QTest::keyRelease(&window, Qt::Key_1, Qt::NoModifier);
QTRY_COMPARE(dblInput->text(), QLatin1String("12.11"));
QCOMPARE(dblInput->hasAcceptableInput(), false);
- QCOMPARE(dblSpy.count(), 2);
+ QCOMPARE(dblSpy.count(), 2 + extraSignals);
QTest::keyPress(&window, Qt::Key_Backspace);
QTest::keyRelease(&window, Qt::Key_Backspace, Qt::NoModifier);
QTRY_COMPARE(dblInput->text(), QLatin1String("12.1"));
QCOMPARE(dblInput->hasAcceptableInput(), false);
QCOMPARE(dblInput->property("acceptable").toBool(), false);
- QCOMPARE(dblSpy.count(), 2);
+ QCOMPARE(dblSpy.count(), 2 + extraSignals);
QTest::keyPress(&window, Qt::Key_Backspace);
QTest::keyRelease(&window, Qt::Key_Backspace, Qt::NoModifier);
QTRY_COMPARE(dblInput->text(), QLatin1String("12."));
QCOMPARE(dblInput->hasAcceptableInput(), false);
QCOMPARE(dblInput->property("acceptable").toBool(), false);
- QCOMPARE(dblSpy.count(), 2);
+ QCOMPARE(dblSpy.count(), 2 + extraSignals);
QTest::keyPress(&window, Qt::Key_Backspace);
QTest::keyRelease(&window, Qt::Key_Backspace, Qt::NoModifier);
QTRY_COMPARE(dblInput->text(), QLatin1String("12"));
QCOMPARE(dblInput->hasAcceptableInput(), false);
QCOMPARE(dblInput->property("acceptable").toBool(), false);
- QCOMPARE(dblSpy.count(), 2);
+ QCOMPARE(dblSpy.count(), 2 + extraSignals);
QTest::keyPress(&window, Qt::Key_Backspace);
QTest::keyRelease(&window, Qt::Key_Backspace, Qt::NoModifier);
QTRY_COMPARE(dblInput->text(), QLatin1String("1"));
QCOMPARE(dblInput->hasAcceptableInput(), false);
QCOMPARE(dblInput->property("acceptable").toBool(), false);
- QCOMPARE(dblSpy.count(), 2);
+ QCOMPARE(dblSpy.count(), 2 + extraSignals);
QTest::keyPress(&window, Qt::Key_1);
QTest::keyRelease(&window, Qt::Key_1, Qt::NoModifier);
QCOMPARE(dblInput->text(), QLatin1String("11"));
QCOMPARE(dblInput->property("acceptable").toBool(), true);
QCOMPARE(dblInput->hasAcceptableInput(), true);
- QCOMPARE(dblSpy.count(), 3);
+ QCOMPARE(dblSpy.count(), 3 + extraSignals);
// Changing the validator properties will re-evaluate whether the input is acceptable.
intValidator->setTop(10);
QCOMPARE(dblInput->property("acceptable").toBool(), false);
QCOMPARE(dblInput->hasAcceptableInput(), false);
- QCOMPARE(dblSpy.count(), 4);
+ QCOMPARE(dblSpy.count(), 4 + extraSignals);
intValidator->setTop(12);
QCOMPARE(dblInput->property("acceptable").toBool(), true);
QCOMPARE(dblInput->hasAcceptableInput(), true);
- QCOMPARE(dblSpy.count(), 5);
+ QCOMPARE(dblSpy.count(), 5 + extraSignals);
QQuickTextInput *strInput = qobject_cast<QQuickTextInput *>(qvariant_cast<QObject *>(window.rootObject()->property("strInput")));
QVERIFY(strInput);
@@ -2586,7 +2600,7 @@ void tst_qquicktextinput::navigation_RTL()
QVERIFY(input->hasActiveFocus());
}
-#if QT_CONFIG(clipboard)
+#if QT_CONFIG(clipboard) && QT_CONFIG(shortcut)
void tst_qquicktextinput::copyAndPaste()
{
if (!PlatformQuirks::isClipboardAvailable())
@@ -2684,7 +2698,7 @@ void tst_qquicktextinput::copyAndPaste()
}
#endif
-#if QT_CONFIG(clipboard)
+#if QT_CONFIG(clipboard) && QT_CONFIG(shortcut)
void tst_qquicktextinput::copyAndPasteKeySequence()
{
if (!PlatformQuirks::isClipboardAvailable())
@@ -2752,7 +2766,7 @@ void tst_qquicktextinput::copyAndPasteKeySequence()
}
#endif
-#if QT_CONFIG(clipboard)
+#if QT_CONFIG(clipboard) && QT_CONFIG(shortcut)
void tst_qquicktextinput::canPasteEmpty()
{
QGuiApplication::clipboard()->clear();
@@ -2768,7 +2782,7 @@ void tst_qquicktextinput::canPasteEmpty()
}
#endif
-#if QT_CONFIG(clipboard)
+#if QT_CONFIG(clipboard) && QT_CONFIG(shortcut)
void tst_qquicktextinput::canPaste()
{
QGuiApplication::clipboard()->setText("Some text");
@@ -2784,7 +2798,7 @@ void tst_qquicktextinput::canPaste()
}
#endif
-#if QT_CONFIG(clipboard)
+#if QT_CONFIG(clipboard) && QT_CONFIG(shortcut)
void tst_qquicktextinput::middleClickPaste()
{
if (!PlatformQuirks::isClipboardAvailable())
@@ -5098,6 +5112,7 @@ void tst_qquicktextinput::remove()
QVERIFY(cursorPositionSpy.count() > 0);
}
+#if QT_CONFIG(shortcut)
void tst_qquicktextinput::keySequence_data()
{
QTest::addColumn<QString>("text");
@@ -5283,6 +5298,8 @@ void tst_qquicktextinput::keySequence()
QCOMPARE(textInput->selectedText(), selectedText);
}
+#endif // QT_CONFIG(shortcut)
+
#define NORMAL 0
#define REPLACE_UNTIL_END 1
@@ -5556,6 +5573,8 @@ void tst_qquicktextinput::redo()
QCOMPARE(spy.count(), 2);
}
+#if QT_CONFIG(shortcut)
+
void tst_qquicktextinput::undo_keypressevents_data()
{
QTest::addColumn<KeyList>("keys");
@@ -5860,6 +5879,8 @@ void tst_qquicktextinput::undo_keypressevents()
QVERIFY(textInput->text().isEmpty());
}
+#endif // QT_CONFIG(shortcut)
+
void tst_qquicktextinput::clear()
{
QString componentStr = "import QtQuick 2.0\nTextInput { focus: true }";
@@ -6391,8 +6412,20 @@ void tst_qquicktextinput::setInputMask_data()
QTest::newRow(QString(insert_mode + "blank=input").toLatin1())
<< QString("9999;0")
<< QString("2004")
+ << QString("24")
<< QString("2004")
- << QString("2004")
+ << bool(insert_text);
+ QTest::newRow(QString(insert_mode + "any_opt").toLatin1())
+ << QString("@xxx@")
+ << QString("@A C@")
+ << QString("@AC@")
+ << QString("@A C@")
+ << bool(insert_text);
+ QTest::newRow(QString(insert_mode + "any_req").toLatin1())
+ << QString("@XXX@")
+ << QString("@A C@")
+ << QString("@AC@@")
+ << QString("@AC@@")
<< bool(insert_text);
}
}
@@ -6435,9 +6468,6 @@ void tst_qquicktextinput::setInputMask()
QTest::keyClick(&window, input.at(i).toLatin1());
}
- QEXPECT_FAIL( "keys blank=input", "To eat blanks or not? Known issue. Task 43172", Abort);
- QEXPECT_FAIL( "insert blank=input", "To eat blanks or not? Known issue. Task 43172", Abort);
-
QCOMPARE(textInput->text(), expectedText);
QCOMPARE(textInput->displayText(), expectedDisplay);
}
diff --git a/tests/auto/quick/qquickvisualdatamodel/data/readFromProxyObject.qml b/tests/auto/quick/qquickvisualdatamodel/data/readFromProxyObject.qml
new file mode 100644
index 0000000000..3983c707a1
--- /dev/null
+++ b/tests/auto/quick/qquickvisualdatamodel/data/readFromProxyObject.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.15
+import QtQuick.Window 2.15
+
+Window {
+ id: window
+ width: 200
+ height: 200
+ color: "red"
+ visible: true
+ Repeater {
+ model: Qt.application.screens
+ Text {
+ required property string name
+ required property int virtualX
+ required property int virtualY
+
+ text: name + virtualX + ", " + virtualY
+ Component.onCompleted: window.name = name
+ }
+ }
+
+ property string name: "wrong"
+}
diff --git a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
index c5a3bceee0..66069c48cb 100644
--- a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
+++ b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
@@ -434,6 +434,7 @@ private slots:
void externalManagedModel();
void delegateModelChangeDelegate();
void checkFilterGroupForDelegate();
+ void readFromProxyObject();
private:
template <int N> void groups_verify(
@@ -4356,6 +4357,21 @@ void tst_qquickvisualdatamodel::checkFilterGroupForDelegate()
QVERIFY(obj->property("ok").toBool());
}
+void tst_qquickvisualdatamodel::readFromProxyObject()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine, testFileUrl("readFromProxyObject.qml"));
+
+ QScopedPointer<QObject> obj(component.create());
+ QVERIFY(obj);
+
+ auto *window = qobject_cast<QQuickWindow *>(obj.get());
+ QVERIFY(window);
+
+ QCOMPARE(window->property("name").type(), QMetaType::QString);
+ QTRY_VERIFY(window->property("name").toString() != QLatin1String("wrong"));
+}
+
QTEST_MAIN(tst_qquickvisualdatamodel)
#include "tst_qquickvisualdatamodel.moc"
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index 7faa621e86..22b04eabd8 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -73,7 +73,7 @@ static QTouchEvent::TouchPoint makeTouchPoint(QQuickItem *item, const QPointF &p
return tp;
}
-static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states = nullptr,
+static TouchEventData makeTouchData(QEvent::Type type, QWindow *w, Qt::TouchPointStates states = {},
const QList<QTouchEvent::TouchPoint>& touchPoints = QList<QTouchEvent::TouchPoint>())
{
TouchEventData d = { type, nullptr, w, states, touchPoints };
@@ -157,7 +157,7 @@ public:
setEnabled(true);
setVisible(true);
- lastEvent = makeTouchData(QEvent::None, window(), nullptr, QList<QTouchEvent::TouchPoint>());//CHECK_VALID
+ lastEvent = makeTouchData(QEvent::None, window(), {}, QList<QTouchEvent::TouchPoint>());//CHECK_VALID
lastVelocity = lastVelocityFromMouseMove = QVector2D();
lastMousePos = QPointF();
@@ -1481,7 +1481,7 @@ void tst_qquickwindow::grab()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QFETCH(bool, visible);
QFETCH(bool, alpha);
@@ -1797,22 +1797,26 @@ void tst_qquickwindow::cursor()
window.resize(320, 290);
QQuickItem parentItem;
+ parentItem.setObjectName("parentItem");
parentItem.setPosition(QPointF(0, 0));
parentItem.setSize(QSizeF(180, 180));
parentItem.setParentItem(window.contentItem());
QQuickItem childItem;
+ childItem.setObjectName("childItem");
childItem.setPosition(QPointF(60, 90));
childItem.setSize(QSizeF(120, 120));
childItem.setParentItem(&parentItem);
QQuickItem clippingItem;
+ clippingItem.setObjectName("clippingItem");
clippingItem.setPosition(QPointF(120, 120));
clippingItem.setSize(QSizeF(180, 180));
clippingItem.setClip(true);
clippingItem.setParentItem(window.contentItem());
QQuickItem clippedItem;
+ clippedItem.setObjectName("clippedItem");
clippedItem.setPosition(QPointF(-30, -30));
clippedItem.setSize(QSizeF(120, 120));
clippedItem.setParentItem(&clippingItem);
@@ -2082,7 +2086,7 @@ void tst_qquickwindow::requestActivate()
QString warning = QString::fromLatin1("Mouse event MousePress not accepted by receiving window");
QWARN(warning.toLatin1().data());
}
- me = QMouseEvent(QEvent::MouseButtonPress, pos, window1->mapToGlobal(pos), Qt::LeftButton, nullptr, Qt::NoModifier);
+ me = QMouseEvent(QEvent::MouseButtonPress, pos, window1->mapToGlobal(pos), Qt::LeftButton, {}, Qt::NoModifier);
QSpontaneKeyEvent::setSpontaneous(&me);
if (!qApp->notify(window1.data(), &me)) {
QString warning = QString::fromLatin1("Mouse event MouseRelease not accepted by receiving window");
@@ -2535,7 +2539,7 @@ void tst_qquickwindow::testRenderJob()
QTRY_COMPARE(RenderJob::deleted, 1);
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QEXPECT_FAIL("", "NoStage job fails on offscreen/minimimal platforms", Continue);
+ QEXPECT_FAIL("", "NoStage job fails on offscreen/minimal platforms", Continue);
QCOMPARE(completedJobs.size(), 1);
#if QT_CONFIG(opengl)
@@ -2856,7 +2860,7 @@ void tst_qquickwindow::pointerEventTypeAndPointCount()
QList<QTouchEvent::TouchPoint>() << QTouchEvent::TouchPoint(1));
- QQuickPointerMouseEvent pme;
+ QQuickPointerMouseEvent pme(nullptr, QQuickPointerDevice::genericMouseDevice());
pme.reset(&me);
QCOMPARE(pme.asMouseEvent(localPosition), &me);
QVERIFY(pme.asPointerMouseEvent());
@@ -2868,7 +2872,7 @@ void tst_qquickwindow::pointerEventTypeAndPointCount()
QCOMPARE(pme.asMouseEvent(localPosition)->localPos(), localPosition);
QCOMPARE(pme.asMouseEvent(localPosition)->screenPos(), screenPosition);
- QQuickPointerTouchEvent pte;
+ QQuickPointerTouchEvent pte(nullptr, QQuickPointerDevice::touchDevice(touchDevice));
pte.reset(&te);
QCOMPARE(pte.asTouchEvent(), &te);
QVERIFY(!pte.asPointerMouseEvent());
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index b6ffdc0f7e..0db8abd951 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -15,7 +15,8 @@ qtConfig(opengl(es1|es2)?) {
qquickframebufferobject \
qquickopenglinfo \
qquickspritesequence \
- qquickshadereffect
+ qquickshadereffect \
+ qquickrendercontrol
}
!cross_compile: PRIVATETESTS += examples
@@ -96,6 +97,8 @@ boot2qt: QUICKTESTS -= qquickgridview qquicklistview qquicktableview qquickposit
!qtConfig(accessibility):QUICKTESTS -= qquickaccessible
+!qtConfig(shortcut):QUICKTESTS -= qquickshortcut
+
qtConfig(private_tests) {
SUBDIRS += $$PRIVATETESTS
SUBDIRS += $$QUICKTESTS
diff --git a/tests/auto/quick/rendernode/tst_rendernode.cpp b/tests/auto/quick/rendernode/tst_rendernode.cpp
index 6ca5231343..ec248e8210 100644
--- a/tests/auto/quick/rendernode/tst_rendernode.cpp
+++ b/tests/auto/quick/rendernode/tst_rendernode.cpp
@@ -218,7 +218,7 @@ void tst_rendernode::renderOrder()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
if (isRunningOnRhi())
QSKIP("Render nodes not yet supported with QRhi");
@@ -251,7 +251,7 @@ void tst_rendernode::messUpState()
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
if (isRunningOnRhi())
QSKIP("Render nodes not yet supported with QRhi");
@@ -312,7 +312,7 @@ void tst_rendernode::matrix()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
if (isRunningOnRhi())
QSKIP("Render nodes not yet supported with QRhi");
diff --git a/tests/auto/quick/scenegraph/tst_scenegraph.cpp b/tests/auto/quick/scenegraph/tst_scenegraph.cpp
index 3f605348c3..12f7efb7d5 100644
--- a/tests/auto/quick/scenegraph/tst_scenegraph.cpp
+++ b/tests/auto/quick/scenegraph/tst_scenegraph.cpp
@@ -241,7 +241,7 @@ void tst_SceneGraph::manyWindows()
{
if ((QGuiApplication::platformName() == QLatin1String("offscreen"))
|| (QGuiApplication::platformName() == QLatin1String("minimal")))
- QSKIP("Skipping due to grabWindow not functional on offscreen/minimimal platforms");
+ QSKIP("Skipping due to grabWindow not functional on offscreen/minimal platforms");
QFETCH(QString, file);
QFETCH(bool, toplevel);
diff --git a/tests/auto/quick/shared/viewtestutil.cpp b/tests/auto/quick/shared/viewtestutil.cpp
index 1680e850f7..67b73f047c 100644
--- a/tests/auto/quick/shared/viewtestutil.cpp
+++ b/tests/auto/quick/shared/viewtestutil.cpp
@@ -73,13 +73,13 @@ void QQuickViewTestUtil::moveMouseAway(QQuickView *window)
void QQuickViewTestUtil::moveAndRelease(QQuickView *window, const QPoint &position)
{
QTest::mouseMove(window, position);
- QTest::mouseRelease(window, Qt::LeftButton, 0, position);
+ QTest::mouseRelease(window, Qt::LeftButton, {}, position);
}
void QQuickViewTestUtil::moveAndPress(QQuickView *window, const QPoint &position)
{
QTest::mouseMove(window, position);
- QTest::mousePress(window, Qt::LeftButton, 0, position);
+ QTest::mousePress(window, Qt::LeftButton, {}, position);
}
void QQuickViewTestUtil::flick(QQuickView *window, const QPoint &from, const QPoint &to, int duration)
@@ -282,14 +282,28 @@ void QQuickViewTestUtil::QaimModel::resetItems(const QList<QPair<QString, QStrin
endResetModel();
}
+class ScopedPrintable
+{
+ Q_DISABLE_COPY_MOVE(ScopedPrintable)
+
+public:
+ ScopedPrintable(const QString &string) : data(QTest::toString(string)) {}
+ ~ScopedPrintable() { delete[] data; }
+
+ operator const char*() const { return data; }
+
+private:
+ const char *data;
+};
+
void QQuickViewTestUtil::QaimModel::matchAgainst(const QList<QPair<QString, QString> > &other, const QString &error1, const QString &error2) {
for (int i=0; i<other.count(); i++) {
QVERIFY2(list.contains(other[i]),
- QTest::toString(other[i].first + QLatin1Char(' ') + other[i].second + QLatin1Char(' ') + error1));
+ ScopedPrintable(other[i].first + QLatin1Char(' ') + other[i].second + QLatin1Char(' ') + error1));
}
for (int i=0; i<list.count(); i++) {
QVERIFY2(other.contains(list[i]),
- QTest::toString(list[i].first + QLatin1Char(' ') + list[i].second + QLatin1Char(' ') + error2));
+ ScopedPrintable(list[i].first + QLatin1Char(' ') + list[i].second + QLatin1Char(' ') + error2));
}
}