From 6ec7695eaa02c923b90d72e3918b9ab50da63e41 Mon Sep 17 00:00:00 2001
From: Bea Lam <bea.lam@nokia.com>
Date: Fri, 8 Apr 2011 14:20:17 +1000
Subject: ListModel::clear() should not clear roles

Clearing a model and then appending a new object with a subset of the
previous roles was causing a crash since ListModel cleared the roles
and VisualDataModel did not, so VisualDataModel was requesting invalid
roles. This could have been fixed by clearing the meta object and
its property cache in in VisualDataModel but this is less efficient,
and also the general use case is for model data to always have the same
roles.

Task-number: QTBUG-18587
Change-Id: Ib11d2292888ab7a41e772b1e11700cd665e94ae7
Reviewed-by: Michael Brasser
---
 src/declarative/util/qdeclarativelistmodel.cpp     |  3 --
 .../tst_qdeclarativelistmodel.cpp                  | 42 ++++++++++++++++++++++
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp
index 9332de4..1d03842 100644
--- a/src/declarative/util/qdeclarativelistmodel.cpp
+++ b/src/declarative/util/qdeclarativelistmodel.cpp
@@ -1301,9 +1301,6 @@ int NestedListModel::count() const
 
 void NestedListModel::clear()
 {
-    _rolesOk = false;
-    roleStrings.clear();
-
     if (_root)
         _root->clear();
 }
diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
index 45072f3..2f7513f 100644
--- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
+++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp
@@ -106,6 +106,7 @@ private slots:
     void property_changes_data();
     void property_changes_worker();
     void property_changes_worker_data();
+    void clear();
 };
 int tst_qdeclarativelistmodel::roleFromName(const QDeclarativeListModel *model, const QString &roleName)
 {
@@ -1091,6 +1092,47 @@ void tst_qdeclarativelistmodel::property_changes_worker_data()
     property_changes_data();
 }
 
+void tst_qdeclarativelistmodel::clear()
+{
+    QDeclarativeEngine engine;
+    QDeclarativeListModel model;
+    QDeclarativeEngine::setContextForObject(&model, engine.rootContext());
+    engine.rootContext()->setContextObject(&model);
+
+    QScriptEngine *seng = QDeclarativeEnginePrivate::getScriptEngine(&engine);
+    QScriptValue sv = seng->newObject();
+    QVariant result;
+
+    model.clear();
+    QCOMPARE(model.count(), 0);
+
+    sv.setProperty("propertyA", "value a");
+    sv.setProperty("propertyB", "value b");
+    model.append(sv);
+    QCOMPARE(model.count(), 1);
+
+    model.clear();
+    QCOMPARE(model.count(), 0);
+
+    model.append(sv);
+    model.append(sv);
+    QCOMPARE(model.count(), 2);
+
+    model.clear();
+    QCOMPARE(model.count(), 0);
+
+    // clearing does not remove the roles
+    sv.setProperty("propertyC", "value c");
+    model.append(sv);
+    QList<int> roles = model.roles();
+    model.clear();
+    QCOMPARE(model.count(), 0);
+    QCOMPARE(model.roles(), roles);
+    QCOMPARE(model.toString(roles[0]), QString("propertyA"));
+    QCOMPARE(model.toString(roles[1]), QString("propertyB"));
+    QCOMPARE(model.toString(roles[2]), QString("propertyC"));
+}
+
 QTEST_MAIN(tst_qdeclarativelistmodel)
 
 #include "tst_qdeclarativelistmodel.moc"
-- 
cgit v0.12