src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
--- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp	Tue Jul 06 15:10:48 2010 +0300
+++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp	Wed Aug 18 10:37:55 2010 +0300
@@ -77,7 +77,7 @@
     QDeclarativeVisualItemModelPrivate() : QObjectPrivate() {}
 
     static void children_append(QDeclarativeListProperty<QDeclarativeItem> *prop, QDeclarativeItem *item) {
-        item->QObject::setParent(prop->object);
+        QDeclarative_setParent_noEvent(item, prop->object);
         static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->children.append(item);
         static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->itemAppended();
         static_cast<QDeclarativeVisualItemModelPrivate *>(prop->data)->emitChildrenChanged();
@@ -113,17 +113,19 @@
   \since 4.7
     \brief The VisualItemModel allows items to be provided to a view.
 
-    The children of the VisualItemModel are provided in a model which
-    can be used in a view.  Note that no delegate should be
-    provided to a view since the VisualItemModel contains the
-    visual delegate (items).
+    A VisualItemModel contains the visual items to be used in a view.
+    When a VisualItemModel is used in a view, the view does not require
+    a delegate since the VisualItemModel already contains the visual
+    delegate (items).
 
     An item can determine its index within the
-    model via the VisualItemModel.index attached property.
+    model via the \l{VisualItemModel::index}{index} attached property.
 
     The example below places three colored rectangles in a ListView.
     \code
-    Item {
+    import Qt 4.7
+
+    Rectangle {
         VisualItemModel {
             id: itemModel
             Rectangle { height: 30; width: 80; color: "red" }
@@ -137,12 +139,23 @@
         }
     }
     \endcode
+
+    \image visualitemmodel.png
+
+    \sa {declarative/modelviews/visualitemmodel}{VisualItemModel example}
 */
 QDeclarativeVisualItemModel::QDeclarativeVisualItemModel(QObject *parent)
     : QDeclarativeVisualModel(*(new QDeclarativeVisualItemModelPrivate), parent)
 {
 }
 
+/*!
+    \qmlattachedproperty int VisualItemModel::index
+    This attached property holds the index of this delegate's item within the model.
+
+    It is attached to each instance of the delegate.
+*/
+
 QDeclarativeListProperty<QDeclarativeItem> QDeclarativeVisualItemModel::children()
 {
     Q_D(QDeclarativeVisualItemModel);
@@ -172,9 +185,11 @@
     return d->children.at(index);
 }
 
-QDeclarativeVisualModel::ReleaseFlags QDeclarativeVisualItemModel::release(QDeclarativeItem *)
+QDeclarativeVisualModel::ReleaseFlags QDeclarativeVisualItemModel::release(QDeclarativeItem *item)
 {
-    // Nothing to do
+    if (item->scene())
+        item->scene()->removeItem(item);
+    QDeclarative_setParent_noEvent(item, this);
     return 0;
 }
 
@@ -270,7 +285,7 @@
                 if (m_roles.count() == 1)
                     m_roleNames.insert("modelData", m_roles.at(0));
                 if (m_roles.count())
-                    m_roleNames.insert("hasModelChildren", 0);
+                    m_roleNames.insert("hasModelChildren", -1);
             } else if (m_listAccessor) {
                 m_roleNames.insert("modelData", 0);
                 if (m_listAccessor->type() == QDeclarativeListAccessor::Instance) {
@@ -605,30 +620,15 @@
     A VisualDataModel encapsulates a model and the delegate that will
     be instantiated for items in the model.
 
-    It is usually not necessary to create a VisualDataModel directly,
-    since the QML views will create one internally.
+    It is usually not necessary to create VisualDataModel elements.
+    However, it can be useful for manipulating and accessing the \l modelIndex 
+    when a QAbstractItemModel subclass is used as the 
+    model. Also, VisualDataModel is used together with \l Package to 
+    provide delegates to multiple views.
 
     The example below illustrates using a VisualDataModel with a ListView.
 
-    \code
-    VisualDataModel {
-        id: visualModel
-        model: myModel
-        delegate: Component {
-            Rectangle {
-                height: 25
-                width: 100
-                Text { text: "Name:" + name}
-            }
-        }
-    }
-    ListView {
-        width: 100
-        height: 100
-        anchors.fill: parent
-        model: visualModel
-    }
-    \endcode
+    \snippet doc/src/snippets/declarative/visualdatamodel.qml 0
 */
 
 QDeclarativeVisualDataModel::QDeclarativeVisualDataModel()
@@ -803,56 +803,28 @@
 /*!
     \qmlproperty QModelIndex VisualDataModel::rootIndex
 
-    QAbstractItemModel provides a heirachical tree of data, whereas
+    QAbstractItemModel provides a hierarchical tree of data, whereas
     QML only operates on list data.  \c rootIndex allows the children of
     any node in a QAbstractItemModel to be provided by this model.
 
     This property only affects models of type QAbstractItemModel.
 
-    \code
-    // main.cpp
-
-    int main(int argc, char ** argv)
-    {
-        QApplication app(argc, argv);
-
-        QDeclarativeView view;
-
-        QDirModel model;
-        view.rootContext()->setContextProperty("myModel", &model);
-
-        view.setSource(QUrl("qrc:view.qml"));
-        view.show();
-
-        return app.exec();
-    }
-
-    #include "main.moc"
-    \endcode
+    For example, here is a simple interactive file system browser.
+    When a directory name is clicked, the view's \c rootIndex is set to the
+    QModelIndex node of the clicked directory, thus updating the view to show
+    the new directory's contents.
 
-    \code
-    // view.qml
-    import Qt 4.7
+    \c main.cpp:
+    \snippet doc/src/snippets/declarative/visualdatamodel_rootindex/main.cpp 0
+   
+    \c view.qml:
+    \snippet doc/src/snippets/declarative/visualdatamodel_rootindex/view.qml 0
 
-    ListView {
-        id: view
-        width: 200
-        height: 200
-        model: VisualDataModel {
-            model: myModel
-            delegate: Component {
-                Rectangle {
-                    height: 25; width: 200
-                    Text { text: filePath }
-                    MouseArea {
-                        anchors.fill: parent;
-                        onClicked: if (hasModelChildren) view.model.rootIndex = view.model.modelIndex(index)
-                    }
-                }
-            }
-        }
-    }
-    \endcode
+    If the \l model is a QAbstractItemModel subclass, the delegate can also
+    reference a \c hasModelChildren property (optionally qualified by a
+    \e model. prefix) that indicates whether the delegate's model item has 
+    any child nodes.
+
 
     \sa modelIndex(), parentModelIndex()
 */
@@ -884,7 +856,7 @@
 /*!
     \qmlmethod QModelIndex VisualDataModel::modelIndex(int index)
 
-    QAbstractItemModel provides a heirachical tree of data, whereas
+    QAbstractItemModel provides a hierarchical tree of data, whereas
     QML only operates on list data.  This function assists in using
     tree models in QML.
 
@@ -904,7 +876,7 @@
 /*!
     \qmlmethod QModelIndex VisualDataModel::parentModelIndex()
 
-    QAbstractItemModel provides a heirachical tree of data, whereas
+    QAbstractItemModel provides a hierarchical tree of data, whereas
     QML only operates on list data.  This function assists in using
     tree models in QML.
 
@@ -998,10 +970,10 @@
 
     The \a parts property selects a VisualDataModel which creates
     delegates from the part named.  This is used in conjunction with
-    the Package element.
+    the \l Package element.
 
     For example, the code below selects a model which creates
-    delegates named \e list from a Package:
+    delegates named \e list from a \l Package:
 
     \code
     VisualDataModel {
@@ -1119,6 +1091,11 @@
     if (d->m_visualItemModel)
         return d->m_visualItemModel->stringValue(index, name);
 
+    if ((!d->m_listModelInterface || !d->m_abstractItemModel) && d->m_listAccessor) {
+        if (QObject *object = d->m_listAccessor->at(index).value<QObject*>())
+            return object->property(name.toUtf8()).toString();
+    }
+
     if ((!d->m_listModelInterface && !d->m_abstractItemModel) || !d->m_delegate)
         return QString();