aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quick')
-rw-r--r--tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp10
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_context.qml16
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_image.qml11
-rw-r--r--tests/auto/quick/qquickgridview/tst_qquickgridview.cpp37
-rw-r--r--tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp28
-rw-r--r--tests/auto/quick/qquickitem2/data/activeFocusOnTab6.qml144
-rw-r--r--tests/auto/quick/qquickitem2/data/activeFocusOnTab7.qml36
-rw-r--r--tests/auto/quick/qquickitem2/data/activeFocusOnTab8.qml36
-rw-r--r--tests/auto/quick/qquickitem2/data/resourcesProperty.qml23
-rw-r--r--tests/auto/quick/qquickitem2/tst_qquickitem.cpp330
-rw-r--r--tests/auto/quick/qquicklistview/data/delayedChanges.qml39
-rw-r--r--tests/auto/quick/qquicklistview/data/emptymodel.qml4
-rw-r--r--tests/auto/quick/qquicklistview/tst_qquicklistview.cpp106
-rw-r--r--tests/auto/quick/qquickmousearea/data/hoverAfterPress.qml29
-rw-r--r--tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp30
-rw-r--r--tests/auto/quick/qquickrepeater/data/visualitemmodel.qml23
-rw-r--r--tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp12
-rw-r--r--tests/auto/quick/qquicktext/data/elideBeforeMaximumLineCount.qml10
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp182
-rw-r--r--tests/auto/quick/qquicktextedit/data/linkInteraction.qml (renamed from tests/auto/quick/qquicktextedit/data/linkActivated.qml)0
-rw-r--r--tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp179
-rw-r--r--tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp13
-rw-r--r--tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp7
-rw-r--r--tests/auto/quick/qquickwindow/data/active.qml29
-rw-r--r--tests/auto/quick/qquickwindow/data/ucantclosethis.qml32
-rw-r--r--tests/auto/quick/qquickwindow/qquickwindow.pro1
-rw-r--r--tests/auto/quick/qquickwindow/tst_qquickwindow.cpp91
-rw-r--r--tests/auto/quick/touchmouse/tst_touchmouse.cpp20
28 files changed, 1359 insertions, 119 deletions
diff --git a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
index 201287b2a8..0377eaa71d 100644
--- a/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
+++ b/tests/auto/quick/qquickanimatedimage/tst_qquickanimatedimage.cpp
@@ -201,26 +201,28 @@ void tst_qquickanimatedimage::mirror_notRunning()
QFETCH(QUrl, fileUrl);
QQuickView window;
+ window.setSource(fileUrl);
window.show();
+ QTRY_VERIFY(window.isExposed());
- window.setSource(fileUrl);
QQuickAnimatedImage *anim = qobject_cast<QQuickAnimatedImage *>(window.rootObject());
QVERIFY(anim);
int width = anim->property("width").toInt();
- QPixmap screenshot = QPixmap::fromImage(window.grabWindow());
+ QImage screenshot = window.grabWindow();
QTransform transform;
transform.translate(width, 0).scale(-1, 1.0);
- QPixmap expected = screenshot.transformed(transform);
+ QImage expected = screenshot.transformed(transform);
int frame = anim->currentFrame();
bool playing = anim->isPlaying();
bool paused = anim->isPlaying();
anim->setProperty("mirror", true);
- screenshot = QPixmap::fromImage(window.grabWindow());
+ screenshot = window.grabWindow();
+ screenshot.save("screen.png");
QCOMPARE(screenshot, expected);
// mirroring should not change the current frame or playing status
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_context.qml b/tests/auto/quick/qquickcanvasitem/data/tst_context.qml
index b72e755ed9..ad44f6d28e 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_context.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_context.qml
@@ -70,4 +70,20 @@ Canvas {
compare(canvas.contextInPaint, canvas.getContext("2d"));
}
}
+
+ TestCase {
+ name: "ContextFontValidation"
+ when: canvas.available
+
+ function test_pixelSize() {
+ wait(100);
+ compare(contextSpy.count, 1);
+
+ var ctx = canvas.getContext("2d");
+ compare(ctx.font, "sans-serif,-1,10,5,50,0,0,0,0,0");
+
+ ctx.font = "80.1px sans-serif";
+ compare(ctx.font, "sans-serif,-1,80,5,50,0,0,0,0,0");
+ }
+ }
}
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml
index 72b6dcdb00..ca95f2aec1 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_image.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_image.qml
@@ -216,6 +216,17 @@ CanvasTestCase {
}
+ property url green: 'green.png'
+
+ function test_url(row) {
+ var canvas = createCanvasObject(row);
+ var ctx = canvas.getContext('2d');
+
+ canvas.loadImage(testCase.green);
+ ctx.drawImage(testCase.green, 0, 0);
+ comparePixel(ctx, 0,0, 0,255,0,255,2);
+ }
+
function test_composite(row) {
var canvas = createCanvasObject(row);
var ctx = canvas.getContext('2d');
diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
index 0c9788ab8e..d0ffba9435 100644
--- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
+++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp
@@ -532,6 +532,7 @@ void tst_QQuickGridView::inserted_defaultLayout(QQuickGridView::Flow flow,
for (int i=0; i<insertCount; i++)
newData << qMakePair(QString("value %1").arg(i), QString::number(i));
model.insertItems(insertIndex, newData);
+ gridview->forceLayout();
QTRY_COMPARE(gridview->property("count").toInt(), model.count());
// check visibleItems.first() is in correct position
@@ -728,6 +729,7 @@ void tst_QQuickGridView::insertBeforeVisible()
for (int i=0; i<insertCount; i++)
newData << qMakePair(QString("value %1").arg(i), QString::number(i));
model.insertItems(insertIndex, newData);
+ gridview->forceLayout();
QTRY_COMPARE(gridview->property("count").toInt(), model.count());
// now, moving to the top of the view should position the inserted items correctly
@@ -958,6 +960,7 @@ void tst_QQuickGridView::removed_defaultLayout(QQuickGridView::Flow flow,
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
model.removeItems(removeIndex, removeCount);
+ gridview->forceLayout();
QTRY_COMPARE(gridview->property("count").toInt(), model.count());
QString firstName;
@@ -1245,6 +1248,7 @@ void tst_QQuickGridView::clear()
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
model.clear();
+ gridview->forceLayout();
QVERIFY(gridview->count() == 0);
QVERIFY(gridview->currentItem() == 0);
@@ -1254,6 +1258,7 @@ void tst_QQuickGridView::clear()
// confirm sanity when adding an item to cleared list
model.addItem("New", "1");
+ gridview->forceLayout();
QTRY_COMPARE(gridview->count(), 1);
QVERIFY(gridview->currentItem() != 0);
QVERIFY(gridview->currentIndex() == 0);
@@ -3483,6 +3488,7 @@ void tst_QQuickGridView::extents()
QCOMPARE(gridview->originY(), origin_empty.y());
for (int i=0; i<30; i++)
model.addItem("Item" + QString::number(i), "");
+ gridview->forceLayout();
QTRY_COMPARE(gridview->count(), model.count());
QCOMPARE(gridview->originX(), origin_nonEmpty.x());
QCOMPARE(gridview->originY(), origin_nonEmpty.y());
@@ -3942,9 +3948,9 @@ void tst_QQuickGridView::onAdd()
ctxt->setContextProperty("delegateHeight", delegateHeight);
window->setSource(testFileUrl("attachedSignals.qml"));
- QObject *object = window->rootObject();
- object->setProperty("width", window->width());
- object->setProperty("height", window->height());
+ QQuickGridView *gridview = qobject_cast<QQuickGridView*>(window->rootObject());
+ gridview->setProperty("width", window->width());
+ gridview->setProperty("height", window->height());
qApp->processEvents();
QList<QPair<QString, QString> > items;
@@ -3952,10 +3958,11 @@ void tst_QQuickGridView::onAdd()
items << qMakePair(QString("value %1").arg(i), QString::number(i));
model.addItems(items);
- QTRY_COMPARE(model.count(), qobject_cast<QQuickGridView*>(window->rootObject())->count());
+ gridview->forceLayout();
+ QTRY_COMPARE(model.count(), gridview->count());
qApp->processEvents();
- QVariantList result = object->property("addedDelegates").toList();
+ QVariantList result = gridview->property("addedDelegates").toList();
QTRY_COMPARE(result.count(), items.count());
for (int i=0; i<items.count(); i++)
QCOMPARE(result[i].toString(), items[i].first);
@@ -3999,11 +4006,12 @@ void tst_QQuickGridView::onRemove()
ctxt->setContextProperty("delegateWidth", delegateWidth);
ctxt->setContextProperty("delegateHeight", delegateHeight);
window->setSource(testFileUrl("attachedSignals.qml"));
- QObject *object = window->rootObject();
+ QQuickGridView *gridview = qobject_cast<QQuickGridView*>(window->rootObject());
model.removeItems(indexToRemove, removeCount);
- QTRY_COMPARE(model.count(), qobject_cast<QQuickGridView*>(window->rootObject())->count());
- QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount));
+ gridview->forceLayout();
+ QTRY_COMPARE(model.count(), gridview->count());
+ QCOMPARE(gridview->property("removedDelegateCount"), QVariant(removeCount));
releaseView(window);
}
@@ -4151,6 +4159,7 @@ void tst_QQuickGridView::margins()
gridview->setContentX(-400);
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
model.removeItems(0, 4);
+ gridview->forceLayout();
QTRY_COMPARE(model.count(), gridview->count());
gridview->setContentX(-240+50);
gridview->returnToBounds();
@@ -4458,6 +4467,7 @@ void tst_QQuickGridView::unaligned()
// removing
model.removeItems(7, 10);
+ gridview->forceLayout();
QTRY_COMPARE(model.count(), gridview->count());
for (int i = 0; i < 18; ++i) {
QQuickItem *item = 0;
@@ -4663,6 +4673,7 @@ void tst_QQuickGridView::addTransitions()
// start animation
if (!newData.isEmpty()) {
model.insertItems(insertionIndex, newData);
+ gridview->forceLayout();
QTRY_COMPARE(model.count(), gridview->count());
}
@@ -4866,6 +4877,7 @@ void tst_QQuickGridView::moveTransitions()
// start animation
model.moveItems(moveFrom, moveTo, moveCount);
+ gridview->forceLayout();
QTRY_COMPARE(gridview->property("targetTransitionsDone").toInt(), expectedTargetData.count());
QTRY_COMPARE(gridview->property("displaceTransitionsDone").toInt(),
@@ -5114,6 +5126,7 @@ void tst_QQuickGridView::removeTransitions()
// start animation
model.removeItems(removalIndex, removalCount);
+ gridview->forceLayout();
QTRY_COMPARE(model.count(), gridview->count());
if (shouldAnimateTargets || expectedDisplacedIndexes.isValid()) {
@@ -5327,6 +5340,7 @@ void tst_QQuickGridView::displacedTransitions()
case ListChange::Polish:
break;
}
+ gridview->forceLayout();
QVariantList resultTargetIndexes = gridview->property("displacedTargetIndexes").toList();
QVariantList resultTargetItems = gridview->property("displacedTargetItems").toList();
@@ -5534,6 +5548,7 @@ void tst_QQuickGridView::multipleTransitions()
for (int j=changes[i].index; j<changes[i].index + changes[i].count; ++j)
targetItems << qMakePair(QString("new item %1").arg(j), QString::number(j));
model.insertItems(changes[i].index, targetItems);
+ gridview->forceLayout();
QTRY_COMPARE(model.count(), gridview->count());
if (i == changes.count() - 1) {
QTRY_VERIFY(!gridview->property("runningAddTargets").toBool());
@@ -5545,6 +5560,7 @@ void tst_QQuickGridView::multipleTransitions()
}
case ListChange::Removed:
model.removeItems(changes[i].index, changes[i].count);
+ gridview->forceLayout();
QTRY_COMPARE(model.count(), gridview->count());
if (i == changes.count() - 1) {
QTRY_VERIFY(!gridview->property("runningRemoveTargets").toBool());
@@ -5555,6 +5571,7 @@ void tst_QQuickGridView::multipleTransitions()
break;
case ListChange::Moved:
model.moveItems(changes[i].index, changes[i].to, changes[i].count);
+ gridview->forceLayout();
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
if (i == changes.count() - 1) {
QTRY_VERIFY(!gridview->property("runningMoveTargets").toBool());
@@ -5566,16 +5583,17 @@ void tst_QQuickGridView::multipleTransitions()
case ListChange::SetCurrent:
gridview->setCurrentIndex(changes[i].index);
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
+ gridview->forceLayout();
break;
case ListChange::SetContentY:
gridview->setContentY(changes[i].pos);
QTRY_COMPARE(QQuickItemPrivate::get(gridview)->polishScheduled, false);
+ gridview->forceLayout();
break;
case ListChange::Polish:
break;
}
}
- QCOMPARE(gridview->count(), model.count());
QList<QQuickItem*> items = findItems<QQuickItem>(contentItem, "wrapper");
int firstVisibleIndex = -1;
@@ -5586,6 +5604,7 @@ void tst_QQuickGridView::multipleTransitions()
break;
}
}
+ QTRY_COMPARE(gridview->count(), model.count());
QVERIFY2(firstVisibleIndex >= 0, QTest::toString(firstVisibleIndex));
// verify all items moved to the correct final positions
diff --git a/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp b/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp
index a790c7b9de..3eea3c955c 100644
--- a/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp
+++ b/tests/auto/quick/qquickimageprovider/tst_qquickimageprovider.cpp
@@ -71,6 +71,9 @@ private slots:
void removeProvider_data();
void removeProvider();
+ void imageProviderId_data();
+ void imageProviderId();
+
void threadTest();
private:
@@ -372,6 +375,31 @@ void tst_qquickimageprovider::removeProvider()
delete obj;
}
+void tst_qquickimageprovider::imageProviderId_data()
+{
+ QTest::addColumn<QString>("providerId");
+
+ QTest::newRow("lowercase") << QStringLiteral("imageprovider");
+ QTest::newRow("CamelCase") << QStringLiteral("ImageProvider");
+ QTest::newRow("UPPERCASE") << QStringLiteral("IMAGEPROVIDER");
+}
+
+void tst_qquickimageprovider::imageProviderId()
+{
+ QFETCH(QString, providerId);
+
+ QQmlEngine engine;
+
+ bool deleteWatch = false;
+ TestQImageProvider *provider = new TestQImageProvider(&deleteWatch);
+
+ engine.addImageProvider(providerId, provider);
+ QVERIFY(engine.imageProvider(providerId) != 0);
+
+ engine.removeImageProvider(providerId);
+ QVERIFY(deleteWatch);
+}
+
class TestThreadProvider : public QQuickImageProvider
{
public:
diff --git a/tests/auto/quick/qquickitem2/data/activeFocusOnTab6.qml b/tests/auto/quick/qquickitem2/data/activeFocusOnTab6.qml
new file mode 100644
index 0000000000..22b4d249f0
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/activeFocusOnTab6.qml
@@ -0,0 +1,144 @@
+import QtQuick 2.1
+
+Item {
+ id: main
+ objectName: "main"
+ width: 800
+ height: 600
+ focus: true
+ Component.onCompleted: button12.focus = true
+ Item {
+ id: sub1
+ objectName: "sub1"
+ width: 230
+ height: 600
+ anchors.top: parent.top
+ anchors.left: parent.left
+ Item {
+ id: button11
+ objectName: "button11"
+ width: 100
+ height: 50
+ activeFocusOnTab: true
+ Accessible.role: Accessible.Table
+ Rectangle {
+ anchors.fill: parent
+ color: parent.activeFocus ? "red" : "black"
+ }
+
+ anchors.top: parent.top
+ anchors.topMargin: 100
+ }
+ Item {
+ id: button12
+ objectName: "button12"
+ activeFocusOnTab: true
+ Accessible.role: Accessible.List
+ Rectangle {
+ anchors.fill: parent
+ color: parent.activeFocus ? "red" : "black"
+ }
+ width: 100
+ height: 50
+
+ anchors.top: button11.bottom
+ anchors.bottomMargin: 100
+ }
+ Item {
+ id: button13
+ objectName: "button13"
+ enabled: false
+ activeFocusOnTab: true
+ Accessible.role: Accessible.Table
+ Rectangle {
+ anchors.fill: parent
+ color: parent.activeFocus ? "red" : "black"
+ }
+ width: 100
+ height: 50
+
+ anchors.top: button12.bottom
+ anchors.bottomMargin: 100
+ }
+ Item {
+ id: button14
+ objectName: "button14"
+ visible: false
+ activeFocusOnTab: true
+ Accessible.role: Accessible.List
+ Rectangle {
+ anchors.fill: parent
+ color: parent.activeFocus ? "red" : "black"
+ }
+ width: 100
+ height: 50
+
+ anchors.top: button12.bottom
+ anchors.bottomMargin: 100
+ }
+ }
+ Item {
+ id: sub2
+ objectName: "sub2"
+ activeFocusOnTab: true
+ Accessible.role: Accessible.Row
+ width: 230
+ height: 600
+ anchors.top: parent.top
+ anchors.left: sub1.right
+ Item {
+ id: button21
+ objectName: "button21"
+ width: 100
+ height: 50
+ activeFocusOnTab: true
+ Accessible.role: Accessible.PushButton
+ Rectangle {
+ anchors.fill: parent
+ color: parent.activeFocus ? "red" : "black"
+ }
+
+ anchors.top: parent.top
+ anchors.topMargin: 100
+ }
+ Item {
+ id: button22
+ objectName: "button22"
+ width: 100
+ height: 50
+ activeFocusOnTab: true
+ Accessible.role: Accessible.RadioButton
+ Rectangle {
+ anchors.fill: parent
+ color: parent.activeFocus ? "red" : "black"
+ }
+
+ anchors.top: button21.bottom
+ anchors.bottomMargin: 100
+ }
+ }
+ Item {
+ id: sub3
+ objectName: "sub3"
+ width: 230
+ height: 600
+ anchors.top: parent.top
+ anchors.left: sub2.right
+ TextEdit {
+ id: edit
+ objectName: "edit"
+ width: 230
+ height: 400
+ readOnly: false
+ activeFocusOnTab: true
+ Accessible.role: Accessible.EditableText
+ wrapMode: TextEdit.Wrap
+ textFormat: TextEdit.RichText
+
+ text: "aaa\n"
+ +"bbb\n"
+ +"ccc\n"
+ +"ddd\n"
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/data/activeFocusOnTab7.qml b/tests/auto/quick/qquickitem2/data/activeFocusOnTab7.qml
new file mode 100644
index 0000000000..e81d9be950
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/activeFocusOnTab7.qml
@@ -0,0 +1,36 @@
+import QtQuick 2.1
+
+Item {
+ id: main
+ objectName: "main"
+ width: 300
+ height: 300
+ Item {
+ id: button1
+ objectName: "button1"
+ width: 300
+ height: 150
+ activeFocusOnTab: true
+ Accessible.role: Accessible.Button
+ Rectangle {
+ anchors.fill: parent
+ color: parent.activeFocus ? "red" : "black"
+ }
+ anchors.top: parent.top
+ anchors.left: parent.left
+ }
+ Item {
+ id: button2
+ objectName: "button2"
+ width: 300
+ height: 150
+ activeFocusOnTab: true
+ Accessible.role: Accessible.Button
+ Rectangle {
+ anchors.fill: parent
+ color: parent.activeFocus ? "red" : "black"
+ }
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/data/activeFocusOnTab8.qml b/tests/auto/quick/qquickitem2/data/activeFocusOnTab8.qml
new file mode 100644
index 0000000000..641a39c1fa
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/activeFocusOnTab8.qml
@@ -0,0 +1,36 @@
+import QtQuick 2.1
+
+Item {
+ id: main
+ objectName: "main"
+ width: 300
+ height: 300
+ Item {
+ id: button1
+ objectName: "button1"
+ width: 300
+ height: 150
+ activeFocusOnTab: true
+ Accessible.role: Accessible.Table
+ Rectangle {
+ anchors.fill: parent
+ color: parent.activeFocus ? "red" : "black"
+ }
+ anchors.top: parent.top
+ anchors.left: parent.left
+ }
+ Item {
+ id: button2
+ objectName: "button2"
+ width: 300
+ height: 150
+ activeFocusOnTab: true
+ Accessible.role: Accessible.Table
+ Rectangle {
+ anchors.fill: parent
+ color: parent.activeFocus ? "red" : "black"
+ }
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/data/resourcesProperty.qml b/tests/auto/quick/qquickitem2/data/resourcesProperty.qml
index b8f18bb375..2c4c0aa5c1 100644
--- a/tests/auto/quick/qquickitem2/data/resourcesProperty.qml
+++ b/tests/auto/quick/qquickitem2/data/resourcesProperty.qml
@@ -8,14 +8,27 @@ Item {
property bool test3
property bool test4
property bool test5
+ property bool test6
Component.onCompleted: {
- test1 = (root.resources.length >= 3)
- test2 = root.resources[0] == item1
- test3 = root.resources[1] == item2
- test4 = root.resources[2] == item3
- test5 = root.resources[10] == null
+ test1 = (root.resources.length === 4)
+ test2 = root.resources[0] === item1
+ test3 = root.resources[1] === item2
+ test4 = root.resources[2] === item3
+ test5 = root.resources[3] === otherObject
+ test6 = root.resources[10] == null
}
+ //Resources can be used explicitly
resources: [ Item { id: item1 }, Item { id: item2 }, Item { id: item3 } ]
+
+ Item {
+ //Item in Data go the children property.
+ }
+
+ QtObject {
+ //Objects in Data which are not items are put in resources.
+ id: otherObject
+ objectName: "subObject";
+ }
}
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index f2d25e81ed..992e81aa64 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -47,6 +47,7 @@
#include <QtGui/private/qinputmethod_p.h>
#include <QtQuick/private/qquickrectangle_p.h>
#include <QtQuick/private/qquicktextinput_p.h>
+#include <QtGui/qpa/qplatformtheme.h>
#include <private/qquickitem_p.h>
#include "../../shared/util.h"
#include "../shared/visualtestutil.h"
@@ -69,6 +70,12 @@ private slots:
void activeFocusOnTab3();
void activeFocusOnTab4();
void activeFocusOnTab5();
+ void activeFocusOnTab6();
+ void activeFocusOnTab7();
+ void activeFocusOnTab8();
+
+ void nextItemInFocusChain();
+ void nextItemInFocusChain2();
void keys();
void keysProcessingOrder();
@@ -108,6 +115,11 @@ private slots:
private:
QQmlEngine engine;
+ bool qt_tab_all_widgets() {
+ if (const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme())
+ return theme->themeHint(QPlatformTheme::TabAllWidgets).toBool();
+ return true;
+ }
};
class KeysTestObject : public QObject
@@ -281,6 +293,9 @@ void tst_QQuickItem::cleanup()
void tst_QQuickItem::activeFocusOnTab()
{
+ if (!qt_tab_all_widgets())
+ QSKIP("This function doesn't support NOT iterating all.");
+
QQuickView *window = new QQuickView(0);
window->setBaseSize(QSize(800,600));
@@ -390,6 +405,9 @@ void tst_QQuickItem::activeFocusOnTab()
void tst_QQuickItem::activeFocusOnTab2()
{
+ if (!qt_tab_all_widgets())
+ QSKIP("This function doesn't support NOT iterating all.");
+
QQuickView *window = new QQuickView(0);
window->setBaseSize(QSize(800,600));
@@ -427,6 +445,9 @@ void tst_QQuickItem::activeFocusOnTab2()
void tst_QQuickItem::activeFocusOnTab3()
{
+ if (!qt_tab_all_widgets())
+ QSKIP("This function doesn't support NOT iterating all.");
+
QQuickView *window = new QQuickView(0);
window->setBaseSize(QSize(800,600));
@@ -606,6 +627,9 @@ void tst_QQuickItem::activeFocusOnTab3()
void tst_QQuickItem::activeFocusOnTab4()
{
+ if (!qt_tab_all_widgets())
+ QSKIP("This function doesn't support NOT iterating all.");
+
QQuickView *window = new QQuickView(0);
window->setBaseSize(QSize(800,600));
@@ -635,6 +659,9 @@ void tst_QQuickItem::activeFocusOnTab4()
void tst_QQuickItem::activeFocusOnTab5()
{
+ if (!qt_tab_all_widgets())
+ QSKIP("This function doesn't support NOT iterating all.");
+
QQuickView *window = new QQuickView(0);
window->setBaseSize(QSize(800,600));
@@ -664,6 +691,273 @@ void tst_QQuickItem::activeFocusOnTab5()
delete window;
}
+void tst_QQuickItem::activeFocusOnTab6()
+{
+ if (qt_tab_all_widgets())
+ QSKIP("This function doesn't support iterating all.");
+
+ QQuickView *window = new QQuickView(0);
+ window->setBaseSize(QSize(800,600));
+
+ window->setSource(testFileUrl("activeFocusOnTab6.qml"));
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QGuiApplication::focusWindow() == window);
+
+ // original: button12
+ QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "button12");
+ QVERIFY(item);
+ QVERIFY(item->hasActiveFocus());
+
+ // Tab: button12->edit
+ QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(key.isAccepted());
+
+ item = findItem<QQuickItem>(window->rootObject(), "edit");
+ QVERIFY(item);
+ QVERIFY(item->hasActiveFocus());
+
+ // BackTab: edit->button12
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(key.isAccepted());
+
+ item = findItem<QQuickItem>(window->rootObject(), "button12");
+ QVERIFY(item);
+ QVERIFY(item->hasActiveFocus());
+
+ // BackTab: button12->button11
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(key.isAccepted());
+
+ item = findItem<QQuickItem>(window->rootObject(), "button11");
+ QVERIFY(item);
+ QVERIFY(item->hasActiveFocus());
+
+ // BackTab: button11->edit
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(key.isAccepted());
+
+ item = findItem<QQuickItem>(window->rootObject(), "edit");
+ QVERIFY(item);
+ QVERIFY(item->hasActiveFocus());
+
+ delete window;
+}
+
+void tst_QQuickItem::activeFocusOnTab7()
+{
+ if (qt_tab_all_widgets())
+ QSKIP("This function doesn't support iterating all.");
+
+ QQuickView *window = new QQuickView(0);
+ window->setBaseSize(QSize(300,300));
+
+ window->setSource(testFileUrl("activeFocusOnTab7.qml"));
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QGuiApplication::focusWindow() == window);
+
+ QQuickItem *item = findItem<QQuickItem>(window->rootObject(), "button1");
+ QVERIFY(item);
+ item->forceActiveFocus();
+ QVERIFY(item->hasActiveFocus());
+
+ // Tab: button1->button1
+ QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(!key.isAccepted());
+
+ QVERIFY(item->hasActiveFocus());
+
+ // BackTab: button1->button1
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(!key.isAccepted());
+
+ QVERIFY(item->hasActiveFocus());
+
+ delete window;
+}
+
+void tst_QQuickItem::activeFocusOnTab8()
+{
+ QQuickView *window = new QQuickView(0);
+ window->setBaseSize(QSize(300,300));
+
+ window->setSource(testFileUrl("activeFocusOnTab8.qml"));
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QGuiApplication::focusWindow() == window);
+
+ QQuickItem *content = window->contentItem();
+ QVERIFY(content);
+ QVERIFY(content->hasActiveFocus());
+
+ QQuickItem *button1 = findItem<QQuickItem>(window->rootObject(), "button1");
+ QVERIFY(button1);
+ QVERIFY(!button1->hasActiveFocus());
+
+ QQuickItem *button2 = findItem<QQuickItem>(window->rootObject(), "button2");
+ QVERIFY(button2);
+ QVERIFY(!button2->hasActiveFocus());
+
+ // Tab: contentItem->button1
+ QKeyEvent key(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(key.isAccepted());
+
+ QVERIFY(button1->hasActiveFocus());
+
+ // Tab: button1->button2
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(key.isAccepted());
+
+ QVERIFY(button2->hasActiveFocus());
+ QVERIFY(!button1->hasActiveFocus());
+
+ // BackTab: button2->button1
+ key = QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::ShiftModifier, "", false, 1);
+ QGuiApplication::sendEvent(window, &key);
+ QVERIFY(key.isAccepted());
+
+ QVERIFY(button1->hasActiveFocus());
+ QVERIFY(!button2->hasActiveFocus());
+
+ delete window;
+}
+
+void tst_QQuickItem::nextItemInFocusChain()
+{
+ if (!qt_tab_all_widgets())
+ QSKIP("This function doesn't support NOT iterating all.");
+
+ QQuickView *window = new QQuickView(0);
+ window->setBaseSize(QSize(800,600));
+
+ window->setSource(testFileUrl("activeFocusOnTab.qml"));
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QGuiApplication::focusWindow() == window);
+
+ QQuickItem *button11 = findItem<QQuickItem>(window->rootObject(), "button11");
+ QVERIFY(button11);
+ QQuickItem *button12 = findItem<QQuickItem>(window->rootObject(), "button12");
+ QVERIFY(button12);
+
+ QQuickItem *sub2 = findItem<QQuickItem>(window->rootObject(), "sub2");
+ QVERIFY(sub2);
+ QQuickItem *button21 = findItem<QQuickItem>(window->rootObject(), "button21");
+ QVERIFY(button21);
+ QQuickItem *button22 = findItem<QQuickItem>(window->rootObject(), "button22");
+ QVERIFY(button22);
+
+ QQuickItem *edit = findItem<QQuickItem>(window->rootObject(), "edit");
+ QVERIFY(edit);
+
+ QQuickItem *next, *prev;
+
+ next = button11->nextItemInFocusChain(true);
+ QVERIFY(next);
+ QCOMPARE(next, button12);
+ prev = button11->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, edit);
+
+ next = button12->nextItemInFocusChain();
+ QVERIFY(next);
+ QCOMPARE(next, sub2);
+ prev = button12->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, button11);
+
+ next = sub2->nextItemInFocusChain(true);
+ QVERIFY(next);
+ QCOMPARE(next, button21);
+ prev = sub2->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, button12);
+
+ next = button21->nextItemInFocusChain();
+ QVERIFY(next);
+ QCOMPARE(next, button22);
+ prev = button21->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, sub2);
+
+ next = button22->nextItemInFocusChain(true);
+ QVERIFY(next);
+ QCOMPARE(next, edit);
+ prev = button22->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, button21);
+
+ next = edit->nextItemInFocusChain();
+ QVERIFY(next);
+ QCOMPARE(next, button11);
+ prev = edit->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, button22);
+
+ delete window;
+}
+
+void tst_QQuickItem::nextItemInFocusChain2()
+{
+ if (qt_tab_all_widgets())
+ QSKIP("This function doesn't support iterating all.");
+
+ QQuickView *window = new QQuickView(0);
+ window->setBaseSize(QSize(800,600));
+
+ window->setSource(testFileUrl("activeFocusOnTab6.qml"));
+ window->show();
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
+ QVERIFY(QGuiApplication::focusWindow() == window);
+
+ QQuickItem *button11 = findItem<QQuickItem>(window->rootObject(), "button11");
+ QVERIFY(button11);
+ QQuickItem *button12 = findItem<QQuickItem>(window->rootObject(), "button12");
+ QVERIFY(button12);
+
+ QQuickItem *edit = findItem<QQuickItem>(window->rootObject(), "edit");
+ QVERIFY(edit);
+
+ QQuickItem *next, *prev;
+
+ next = button11->nextItemInFocusChain(true);
+ QVERIFY(next);
+ QCOMPARE(next, button12);
+ prev = button11->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, edit);
+
+ next = button12->nextItemInFocusChain();
+ QVERIFY(next);
+ QCOMPARE(next, edit);
+ prev = button12->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, button11);
+
+ next = edit->nextItemInFocusChain();
+ QVERIFY(next);
+ QCOMPARE(next, button11);
+ prev = edit->nextItemInFocusChain(false);
+ QVERIFY(prev);
+ QCOMPARE(prev, button12);
+
+ delete window;
+}
+
void tst_QQuickItem::keys()
{
QQuickView *window = new QQuickView(0);
@@ -1633,15 +1927,35 @@ void tst_QQuickItem::resourcesProperty()
{
QQmlComponent component(&engine, testFileUrl("resourcesProperty.qml"));
- QObject *o = component.create();
- QVERIFY(o != 0);
+ QObject *object = component.create();
+ QVERIFY(object != 0);
- QCOMPARE(o->property("test1").toBool(), true);
- QCOMPARE(o->property("test2").toBool(), true);
- QCOMPARE(o->property("test3").toBool(), true);
- QCOMPARE(o->property("test4").toBool(), true);
- QCOMPARE(o->property("test5").toBool(), true);
- delete o;
+ QQmlProperty property(object, "resources", component.creationContext());
+
+ QVERIFY(property.isValid());
+ QQmlListReference list = qvariant_cast<QQmlListReference>(property.read());
+ QVERIFY(list.isValid());
+
+ QCOMPARE(list.count(), 4);
+
+ QCOMPARE(object->property("test1").toBool(), true);
+ QCOMPARE(object->property("test2").toBool(), true);
+ QCOMPARE(object->property("test3").toBool(), true);
+ QCOMPARE(object->property("test4").toBool(), true);
+ QCOMPARE(object->property("test5").toBool(), true);
+ QCOMPARE(object->property("test6").toBool(), true);
+
+ QObject *subObject = object->findChild<QObject *>("subObject");
+
+ QVERIFY(subObject);
+
+ QCOMPARE(object, subObject->parent());
+
+ delete subObject;
+
+ QCOMPARE(list.count(), 3);
+
+ delete object;
}
void tst_QQuickItem::propertyChanges()
diff --git a/tests/auto/quick/qquicklistview/data/delayedChanges.qml b/tests/auto/quick/qquicklistview/data/delayedChanges.qml
new file mode 100644
index 0000000000..590af39c02
--- /dev/null
+++ b/tests/auto/quick/qquicklistview/data/delayedChanges.qml
@@ -0,0 +1,39 @@
+import QtQuick 2.1
+
+Item {
+ width: 400
+ height: 400
+ function takeTwo()
+ {
+ listView.model.remove(0);
+ listView.model.remove(0);
+ }
+ function takeTwo_sync()
+ {
+ listView.model.remove(0);
+ listView.forceLayout();
+ listView.model.remove(0);
+ listView.forceLayout();
+ }
+
+ ListView {
+ id: listView
+ height: parent.height
+ width: 400
+ model: ListModel {
+ ListElement { name: "A" }
+ ListElement { name: "B" }
+ ListElement { name: "C" }
+ ListElement { name: "D" }
+ ListElement { name: "E" }
+ ListElement { name: "F" }
+ ListElement { name: "G" }
+ ListElement { name: "H" }
+ ListElement { name: "I" }
+ ListElement { name: "J" }
+ }
+ delegate: Text {
+ text: index + listView.count
+ }
+ }
+}
diff --git a/tests/auto/quick/qquicklistview/data/emptymodel.qml b/tests/auto/quick/qquicklistview/data/emptymodel.qml
index 16bcd3f9ae..3feec691cf 100644
--- a/tests/auto/quick/qquicklistview/data/emptymodel.qml
+++ b/tests/auto/quick/qquicklistview/data/emptymodel.qml
@@ -1,4 +1,4 @@
-import QtQuick 2.0
+import QtQuick 2.1
Rectangle {
ListModel {
id: model
@@ -12,11 +12,13 @@ Rectangle {
}
function remove() {
model.remove(0)
+ list.forceLayout()
isCurrentItemNull = list.currentItem === null //check no seg fault
}
function add() {
model.append({name: "hello"})
+ list.forceLayout()
isCurrentItemNull = list.currentItem === null
}
property bool isCurrentItemNull
diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
index f8c7de6635..bec61eaccb 100644
--- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
+++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp
@@ -208,10 +208,11 @@ private slots:
void parentBinding();
void defaultHighlightMoveDuration();
void accessEmptyCurrentItem_QTBUG_30227();
+ void delayedChanges_QTBUG_30555();
private:
- template <class T> void items(const QUrl &source, bool forceLayout);
- template <class T> void changed(const QUrl &source, bool forceLayout);
+ template <class T> void items(const QUrl &source);
+ template <class T> void changed(const QUrl &source);
template <class T> void inserted(const QUrl &source);
template <class T> void inserted_more(QQuickItemView::VerticalLayoutDirection verticalLayoutDirection = QQuickItemView::TopToBottom);
template <class T> void removed(const QUrl &source, bool animated);
@@ -329,7 +330,7 @@ void tst_QQuickListView::cleanupTestCase()
}
template <class T>
-void tst_QQuickListView::items(const QUrl &source, bool forceLayout)
+void tst_QQuickListView::items(const QUrl &source)
{
QQuickView *window = createView();
@@ -349,6 +350,7 @@ void tst_QQuickListView::items(const QUrl &source, bool forceLayout)
QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list");
QTRY_VERIFY(listview != 0);
+ listview->forceLayout();
QQuickItem *contentItem = listview->contentItem();
QTRY_VERIFY(contentItem != 0);
@@ -359,6 +361,7 @@ void tst_QQuickListView::items(const QUrl &source, bool forceLayout)
QTRY_VERIFY(listview->highlightItem() != 0);
QTRY_COMPARE(listview->count(), model.count());
QTRY_COMPARE(window->rootObject()->property("count").toInt(), model.count());
+ listview->forceLayout();
QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item
// current item should be first item
@@ -398,8 +401,7 @@ void tst_QQuickListView::items(const QUrl &source, bool forceLayout)
ctxt->setContextProperty("testModel", &model2);
// Force a layout, necessary if ListView is completed before VisualDataModel.
- if (forceLayout)
- QCOMPARE(listview->property("count").toInt(), 0);
+ listview->forceLayout();
int itemCount = findItems<QQuickItem>(contentItem, "wrapper").count();
QTRY_VERIFY(itemCount == 0);
@@ -413,7 +415,7 @@ void tst_QQuickListView::items(const QUrl &source, bool forceLayout)
template <class T>
-void tst_QQuickListView::changed(const QUrl &source, bool forceLayout)
+void tst_QQuickListView::changed(const QUrl &source)
{
QQuickView *window = createView();
@@ -431,15 +433,15 @@ void tst_QQuickListView::changed(const QUrl &source, bool forceLayout)
window->setSource(source);
qApp->processEvents();
- QQuickFlickable *listview = findItem<QQuickFlickable>(window->rootObject(), "list");
+ QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list");
QTRY_VERIFY(listview != 0);
+ listview->forceLayout();
QQuickItem *contentItem = listview->contentItem();
QTRY_VERIFY(contentItem != 0);
// Force a layout, necessary if ListView is completed before VisualDataModel.
- if (forceLayout)
- QCOMPARE(listview->property("count").toInt(), model.count());
+ listview->forceLayout();
model.modifyItem(1, "Will", "9876");
QQuickText *name = findItem<QQuickText>(contentItem, "textName", 1);
@@ -579,22 +581,24 @@ void tst_QQuickListView::inserted_more(QQuickItemView::VerticalLayoutDirection v
QQuickItem *contentItem = listview->contentItem();
QTRY_VERIFY(contentItem != 0);
- bool waitForPolish = (contentY != 0);
if (verticalLayoutDirection == QQuickItemView::BottomToTop) {
listview->setVerticalLayoutDirection(verticalLayoutDirection);
QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
contentY = -listview->height() - contentY;
}
listview->setContentY(contentY);
- if (waitForPolish)
- QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
QList<QPair<QString, QString> > newData;
for (int i=0; i<insertCount; i++)
newData << qMakePair(QString("value %1").arg(i), QString::number(i));
model.insertItems(insertIndex, newData);
+
+ //Wait for polish (updates list to the model changes)
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
+
QTRY_COMPARE(listview->property("count").toInt(), model.count());
+
// check visibleItems.first() is in correct position
QQuickItem *item0 = findItem<QQuickItem>(contentItem, "wrapper", 0);
QVERIFY(item0);
@@ -1019,17 +1023,17 @@ void tst_QQuickListView::removed_more(const QUrl &source, QQuickItemView::Vertic
QQuickItem *contentItem = listview->contentItem();
QTRY_VERIFY(contentItem != 0);
- bool waitForPolish = (contentY != 0);
if (verticalLayoutDirection == QQuickItemView::BottomToTop) {
listview->setVerticalLayoutDirection(verticalLayoutDirection);
QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
contentY = -listview->height() - contentY;
}
listview->setContentY(contentY);
- if (waitForPolish)
- QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
model.removeItems(removeIndex, removeCount);
+ //Wait for polish (updates list to the model changes)
+ QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
+
QTRY_COMPARE(listview->property("count").toInt(), model.count());
// check visibleItems.first() is in correct position
@@ -1219,6 +1223,7 @@ void tst_QQuickListView::clear(const QUrl &source, QQuickItemView::VerticalLayou
// confirm sanity when adding an item to cleared list
model.addItem("New", "1");
+ listview->forceLayout();
QTRY_VERIFY(listview->count() == 1);
QVERIFY(listview->currentItem() != 0);
QVERIFY(listview->currentIndex() == 0);
@@ -1945,6 +1950,7 @@ void tst_QQuickListView::sections(const QUrl &source)
// Remove section boundary
model.removeItem(5);
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
// New section header created
@@ -1953,6 +1959,7 @@ void tst_QQuickListView::sections(const QUrl &source)
QTRY_COMPARE(item->height(), 40.0);
model.insertItem(3, "New Item", "0");
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
// Section header moved
@@ -1966,6 +1973,7 @@ void tst_QQuickListView::sections(const QUrl &source)
// insert item which will become a section header
model.insertItem(6, "Replace header", "1");
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
item = findItem<QQuickItem>(contentItem, "wrapper", 6);
@@ -2061,6 +2069,7 @@ void tst_QQuickListView::sectionsDelegate()
// remove section boundary
model.removeItem(5);
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
for (int i = 0; i < 3; ++i) {
QQuickItem *item = findItem<QQuickItem>(contentItem,
@@ -2288,6 +2297,7 @@ void tst_QQuickListView::sectionsPositioning()
listview->setContentY(120);
QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
model.removeItem(5);
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
for (int i = 1; i < 3; ++i) {
QQuickItem *item = findVisibleChild(contentItem,
@@ -2485,7 +2495,8 @@ void tst_QQuickListView::currentIndex_delayedItemCreation()
QTRY_VERIFY(contentItem != 0);
QSignalSpy spy(listview, SIGNAL(currentItemChanged()));
- QCOMPARE(listview->currentIndex(), 0);
+ //QCOMPARE(listview->currentIndex(), 0);
+ listview->forceLayout();
QTRY_COMPARE(spy.count(), 1);
releaseView(window);
@@ -2536,6 +2547,7 @@ void tst_QQuickListView::currentIndex()
for (int i = 0; i < 30; i++)
model.addItem("Item" + QString::number(i), QString::number(i));
ctxt->setContextProperty("testModel", &model);
+ listview->forceLayout();
QCOMPARE(listview->currentIndex(), 0);
QCOMPARE(listview->currentItem(), findItem<QQuickItem>(contentItem, "wrapper", 0));
@@ -2679,6 +2691,7 @@ void tst_QQuickListView::keyNavigation()
QTRY_COMPARE(listview->currentIndex(), i+1);
}
QTest::keyRelease(window, forwardsKey);
+ listview->forceLayout();
QTRY_COMPARE(listview->currentIndex(), model.count()-1);
QTRY_COMPARE(listview->contentX(), contentPosAtLastItem.x());
QTRY_COMPARE(listview->contentY(), contentPosAtLastItem.y());
@@ -2689,6 +2702,7 @@ void tst_QQuickListView::keyNavigation()
QTRY_COMPARE(listview->currentIndex(), i-1);
}
QTest::keyRelease(window, backwardsKey);
+ listview->forceLayout();
QTRY_COMPARE(listview->currentIndex(), 0);
QTRY_COMPARE(listview->contentX(), contentPosAtFirstItem.x());
QTRY_COMPARE(listview->contentY(), contentPosAtFirstItem.y());
@@ -3123,6 +3137,7 @@ void tst_QQuickListView::resetModel()
strings << "four" << "five" << "six" << "seven";
model.setStringList(strings);
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.rowCount());
for (int i = 0; i < model.rowCount(); ++i) {
@@ -3470,6 +3485,7 @@ void tst_QQuickListView::header()
QCOMPARE(item->position(), firstDelegatePos);
model.clear();
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
QCOMPARE(header->position(), initialHeaderPos); // header should stay where it is
if (orientation == QQuickListView::Vertical)
@@ -3865,6 +3881,7 @@ void tst_QQuickListView::extents()
QCOMPARE(listview->originY(), origin_empty.y());
for (int i=0; i<30; i++)
model.addItem("Item" + QString::number(i), "");
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
QCOMPARE(listview->originX(), origin_nonEmpty.x());
QCOMPARE(listview->originY(), origin_nonEmpty.y());
@@ -4262,6 +4279,7 @@ void tst_QQuickListView::resizeFirstDelegate()
for (int i = 0; i < 10; i++)
model.addItem("Item" + QString::number(i), "");
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
item = findItem<QQuickItem>(contentItem, "wrapper", 1);
@@ -4461,6 +4479,7 @@ void tst_QQuickListView::indexAt_itemAt()
void tst_QQuickListView::incrementalModel()
{
QQuickView *window = createView();
+ QSKIP("QTBUG-30716");
IncrementalModel model;
QQmlContext *ctxt = window->rootContext();
@@ -4471,14 +4490,17 @@ void tst_QQuickListView::incrementalModel()
QQuickListView *listview = findItem<QQuickListView>(window->rootObject(), "list");
QTRY_VERIFY(listview != 0);
+ listview->forceLayout();
QQuickItem *contentItem = listview->contentItem();
QTRY_VERIFY(contentItem != 0);
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), 20);
listview->positionViewAtIndex(10, QQuickListView::Beginning);
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), 25);
delete window;
@@ -4503,18 +4525,19 @@ void tst_QQuickListView::onAdd()
ctxt->setContextProperty("delegateHeight", delegateHeight);
window->setSource(testFileUrl("attachedSignals.qml"));
- QObject *object = window->rootObject();
- object->setProperty("width", window->width());
- object->setProperty("height", window->height());
+ QQuickListView* listview = qobject_cast<QQuickListView*>(window->rootObject());
+ listview->setProperty("width", window->width());
+ listview->setProperty("height", window->height());
qApp->processEvents();
QList<QPair<QString, QString> > items;
for (int i=0; i<itemsToAdd; i++)
items << qMakePair(QString("value %1").arg(i), QString::number(i));
model.addItems(items);
- QTRY_COMPARE(window->rootObject()->property("count").toInt(), model.count());
+ listview->forceLayout();
+ QTRY_COMPARE(listview->property("count").toInt(), model.count());
- QVariantList result = object->property("addedDelegates").toList();
+ QVariantList result = listview->property("addedDelegates").toList();
QCOMPARE(result.count(), items.count());
for (int i=0; i<items.count(); i++)
QCOMPARE(result[i].toString(), items[i].first);
@@ -4557,12 +4580,13 @@ void tst_QQuickListView::onRemove()
ctxt->setContextProperty("delegateHeight", delegateHeight);
window->setSource(testFileUrl("attachedSignals.qml"));
- QObject *object = window->rootObject();
+ QQuickListView *listview = qobject_cast<QQuickListView *>(window->rootObject());
model.removeItems(indexToRemove, removeCount);
- QTRY_COMPARE(window->rootObject()->property("count").toInt(), model.count());
+ listview->forceLayout();
+ QTRY_COMPARE(listview->property("count").toInt(), model.count());
- QCOMPARE(object->property("removedDelegateCount"), QVariant(removeCount));
+ QCOMPARE(listview->property("removedDelegateCount"), QVariant(removeCount));
releaseView(window);
}
@@ -4741,6 +4765,7 @@ void tst_QQuickListView::margins()
// and originY is updated
listview->setContentY(100);
model.removeItem(1);
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), model.count());
listview->setContentY(-50);
QTRY_COMPARE(QQuickItemPrivate::get(listview)->polishScheduled, false);
@@ -4979,22 +5004,22 @@ void tst_QQuickListView::snapToItem()
void tst_QQuickListView::qAbstractItemModel_package_items()
{
- items<QaimModel>(testFileUrl("listviewtest-package.qml"), true);
+ items<QaimModel>(testFileUrl("listviewtest-package.qml"));
}
void tst_QQuickListView::qAbstractItemModel_items()
{
- items<QaimModel>(testFileUrl("listviewtest.qml"), false);
+ items<QaimModel>(testFileUrl("listviewtest.qml"));
}
void tst_QQuickListView::qAbstractItemModel_package_changed()
{
- changed<QaimModel>(testFileUrl("listviewtest-package.qml"), true);
+ changed<QaimModel>(testFileUrl("listviewtest-package.qml"));
}
void tst_QQuickListView::qAbstractItemModel_changed()
{
- changed<QaimModel>(testFileUrl("listviewtest.qml"), false);
+ changed<QaimModel>(testFileUrl("listviewtest.qml"));
}
void tst_QQuickListView::qAbstractItemModel_package_inserted()
@@ -5555,6 +5580,7 @@ void tst_QQuickListView::populateTransitions()
// clear the model
window->rootContext()->setContextProperty("testModel", QVariant());
+ listview->forceLayout();
QTRY_COMPARE(listview->count(), 0);
QTRY_COMPARE(findItems<QQuickItem>(contentItem, "wrapper").count(), 0);
listview->setProperty("countPopulateTransitions", 0);
@@ -5683,6 +5709,7 @@ void tst_QQuickListView::addTransitions()
if (!newData.isEmpty()) {
model.insertItems(insertionIndex, newData);
QTRY_COMPARE(model.count(), listview->count());
+ listview->forceLayout();
}
QList<QQuickItem *> targetItems = findItems<QQuickItem>(contentItem, "wrapper", targetIndexes);
@@ -6291,6 +6318,7 @@ void tst_QQuickListView::displacedTransitions()
case ListChange::Polish:
break;
}
+ listview->forceLayout();
QVariantList resultTargetIndexes = listview->property("displacedTargetIndexes").toList();
QVariantList resultTargetItems = listview->property("displacedTargetItems").toList();
@@ -6539,6 +6567,7 @@ void tst_QQuickListView::multipleTransitions()
break;
}
}
+ listview->forceLayout();
QCOMPARE(listview->count(), model.count());
// verify all items moved to the correct final positions
@@ -6822,6 +6851,7 @@ void tst_QQuickListView::accessEmptyCurrentItem_QTBUG_30227()
QQuickListView *listview = window->rootObject()->findChild<QQuickListView*>();
QTRY_VERIFY(listview != 0);
+ listview->forceLayout();
QMetaObject::invokeMethod(window->rootObject(), "remove");
QVERIFY(window->rootObject()->property("isCurrentItemNull").toBool());
@@ -6830,6 +6860,26 @@ void tst_QQuickListView::accessEmptyCurrentItem_QTBUG_30227()
QVERIFY(!window->rootObject()->property("isCurrentItemNull").toBool());
}
+void tst_QQuickListView::delayedChanges_QTBUG_30555()
+{
+ QQuickView *window = createView();
+ window->setSource(testFileUrl("delayedChanges.qml"));
+
+ QQuickListView *listview = window->rootObject()->findChild<QQuickListView*>();
+ QTRY_VERIFY(listview != 0);
+
+ QCOMPARE(listview->count(), 10);
+
+ //Takes two just like in the bug report
+ QMetaObject::invokeMethod(window->rootObject(), "takeTwo");
+ QTRY_COMPARE(listview->count(), 8);
+
+ QMetaObject::invokeMethod(window->rootObject(), "takeTwo_sync");
+ QCOMPARE(listview->count(), 6);
+
+ delete window;
+}
+
QTEST_MAIN(tst_QQuickListView)
#include "tst_qquicklistview.moc"
diff --git a/tests/auto/quick/qquickmousearea/data/hoverAfterPress.qml b/tests/auto/quick/qquickmousearea/data/hoverAfterPress.qml
new file mode 100644
index 0000000000..69ec8fbd47
--- /dev/null
+++ b/tests/auto/quick/qquickmousearea/data/hoverAfterPress.qml
@@ -0,0 +1,29 @@
+import QtQuick 2.0
+
+Item {
+ width: 500
+ height: 500
+
+ Rectangle {
+ width: 300
+ height: 300
+ color: "grey"
+ x: 100
+ y: 100
+
+ MouseArea {
+ id: mouseArea
+ objectName: "mouseArea"
+ anchors.fill: parent
+ hoverEnabled: true
+ onPressed: mouse.accepted = false
+ //onContainsMouseChanged: print("containsMouse changed =", containsMouse)
+
+ Rectangle {
+ visible: parent.containsMouse
+ color: "red"
+ width: 10; height: 10
+ }
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
index fa33f3f626..a582c62701 100644
--- a/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
+++ b/tests/auto/quick/qquickmousearea/tst_qquickmousearea.cpp
@@ -78,6 +78,7 @@ private slots:
void hoverPosition();
void hoverPropagation();
void hoverVisible();
+ void hoverAfterPress();
void disableAfterPress();
void onWheel();
void transformedMouseArea_data();
@@ -585,7 +586,7 @@ void tst_QQuickMouseArea::pressedCanceledOnWindowDeactivate()
QWindow *secondWindow = qvariant_cast<QWindow*>(window->rootObject()->property("secondWindow"));
secondWindow->setProperty("visible", true);
- QTest::qWaitForWindowActive(secondWindow);
+ QTest::qWaitForWindowExposed(secondWindow);
QVERIFY(!window->rootObject()->property("pressed").toBool());
QVERIFY(window->rootObject()->property("canceled").toBool());
@@ -1007,6 +1008,33 @@ void tst_QQuickMouseArea::hoverVisible()
delete window;
}
+void tst_QQuickMouseArea::hoverAfterPress()
+{
+ QQuickView *window = createView();
+ window->setSource(testFileUrl("hoverAfterPress.qml"));
+
+ QQuickItem *root = window->rootObject();
+ QVERIFY(root != 0);
+
+ QQuickMouseArea *mouseArea = window->rootObject()->findChild<QQuickMouseArea*>("mouseArea");
+ QVERIFY(mouseArea != 0);
+ QTest::mouseMove(window, QPoint(22,33));
+ QCOMPARE(mouseArea->hovered(), false);
+ QTest::mouseMove(window, QPoint(200,200));
+ QCOMPARE(mouseArea->hovered(), true);
+ QTest::mouseMove(window, QPoint(22,33));
+ QCOMPARE(mouseArea->hovered(), false);
+ QTest::mouseMove(window, QPoint(200,200));
+ QCOMPARE(mouseArea->hovered(), true);
+ QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(200,200));
+ QCOMPARE(mouseArea->hovered(), true);
+ QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(200,200));
+ QCOMPARE(mouseArea->hovered(), true);
+ QTest::mouseMove(window, QPoint(22,33));
+ QCOMPARE(mouseArea->hovered(), false);
+ delete window;
+}
+
void tst_QQuickMouseArea::disableAfterPress()
{
QQuickView *window = createView();
diff --git a/tests/auto/quick/qquickrepeater/data/visualitemmodel.qml b/tests/auto/quick/qquickrepeater/data/visualitemmodel.qml
new file mode 100644
index 0000000000..b1b7b97881
--- /dev/null
+++ b/tests/auto/quick/qquickrepeater/data/visualitemmodel.qml
@@ -0,0 +1,23 @@
+import QtQuick 2.0
+
+Rectangle {
+ width: 360
+ height: 360
+
+ VisualItemModel {
+ id: visItemModel
+ Rectangle {
+ width: 20
+ height: 20
+ color: "red"
+ }
+ }
+
+ Column {
+ anchors.fill: parent
+ Repeater {
+ model: visItemModel
+ }
+ }
+}
+
diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
index 582503f938..9fb76f9584 100644
--- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
+++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
@@ -78,6 +78,7 @@ private slots:
void asynchronous();
void initParent();
void dynamicModelCrash();
+ void visualItemModelCrash();
};
class TestObject : public QObject
@@ -732,6 +733,17 @@ void tst_QQuickRepeater::dynamicModelCrash()
QVERIFY(qvariant_cast<QObject *>(repeater->model()) == 0);
}
+void tst_QQuickRepeater::visualItemModelCrash()
+{
+ // This used to crash because the model would get
+ // deleted before the repeater, leading to double-deletion
+ // of the items.
+ QQuickView *window = createView();
+ window->setSource(testFileUrl("visualitemmodel.qml"));
+ qApp->processEvents();
+ delete window;
+}
+
QTEST_MAIN(tst_QQuickRepeater)
#include "tst_qquickrepeater.moc"
diff --git a/tests/auto/quick/qquicktext/data/elideBeforeMaximumLineCount.qml b/tests/auto/quick/qquicktext/data/elideBeforeMaximumLineCount.qml
new file mode 100644
index 0000000000..7f1ce705dd
--- /dev/null
+++ b/tests/auto/quick/qquicktext/data/elideBeforeMaximumLineCount.qml
@@ -0,0 +1,10 @@
+import QtQuick 2.0
+
+Text {
+ width: implicitWidth / 2
+ height: implicitHeight / 2
+ elide: Text.ElideRight
+ maximumLineCount: 4
+
+ text: "Line one\nLine two\nLine three\nLine four"
+}
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index b95a646bd6..fdaa1d6617 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -110,8 +110,8 @@ private slots:
void letterSpacing();
void wordSpacing();
- void clickLink_data();
- void clickLink();
+ void linkInteraction_data();
+ void linkInteraction();
void implicitSize_data();
void implicitSize();
@@ -149,6 +149,8 @@ private slots:
void htmlLists();
void htmlLists_data();
+ void elideBeforeMaximumLineCount();
+
private:
QStringList standard;
QStringList richText;
@@ -1480,15 +1482,30 @@ void tst_qquicktext::wordSpacing()
class EventSender : public QQuickItem
{
public:
- void sendEvent(QMouseEvent *event) {
- if (event->type() == QEvent::MouseButtonPress)
- mousePressEvent(event);
- else if (event->type() == QEvent::MouseButtonRelease)
- mouseReleaseEvent(event);
- else if (event->type() == QEvent::MouseMove)
- mouseMoveEvent(event);
- else
+ void sendEvent(QEvent *event) {
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ mousePressEvent(static_cast<QMouseEvent *>(event));
+ break;
+ case QEvent::MouseButtonRelease:
+ mouseReleaseEvent(static_cast<QMouseEvent *>(event));
+ break;
+ case QEvent::MouseMove:
+ mouseMoveEvent(static_cast<QMouseEvent *>(event));
+ break;
+ case QEvent::HoverEnter:
+ hoverEnterEvent(static_cast<QHoverEvent *>(event));
+ break;
+ case QEvent::HoverLeave:
+ hoverLeaveEvent(static_cast<QHoverEvent *>(event));
+ break;
+ case QEvent::HoverMove:
+ hoverMoveEvent(static_cast<QHoverEvent *>(event));
+ break;
+ default:
qWarning() << "Trying to send unsupported event type";
+ break;
+ }
}
};
@@ -1498,10 +1515,12 @@ class LinkTest : public QObject
public:
LinkTest() {}
- QString link;
+ QString clickedLink;
+ QString hoveredLink;
public slots:
- void linkClicked(QString l) { link = l; }
+ void linkClicked(QString l) { clickedLink = l; }
+ void linkHovered(QString l) { hoveredLink = l; }
};
class TextMetrics
@@ -1587,13 +1606,15 @@ public:
typedef QVector<QPointF> PointVector;
Q_DECLARE_METATYPE(PointVector);
-void tst_qquicktext::clickLink_data()
+void tst_qquicktext::linkInteraction_data()
{
QTest::addColumn<QString>("text");
QTest::addColumn<qreal>("width");
QTest::addColumn<QString>("bindings");
QTest::addColumn<PointVector>("mousePositions");
- QTest::addColumn<QString>("link");
+ QTest::addColumn<QString>("clickedLink");
+ QTest::addColumn<QString>("hoverEnterLink");
+ QTest::addColumn<QString>("hoverMoveLink");
const QString singleLineText = "this text has a <a href=\\\"http://qt-project.org/single\\\">link</a> in it";
const QString singleLineLink = "http://qt-project.org/single";
@@ -1610,196 +1631,229 @@ void tst_qquicktext::clickLink_data()
<< singleLineText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(18).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
QTest::newRow("click on text")
<< singleLineText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(13).center())
- << QString();
+ << QString()
+ << QString() << QString();
QTest::newRow("drag within link")
<< singleLineText << 240.
<< ""
<< (PointVector()
<< metrics.characterRectangle(17).center()
<< metrics.characterRectangle(19).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
QTest::newRow("drag away from link")
<< singleLineText << 240.
<< ""
<< (PointVector()
<< metrics.characterRectangle(18).center()
<< metrics.characterRectangle(13).center())
- << QString();
+ << QString()
+ << singleLineLink << QString();
QTest::newRow("drag on to link")
<< singleLineText << 240.
<< ""
<< (PointVector()
<< metrics.characterRectangle(13).center()
<< metrics.characterRectangle(18).center())
- << QString();
+ << QString()
+ << QString() << singleLineLink;
QTest::newRow("click on bottom right aligned link")
<< singleLineText << 240.
<< "horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignBottom"
<< (PointVector() << metrics.characterRectangle(18, Qt::AlignRight, Qt::AlignBottom).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
QTest::newRow("click on center aligned link")
<< singleLineText << 240.
<< "horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter"
<< (PointVector() << metrics.characterRectangle(18, Qt::AlignHCenter, Qt::AlignVCenter).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
QTest::newRow("click on rich text link")
<< singleLineText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(18).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
QTest::newRow("click on rich text")
<< singleLineText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(13).center())
- << QString();
+ << QString()
+ << QString() << QString();
QTest::newRow("click on bottom right aligned rich text link")
<< singleLineText << 240.
<< "textFormat: Text.RichText; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignBottom"
<< (PointVector() << metrics.characterRectangle(18, Qt::AlignRight, Qt::AlignBottom).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
QTest::newRow("click on center aligned rich text link")
<< singleLineText << 240.
<< "textFormat: Text.RichText; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter"
<< (PointVector() << metrics.characterRectangle(18, Qt::AlignHCenter, Qt::AlignVCenter).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
} {
const TextMetrics metrics("this text has a li", Qt::ElideRight);
QTest::newRow("click on right elided link")
<< singleLineText << metrics.width() + 2
<< "elide: Text.ElideRight"
<< (PointVector() << metrics.characterRectangle(17).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
} {
const TextMetrics metrics("ink in it", Qt::ElideLeft);
QTest::newRow("click on left elided link")
<< singleLineText << metrics.width() + 2
<< "elide: Text.ElideLeft"
<< (PointVector() << metrics.characterRectangle(2).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
} {
const TextMetrics metrics("this text\nhas multiple\nlines in it");
QTest::newRow("click on second line")
<< multipleLineText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(18).center())
- << multipleLineLink;
+ << multipleLineLink
+ << multipleLineLink << multipleLineLink;
QTest::newRow("click on third line")
<< multipleLineText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(25).center())
- << multipleLineLink;
+ << multipleLineLink
+ << multipleLineLink << multipleLineLink;
QTest::newRow("drag from second line to third")
<< multipleLineText << 240.
<< ""
<< (PointVector()
<< metrics.characterRectangle(18).center()
<< metrics.characterRectangle(25).center())
- << multipleLineLink;
+ << multipleLineLink
+ << multipleLineLink << multipleLineLink;
QTest::newRow("click on rich text second line")
<< multipleLineText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(18).center())
- << multipleLineLink;
+ << multipleLineLink
+ << multipleLineLink << multipleLineLink;
QTest::newRow("click on rich text third line")
<< multipleLineText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(25).center())
- << multipleLineLink;
+ << multipleLineLink
+ << multipleLineLink << multipleLineLink;
QTest::newRow("drag rich text from second line to third")
<< multipleLineText << 240.
<< "textFormat: Text.RichText"
<< (PointVector()
<< metrics.characterRectangle(18).center()
<< metrics.characterRectangle(25).center())
- << multipleLineLink;
+ << multipleLineLink
+ << multipleLineLink << multipleLineLink;
} {
const TextMetrics metrics("this text has a nested link in it");
QTest::newRow("click on left outer link")
<< nestedText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(22).center())
- << outerLink;
+ << outerLink
+ << outerLink << outerLink;
QTest::newRow("click on right outer link")
<< nestedText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(27).center())
- << outerLink;
+ << outerLink
+ << outerLink << outerLink;
QTest::newRow("click on inner link left")
<< nestedText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(23).center())
- << innerLink;
+ << innerLink
+ << innerLink << innerLink;
QTest::newRow("click on inner link right")
<< nestedText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(26).center())
- << innerLink;
+ << innerLink
+ << innerLink << innerLink;
QTest::newRow("drag from inner to outer link")
<< nestedText << 240.
<< ""
<< (PointVector()
<< metrics.characterRectangle(25).center()
<< metrics.characterRectangle(30).center())
- << QString();
+ << QString()
+ << innerLink << outerLink;
QTest::newRow("drag from outer to inner link")
<< nestedText << 240.
<< ""
<< (PointVector()
<< metrics.characterRectangle(30).center()
<< metrics.characterRectangle(25).center())
- << QString();
+ << QString()
+ << outerLink << innerLink;
QTest::newRow("click on left outer rich text link")
<< nestedText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(22).center())
- << outerLink;
+ << outerLink
+ << outerLink << outerLink;
QTest::newRow("click on right outer rich text link")
<< nestedText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(27).center())
- << outerLink;
+ << outerLink
+ << outerLink << outerLink;
QTest::newRow("click on inner rich text link left")
<< nestedText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(23).center())
- << innerLink;
+ << innerLink
+ << innerLink << innerLink;
QTest::newRow("click on inner rich text link right")
<< nestedText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(26).center())
- << innerLink;
+ << innerLink
+ << innerLink << innerLink;
QTest::newRow("drag from inner to outer rich text link")
<< nestedText << 240.
<< "textFormat: Text.RichText"
<< (PointVector()
<< metrics.characterRectangle(25).center()
<< metrics.characterRectangle(30).center())
- << QString();
+ << QString()
+ << innerLink << outerLink;
QTest::newRow("drag from outer to inner rich text link")
<< nestedText << 240.
<< "textFormat: Text.RichText"
<< (PointVector()
<< metrics.characterRectangle(30).center()
<< metrics.characterRectangle(25).center())
- << QString();
+ << QString()
+ << outerLink << innerLink;
}
}
-void tst_qquicktext::clickLink()
+void tst_qquicktext::linkInteraction()
{
QFETCH(QString, text);
QFETCH(qreal, width);
QFETCH(QString, bindings);
QFETCH(PointVector, mousePositions);
- QFETCH(QString, link);
+ QFETCH(QString, clickedLink);
+ QFETCH(QString, hoverEnterLink);
+ QFETCH(QString, hoverMoveLink);
QString componentStr =
- "import QtQuick 2.0\nText {\n"
+ "import QtQuick 2.2\nText {\n"
"width: " + QString::number(width) + "\n"
"height: 320\n"
"text: \"" + text + "\"\n"
@@ -1813,28 +1867,46 @@ void tst_qquicktext::clickLink()
LinkTest test;
QObject::connect(textObject, SIGNAL(linkActivated(QString)), &test, SLOT(linkClicked(QString)));
+ QObject::connect(textObject, SIGNAL(linkHovered(QString)), &test, SLOT(linkHovered(QString)));
QVERIFY(mousePositions.count() > 0);
QPointF mousePosition = mousePositions.first();
{
+ QHoverEvent he(QEvent::HoverEnter, mousePosition, QPointF());
+ static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&he);
+
QMouseEvent me(QEvent::MouseButtonPress, mousePosition, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
}
+ QCOMPARE(test.hoveredLink, hoverEnterLink);
+ QCOMPARE(textObject->hoveredLink(), hoverEnterLink);
+
for (int i = 1; i < mousePositions.count(); ++i) {
mousePosition = mousePositions.at(i);
+ QHoverEvent he(QEvent::HoverMove, mousePosition, QPointF());
+ static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&he);
+
QMouseEvent me(QEvent::MouseMove, mousePosition, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
}
+ QCOMPARE(test.hoveredLink, hoverMoveLink);
+ QCOMPARE(textObject->hoveredLink(), hoverMoveLink);
+
{
+ QHoverEvent he(QEvent::HoverLeave, mousePosition, QPointF());
+ static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&he);
+
QMouseEvent me(QEvent::MouseButtonRelease, mousePosition, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
}
- QCOMPARE(test.link, link);
+ QCOMPARE(test.clickedLink, clickedLink);
+ QCOMPARE(test.hoveredLink, QString());
+ QCOMPARE(textObject->hoveredLink(), QString());
delete textObject;
}
@@ -3638,6 +3710,18 @@ void tst_qquicktext::htmlLists_data()
QTest::newRow("unordered list bad") << "<ul type=\"bad\"><li>one</li><li>two</li></ul>" << 2;
}
+void tst_qquicktext::elideBeforeMaximumLineCount()
+{ // QTBUG-31471
+ QQmlComponent component(&engine, testFile("elideBeforeMaximumLineCount.qml"));
+
+ QScopedPointer<QObject> object(component.create());
+
+ QQuickText *item = qobject_cast<QQuickText *>(object.data());
+ QVERIFY(item);
+
+ QCOMPARE(item->lineCount(), 2);
+}
+
QTEST_MAIN(tst_qquicktext)
#include "tst_qquicktext.moc"
diff --git a/tests/auto/quick/qquicktextedit/data/linkActivated.qml b/tests/auto/quick/qquicktextedit/data/linkInteraction.qml
index d3bba82b59..d3bba82b59 100644
--- a/tests/auto/quick/qquicktextedit/data/linkActivated.qml
+++ b/tests/auto/quick/qquicktextedit/data/linkInteraction.qml
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
index 2db79d7794..09ea35cd9e 100644
--- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
@@ -144,7 +144,7 @@ private slots:
void positionAt_data();
void positionAt();
- void linkActivated();
+ void linkInteraction();
void cursorDelegate_data();
void cursorDelegate();
@@ -183,6 +183,8 @@ private slots:
void getText();
void getFormattedText_data();
void getFormattedText();
+ void append_data();
+ void append();
void insert_data();
void insert();
void remove_data();
@@ -2342,9 +2344,9 @@ void tst_qquicktextedit::positionAt()
QVERIFY(texteditObject->positionAt(x0 / 2, y1) > 0);
}
-void tst_qquicktextedit::linkActivated()
+void tst_qquicktextedit::linkInteraction()
{
- QQuickView window(testFileUrl("linkActivated.qml"));
+ QQuickView window(testFileUrl("linkInteraction.qml"));
QVERIFY(window.rootObject() != 0);
window.show();
window.requestActivate();
@@ -2354,6 +2356,7 @@ void tst_qquicktextedit::linkActivated()
QVERIFY(texteditObject != 0);
QSignalSpy spy(texteditObject, SIGNAL(linkActivated(QString)));
+ QSignalSpy hover(texteditObject, SIGNAL(linkHovered(QString)));
const QString link("http://example.com/");
@@ -2362,21 +2365,31 @@ void tst_qquicktextedit::linkActivated()
QTest::mouseClick(&window, Qt::LeftButton, 0, linkPos.toPoint());
QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(hover.count(), 1);
QCOMPARE(spy.last()[0].toString(), link);
+ QCOMPARE(hover.last()[0].toString(), link);
+ QCOMPARE(texteditObject->hoveredLink(), link);
QTest::mouseClick(&window, Qt::LeftButton, 0, textPos.toPoint());
- QTest::qWait(50);
- QCOMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(hover.count(), 2);
+ QCOMPARE(hover.last()[0].toString(), QString());
+ QCOMPARE(texteditObject->hoveredLink(), QString());
texteditObject->setReadOnly(true);
QTest::mouseClick(&window, Qt::LeftButton, 0, linkPos.toPoint());
QTRY_COMPARE(spy.count(), 2);
+ QTRY_COMPARE(hover.count(), 3);
QCOMPARE(spy.last()[0].toString(), link);
+ QCOMPARE(hover.last()[0].toString(), link);
+ QCOMPARE(texteditObject->hoveredLink(), link);
QTest::mouseClick(&window, Qt::LeftButton, 0, textPos.toPoint());
- QTest::qWait(50);
- QCOMPARE(spy.count(), 2);
+ QTRY_COMPARE(spy.count(), 2);
+ QTRY_COMPARE(hover.count(), 4);
+ QCOMPARE(hover.last()[0].toString(), QString());
+ QCOMPARE(texteditObject->hoveredLink(), QString());
}
void tst_qquicktextedit::cursorDelegate_data()
@@ -3817,6 +3830,158 @@ void tst_qquicktextedit::getFormattedText()
}
}
+void tst_qquicktextedit::append_data()
+{
+ QTest::addColumn<QString>("text");
+ QTest::addColumn<QQuickTextEdit::TextFormat>("textFormat");
+ QTest::addColumn<int>("selectionStart");
+ QTest::addColumn<int>("selectionEnd");
+ QTest::addColumn<QString>("appendText");
+ QTest::addColumn<QString>("expectedText");
+ QTest::addColumn<int>("expectedSelectionStart");
+ QTest::addColumn<int>("expectedSelectionEnd");
+ QTest::addColumn<int>("expectedCursorPosition");
+ QTest::addColumn<bool>("selectionChanged");
+ QTest::addColumn<bool>("cursorPositionChanged");
+
+ QTest::newRow("cursor kept intact (beginning)")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 0 << 0
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << 0 << 0 << 0
+ << false << false;
+
+ QTest::newRow("cursor kept intact (middle)")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 18 << 18
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << 18 << 18 << 18
+ << false << false;
+
+ QTest::newRow("cursor follows (end)")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << standard.at(0).length() << standard.at(0).length()
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << standard.at(0).length() + 6 << standard.at(0).length() + 6 << standard.at(0).length() + 6
+ << false << true;
+
+ QTest::newRow("selection kept intact (beginning)")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 0 << 18
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << 0 << 18 << 18
+ << false << false;
+
+ QTest::newRow("selection kept intact (middle)")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 14 << 18
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << 14 << 18 << 18
+ << false << false;
+
+ QTest::newRow("selection kept intact, cursor follows (end)")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 18 << standard.at(0).length()
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << 18 << standard.at(0).length() + 6 << standard.at(0).length() + 6
+ << false << true;
+
+ QTest::newRow("reversed selection kept intact")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 18 << 14
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << 14 << 18 << 14
+ << false << false;
+
+ QTest::newRow("rich text into plain text")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 0 << 0
+ << QString("<b>Hello</b>")
+ << standard.at(0) + QString("\n<b>Hello</b>")
+ << 0 << 0 << 0
+ << false << false;
+
+ QTest::newRow("rich text into rich text")
+ << standard.at(0) << QQuickTextEdit::RichText
+ << 0 << 0
+ << QString("<b>Hello</b>")
+ << standard.at(0) + QChar(QChar::ParagraphSeparator) + QString("Hello")
+ << 0 << 0 << 0
+ << false << false;
+
+ QTest::newRow("rich text into auto text")
+ << standard.at(0) << QQuickTextEdit::AutoText
+ << 0 << 0
+ << QString("<b>Hello</b>")
+ << standard.at(0) + QString("\nHello")
+ << 0 << 0 << 0
+ << false << false;
+}
+
+void tst_qquicktextedit::append()
+{
+ QFETCH(QString, text);
+ QFETCH(QQuickTextEdit::TextFormat, textFormat);
+ QFETCH(int, selectionStart);
+ QFETCH(int, selectionEnd);
+ QFETCH(QString, appendText);
+ QFETCH(QString, expectedText);
+ QFETCH(int, expectedSelectionStart);
+ QFETCH(int, expectedSelectionEnd);
+ QFETCH(int, expectedCursorPosition);
+ QFETCH(bool, selectionChanged);
+ QFETCH(bool, cursorPositionChanged);
+
+ QString componentStr = "import QtQuick 2.2\nTextEdit { text: \"" + text + "\" }";
+ QQmlComponent textEditComponent(&engine);
+ textEditComponent.setData(componentStr.toLatin1(), QUrl());
+ QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(textEditComponent.create());
+ QVERIFY(textEdit != 0);
+
+ textEdit->setTextFormat(textFormat);
+ textEdit->select(selectionStart, selectionEnd);
+
+ QSignalSpy selectionSpy(textEdit, SIGNAL(selectedTextChanged()));
+ QSignalSpy selectionStartSpy(textEdit, SIGNAL(selectionStartChanged()));
+ QSignalSpy selectionEndSpy(textEdit, SIGNAL(selectionEndChanged()));
+ QSignalSpy textSpy(textEdit, SIGNAL(textChanged()));
+ QSignalSpy cursorPositionSpy(textEdit, SIGNAL(cursorPositionChanged()));
+
+ textEdit->append(appendText);
+
+ if (textFormat == QQuickTextEdit::RichText || (textFormat == QQuickTextEdit::AutoText && (
+ Qt::mightBeRichText(text) || Qt::mightBeRichText(appendText)))) {
+ QCOMPARE(textEdit->getText(0, expectedText.length()), expectedText);
+ } else {
+ QCOMPARE(textEdit->text(), expectedText);
+
+ }
+ QCOMPARE(textEdit->length(), expectedText.length());
+
+ QCOMPARE(textEdit->selectionStart(), expectedSelectionStart);
+ QCOMPARE(textEdit->selectionEnd(), expectedSelectionEnd);
+ QCOMPARE(textEdit->cursorPosition(), expectedCursorPosition);
+
+ if (selectionStart > selectionEnd)
+ qSwap(selectionStart, selectionEnd);
+
+ QEXPECT_FAIL("into selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue);
+ QEXPECT_FAIL("into reversed selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue);
+ QCOMPARE(selectionSpy.count() > 0, selectionChanged);
+ QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart);
+ QEXPECT_FAIL("into reversed selection", "selectionEndChanged signal not emitted", Continue);
+ QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd);
+ QCOMPARE(textSpy.count() > 0, text != expectedText);
+ QCOMPARE(cursorPositionSpy.count() > 0, cursorPositionChanged);
+}
+
void tst_qquicktextedit::insert_data()
{
QTest::addColumn<QString>("text");
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index b1648cbed2..7a61ceb7fd 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -3149,6 +3149,7 @@ void tst_qquicktextinput::echoMode()
QCOMPARE(initial, QLatin1String("ABCDefgh"));
QCOMPARE(input->echoMode(), QQuickTextInput::Normal);
QCOMPARE(input->displayText(), input->text());
+ const QString passwordMaskCharacter = qApp->styleHints()->passwordMaskCharacter();
//Normal
ref &= ~Qt::ImhHiddenText;
ref &= ~(Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData);
@@ -3156,7 +3157,7 @@ void tst_qquicktextinput::echoMode()
input->setEchoMode(QQuickTextInput::NoEcho);
QCOMPARE(input->text(), initial);
QCOMPARE(input->displayText(), QLatin1String(""));
- QCOMPARE(input->passwordCharacter(), QLatin1String("*"));
+ QCOMPARE(input->passwordCharacter(), passwordMaskCharacter);
//NoEcho
ref |= Qt::ImhHiddenText;
ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData);
@@ -3166,7 +3167,7 @@ void tst_qquicktextinput::echoMode()
ref |= Qt::ImhHiddenText;
ref |= (Qt::ImhNoAutoUppercase | Qt::ImhNoPredictiveText | Qt::ImhSensitiveData);
QCOMPARE(input->text(), initial);
- QCOMPARE(input->displayText(), QLatin1String("********"));
+ QCOMPARE(input->displayText(), QString(8, passwordMaskCharacter.at(0)));
QCOMPARE((Qt::InputMethodHints) input->inputMethodQuery(Qt::ImHints).toInt(), ref);
// clearing input hints do not clear bits set by echo mode
input->setInputMethodHints(Qt::ImhNone);
@@ -3221,7 +3222,7 @@ void tst_qquicktextinput::passwordEchoDelay()
QQuickItem *cursor = input->findChild<QQuickItem *>("cursor");
QVERIFY(cursor);
- QChar fillChar = QLatin1Char('*');
+ QChar fillChar = qApp->styleHints()->passwordMaskCharacter();
input->setEchoMode(QQuickTextInput::Password);
QCOMPARE(input->displayText(), QString(8, fillChar));
@@ -6124,6 +6125,12 @@ void tst_qquicktextinput::keypress_inputMask_data()
keys << Qt::Key_Home << "12ab";
QTest::newRow("uppercase") << QString("9999 >AA;_") << keys << QString("12 AB") << QString("12__ AB");
}
+ {
+ KeyList keys;
+ // inserting '12ab'
+ keys << Qt::Key_Right << Qt::Key_Right << "1";
+ QTest::newRow("Move in mask") << QString("#0:00;*") << keys << QString(":1") << QString("**:1*");
+ }
}
void tst_qquicktextinput::keypress_inputMask()
diff --git a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
index d16bf81d88..d374d71280 100644
--- a/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
+++ b/tests/auto/quick/qquickvisualdatamodel/tst_qquickvisualdatamodel.cpp
@@ -615,6 +615,7 @@ void tst_qquickvisualdatamodel::childChanged()
vdm->setRootIndex(QVariant::fromValue(model.indexFromItem(model.item(1,0))));
QCOMPARE(listview->count(), 1);
+ listview->forceLayout();
QQuickText *name = findItem<QQuickText>(contentItem, "display", 0);
QVERIFY(name);
QCOMPARE(name->text(), QString("Row 2 Child Item"));
@@ -628,6 +629,7 @@ void tst_qquickvisualdatamodel::childChanged()
model.item(1,0)->appendRow(new QStandardItem(QLatin1String("Row 2 Child Item 2")));
QCOMPARE(listview->count(), 2);
+ listview->forceLayout();
name = findItem<QQuickText>(contentItem, "display", 1);
QVERIFY(name != 0);
QCOMPARE(name->text(), QString("Row 2 Child Item 2"));
@@ -638,6 +640,8 @@ void tst_qquickvisualdatamodel::childChanged()
vdm->setRootIndex(QVariant::fromValue(QModelIndex()));
QCOMPARE(listview->count(), 3);
+
+ listview->forceLayout();
name = findItem<QQuickText>(contentItem, "display", 0);
QVERIFY(name);
QCOMPARE(name->text(), QString("Row 1 Item"));
@@ -989,6 +993,8 @@ void tst_qquickvisualdatamodel::packagesDestroyed()
QQuickItem *rightContent = rightview->contentItem();
QTRY_VERIFY(rightContent != 0);
+ leftview->forceLayout();
+ rightview->forceLayout();
QCOMPARE(leftview->currentIndex(), 0);
QCOMPARE(rightview->currentIndex(), 0);
@@ -3548,6 +3554,7 @@ void tst_qquickvisualdatamodel::resolve()
evaluate<void>(visualModel, setupExpression);
QCOMPARE(evaluate<int>(listView, "count"), unresolvedCount);
+ listView->forceLayout();
evaluate<void>(visualModel, resolveExpression);
QCOMPARE(evaluate<int>(listView, "count"), inItems ? visualCount : modelCount);
diff --git a/tests/auto/quick/qquickwindow/data/active.qml b/tests/auto/quick/qquickwindow/data/active.qml
new file mode 100644
index 0000000000..af0b7edeb2
--- /dev/null
+++ b/tests/auto/quick/qquickwindow/data/active.qml
@@ -0,0 +1,29 @@
+import QtQuick 2.1
+import QtQuick.Window 2.1
+
+Window {
+ id: window1;
+ objectName: "window1";
+ color: "#00FF00";
+ width: 100; height: 100;
+ Item {
+ objectName: "item1"
+ width: 100; height: 100;
+ MouseArea {
+ objectName: "mousearea"
+ anchors.fill: parent;
+ onPressed: window2.requestActivate();
+ }
+ Component.onCompleted: window2.show();
+ }
+
+ Window {
+ id: window2;
+ objectName: "window2";
+ color: "#FF0000";
+ width: 100; height: 100;
+ Item {
+ width: 100; height: 100;
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickwindow/data/ucantclosethis.qml b/tests/auto/quick/qquickwindow/data/ucantclosethis.qml
new file mode 100644
index 0000000000..aa68cf5105
--- /dev/null
+++ b/tests/auto/quick/qquickwindow/data/ucantclosethis.qml
@@ -0,0 +1,32 @@
+import QtQuick 2.1
+import QtQuick.Window 2.1
+
+Window {
+ width: 240
+ height: 75
+ title: "Hammer sez"
+ color: "#e0c31e"
+ property bool canCloseThis: false;
+ Rectangle {
+ color: "#14148c"
+ width: parent.width * 0.85
+ height: parent.height * 0.7
+ anchors.horizontalCenter: parent.horizontalCenter
+ Text {
+ id: text
+ anchors.centerIn: parent
+ color: "white"
+ textFormat: Text.StyledText
+ text: "whoa-oa-oa-oh<br/>U can't <font color='#b40000' size='+1'>close</font> this"
+ }
+ }
+ onClosing: {
+ if (canCloseThis) {
+ text.text = "uncle! I give up"
+ // the event is accepted by default
+ } else {
+ close.accepted = false
+ text.text = "...but you still can't close this"
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickwindow/qquickwindow.pro b/tests/auto/quick/qquickwindow/qquickwindow.pro
index 05b58fcb4c..46cf96423f 100644
--- a/tests/auto/quick/qquickwindow/qquickwindow.pro
+++ b/tests/auto/quick/qquickwindow/qquickwindow.pro
@@ -11,6 +11,7 @@ QT += core-private gui-private qml-private quick-private testlib
TESTDATA = data/*
OTHER_FILES += \
+ data/active.qml \
data/AnimationsWhileHidden.qml \
data/Headless.qml \
data/showHideAnimate.qml
diff --git a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
index 2d3c8f7ca7..e2bb6b431c 100644
--- a/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/auto/quick/qquickwindow/tst_qquickwindow.cpp
@@ -48,6 +48,7 @@
#include <QtQml/QQmlComponent>
#include <QtQuick/private/qquickrectangle_p.h>
#include "../../shared/util.h"
+#include "../shared/visualtestutil.h"
#include <QSignalSpy>
#include <qpa/qwindowsysteminterface.h>
#include <private/qquickwindow_p.h>
@@ -304,6 +305,7 @@ private slots:
void qmlCreation();
void clearColor();
+ void grab_data();
void grab();
void multipleWindows();
@@ -322,6 +324,10 @@ private slots:
void testExpose();
+ void requestActivate();
+
+ void blockClosing();
+
#ifndef QT_NO_CURSOR
void cursor();
#endif
@@ -929,15 +935,28 @@ void tst_qquickwindow::clearColor()
QCOMPARE(window->color(), QColor(Qt::blue));
}
+void tst_qquickwindow::grab_data()
+{
+ QTest::addColumn<bool>("visible");
+ QTest::newRow("visible") << true;
+ QTest::newRow("invisible") << false;
+}
+
void tst_qquickwindow::grab()
{
+ QFETCH(bool, visible);
+
QQuickWindow window;
window.setColor(Qt::red);
window.resize(250, 250);
- window.show();
- QVERIFY(QTest::qWaitForWindowExposed(&window));
+ if (visible) {
+ window.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&window));
+ } else {
+ window.create();
+ }
QImage content = window.grabWindow();
QCOMPARE(content.width(), window.width());
@@ -1400,6 +1419,74 @@ void tst_qquickwindow::testExpose()
QTRY_COMPARE(swapSpy.size(), 1);
}
+void tst_qquickwindow::requestActivate()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("active.qml"));
+ QQuickWindow* window1 = qobject_cast<QQuickWindow *>(component.create());
+ QVERIFY(window1);
+
+ QWindowList windows = QGuiApplication::topLevelWindows();
+ QVERIFY(windows.size() == 2);
+
+ for (int i = 0; i < windows.size(); ++i) {
+ if (windows.at(i)->objectName() == window1->objectName()) {
+ windows.removeAt(i);
+ break;
+ }
+ }
+ QVERIFY(windows.size() == 1);
+ QVERIFY(windows.at(0)->objectName() == "window2");
+
+ window1->show();
+ window1->requestActivate();
+
+ QTRY_VERIFY(QGuiApplication::focusWindow() == window1);
+ QVERIFY(window1->isActive() == true);
+
+ QQuickItem *item = QQuickVisualTestUtil::findItem<QQuickItem>(window1->contentItem(), "item1");
+ QVERIFY(item);
+
+ //copied from src/qmltest/quicktestevent.cpp
+ QPoint pos = item->mapToScene(QPointF(item->width()/2, item->height()/2)).toPoint();
+
+ QMouseEvent me(QEvent::MouseButtonPress, pos, window1->mapToGlobal(pos), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ QSpontaneKeyEvent::setSpontaneous(&me);
+ if (!qApp->notify(window1, &me)) {
+ 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, 0, Qt::NoModifier);
+ QSpontaneKeyEvent::setSpontaneous(&me);
+ if (!qApp->notify(window1, &me)) {
+ QString warning = QString::fromLatin1("Mouse event MouseRelease not accepted by receiving window");
+ QWARN(warning.toLatin1().data());
+ }
+
+ QTRY_VERIFY(QGuiApplication::focusWindow() == windows.at(0));
+ QVERIFY(windows.at(0)->isActive());
+}
+
+void tst_qquickwindow::blockClosing()
+{
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadUrl(testFileUrl("ucantclosethis.qml"));
+ QQuickWindow* window = qobject_cast<QQuickWindow *>(component.create());
+ QVERIFY(window);
+ window->show();
+ QTest::qWaitForWindowExposed(window);
+ QVERIFY(window->isVisible());
+ QWindowSystemInterface::handleCloseEvent(window);
+ QVERIFY(window->isVisible());
+ QWindowSystemInterface::handleCloseEvent(window);
+ QVERIFY(window->isVisible());
+ window->setProperty("canCloseThis", true);
+ QWindowSystemInterface::handleCloseEvent(window);
+ QTRY_VERIFY(!window->isVisible());
+}
+
QTEST_MAIN(tst_qquickwindow)
#include "tst_qquickwindow.moc"
diff --git a/tests/auto/quick/touchmouse/tst_touchmouse.cpp b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
index 15a4f0cc27..4779942406 100644
--- a/tests/auto/quick/touchmouse/tst_touchmouse.cpp
+++ b/tests/auto/quick/touchmouse/tst_touchmouse.cpp
@@ -195,8 +195,9 @@ void tst_TouchMouse::simpleTouchEvent()
window->setSource(testFileUrl("singleitem.qml"));
window->show();
- window->requestActivate();
QVERIFY(QTest::qWaitForWindowExposed(window));
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
QVERIFY(window->rootObject() != 0);
EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
@@ -344,7 +345,9 @@ void tst_TouchMouse::mouse()
window->setSource(testFileUrl("twoitems.qml"));
window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
QVERIFY(window->rootObject() != 0);
EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
@@ -376,7 +379,9 @@ void tst_TouchMouse::touchOverMouse()
window->setSource(testFileUrl("twoitems.qml"));
window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
QVERIFY(window->rootObject() != 0);
EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
@@ -417,7 +422,9 @@ void tst_TouchMouse::mouseOverTouch()
window->setSource(testFileUrl("twoitems.qml"));
window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
QVERIFY(window->rootObject() != 0);
EventItem *eventItem1 = window->rootObject()->findChild<EventItem*>("eventItem1");
@@ -461,7 +468,9 @@ void tst_TouchMouse::buttonOnFlickable()
window->setSource(testFileUrl("buttononflickable.qml"));
window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
QVERIFY(window->rootObject() != 0);
QQuickFlickable *flickable = window->rootObject()->findChild<QQuickFlickable*>("flickable");
@@ -569,7 +578,9 @@ void tst_TouchMouse::buttonOnTouch()
QQuickView *window = createView();
window->setSource(testFileUrl("buttonontouch.qml"));
window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
QVERIFY(window->rootObject() != 0);
QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea");
@@ -691,7 +702,9 @@ void tst_TouchMouse::pinchOnFlickable()
QQuickView *window = createView();
window->setSource(testFileUrl("pinchonflickable.qml"));
window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
QVERIFY(window->rootObject() != 0);
QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea");
@@ -758,7 +771,9 @@ void tst_TouchMouse::flickableOnPinch()
QQuickView *window = createView();
window->setSource(testFileUrl("flickableonpinch.qml"));
window->show();
+ QVERIFY(QTest::qWaitForWindowExposed(window));
window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
QVERIFY(window->rootObject() != 0);
QQuickPinchArea *pinchArea = window->rootObject()->findChild<QQuickPinchArea*>("pincharea");
@@ -935,8 +950,9 @@ void tst_TouchMouse::tapOnDismissiveTopMouseAreaClicksBottomOne()
window->setSource(testFileUrl("twoMouseAreas.qml"));
window->show();
- window->requestActivate();
QVERIFY(QTest::qWaitForWindowExposed(window));
+ window->requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(window));
QVERIFY(window->rootObject() != 0);
QQuickMouseArea *bottomMouseArea =