From ce9bc843443f2c61361afa75a62a7d39029557e6 Mon Sep 17 00:00:00 2001
From: Martin Jones <martin.jones@nokia.com>
Date: Wed, 5 May 2010 14:38:55 +1000
Subject: QList<QObject*> models now update their properties when they change.

Task-number: QTBUG-10348
---
 doc/src/declarative/qdeclarativemodels.qdoc           | 11 +++++++++--
 examples/declarative/objectlistmodel/dataobject.cpp   | 10 ++++++++--
 examples/declarative/objectlistmodel/dataobject.h     |  8 ++++++--
 examples/declarative/objectlistmodel/view.qml         |  2 +-
 src/declarative/QmlChanges.txt                        |  4 ++++
 .../graphicsitems/qdeclarativevisualitemmodel.cpp     |  8 ++++++--
 .../declarative/qdeclarativerepeater/data/objlist.qml |  2 +-
 .../qdeclarativerepeater/tst_qdeclarativerepeater.cpp | 19 ++++++++++++++-----
 8 files changed, 49 insertions(+), 15 deletions(-)

diff --git a/doc/src/declarative/qdeclarativemodels.qdoc b/doc/src/declarative/qdeclarativemodels.qdoc
index 91acb3c..9b706a1 100644
--- a/doc/src/declarative/qdeclarativemodels.qdoc
+++ b/doc/src/declarative/qdeclarativemodels.qdoc
@@ -283,7 +283,9 @@ QDeclarativeContext *ctxt = view.rootContext();
 ctxt->setContextProperty("myModel", QVariant::fromValue(dataList));
 \endcode
 
-The properties of the object may then be accessed in the delegate:
+The QObject* is available as the \c modelData property.  As a convenience,
+the properties of the object are also made available directly in the
+delegate's context:
 
 \code
 ListView {
@@ -295,13 +297,18 @@ ListView {
        Rectangle {
             height: 25
             width: 100
-            color: model.color
+            color: model.modelData.color
             Text { text: name }
        }
    }
 }
 \endcode
 
+Note the use of the fully qualified access to the \c color property.  
+The properties of the object are not replicated in the \c model
+object, since they are easily available via the modelData
+object.
+
 Note: There is no way for the view to know that the contents of a QList
 have changed.  If the QList is changed, it will be necessary to reset
 the model by calling QDeclarativeContext::setContextProperty() again.
diff --git a/examples/declarative/objectlistmodel/dataobject.cpp b/examples/declarative/objectlistmodel/dataobject.cpp
index 4c44ee4..14be1b9 100644
--- a/examples/declarative/objectlistmodel/dataobject.cpp
+++ b/examples/declarative/objectlistmodel/dataobject.cpp
@@ -59,7 +59,10 @@ QString DataObject::name() const
 
 void DataObject::setName(const QString &name)
 {
-    m_name = name;
+    if (name != m_name) {
+        m_name = name;
+        emit nameChanged();
+    }
 }
 
 QString DataObject::color() const
@@ -69,5 +72,8 @@ QString DataObject::color() const
 
 void DataObject::setColor(const QString &color)
 {
-    m_color = color;
+    if (color != m_color) {
+        m_color = color;
+        emit colorChanged();
+    }
 }
diff --git a/examples/declarative/objectlistmodel/dataobject.h b/examples/declarative/objectlistmodel/dataobject.h
index 6804474..852110d 100644
--- a/examples/declarative/objectlistmodel/dataobject.h
+++ b/examples/declarative/objectlistmodel/dataobject.h
@@ -48,8 +48,8 @@ class DataObject : public QObject
 {
     Q_OBJECT
 
-    Q_PROPERTY(QString name READ name WRITE setName)
-    Q_PROPERTY(QString color READ color WRITE setColor)
+    Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
+    Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged)
 
 public:
     DataObject(QObject *parent=0);
@@ -61,6 +61,10 @@ public:
     QString color() const;
     void setColor(const QString &color);
 
+signals:
+    void nameChanged();
+    void colorChanged();
+
 private:
     QString m_name;
     QString m_color;
diff --git a/examples/declarative/objectlistmodel/view.qml b/examples/declarative/objectlistmodel/view.qml
index 908e388..2b8383f 100644
--- a/examples/declarative/objectlistmodel/view.qml
+++ b/examples/declarative/objectlistmodel/view.qml
@@ -9,7 +9,7 @@ ListView {
         Rectangle {
             height: 25
             width: 100
-            color: model.color
+            color: model.modelData.color
             Text { text: name }
         }
     }
diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt
index 7218f78..dfc4244 100644
--- a/src/declarative/QmlChanges.txt
+++ b/src/declarative/QmlChanges.txt
@@ -4,6 +4,10 @@ The changes below are pre Qt 4.7.0 RC
 Flickable: overShoot is replaced by boundsBehavior enumeration.
 Component: isReady, isLoading, isError and isNull properties removed, use
     status property instead
+QList<QObject*> models no longer provide properties in model object.  The
+properties are now updated when the object changes.  An object's property
+"foo" may now be accessed as "foo", modelData.foo" or model.modelData.foo"
+
 
 C++ API
 -------
diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
index 2addc77..f01d4c2 100644
--- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
+++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
@@ -437,8 +437,7 @@ int QDeclarativeVisualDataModelDataMetaObject::createProperty(const char *name,
     if ((!model->m_listModelInterface || !model->m_abstractItemModel) && model->m_listAccessor) {
         if (model->m_listAccessor->type() == QDeclarativeListAccessor::ListProperty) {
             model->ensureRoles();
-            QObject *object = model->m_listAccessor->at(data->m_index).value<QObject*>();
-            if (object && (object->property(name).isValid() || qstrcmp(name,"modelData")==0))
+            if (qstrcmp(name,"modelData") == 0)
                 return QDeclarativeOpenMetaObject::createProperty(name, type);
         }
     }
@@ -1029,6 +1028,11 @@ QDeclarativeItem *QDeclarativeVisualDataModel::item(int index, const QByteArray
         if (!ccontext) ccontext = qmlContext(this);
         QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext);
         QDeclarativeVisualDataModelData *data = new QDeclarativeVisualDataModelData(index, this);
+        if ((!d->m_listModelInterface || !d->m_abstractItemModel) && d->m_listAccessor
+            && d->m_listAccessor->type() == QDeclarativeListAccessor::ListProperty) {
+            ctxt->setContextObject(d->m_listAccessor->at(index).value<QObject*>());
+            ctxt = new QDeclarativeContext(ctxt, ctxt);
+        }
         ctxt->setContextProperty(QLatin1String("model"), data);
         ctxt->setContextObject(data);
         d->m_completePending = false;
diff --git a/tests/auto/declarative/qdeclarativerepeater/data/objlist.qml b/tests/auto/declarative/qdeclarativerepeater/data/objlist.qml
index 17c5d8d..e1bd2e2 100644
--- a/tests/auto/declarative/qdeclarativerepeater/data/objlist.qml
+++ b/tests/auto/declarative/qdeclarativerepeater/data/objlist.qml
@@ -14,7 +14,7 @@ Rectangle {
         property int instantiated: 0
         Component {
             Item{
-                Component.onCompleted: {if(index!=model.idx) repeater.errors += 1; repeater.instantiated++}
+                Component.onCompleted: {if(index!=modelData.idx) repeater.errors += 1; repeater.instantiated++}
             }
         }
     }
diff --git a/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp b/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp
index 8be7d80..e6b2fdd 100644
--- a/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp
+++ b/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp
@@ -185,15 +185,24 @@ void tst_QDeclarativeRepeater::numberModel()
     delete canvas;
 }
 
+class MyObject : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(int idx READ idx CONSTANT)
+public:
+    MyObject(int i) : QObject(), m_idx(i) {}
+
+    int idx() const { return m_idx; }
+
+    int m_idx;
+};
+
 void tst_QDeclarativeRepeater::objectList()
 {
     QDeclarativeView *canvas = createView();
-
     QObjectList data;
-    for(int i=0; i<100; i++){
-        data << new QObject();
-        data.back()->setProperty("idx", i);
-    }
+    for(int i=0; i<100; i++)
+        data << new MyObject(i);
 
     QDeclarativeContext *ctxt = canvas->rootContext();
     ctxt->setContextProperty("testData", QVariant::fromValue(data));
-- 
cgit v0.12