Don't double reference items created following a model reset.
authorAndrew den Exter <andrew.den-exter@nokia.com>
Tue, 17 Jul 2012 00:47:45 +0000 (10:47 +1000)
committerQt by Nokia <qt-info@nokia.com>
Tue, 17 Jul 2012 10:49:15 +0000 (12:49 +0200)
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>
src/quick/items/qquickrepeater.cpp
tests/auto/quick/qquickrepeater/tst_qquickrepeater.cpp
tests/auto/quick/shared/viewtestutil.cpp
tests/auto/quick/shared/viewtestutil.h

index 3160951..8ebdccf 100644 (file)
@@ -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;
index 171e330..0fb2416 100644 (file)
@@ -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;
index 59ebed5..f68ca1f 100644 (file)
@@ -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]),
index 66921a7..3108030 100644 (file)
@@ -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);