Update ListModel's internal indexes when items are inserted/removed.
authorAndrew den Exter <andrew.den-exter@nokia.com>
Wed, 27 Jul 2011 07:54:04 +0000 (17:54 +1000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 28 Jul 2011 02:34:22 +0000 (04:34 +0200)
The changed signals of cached items were being emitted with
incorrect indexes if a previous item in the list was inserted or
removed, resulting in changes not being reflected in views.

Task-number: QTBUG-20286
Change-Id: Id2fb8e2875c6cbd4f2e4d14ef859b7a7a4bac8d9
Reviewed-on: http://codereview.qt.nokia.com/2252
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Bea Lam <bea.lam@nokia.com>
src/declarative/util/qdeclarativelistmodel.cpp
tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp

index 8659c5b..e35d64b 100644 (file)
@@ -1373,6 +1373,11 @@ void NestedListModel::remove(int index)
         return;
     ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(index));
     _root->values.removeAt(index);
+    for (int i = 0; i < _root->values.count(); ++i) {
+        ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(i));
+        if (node)
+            node->listIndex = i;
+    }
     if (node)
         delete node;
 }
@@ -1388,6 +1393,11 @@ bool NestedListModel::insert(int index, v8::Handle<v8::Value> valuemap)
     mn->listIndex = index;
     mn->setObjectValue(valuemap);
     _root->values.insert(index,QVariant::fromValue(mn));
+    for (int i = index + 1; i < _root->values.count(); ++i) {
+        ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(i));
+        if (node)
+            node->listIndex = i;
+    }
     return true;
 }
 
@@ -1396,6 +1406,11 @@ void NestedListModel::move(int from, int to, int n)
     if (!_root)
         return;
     qdeclarativelistmodel_move<QVariantList>(from, to, n, &_root->values);
+    for (int i = qMin(from, to), end = qMin(_root->values.count(), qMax(from, to) + n); i < end; ++i) {
+        ModelNode *node = qvariant_cast<ModelNode *>(_root->values.at(i));
+        if (node)
+            node->listIndex = i;
+    }
 }
 
 v8::Handle<v8::Value> NestedListModel::get(int index) const
index cfd3981..3132239 100644 (file)
@@ -963,7 +963,7 @@ void tst_qdeclarativelistmodel::property_changes()
     QString qml = "import QtQuick 2.0\n"
                   "Connections {\n"
                         "property bool gotSignal: false\n"
-                        "target: model.get(0)\n"
+                        "target: model.get(" + QString::number(listIndex) + ")\n"
                         + signalHandler + " gotSignal = true\n"
                   "}\n";
     QDeclarativeComponent component(&engine);
@@ -1015,6 +1015,31 @@ void tst_qdeclarativelistmodel::property_changes_data()
     QTest::newRow("setProperty: plain, no changes") << "append({'a':123, 'b':456, 'c':789});" << "setProperty(0, 'b', 456);"
             << "b" << 0 << false << "get(0).b == 456";
 
+    QTest::newRow("set: inserted item")
+            << "{append({'a':123, 'b':456, 'c':789}); get(0); insert(0, {'a':0, 'b':0, 'c':0});}"
+            << "set(1, {'a':456});"
+            << "a" << 1 << true << "get(1).a == 456";
+    QTest::newRow("setProperty: inserted item")
+            << "{append({'a':123, 'b':456, 'c':789}); get(0); insert(0, {'a':0, 'b':0, 'c':0});}"
+            << "setProperty(1, 'a', 456);"
+            << "a" << 1 << true << "get(1).a == 456";
+    QTest::newRow("get: inserted item")
+            << "{append({'a':123, 'b':456, 'c':789}); get(0); insert(0, {'a':0, 'b':0, 'c':0});}"
+            << "get(1).a = 456;"
+            << "a" << 1 << true << "get(1).a == 456";
+    QTest::newRow("set: removed item")
+            << "{append({'a':0, 'b':0, 'c':0}); append({'a':123, 'b':456, 'c':789}); get(1); remove(0);}"
+            << "set(0, {'a':456});"
+            << "a" << 0 << true << "get(0).a == 456";
+    QTest::newRow("setProperty: removed item")
+            << "{append({'a':0, 'b':0, 'c':0}); append({'a':123, 'b':456, 'c':789}); get(1); remove(0);}"
+            << "setProperty(0, 'a', 456);"
+            << "a" << 0 << true << "get(0).a == 456";
+    QTest::newRow("get: removed item")
+            << "{append({'a':0, 'b':0, 'c':0}); append({'a':123, 'b':456, 'c':789}); get(1); remove(0);}"
+            << "get(0).a = 456;"
+            << "a" << 0 << true << "get(0).a == 456";
+
     // Following tests only call set() since setProperty() only allows plain
     // values, not lists, as the argument.
     // Note that when a list is changed, itemsChanged() is currently always