diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index 2fd79715e1463505d868249e46098e9f0465cdca..93cb5e4e9dd56bb880c3f1341cfc079f4fc61cc4 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -273,9 +273,13 @@ QVariant QQuickItemView::model() const return d->modelVariant; } -void QQuickItemView::setModel(const QVariant &model) +void QQuickItemView::setModel(const QVariant &m) { Q_D(QQuickItemView); + QVariant model = m; + if (model.userType() == qMetaTypeId<QJSValue>()) + model = model.value<QJSValue>().toVariant(); + if (d->modelVariant == model) return; if (d->model) { diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 825845eca927c6bf391292f64a44c7908e948362..6cf3e33de93dc525800297e235a14ae03cb70b46 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -607,9 +607,13 @@ QVariant QQuickPathView::model() const return d->modelVariant; } -void QQuickPathView::setModel(const QVariant &model) +void QQuickPathView::setModel(const QVariant &m) { Q_D(QQuickPathView); + QVariant model = m; + if (model.userType() == qMetaTypeId<QJSValue>()) + model = model.value<QJSValue>().toVariant(); + if (d->modelVariant == model) return; diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp index 8e13947d781fdc4e9aa0bf5b5f75f04cd46e465a..e2a30438574694af7656fe2272a40a550ffa355d 100644 --- a/src/quick/items/qquickrepeater.cpp +++ b/src/quick/items/qquickrepeater.cpp @@ -183,9 +183,13 @@ QVariant QQuickRepeater::model() const return d->dataSource; } -void QQuickRepeater::setModel(const QVariant &model) +void QQuickRepeater::setModel(const QVariant &m) { Q_D(QQuickRepeater); + QVariant model = m; + if (model.userType() == qMetaTypeId<QJSValue>()) + model = model.value<QJSValue>().toVariant(); + if (d->dataSource == model) return; diff --git a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp index b65aad543df5600c017f942b822bef387dfef2f9..123d7f503225ddfc96d3c620e5271fe06ba85930 100644 --- a/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp +++ b/tests/auto/quick/qquickgridview/tst_qquickgridview.cpp @@ -204,6 +204,8 @@ private slots: void displayMargin(); void negativeDisplayMargin(); + void jsArrayChange(); + private: QList<int> toIntList(const QVariantList &list); void matchIndexLists(const QVariantList &indexLists, const QList<int> &expectedIndexes); @@ -6430,6 +6432,33 @@ void tst_QQuickGridView::negativeDisplayMargin() delete window; } +void tst_QQuickGridView::jsArrayChange() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData("import QtQuick 2.4; GridView {}", QUrl()); + + QScopedPointer<QQuickGridView> view(qobject_cast<QQuickGridView *>(component.create())); + QVERIFY(!view.isNull()); + + QSignalSpy spy(view.data(), SIGNAL(modelChanged())); + QVERIFY(spy.isValid()); + + QJSValue array1 = engine.newArray(3); + QJSValue array2 = engine.newArray(3); + for (int i = 0; i < 3; ++i) { + array1.setProperty(i, i); + array2.setProperty(i, i); + } + + view->setModel(QVariant::fromValue(array1)); + QCOMPARE(spy.count(), 1); + + // no change + view->setModel(QVariant::fromValue(array2)); + QCOMPARE(spy.count(), 1); +} + QTEST_MAIN(tst_QQuickGridView) #include "tst_qquickgridview.moc" diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 5122b6aa388aa13ad74af7b83be20e95e2ce4564..9e8a813d5401d358a7095b4bfb78cd3081b6e1e7 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -239,6 +239,8 @@ private slots: void QTBUG_39492_data(); void QTBUG_39492(); + void jsArrayChange(); + private: template <class T> void items(const QUrl &source); template <class T> void changed(const QUrl &source); @@ -7945,6 +7947,33 @@ void tst_QQuickListView::QTBUG_39492() releaseView(window); } +void tst_QQuickListView::jsArrayChange() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData("import QtQuick 2.4; ListView {}", QUrl()); + + QScopedPointer<QQuickListView> view(qobject_cast<QQuickListView *>(component.create())); + QVERIFY(!view.isNull()); + + QSignalSpy spy(view.data(), SIGNAL(modelChanged())); + QVERIFY(spy.isValid()); + + QJSValue array1 = engine.newArray(3); + QJSValue array2 = engine.newArray(3); + for (int i = 0; i < 3; ++i) { + array1.setProperty(i, i); + array2.setProperty(i, i); + } + + view->setModel(QVariant::fromValue(array1)); + QCOMPARE(spy.count(), 1); + + // no change + view->setModel(QVariant::fromValue(array2)); + QCOMPARE(spy.count(), 1); +} + QTEST_MAIN(tst_QQuickListView) #include "tst_qquicklistview.moc" diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index 0e9994899f9d1e9567af9a6bccfc71c783d34231..992b2347dd2a95e2c4d9984f7fca6d7a0361f439 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -139,6 +139,7 @@ private slots: void changePathDuringRefill(); void nestedinFlickable(); void flickableDelegate(); + void jsArrayChange(); }; class TestObject : public QObject @@ -2290,6 +2291,33 @@ void tst_QQuickPathView::flickableDelegate() QCOMPARE(moveStartedSpy.count(), 0); } +void tst_QQuickPathView::jsArrayChange() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData("import QtQuick 2.4; PathView {}", QUrl()); + + QScopedPointer<QQuickPathView> view(qobject_cast<QQuickPathView *>(component.create())); + QVERIFY(!view.isNull()); + + QSignalSpy spy(view.data(), SIGNAL(modelChanged())); + QVERIFY(spy.isValid()); + + QJSValue array1 = engine.newArray(3); + QJSValue array2 = engine.newArray(3); + for (int i = 0; i < 3; ++i) { + array1.setProperty(i, i); + array2.setProperty(i, i); + } + + view->setModel(QVariant::fromValue(array1)); + QCOMPARE(spy.count(), 1); + + // no change + view->setModel(QVariant::fromValue(array2)); + QCOMPARE(spy.count(), 1); +} + QTEST_MAIN(tst_QQuickPathView) #include "tst_qquickpathview.moc" diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp index 1396dd4783700c2235f6c2ffda8eb71969279903..258eaee981746ea8f57409fec9768fcd7b1a08be 100644 --- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp +++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp @@ -72,6 +72,7 @@ private slots: void dynamicModelCrash(); void visualItemModelCrash(); void invalidContextCrash(); + void jsArrayChange(); }; class TestObject : public QObject @@ -779,6 +780,33 @@ void tst_QQuickRepeater::invalidContextCrash() root.reset(0); } +void tst_QQuickRepeater::jsArrayChange() +{ + QQmlEngine engine; + QQmlComponent component(&engine); + component.setData("import QtQuick 2.4; Repeater {}", QUrl()); + + QScopedPointer<QQuickRepeater> repeater(qobject_cast<QQuickRepeater *>(component.create())); + QVERIFY(!repeater.isNull()); + + QSignalSpy spy(repeater.data(), SIGNAL(modelChanged())); + QVERIFY(spy.isValid()); + + QJSValue array1 = engine.newArray(3); + QJSValue array2 = engine.newArray(3); + for (int i = 0; i < 3; ++i) { + array1.setProperty(i, i); + array2.setProperty(i, i); + } + + repeater->setModel(QVariant::fromValue(array1)); + QCOMPARE(spy.count(), 1); + + // no change + repeater->setModel(QVariant::fromValue(array2)); + QCOMPARE(spy.count(), 1); +} + QTEST_MAIN(tst_QQuickRepeater) #include "tst_qquickrepeater.moc"