aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2012-07-17 10:47:45 +1000
committerQt by Nokia <qt-info@nokia.com>2012-07-17 12:49:15 +0200
commit6a79d26b8353c241c3ffa21931efa279eeee1a28 (patch)
tree7be32929c6cc179a25eb16270e5713f23fd037ea
parentba94fbedd648b04a28d67b920db2883e73459d1f (diff)
Don't double reference items created following a model reset.
If the model was reset then regenerate and exit immediately rather than processing the change set. Task-number: QTBUG-26536 Change-Id: I9d4f20d450a5116957c9468ba6088caad026a497 Reviewed-by: Martin Jones <martin.jones@nokia.com>
-rw-r--r--src/quick/items/qquickrepeater.cpp4
-rw-r--r--tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp79
-rw-r--r--tests/auto/quick/shared/viewtestutil.cpp7
-rw-r--r--tests/auto/quick/shared/viewtestutil.h1
4 files changed, 90 insertions, 1 deletions
diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp
index 31609515c7..8ebdccf7d9 100644
--- a/src/quick/items/qquickrepeater.cpp
+++ b/src/quick/items/qquickrepeater.cpp
@@ -427,7 +427,9 @@ void QQuickRepeater::modelUpdated(const QQuickChangeSet &changeSet, bool reset)
if (reset) {
regenerate();
- emit countChanged();
+ if (changeSet.difference() != 0)
+ emit countChanged();
+ return;
}
int difference = 0;
diff --git a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
index 171e3301d9..0fb2416808 100644
--- a/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
+++ b/tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
@@ -74,6 +74,7 @@ private slots:
void itemModel();
void resetModel();
void modelChanged();
+ void modelReset();
void properties();
void asynchronous();
void initParent();
@@ -543,6 +544,84 @@ void tst_QQuickRepeater::modelChanged()
delete rootObject;
}
+void tst_QQuickRepeater::modelReset()
+{
+ QaimModel model;
+
+ QQmlEngine engine;
+ QQmlContext *ctxt = engine.rootContext();
+ ctxt->setContextProperty("testData", &model);
+
+ QQmlComponent component(&engine, testFileUrl("repeater2.qml"));
+ QScopedPointer<QObject> object(component.create());
+ QQuickItem *rootItem = qobject_cast<QQuickItem *>(object.data());
+ QVERIFY(rootItem);
+
+ QQuickRepeater *repeater = findItem<QQuickRepeater>(rootItem, "repeater");
+ QVERIFY(repeater != 0);
+ QQuickItem *container = findItem<QQuickItem>(rootItem, "container");
+ QVERIFY(container != 0);
+
+ QCOMPARE(repeater->count(), 0);
+
+ QSignalSpy countSpy(repeater, SIGNAL(countChanged()));
+ QSignalSpy addedSpy(repeater, SIGNAL(itemAdded(int,QQuickItem*)));
+ QSignalSpy removedSpy(repeater, SIGNAL(itemRemoved(int,QQuickItem*)));
+
+
+ QList<QPair<QString, QString> > items = QList<QPair<QString, QString> >()
+ << qMakePair(QString::fromLatin1("one"), QString::fromLatin1("1"))
+ << qMakePair(QString::fromLatin1("two"), QString::fromLatin1("2"))
+ << qMakePair(QString::fromLatin1("three"), QString::fromLatin1("3"));
+
+ model.resetItems(items);
+
+ QCOMPARE(countSpy.count(), 1);
+ QCOMPARE(removedSpy.count(), 0);
+ QCOMPARE(addedSpy.count(), items.count());
+ for (int i = 0; i< items.count(); i++) {
+ QCOMPARE(addedSpy.at(i).at(0).toInt(), i);
+ QCOMPARE(addedSpy.at(i).at(1).value<QQuickItem*>(), repeater->itemAt(i));
+ }
+
+ countSpy.clear();
+ addedSpy.clear();
+
+ model.reset();
+ QCOMPARE(countSpy.count(), 0);
+ QCOMPARE(removedSpy.count(), 3);
+ QCOMPARE(addedSpy.count(), 3);
+ for (int i = 0; i< items.count(); i++) {
+ QCOMPARE(addedSpy.at(i).at(0).toInt(), i);
+ QCOMPARE(addedSpy.at(i).at(1).value<QQuickItem*>(), repeater->itemAt(i));
+ }
+
+ addedSpy.clear();
+ removedSpy.clear();
+
+ items.append(qMakePair(QString::fromLatin1("four"), QString::fromLatin1("4")));
+ items.append(qMakePair(QString::fromLatin1("five"), QString::fromLatin1("5")));
+
+ model.resetItems(items);
+ QCOMPARE(countSpy.count(), 1);
+ QCOMPARE(removedSpy.count(), 3);
+ QCOMPARE(addedSpy.count(), 5);
+ for (int i = 0; i< items.count(); i++) {
+ QCOMPARE(addedSpy.at(i).at(0).toInt(), i);
+ QCOMPARE(addedSpy.at(i).at(1).value<QQuickItem*>(), repeater->itemAt(i));
+ }
+
+ countSpy.clear();
+ addedSpy.clear();
+ removedSpy.clear();
+
+ items.clear();
+ model.resetItems(items);
+ QCOMPARE(countSpy.count(), 1);
+ QCOMPARE(removedSpy.count(), 5);
+ QCOMPARE(addedSpy.count(), 0);
+}
+
void tst_QQuickRepeater::properties()
{
QQmlEngine engine;
diff --git a/tests/auto/quick/shared/viewtestutil.cpp b/tests/auto/quick/shared/viewtestutil.cpp
index 59ebed50b9..f68ca1fd33 100644
--- a/tests/auto/quick/shared/viewtestutil.cpp
+++ b/tests/auto/quick/shared/viewtestutil.cpp
@@ -403,6 +403,13 @@ void QQuickViewTestUtil::QaimModel::reset()
emit endResetModel();
}
+void QQuickViewTestUtil::QaimModel::resetItems(const QList<QPair<QString, QString> > &items)
+{
+ beginResetModel();
+ list = items;
+ endResetModel();
+}
+
void QQuickViewTestUtil::QaimModel::matchAgainst(const QList<QPair<QString, QString> > &other, const QString &error1, const QString &error2) {
for (int i=0; i<other.count(); i++) {
QVERIFY2(list.contains(other[i]),
diff --git a/tests/auto/quick/shared/viewtestutil.h b/tests/auto/quick/shared/viewtestutil.h
index 66921a7273..3108030406 100644
--- a/tests/auto/quick/shared/viewtestutil.h
+++ b/tests/auto/quick/shared/viewtestutil.h
@@ -144,6 +144,7 @@ namespace QQuickViewTestUtil
void clear();
void reset();
+ void resetItems(const QList<QPair<QString, QString> > &items);
void matchAgainst(const QList<QPair<QString, QString> > &other, const QString &error1, const QString &error2);