Refactor QSGVisualDataModel.
authorAndrew den Exter <andrew.den-exter@nokia.com>
Tue, 30 Aug 2011 05:00:30 +0000 (15:00 +1000)
committerQt by Nokia <qt-info@nokia.com>
Wed, 21 Sep 2011 06:23:52 +0000 (08:23 +0200)
Split the wrapper for Package models out into its own visual model
class, add a QSGVisualAdaptorModel class which encapsulates the
creation and maintenance of delegate context data, and move
QSGVisualDataModel to its own source files.

Task-number: QTBUG-20107
Change-Id: Icdea2756a119c327ec2c748be893daf622bc1356
Reviewed-on: http://codereview.qt-project.org/4033
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Martin Jones <martin.jones@nokia.com>

13 files changed:
src/declarative/items/items.pri
src/declarative/items/qsgitemsmodule.cpp
src/declarative/items/qsgitemview_p_p.h
src/declarative/items/qsgpathview_p_p.h
src/declarative/items/qsgrepeater.cpp
src/declarative/items/qsgvisualadaptormodel.cpp [new file with mode: 0644]
src/declarative/items/qsgvisualadaptormodel_p.h [new file with mode: 0644]
src/declarative/items/qsgvisualdatamodel.cpp [new file with mode: 0644]
src/declarative/items/qsgvisualdatamodel_p.h [new file with mode: 0644]
src/declarative/items/qsgvisualitemmodel.cpp
src/declarative/items/qsgvisualitemmodel_p.h
tests/auto/declarative/qsgvisualdatamodel/data/visualdatamodel.qml
tests/auto/declarative/qsgvisualdatamodel/tst_qsgvisualdatamodel.cpp

index 9880dd8..0433074 100644 (file)
@@ -37,6 +37,8 @@ HEADERS += \
     $$PWD/qsgflickable_p.h \
     $$PWD/qsgflickable_p_p.h \
     $$PWD/qsglistview_p.h \
+    $$PWD/qsgvisualadaptormodel_p.h \
+    $$PWD/qsgvisualdatamodel_p.h \
     $$PWD/qsgvisualitemmodel_p.h \
     $$PWD/qsgrepeater_p.h \
     $$PWD/qsgrepeater_p_p.h \
@@ -89,6 +91,8 @@ SOURCES += \
     $$PWD/qsgpincharea.cpp \
     $$PWD/qsgflickable.cpp \
     $$PWD/qsglistview.cpp \
+    $$PWD/qsgvisualadaptormodel.cpp \
+    $$PWD/qsgvisualdatamodel.cpp \
     $$PWD/qsgvisualitemmodel.cpp \
     $$PWD/qsgrepeater.cpp \
     $$PWD/qsggridview.cpp \
index 2ad7e59..41823c1 100644 (file)
@@ -58,6 +58,7 @@
 #include "qsgflickable_p_p.h"
 #include "qsglistview_p.h"
 #include "qsgvisualitemmodel_p.h"
+#include "qsgvisualdatamodel_p.h"
 #include "qsggridview_p.h"
 #include "qsgpathview_p.h"
 #include <private/qdeclarativepath_p.h>
index 2164dd6..afa50af 100644 (file)
@@ -44,7 +44,7 @@
 
 #include "qsgitemview_p.h"
 #include "qsgflickable_p_p.h"
-#include "qsgvisualitemmodel_p.h"
+#include "qsgvisualdatamodel_p.h"
 #include <private/qdeclarativechangeset_p.h>
 
 
index 30bb74a..520de42 100644 (file)
@@ -56,7 +56,7 @@
 
 #include "qsgpathview_p.h"
 #include "qsgitem_p.h"
-#include "qsgvisualitemmodel_p.h"
+#include "qsgvisualdatamodel_p.h"
 
 #include <QtDeclarative/qdeclarative.h>
 #include <QtCore/qdatetime.h>
index bdb3a3d..4e2fa63 100644 (file)
@@ -41,7 +41,7 @@
 
 #include "qsgrepeater_p.h"
 #include "qsgrepeater_p_p.h"
-#include "qsgvisualitemmodel_p.h"
+#include "qsgvisualdatamodel_p.h"
 
 #include <private/qdeclarativeglobal_p.h>
 #include <private/qdeclarativelistaccessor_p.h>
diff --git a/src/declarative/items/qsgvisualadaptormodel.cpp b/src/declarative/items/qsgvisualadaptormodel.cpp
new file mode 100644 (file)
index 0000000..3eb6214
--- /dev/null
@@ -0,0 +1,889 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgvisualadaptormodel_p.h"
+#include "qsgitem.h"
+
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+#include <QtDeclarative/qdeclarativeinfo.h>
+
+#include <private/qdeclarativecontext_p.h>
+#include <private/qdeclarativepackage_p.h>
+#include <private/qdeclarativeopenmetaobject_p.h>
+#include <private/qdeclarativelistaccessor_p.h>
+#include <private/qdeclarativedata_p.h>
+#include <private/qdeclarativepropertycache_p.h>
+#include <private/qdeclarativeguard_p.h>
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qlistmodelinterface_p.h>
+#include <private/qmetaobjectbuilder_p.h>
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qintrusivelist_p.h>
+#include <private/qobject_p.h>
+
+#include <QtCore/qhash.h>
+#include <QtCore/qlist.h>
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_METATYPE(QModelIndex)
+
+class VDMDelegateDataType : public QDeclarativeRefCount
+{
+public:
+    VDMDelegateDataType()
+        : metaObject(0)
+        , propertyCache(0)
+        , propertyOffset(0)
+        , signalOffset(0)
+        , shared(true)
+    {
+    }
+
+    VDMDelegateDataType(const VDMDelegateDataType &type)
+        : metaObject(0)
+        , propertyCache(0)
+        , propertyOffset(type.propertyOffset)
+        , signalOffset(type.signalOffset)
+        , shared(false)
+        , builder(type.metaObject, QMetaObjectBuilder::Properties
+                | QMetaObjectBuilder::Signals
+                | QMetaObjectBuilder::SuperClass
+                | QMetaObjectBuilder::ClassName)
+    {
+        builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+    }
+
+    ~VDMDelegateDataType()
+    {
+        if (propertyCache)
+            propertyCache->release();
+        qFree(metaObject);
+    }
+
+    QMetaObject *metaObject;
+    QDeclarativePropertyCache *propertyCache;
+    int propertyOffset;
+    int signalOffset;
+    bool shared : 1;
+    QMetaObjectBuilder builder;
+};
+
+class QSGVisualAdaptorModelData : public QObject
+{
+    Q_OBJECT
+    Q_PROPERTY(int index READ index NOTIFY indexChanged)
+public:
+    QSGVisualAdaptorModelData(int index, QSGVisualAdaptorModel *model);
+    ~QSGVisualAdaptorModelData();
+
+    int index() const;
+    void setIndex(int index);
+
+Q_SIGNALS:
+    void indexChanged();
+
+public:
+    int m_index;
+    QDeclarativeGuard<QSGVisualAdaptorModel> m_model;
+    QIntrusiveListNode m_cacheNode;
+};
+
+typedef QIntrusiveList<QSGVisualAdaptorModelData, &QSGVisualAdaptorModelData::m_cacheNode> QSGVisualAdaptorModelDataCache;
+
+class QSGVisualAdaptorModelDataMetaObject;
+class QSGVisualAdaptorModelPrivate : public QObjectPrivate
+{
+    Q_DECLARE_PUBLIC(QSGVisualAdaptorModel)
+public:
+    QSGVisualAdaptorModelPrivate()
+        : m_engine(0)
+        , m_listAccessor(0)
+        , m_delegateDataType(0)
+        , createModelData(&initializeModelData)
+        , m_ref(0)
+        , m_count(0)
+        , m_objectList(false)
+    {
+    }
+
+
+    static QSGVisualAdaptorModelPrivate *get(QSGVisualAdaptorModel *m) {
+        return static_cast<QSGVisualAdaptorModelPrivate *>(QObjectPrivate::get(m));
+    }
+
+    void addProperty(int role, int propertyId, const char *propertyName, const char *propertyType, bool isModelData = false);
+    template <typename T> void setModelDataType()
+    {
+        createModelData = &T::create;
+        m_delegateDataType->builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
+        m_delegateDataType->builder.setClassName(T::staticMetaObject.className());
+        m_delegateDataType->builder.setSuperClass(&T::staticMetaObject);
+        m_delegateDataType->propertyOffset = T::staticMetaObject.propertyCount();
+        m_delegateDataType->signalOffset = T::staticMetaObject.methodCount();
+    }
+    QSGVisualAdaptorModelData *createMetaObject(int index, QSGVisualAdaptorModel *model);
+
+    static QSGVisualAdaptorModelData *initializeModelData(int index, QSGVisualAdaptorModel *model) {
+        return get(model)->createMetaObject(index, model);
+    }
+
+    typedef QSGVisualAdaptorModelData *(*CreateModelData)(int index, QSGVisualAdaptorModel *model);
+
+    struct PropertyData {
+        int role;
+        bool isModelData : 1;
+    };
+
+    int modelCount() const {
+        if (m_listModelInterface)
+            return m_listModelInterface->count();
+        if (m_abstractItemModel)
+            return m_abstractItemModel->rowCount(m_root);
+        if (m_listAccessor)
+            return m_listAccessor->count();
+        return 0;
+    }
+
+    QDeclarativeGuard<QDeclarativeEngine> m_engine;
+    QDeclarativeGuard<QListModelInterface> m_listModelInterface;
+    QDeclarativeGuard<QAbstractItemModel> m_abstractItemModel;
+    QDeclarativeListAccessor *m_listAccessor;
+    VDMDelegateDataType *m_delegateDataType;
+    CreateModelData createModelData;
+
+    int m_ref;
+    int m_count;
+    QSGVisualAdaptorModel::Flags m_flags;
+    bool m_objectList : 1;
+
+    QVariant m_modelVariant;
+    QModelIndex m_root;
+
+    QList<int> m_roles;
+    QList<int> watchedRoleIds;
+    QList<QByteArray> watchedRoles;
+    QHash<QByteArray,int> m_roleNames;
+    QVector<PropertyData> m_propertyData;
+    QSGVisualAdaptorModelDataCache m_cache;
+};
+
+class QSGVisualAdaptorModelDataMetaObject : public QAbstractDynamicMetaObject
+{
+public:
+    QSGVisualAdaptorModelDataMetaObject(QSGVisualAdaptorModelData *data, VDMDelegateDataType *type)
+        : m_data(data)
+        , m_type(type)
+    {
+        QObjectPrivate *op = QObjectPrivate::get(m_data);
+        *static_cast<QMetaObject *>(this) = *type->metaObject;
+        op->metaObject = this;
+        m_type->addref();
+    }
+
+    ~QSGVisualAdaptorModelDataMetaObject() { m_type->release(); }
+
+    QSGVisualAdaptorModelData *m_data;
+    VDMDelegateDataType *m_type;
+};
+
+class QSGVDMAbstractItemModelDataMetaObject : public QSGVisualAdaptorModelDataMetaObject
+{
+public:
+    QSGVDMAbstractItemModelDataMetaObject(QSGVisualAdaptorModelData *object, VDMDelegateDataType *type)
+        : QSGVisualAdaptorModelDataMetaObject(object, type) {}
+
+    int metaCall(QMetaObject::Call call, int id, void **arguments)
+    {
+        if (call == QMetaObject::ReadProperty && id >= m_type->propertyOffset) {
+            QSGVisualAdaptorModelPrivate *model = QSGVisualAdaptorModelPrivate::get(m_data->m_model);
+            if (m_data->m_index == -1 || !model->m_abstractItemModel)
+                return -1;
+            *static_cast<QVariant *>(arguments[0]) = model->m_abstractItemModel->index(
+                    m_data->m_index, 0, model->m_root).data(model->m_propertyData.at(id - m_type->propertyOffset).role);
+            return -1;
+        } else {
+            return m_data->qt_metacall(call, id, arguments);
+        }
+    }
+};
+
+class QSGVDMAbstractItemModelData : public QSGVisualAdaptorModelData
+{
+    Q_OBJECT
+    Q_PROPERTY(bool hasModelChildren READ hasModelChildren CONSTANT)
+public:
+    bool hasModelChildren() const
+    {
+        QSGVisualAdaptorModelPrivate *model = QSGVisualAdaptorModelPrivate::get(m_model);
+        return model->m_abstractItemModel->hasChildren(model->m_abstractItemModel->index(m_index, 0, model->m_root));
+    }
+
+    static QSGVisualAdaptorModelData *create(int index, QSGVisualAdaptorModel *model) {
+        return new QSGVDMAbstractItemModelData(index, model); }
+private:
+    QSGVDMAbstractItemModelData(int index, QSGVisualAdaptorModel *model)
+        : QSGVisualAdaptorModelData(index, model)
+    {
+        new QSGVDMAbstractItemModelDataMetaObject(
+                this, QSGVisualAdaptorModelPrivate::get(m_model)->m_delegateDataType);
+    }
+};
+
+class QSGVDMListModelInterfaceDataMetaObject : public QSGVisualAdaptorModelDataMetaObject
+{
+public:
+    QSGVDMListModelInterfaceDataMetaObject(QSGVisualAdaptorModelData *object, VDMDelegateDataType *type)
+        : QSGVisualAdaptorModelDataMetaObject(object, type) {}
+
+    int metaCall(QMetaObject::Call call, int id, void **arguments)
+    {
+        if (call == QMetaObject::ReadProperty && id >= m_type->propertyOffset) {
+            QSGVisualAdaptorModelPrivate *model = QSGVisualAdaptorModelPrivate::get(m_data->m_model);
+            if (m_data->m_index == -1 || !model->m_listModelInterface)
+                return -1;
+            *static_cast<QVariant *>(arguments[0]) = model->m_listModelInterface->data(
+                    m_data->m_index, model->m_propertyData.at(id - m_type->propertyOffset).role);
+            return -1;
+        } else {
+            return m_data->qt_metacall(call, id, arguments);
+        }
+    }
+};
+
+class QSGVDMListModelInterfaceData : public QSGVisualAdaptorModelData
+{
+public:
+    static QSGVisualAdaptorModelData *create(int index, QSGVisualAdaptorModel *model) {
+        return new QSGVDMListModelInterfaceData(index, model); }
+private:
+    QSGVDMListModelInterfaceData(int index, QSGVisualAdaptorModel *model)
+        : QSGVisualAdaptorModelData(index, model)
+    {
+        new QSGVDMListModelInterfaceDataMetaObject(
+                this, QSGVisualAdaptorModelPrivate::get(m_model)->m_delegateDataType);
+    }
+};
+
+class QSGVDMListAccessorData : public QSGVisualAdaptorModelData
+{
+    Q_OBJECT
+    Q_PROPERTY(QVariant modelData READ modelData CONSTANT)
+public:
+    QVariant modelData() const {
+        return QSGVisualAdaptorModelPrivate::get(m_model)->m_listAccessor->at(m_index); }
+
+    static QSGVisualAdaptorModelData *create(int index, QSGVisualAdaptorModel *model) {
+        return new QSGVDMListAccessorData(index, model); }
+private:
+    QSGVDMListAccessorData(int index, QSGVisualAdaptorModel *model)
+        : QSGVisualAdaptorModelData(index, model)
+    {
+    }
+};
+
+class QSGVDMObjectDataMetaObject : public QSGVisualAdaptorModelDataMetaObject
+{
+public:
+    QSGVDMObjectDataMetaObject(QSGVisualAdaptorModelData *data, VDMDelegateDataType *type)
+        : QSGVisualAdaptorModelDataMetaObject(data, type)
+        , m_object(QSGVisualAdaptorModelPrivate::get(data->m_model)->m_listAccessor->at(data->m_index).value<QObject *>())
+    {}
+
+    int metaCall(QMetaObject::Call call, int id, void **arguments)
+    {
+        if (id >= m_type->propertyOffset
+                && (call == QMetaObject::ReadProperty
+                || call == QMetaObject::WriteProperty
+                || call == QMetaObject::ResetProperty)) {
+            if (m_object)
+                QMetaObject::metacall(m_object, call, id - m_type->propertyOffset + 1, arguments);
+            return -1;
+        } else if (id >= m_type->signalOffset && call == QMetaObject::InvokeMetaMethod) {
+            QMetaObject::activate(m_data, this, id, 0);
+            return -1;
+        } else {
+            return m_data->qt_metacall(call, id, arguments);
+        }
+    }
+
+    int createProperty(const char *name, const char *)
+    {
+        if (!m_object)
+            return -1;
+        const QMetaObject *metaObject = m_object->metaObject();
+
+        const int previousPropertyCount = propertyCount() - propertyOffset();
+        int propertyIndex = metaObject->indexOfProperty(name);
+        if (propertyIndex == -1)
+            return -1;
+        if (previousPropertyCount + 1 == metaObject->propertyCount())
+            return propertyIndex + m_type->propertyOffset - 1;
+
+        if (m_type->shared) {
+            VDMDelegateDataType *type = m_type;
+            m_type = new VDMDelegateDataType(*m_type);
+            type->release();
+        }
+
+        const int previousMethodCount = methodCount();
+        int notifierId = previousMethodCount;
+        for (int propertyId = previousPropertyCount; propertyId < metaObject->propertyCount() - 1; ++propertyId) {
+            QMetaProperty property = metaObject->property(propertyId + 1);
+            QMetaPropertyBuilder propertyBuilder;
+            if (property.hasNotifySignal()) {
+                m_type->builder.addSignal("__" + QByteArray::number(propertyId) + "()");
+                propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName(), notifierId);
+                ++notifierId;
+            } else {
+                propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName());
+            }
+            propertyBuilder.setWritable(property.isWritable());
+            propertyBuilder.setResettable(property.isResettable());
+            propertyBuilder.setConstant(property.isConstant());
+        }
+
+        if (m_type->metaObject)
+            qFree(m_type->metaObject);
+        m_type->metaObject = m_type->builder.toMetaObject();
+        *static_cast<QMetaObject *>(this) = *m_type->metaObject;
+
+        notifierId = previousMethodCount;
+        for (int i = previousPropertyCount; i < metaObject->propertyCount(); ++i) {
+            QMetaProperty property = metaObject->property(i);
+            if (property.hasNotifySignal()) {
+                QDeclarativePropertyPrivate::connect(
+                        m_object, property.notifySignalIndex(), m_data, notifierId);
+                ++notifierId;
+            }
+        }
+        return propertyIndex + m_type->propertyOffset - 1;
+    }
+
+    QDeclarativeGuard<QObject> m_object;
+};
+
+class QSGVDMObjectData : public QSGVisualAdaptorModelData, public QSGVisualAdaptorModelProxyInterface
+{
+    Q_OBJECT
+    Q_PROPERTY(QObject *modelData READ modelData CONSTANT)
+    Q_INTERFACES(QSGVisualAdaptorModelProxyInterface)
+public:
+    QObject *modelData() const { return m_metaObject->m_object; }
+    QObject *proxiedObject() { return m_metaObject->m_object; }
+
+    static QSGVisualAdaptorModelData *create(int index, QSGVisualAdaptorModel *model) {
+        return new QSGVDMObjectData(index, model); }
+
+private:
+    QSGVDMObjectData(int index, QSGVisualAdaptorModel *model)
+        : QSGVisualAdaptorModelData(index, model)
+        , m_metaObject(new QSGVDMObjectDataMetaObject(this, QSGVisualAdaptorModelPrivate::get(m_model)->m_delegateDataType))
+    {
+    }
+
+    QSGVDMObjectDataMetaObject *m_metaObject;
+};
+
+void QSGVisualAdaptorModelPrivate::addProperty(
+        int role, int propertyId, const char *propertyName, const char *propertyType, bool isModelData)
+{
+    PropertyData propertyData;
+    propertyData.role = role;
+    propertyData.isModelData = isModelData;
+    m_delegateDataType->builder.addSignal("__" + QByteArray::number(propertyId) + "()");
+    QMetaPropertyBuilder property = m_delegateDataType->builder.addProperty(
+            propertyName, propertyType, propertyId);
+    property.setWritable(false);
+
+    m_propertyData.append(propertyData);
+}
+
+QSGVisualAdaptorModelData *QSGVisualAdaptorModelPrivate::createMetaObject(int index, QSGVisualAdaptorModel *model)
+{
+    Q_ASSERT(!m_delegateDataType);
+
+    m_objectList = false;
+    m_propertyData.clear();
+    if (m_listAccessor
+            && m_listAccessor->type() != QDeclarativeListAccessor::ListProperty
+            && m_listAccessor->type() != QDeclarativeListAccessor::Instance) {
+        createModelData = &QSGVDMListAccessorData::create;
+        m_flags = QSGVisualAdaptorModel::MetaObjectCacheable;
+        return QSGVDMListAccessorData::create(index, model);
+    }
+
+    m_delegateDataType = new VDMDelegateDataType;
+    if (m_listModelInterface) {
+        setModelDataType<QSGVDMListModelInterfaceData>();
+        QList<int> roles = m_listModelInterface->roles();
+        for (int propertyId = 0; propertyId < roles.count(); ++propertyId) {
+            const int role = roles.at(propertyId);
+            const QByteArray propertyName = m_listModelInterface->toString(role).toUtf8();
+            addProperty(role, propertyId, propertyName, "QVariant");
+            m_roleNames.insert(propertyName, role);
+        }
+        if (m_propertyData.count() == 1)
+            addProperty(roles.first(), 1, "modelData", "QVariant", true);
+        m_flags = QSGVisualAdaptorModel::MetaObjectCacheable;
+    } else if (m_abstractItemModel) {
+        setModelDataType<QSGVDMAbstractItemModelData>();
+        QHash<int, QByteArray> roleNames = m_abstractItemModel->roleNames();
+        for (QHash<int, QByteArray>::const_iterator it = roleNames.begin(); it != roleNames.end(); ++it) {
+            addProperty(it.key(), m_propertyData.count(), it.value(), "QVariant");
+            m_roleNames.insert(it.value(), it.key());
+        }
+        if (m_propertyData.count() == 1)
+            addProperty(roleNames.begin().key(), 1, "modelData", "QVariant", true);
+        m_flags = QSGVisualAdaptorModel::MetaObjectCacheable;
+    } else if (m_listAccessor) {
+        setModelDataType<QSGVDMObjectData>();
+        m_objectList = true;
+        m_flags = QSGVisualAdaptorModel::ProxiedObject;
+    } else {
+        Q_ASSERT(!"No model set on VisualDataModel");
+        return 0;
+    }
+    m_delegateDataType->metaObject = m_delegateDataType->builder.toMetaObject();
+    if (!m_objectList) {
+        m_delegateDataType->propertyCache = new QDeclarativePropertyCache(
+                m_engine, m_delegateDataType->metaObject);
+    }
+    return createModelData(index, model);
+}
+
+QSGVisualAdaptorModelData::QSGVisualAdaptorModelData(int index, QSGVisualAdaptorModel *model)
+    : m_index(index)
+    , m_model(model)
+{
+}
+
+QSGVisualAdaptorModelData::~QSGVisualAdaptorModelData()
+{
+}
+
+int QSGVisualAdaptorModelData::index() const
+{
+    return m_index;
+}
+
+// This is internal only - it should not be set from qml
+void QSGVisualAdaptorModelData::setIndex(int index)
+{
+    m_index = index;
+    emit indexChanged();
+}
+
+//---------------------------------------------------------------------------
+
+QSGVisualAdaptorModel::QSGVisualAdaptorModel(QObject *parent)
+    : QObject(*(new QSGVisualAdaptorModelPrivate), parent)
+{
+}
+
+QSGVisualAdaptorModel::~QSGVisualAdaptorModel()
+{
+    Q_D(QSGVisualAdaptorModel);
+    if (d->m_listAccessor)
+        delete d->m_listAccessor;
+    if (d->m_delegateDataType)
+        d->m_delegateDataType->release();
+}
+
+QSGVisualAdaptorModel::Flags QSGVisualAdaptorModel::flags() const
+{
+    Q_D(const QSGVisualAdaptorModel);
+    return d->m_flags;
+}
+
+QVariant QSGVisualAdaptorModel::model() const
+{
+    Q_D(const QSGVisualAdaptorModel);
+    return d->m_modelVariant;
+}
+
+void QSGVisualAdaptorModel::setModel(const QVariant &model, QDeclarativeEngine *engine)
+{
+    Q_D(QSGVisualAdaptorModel);
+    delete d->m_listAccessor;
+    d->m_engine = engine;
+    d->m_listAccessor = 0;
+    d->m_modelVariant = model;
+    if (d->m_listModelInterface) {
+        // Assume caller has released all items.
+        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsChanged(int,int,QList<int>)),
+                this, SLOT(_q_itemsChanged(int,int,QList<int>)));
+        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsInserted(int,int)),
+                this, SLOT(_q_itemsInserted(int,int)));
+        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsRemoved(int,int)),
+                this, SLOT(_q_itemsRemoved(int,int)));
+        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsMoved(int,int,int)),
+                this, SLOT(_q_itemsMoved(int,int,int)));
+        d->m_listModelInterface = 0;
+    } else if (d->m_abstractItemModel) {
+        QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
+                            this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
+        QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+                            this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+        QObject::disconnect(d->m_abstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+                            this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
+        QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+                            this, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
+        QObject::disconnect(d->m_abstractItemModel, SIGNAL(modelReset()), this, SLOT(_q_modelReset()));
+        QObject::disconnect(d->m_abstractItemModel, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
+        d->m_abstractItemModel = 0;
+    }
+
+    d->m_roles.clear();
+    d->m_roleNames.clear();
+    d->m_flags = QSGVisualAdaptorModel::Flags();
+    if (d->m_delegateDataType)
+        d->m_delegateDataType->release();
+    d->m_delegateDataType = 0;
+    d->createModelData = &QSGVisualAdaptorModelPrivate::initializeModelData;
+
+    if (d->m_count)
+        emit itemsRemoved(0, d->m_count);
+
+    QObject *object = qvariant_cast<QObject *>(model);
+    if (object && (d->m_listModelInterface = qobject_cast<QListModelInterface *>(object))) {
+        QObject::connect(d->m_listModelInterface, SIGNAL(itemsChanged(int,int,QList<int>)),
+                         this, SLOT(_q_itemsChanged(int,int,QList<int>)));
+        QObject::connect(d->m_listModelInterface, SIGNAL(itemsInserted(int,int)),
+                         this, SLOT(_q_itemsInserted(int,int)));
+        QObject::connect(d->m_listModelInterface, SIGNAL(itemsRemoved(int,int)),
+                         this, SLOT(_q_itemsRemoved(int,int)));
+        QObject::connect(d->m_listModelInterface, SIGNAL(itemsMoved(int,int,int)),
+                         this, SLOT(_q_itemsMoved(int,int,int)));
+        if ((d->m_count = d->m_listModelInterface->count()))
+            emit itemsInserted(0, d->m_count);
+        return;
+    } else if (object && (d->m_abstractItemModel = qobject_cast<QAbstractItemModel *>(object))) {
+        QObject::connect(d->m_abstractItemModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
+                            this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
+        QObject::connect(d->m_abstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
+                            this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
+        QObject::connect(d->m_abstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+                            this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
+        QObject::connect(d->m_abstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
+                            this, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
+        QObject::connect(d->m_abstractItemModel, SIGNAL(modelReset()), this, SLOT(_q_modelReset()));
+        QObject::connect(d->m_abstractItemModel, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
+
+        if ((d->m_count = d->m_abstractItemModel->rowCount(d->m_root)))
+            emit itemsInserted(0, d->m_count);
+        return;
+    }
+
+    d->m_listAccessor = new QDeclarativeListAccessor;
+    d->m_listAccessor->setList(model, d->m_engine);
+    if ((d->m_count = d->m_listAccessor->count()))
+        emit itemsInserted(0, d->m_count);
+}
+
+QVariant QSGVisualAdaptorModel::rootIndex() const
+{
+    Q_D(const QSGVisualAdaptorModel);
+    return QVariant::fromValue(d->m_root);
+}
+
+void QSGVisualAdaptorModel::setRootIndex(const QVariant &root)
+{
+    Q_D(QSGVisualAdaptorModel);
+    QModelIndex modelIndex = qvariant_cast<QModelIndex>(root);
+    if (d->m_root != modelIndex) {
+        int oldCount = d->modelCount();
+        d->m_root = modelIndex;
+        if (d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(modelIndex))
+            d->m_abstractItemModel->fetchMore(modelIndex);
+        int newCount = d->modelCount();
+        if (oldCount)
+            emit itemsRemoved(0, oldCount);
+        if (newCount)
+            emit itemsInserted(0, newCount);
+        emit rootIndexChanged();
+    }
+}
+
+QVariant QSGVisualAdaptorModel::modelIndex(int idx) const
+{
+    Q_D(const QSGVisualAdaptorModel);
+    if (d->m_abstractItemModel)
+        return QVariant::fromValue(d->m_abstractItemModel->index(idx, 0, d->m_root));
+    return QVariant::fromValue(QModelIndex());
+}
+
+QVariant QSGVisualAdaptorModel::parentModelIndex() const
+{
+    Q_D(const QSGVisualAdaptorModel);
+    if (d->m_abstractItemModel)
+        return QVariant::fromValue(d->m_abstractItemModel->parent(d->m_root));
+    return QVariant::fromValue(QModelIndex());
+}
+
+int QSGVisualAdaptorModel::count() const
+{
+    Q_D(const QSGVisualAdaptorModel);
+    return d->modelCount();
+}
+
+QObject *QSGVisualAdaptorModel::data(int index)
+{
+    Q_D(QSGVisualAdaptorModel);
+    QSGVisualAdaptorModelData *data = d->createModelData(index, this);
+    d->m_cache.insert(data);
+    return data;
+}
+
+QString QSGVisualAdaptorModel::stringValue(int index, const QString &name)
+{
+    Q_D(QSGVisualAdaptorModel);
+    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();
+    }
+
+    QString val;
+    QSGVisualAdaptorModelData *data = d->createModelData(index, this);
+
+    QDeclarativeData *ddata = QDeclarativeData::get(data);
+    if (ddata && ddata->propertyCache) {
+        QDeclarativePropertyCache::Data *prop = ddata->propertyCache->property(name);
+        if (prop) {
+            if (prop->propType == QVariant::String) {
+                void *args[] = { &val, 0 };
+                QMetaObject::metacall(data, QMetaObject::ReadProperty, prop->coreIndex, args);
+            } else if (prop->propType == qMetaTypeId<QVariant>()) {
+                QVariant v;
+                void *args[] = { &v, 0 };
+                QMetaObject::metacall(data, QMetaObject::ReadProperty, prop->coreIndex, args);
+                val = v.toString();
+            }
+        } else {
+            val = data->property(name.toUtf8()).toString();
+        }
+    } else {
+        val = data->property(name.toUtf8()).toString();
+    }
+
+    delete data;
+
+    return val;
+}
+
+int QSGVisualAdaptorModel::indexOf(QObject *object) const
+{
+    if (QSGVisualAdaptorModelData *data = qobject_cast<QSGVisualAdaptorModelData *>(object))
+        return data->index();
+    return -1;
+}
+
+bool QSGVisualAdaptorModel::canFetchMore() const
+{
+    Q_D(const QSGVisualAdaptorModel);
+    return d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(d->m_root);
+}
+
+void QSGVisualAdaptorModel::fetchMore()
+{
+    Q_D(QSGVisualAdaptorModel);
+    if (d->m_abstractItemModel)
+        d->m_abstractItemModel->fetchMore(d->m_root);
+}
+
+void QSGVisualAdaptorModel::replaceWatchedRoles(const QList<QByteArray> &oldRoles, const QList<QByteArray> &newRoles)
+{
+    Q_D(QSGVisualAdaptorModel);
+    d->watchedRoleIds.clear();
+    foreach (const QByteArray &oldRole, oldRoles)
+        d->watchedRoles.removeOne(oldRole);
+    d->watchedRoles += newRoles;
+}
+
+void QSGVisualAdaptorModel::_q_itemsChanged(int index, int count, const QList<int> &roles)
+{
+    Q_D(QSGVisualAdaptorModel);
+    bool changed = roles.isEmpty();
+    if (!d->watchedRoles.isEmpty() && d->watchedRoleIds.isEmpty()) {
+        foreach (QByteArray r, d->watchedRoles) {
+            if (d->m_roleNames.contains(r))
+                d->watchedRoleIds << d->m_roleNames.value(r);
+        }
+    }
+
+    QVector<int> signalIndexes;
+    for (int i = 0; i < roles.count(); ++i) {
+        const int role = roles.at(i);
+        if (!changed && d->watchedRoleIds.contains(role))
+            changed = true;
+        for (int propertyId = 0; propertyId < d->m_propertyData.count(); ++propertyId) {
+            if (d->m_propertyData.at(propertyId).role == role)
+                signalIndexes.append(propertyId + d->m_delegateDataType->signalOffset);
+        }
+    }
+    if (roles.isEmpty()) {
+        for (int propertyId = 0; propertyId < d->m_propertyData.count(); ++propertyId)
+            signalIndexes.append(propertyId + d->m_delegateDataType->signalOffset);
+    }
+
+    typedef QSGVisualAdaptorModelDataCache::iterator iterator;
+    for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) {
+        const int idx = it->index();
+        if (idx >= index && idx < index + count) {
+            QSGVisualAdaptorModelData *data = *it;
+            for (int i = 0; i < signalIndexes.count(); ++i)
+                QMetaObject::activate(data, signalIndexes.at(i), 0);
+        }
+    }
+    if (changed)
+        emit itemsChanged(index, count);
+}
+
+void QSGVisualAdaptorModel::_q_itemsInserted(int index, int count)
+{
+    Q_D(QSGVisualAdaptorModel);
+    if (count <= 0)
+        return;
+    d->m_count += count;
+
+    typedef QSGVisualAdaptorModelDataCache::iterator iterator;
+    for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) {
+        if (it->index() >= index)
+            it->setIndex(it->index() + count);
+    }
+
+    emit itemsInserted(index, count);
+}
+
+void QSGVisualAdaptorModel::_q_itemsRemoved(int index, int count)
+{
+    Q_D(QSGVisualAdaptorModel);
+    if (count <= 0)
+        return;
+    d->m_count -= count;
+
+    typedef QSGVisualAdaptorModelDataCache::iterator iterator;
+    for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) {
+        if (it->index() >= index + count)
+            it->setIndex(it->index() - count);
+        else  if (it->index() >= index)
+            it->setIndex(-1);
+    }
+
+    emit itemsRemoved(index, count);
+}
+
+void QSGVisualAdaptorModel::_q_itemsMoved(int from, int to, int count)
+{
+    Q_D(QSGVisualAdaptorModel);
+    const int minimum = qMin(from, to);
+    const int maximum = qMax(from, to) + count;
+    const int difference = from > to ? count : -count;
+
+    typedef QSGVisualAdaptorModelDataCache::iterator iterator;
+    for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) {
+        if (it->index() >= from && it->index() < from + count)
+            it->setIndex(it->index() - from + to);
+        else if (it->index() >= minimum && it->index() < maximum)
+            it->setIndex(it->index() + difference);
+    }
+    emit itemsMoved(from, to, count);
+}
+
+void QSGVisualAdaptorModel::_q_rowsInserted(const QModelIndex &parent, int begin, int end)
+{
+    Q_D(QSGVisualAdaptorModel);
+    if (parent == d->m_root)
+        _q_itemsInserted(begin, end - begin + 1);
+}
+
+void QSGVisualAdaptorModel::_q_rowsRemoved(const QModelIndex &parent, int begin, int end)
+{
+    Q_D(QSGVisualAdaptorModel);
+    if (parent == d->m_root)
+        _q_itemsRemoved(begin, end - begin + 1);
+}
+
+void QSGVisualAdaptorModel::_q_rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
+{
+   Q_D(QSGVisualAdaptorModel);
+    const int count = sourceEnd - sourceStart + 1;
+    if (destinationParent == d->m_root && sourceParent == d->m_root) {
+        _q_itemsMoved(sourceStart, sourceStart > destinationRow ? destinationRow : destinationRow-count, count);
+    } else if (sourceParent == d->m_root) {
+        _q_itemsRemoved(sourceStart, count);
+    } else if (destinationParent == d->m_root) {
+        _q_itemsInserted(destinationRow, count);
+    }
+}
+
+void QSGVisualAdaptorModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end)
+{
+    Q_D(QSGVisualAdaptorModel);
+    if (begin.parent() == d->m_root)
+        _q_itemsChanged(begin.row(), end.row() - begin.row() + 1, d->m_roles);
+}
+
+void QSGVisualAdaptorModel::_q_layoutChanged()
+{
+    Q_D(QSGVisualAdaptorModel);
+    _q_itemsChanged(0, count(), d->m_roles);
+}
+
+void QSGVisualAdaptorModel::_q_modelReset()
+{
+    Q_D(QSGVisualAdaptorModel);
+    int oldCount = d->m_count;
+    d->m_root = QModelIndex();
+    d->m_count = d->modelCount();
+    emit modelReset(oldCount, d->m_count);
+    emit rootIndexChanged();
+    if (d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(d->m_root))
+        d->m_abstractItemModel->fetchMore(d->m_root);
+}
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QListModelInterface)
+
+#include <qsgvisualadaptormodel.moc>
diff --git a/src/declarative/items/qsgvisualadaptormodel_p.h b/src/declarative/items/qsgvisualadaptormodel_p.h
new file mode 100644 (file)
index 0000000..bc9d388
--- /dev/null
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGVISUALADAPTORMODEL_P_H
+#define QSGVISUALADAPTORMODEL_P_H
+
+#include <QtCore/qobject.h>
+#include <QtCore/qabstractitemmodel.h>
+
+#include <QtDeclarative/private/qdeclarativerefcount_p.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+class QDeclarativeEngine;
+
+class QSGVisualAdaptorModelPrivate;
+class QSGVisualAdaptorModel : public QObject
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QSGVisualAdaptorModel)
+public:
+    enum Flag
+    {
+        MetaObjectCacheable = 0x01,
+        ProxiedObject       = 0x02
+    };
+    Q_DECLARE_FLAGS(Flags, Flag)
+
+    QSGVisualAdaptorModel(QObject *parent = 0);
+    virtual ~QSGVisualAdaptorModel();
+
+    Flags flags() const;
+
+    QVariant model() const;
+    void setModel(const QVariant &, QDeclarativeEngine *);
+
+    QVariant rootIndex() const;
+    void setRootIndex(const QVariant &root);
+
+    QVariant modelIndex(int idx) const;
+    QVariant parentModelIndex() const;
+
+    int count() const;
+    QObject *data(int index);
+    QString stringValue(int index, const QString &role);
+    void replaceWatchedRoles(const QList<QByteArray> &oldRoles, const QList<QByteArray> &newRoles);
+    int indexOf(QObject *object) const;
+
+    bool canFetchMore() const;
+    void fetchMore();
+
+Q_SIGNALS:
+    void rootIndexChanged();
+    void modelReset(int oldCount, int newCount);
+
+    void itemsInserted(int index, int count);
+    void itemsRemoved(int index, int count);
+    void itemsMoved(int from, int to, int count);
+    void itemsChanged(int index, int count);
+
+private Q_SLOTS:
+    void _q_itemsChanged(int, int, const QList<int> &);
+    void _q_itemsInserted(int index, int count);
+    void _q_itemsRemoved(int index, int count);
+    void _q_itemsMoved(int from, int to, int count);
+    void _q_rowsInserted(const QModelIndex &,int,int);
+    void _q_rowsRemoved(const QModelIndex &,int,int);
+    void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
+    void _q_dataChanged(const QModelIndex&,const QModelIndex&);
+    void _q_layoutChanged();
+    void _q_modelReset();
+
+private:
+    Q_DISABLE_COPY(QSGVisualAdaptorModel)
+};
+
+class QSGVisualAdaptorModelProxyInterface
+{
+public:
+    virtual ~QSGVisualAdaptorModelProxyInterface() {}
+
+    virtual QObject *proxiedObject() = 0;
+};
+
+Q_DECLARE_INTERFACE(QSGVisualAdaptorModelProxyInterface, "com.trolltech.qml.QSGVisualAdaptorModelProxyInterface")
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/declarative/items/qsgvisualdatamodel.cpp b/src/declarative/items/qsgvisualdatamodel.cpp
new file mode 100644 (file)
index 0000000..219d1dc
--- /dev/null
@@ -0,0 +1,849 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsgvisualdatamodel_p.h"
+#include "qsgitem.h"
+
+#include <QtCore/qcoreapplication.h>
+#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeengine.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
+#include <QtDeclarative/qdeclarativeinfo.h>
+
+#include <private/qdeclarativecontext_p.h>
+#include <private/qdeclarativepackage_p.h>
+#include <private/qdeclarativeopenmetaobject_p.h>
+#include <private/qdeclarativelistaccessor_p.h>
+#include <private/qdeclarativedata_p.h>
+#include <private/qdeclarativepropertycache_p.h>
+#include <private/qdeclarativeguard_p.h>
+#include <private/qdeclarativeglobal_p.h>
+#include <private/qmetaobjectbuilder_p.h>
+#include <private/qdeclarativeproperty_p.h>
+#include <private/qsgvisualadaptormodel_p.h>
+#include <private/qobject_p.h>
+
+#include <QtCore/qhash.h>
+#include <QtCore/qlist.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGVisualDataModelParts;
+class QSGVisualDataModelData;
+class QSGVisualDataModelDataMetaObject;
+class QSGVisualDataModelPrivate : public QObjectPrivate
+{
+    Q_DECLARE_PUBLIC(QSGVisualDataModel)
+public:
+    QSGVisualDataModelPrivate(QDeclarativeContext *);
+
+    static QSGVisualDataModelPrivate *get(QSGVisualDataModel *m) {
+        return static_cast<QSGVisualDataModelPrivate *>(QObjectPrivate::get(m));
+    }
+
+    void init();
+    void connectModel(QSGVisualAdaptorModel *model);
+
+    QObject *object(int index, bool complete);
+    QSGVisualDataModel::ReleaseFlags release(QObject *object);
+    QString stringValue(int index, const QString &name);
+    void emitCreatedPackage(int index, QDeclarativePackage *package) {
+        emit q_func()->createdPackage(index, package); }
+    void emitDestroyingPackage(QDeclarativePackage *package) {
+        emit q_func()->destroyingPackage(package); }
+
+    QSGVisualAdaptorModel *m_adaptorModel;
+    QDeclarativeComponent *m_delegate;
+    QDeclarativeGuard<QDeclarativeContext> m_context;
+
+    struct ObjectRef {
+        ObjectRef(QObject *object=0) : obj(object), ref(1) {}
+        QObject *obj;
+        int ref;
+    };
+    class Cache : public QHash<int, ObjectRef> {
+    public:
+        QObject *getItem(int index) {
+            QObject *item = 0;
+            QHash<int,ObjectRef>::iterator it = find(index);
+            if (it != end()) {
+                (*it).ref++;
+                item = (*it).obj;
+            }
+            return item;
+        }
+        QObject *item(int index) {
+            QObject *item = 0;
+            QHash<int, ObjectRef>::const_iterator it = find(index);
+            if (it != end())
+                item = (*it).obj;
+            return item;
+        }
+        void insertItem(int index, QObject *obj) {
+            insert(index, ObjectRef(obj));
+        }
+        bool releaseItem(QObject *obj) {
+            QHash<int, ObjectRef>::iterator it = begin();
+            for (; it != end(); ++it) {
+                ObjectRef &objRef = *it;
+                if (objRef.obj == obj) {
+                    if (--objRef.ref == 0) {
+                        erase(it);
+                        return true;
+                    }
+                    break;
+                }
+            }
+            return false;
+        }
+    };
+
+    Cache m_cache;
+    QHash<QObject *, QDeclarativePackage*> m_packaged;
+
+    QSGVisualDataModelParts *m_parts;
+    friend class QSGVisualItemParts;
+
+    friend class QSGVisualDataModelData;
+    bool m_delegateValidated : 1;
+    bool m_completePending : 1;
+
+    QList<QByteArray> watchedRoles;
+};
+
+//---------------------------------------------------------------------------
+
+class QSGVisualPartsModel : public QSGVisualModel
+{
+    Q_OBJECT
+
+public:
+    QSGVisualPartsModel(QSGVisualDataModel *model, const QString &part, QObject *parent = 0);
+    ~QSGVisualPartsModel();
+
+    int count() const;
+    bool isValid() const;
+    QSGItem *item(int index, bool complete=true);
+    ReleaseFlags release(QSGItem *item);
+    bool completePending() const;
+    void completeItem();
+    QString stringValue(int index, const QString &role);
+    void setWatchedRoles(QList<QByteArray> roles);
+
+    int indexOf(QSGItem *item, QObject *objectContext) const;
+
+public Q_SLOTS:
+    void createdPackage(int index, QDeclarativePackage *package);
+    void destroyingPackage(QDeclarativePackage *package);
+
+private:
+    QSGVisualDataModel *m_model;
+    QHash<QObject *, QDeclarativePackage *> m_packaged;
+    QString m_part;
+    QList<QByteArray> m_watchedRoles;
+};
+
+class QSGVisualDataModelPartsMetaObject : public QDeclarativeOpenMetaObject
+{
+public:
+    QSGVisualDataModelPartsMetaObject(QObject *parent)
+    : QDeclarativeOpenMetaObject(parent) {}
+
+    virtual void propertyCreated(int, QMetaPropertyBuilder &);
+    virtual QVariant initialValue(int);
+};
+
+class QSGVisualDataModelParts : public QObject
+{
+Q_OBJECT
+public:
+    QSGVisualDataModelParts(QSGVisualDataModel *parent);
+
+private:
+    friend class QSGVisualDataModelPartsMetaObject;
+    QSGVisualDataModel *model;
+};
+
+void QSGVisualDataModelPartsMetaObject::propertyCreated(int, QMetaPropertyBuilder &prop)
+{
+    prop.setWritable(false);
+}
+
+QVariant QSGVisualDataModelPartsMetaObject::initialValue(int id)
+{
+    QSGVisualPartsModel *m = new QSGVisualPartsModel(
+            static_cast<QSGVisualDataModelParts *>(object())->model,
+            QString::fromUtf8(name(id)),
+            object());
+    return QVariant::fromValue(static_cast<QObject *>(m));
+}
+
+QSGVisualDataModelParts::QSGVisualDataModelParts(QSGVisualDataModel *parent)
+: QObject(parent), model(parent)
+{
+    new QSGVisualDataModelPartsMetaObject(this);
+}
+
+QSGVisualDataModelPrivate::QSGVisualDataModelPrivate(QDeclarativeContext *ctxt)
+    : m_adaptorModel(0)
+    , m_delegate(0)
+    , m_context(ctxt)
+    , m_parts(0)
+    , m_delegateValidated(false)
+    , m_completePending(false)
+{
+}
+
+//---------------------------------------------------------------------------
+
+/*!
+    \qmlclass VisualDataModel QSGVisualDataModel
+    \inqmlmodule QtQuick 2
+    \ingroup qml-working-with-data
+    \brief The VisualDataModel encapsulates a model and delegate
+
+    A VisualDataModel encapsulates a model and the delegate that will
+    be instantiated for items in the model.
+
+    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.
+
+    \snippet doc/src/snippets/declarative/visualdatamodel.qml 0
+*/
+
+void QSGVisualDataModelPrivate::connectModel(QSGVisualAdaptorModel *model)
+{
+    Q_Q(QSGVisualDataModel);
+
+    QObject::connect(model, SIGNAL(itemsInserted(int,int)), q, SLOT(_q_itemsInserted(int,int)));
+    QObject::connect(model, SIGNAL(itemsRemoved(int,int)), q, SLOT(_q_itemsRemoved(int,int)));
+    QObject::connect(model, SIGNAL(itemsMoved(int,int,int)), q, SLOT(_q_itemsMoved(int,int,int)));
+    QObject::connect(model, SIGNAL(itemsChanged(int,int)), q, SLOT(_q_itemsChanged(int,int)));
+    QObject::connect(model, SIGNAL(modelReset(int,int)), q, SLOT(_q_modelReset(int,int)));
+}
+
+void QSGVisualDataModelPrivate::init()
+{
+    Q_Q(QSGVisualDataModel);
+    m_adaptorModel = new QSGVisualAdaptorModel;
+    QObject::connect(m_adaptorModel, SIGNAL(rootIndexChanged()), q, SIGNAL(rootIndexChanged()));
+    connectModel(m_adaptorModel);
+}
+
+QSGVisualDataModel::QSGVisualDataModel()
+: QSGVisualModel(*(new QSGVisualDataModelPrivate(0)))
+{
+    Q_D(QSGVisualDataModel);
+    d->init();
+}
+
+QSGVisualDataModel::QSGVisualDataModel(QDeclarativeContext *ctxt, QObject *parent)
+: QSGVisualModel(*(new QSGVisualDataModelPrivate(ctxt)), parent)
+{
+    Q_D(QSGVisualDataModel);
+    d->init();
+}
+
+QSGVisualDataModel::~QSGVisualDataModel()
+{
+    Q_D(QSGVisualDataModel);
+    delete d->m_adaptorModel;
+}
+
+/*!
+    \qmlproperty model QtQuick2::VisualDataModel::model
+    This property holds the model providing data for the VisualDataModel.
+
+    The model provides a set of data that is used to create the items
+    for a view.  For large or dynamic datasets the model is usually
+    provided by a C++ model object.  The C++ model object must be a \l
+    {QAbstractItemModel} subclass or a simple list.
+
+    Models can also be created directly in QML, using a \l{ListModel} or
+    \l{XmlListModel}.
+
+    \sa {qmlmodels}{Data Models}
+*/
+QVariant QSGVisualDataModel::model() const
+{
+    Q_D(const QSGVisualDataModel);
+    return d->m_adaptorModel->model();
+}
+
+void QSGVisualDataModel::setModel(const QVariant &model)
+{
+    Q_D(QSGVisualDataModel);
+    d->m_adaptorModel->setModel(model, d->m_context ? d->m_context->engine() : qmlEngine(this));
+    if (d->m_adaptorModel->canFetchMore())
+        QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
+}
+
+/*!
+    \qmlproperty Component QtQuick2::VisualDataModel::delegate
+
+    The delegate provides a template defining each item instantiated by a view.
+    The index is exposed as an accessible \c index property.  Properties of the
+    model are also available depending upon the type of \l {qmlmodels}{Data Model}.
+*/
+QDeclarativeComponent *QSGVisualDataModel::delegate() const
+{
+    Q_D(const QSGVisualDataModel);
+    return d->m_delegate;
+}
+
+void QSGVisualDataModel::setDelegate(QDeclarativeComponent *delegate)
+{
+    Q_D(QSGVisualDataModel);
+    bool wasValid = d->m_delegate != 0;
+    d->m_delegate = delegate;
+    d->m_delegateValidated = false;
+    if (!wasValid && d->m_adaptorModel->count() && d->m_delegate) {
+        emit itemsInserted(0, d->m_adaptorModel->count());
+        emit countChanged();
+    }
+    if (wasValid && !d->m_delegate && d->m_adaptorModel->count()) {
+        _q_itemsRemoved(0, d->m_adaptorModel->count());
+        emit countChanged();
+    }
+}
+
+/*!
+    \qmlproperty QModelIndex QtQuick2::VisualDataModel::rootIndex
+
+    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 that
+    are hierarchical (e.g, a tree model).
+
+    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.
+
+    \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
+
+    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()
+*/
+QVariant QSGVisualDataModel::rootIndex() const
+{
+    Q_D(const QSGVisualDataModel);
+    return d->m_adaptorModel->rootIndex();
+}
+
+void QSGVisualDataModel::setRootIndex(const QVariant &root)
+{
+    Q_D(QSGVisualDataModel);
+    d->m_adaptorModel->setRootIndex(root);
+}
+
+/*!
+    \qmlmethod QModelIndex QtQuick2::VisualDataModel::modelIndex(int index)
+
+    QAbstractItemModel provides a hierarchical tree of data, whereas
+    QML only operates on list data.  This function assists in using
+    tree models in QML.
+
+    Returns a QModelIndex for the specified index.
+    This value can be assigned to rootIndex.
+
+    \sa rootIndex
+*/
+QVariant QSGVisualDataModel::modelIndex(int idx) const
+{
+    Q_D(const QSGVisualDataModel);
+    return d->m_adaptorModel->modelIndex(idx);
+}
+
+/*!
+    \qmlmethod QModelIndex QtQuick2::VisualDataModel::parentModelIndex()
+
+    QAbstractItemModel provides a hierarchical tree of data, whereas
+    QML only operates on list data.  This function assists in using
+    tree models in QML.
+
+    Returns a QModelIndex for the parent of the current rootIndex.
+    This value can be assigned to rootIndex.
+
+    \sa rootIndex
+*/
+QVariant QSGVisualDataModel::parentModelIndex() const
+{
+    Q_D(const QSGVisualDataModel);
+    return d->m_adaptorModel->parentModelIndex();
+}
+
+int QSGVisualDataModel::count() const
+{
+    Q_D(const QSGVisualDataModel);
+    if (!d->m_delegate)
+        return 0;
+    return d->m_adaptorModel->count();
+}
+
+QSGVisualDataModel::ReleaseFlags QSGVisualDataModelPrivate::release(QObject *object)
+{
+    QSGVisualDataModel::ReleaseFlags stat = 0;
+
+    if (m_cache.releaseItem(object)) {
+        // Remove any bindings to avoid warnings due to parent change.
+        QObjectPrivate *p = QObjectPrivate::get(object);
+        Q_ASSERT(p->declarativeData);
+        QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
+        if (d->ownContext && d->context)
+            d->context->clearContext();
+        stat |= QSGVisualDataModel::Destroyed;
+        object->deleteLater();
+    } else {
+        stat |= QSGVisualDataModel::Referenced;
+    }
+
+    return stat;
+}
+
+/*
+  Returns ReleaseStatus flags.
+*/
+
+QSGVisualDataModel::ReleaseFlags QSGVisualDataModel::release(QSGItem *item)
+{
+    Q_D(QSGVisualDataModel);
+    QSGVisualModel::ReleaseFlags stat = d->release(item);
+    if (stat & Destroyed)
+        item->setParentItem(0);
+    return stat;
+}
+
+/*!
+    \qmlproperty object QtQuick2::VisualDataModel::parts
+
+    The \a parts property selects a VisualDataModel which creates
+    delegates from the part named.  This is used in conjunction with
+    the \l Package element.
+
+    For example, the code below selects a model which creates
+    delegates named \e list from a \l Package:
+
+    \code
+    VisualDataModel {
+        id: visualModel
+        delegate: Package {
+            Item { Package.name: "list" }
+        }
+        model: myModel
+    }
+
+    ListView {
+        width: 200; height:200
+        model: visualModel.parts.list
+    }
+    \endcode
+
+    \sa Package
+*/
+
+QObject *QSGVisualDataModel::parts()
+{
+    Q_D(QSGVisualDataModel);
+    if (!d->m_parts)
+        d->m_parts = new QSGVisualDataModelParts(this);
+    return d->m_parts;
+}
+
+QObject *QSGVisualDataModelPrivate::object(int index, bool complete)
+{
+    Q_Q(QSGVisualDataModel);
+    if (m_adaptorModel->count() <= 0 || !m_delegate)
+        return 0;
+    QObject *nobj = m_cache.getItem(index);
+    bool needComplete = false;
+    if (!nobj) {
+        QObject *data = m_adaptorModel->data(index);
+
+        QDeclarativeContext *rootContext = new QDeclarativeContext(
+                m_context ? m_context.data() : qmlContext(q));
+        QDeclarativeContext *ctxt = rootContext;
+        if (m_adaptorModel->flags() & QSGVisualAdaptorModel::ProxiedObject) {
+            if (QSGVisualAdaptorModelProxyInterface *proxy = qobject_cast<QSGVisualAdaptorModelProxyInterface *>(data)) {
+                ctxt->setContextObject(proxy->proxiedObject());
+                ctxt = new QDeclarativeContext(ctxt, ctxt);
+            }
+        }
+
+        QDeclarative_setParent_noEvent(data, ctxt);
+        ctxt->setContextProperty(QLatin1String("model"), data);
+        ctxt->setContextObject(data);
+
+        m_completePending = false;
+        nobj = m_delegate->beginCreate(ctxt);
+        if (complete) {
+            m_delegate->completeCreate();
+        } else {
+            m_completePending = true;
+            needComplete = true;
+        }
+        if (nobj) {
+            QDeclarative_setParent_noEvent(rootContext, nobj);
+            m_cache.insertItem(index, nobj);
+            if (QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(nobj))
+                emitCreatedPackage(index, package);
+        } else {
+            delete rootContext;
+            qmlInfo(q, m_delegate->errors()) << "Error creating delegate";
+        }
+    }
+
+    if (index == m_adaptorModel->count() -1 && m_adaptorModel->canFetchMore())
+        QCoreApplication::postEvent(q, new QEvent(QEvent::UpdateRequest));
+
+    return nobj;
+}
+
+QSGItem *QSGVisualDataModel::item(int index, bool complete)
+{
+    Q_D(QSGVisualDataModel);
+    QObject *object = d->object(index, complete);
+    if (QSGItem *item = qobject_cast<QSGItem *>(object))
+        return item;
+
+    if (completePending())
+        completeItem();
+    d->release(object);
+    if (!d->m_delegateValidated) {
+        qmlInfo(d->m_delegate) << tr("Delegate component must be Item type.");
+        d->m_delegateValidated = true;
+    }
+    return 0;
+}
+
+bool QSGVisualDataModel::completePending() const
+{
+    Q_D(const QSGVisualDataModel);
+    return d->m_completePending;
+}
+
+void QSGVisualDataModel::completeItem()
+{
+    Q_D(QSGVisualDataModel);
+    d->m_delegate->completeCreate();
+    d->m_completePending = false;
+}
+
+QString QSGVisualDataModelPrivate::stringValue(int index, const QString &name)
+{
+    return m_adaptorModel->stringValue(index, name);
+}
+
+QString QSGVisualDataModel::stringValue(int index, const QString &name)
+{
+    Q_D(QSGVisualDataModel);
+    return d->stringValue(index, name);
+}
+
+int QSGVisualDataModel::indexOf(QSGItem *item, QObject *) const
+{
+    Q_D(const QSGVisualDataModel);
+    return d->m_adaptorModel->indexOf(item);
+}
+
+void QSGVisualDataModel::setWatchedRoles(QList<QByteArray> roles)
+{
+    Q_D(QSGVisualDataModel);
+    d->m_adaptorModel->replaceWatchedRoles(d->watchedRoles, roles);
+    d->watchedRoles = roles;
+}
+
+bool QSGVisualDataModel::event(QEvent *e)
+{
+    Q_D(QSGVisualDataModel);
+    if (e->type() == QEvent::UpdateRequest)
+        d->m_adaptorModel->fetchMore();
+    return QSGVisualModel::event(e);
+}
+
+void QSGVisualDataModel::_q_itemsChanged(int index, int count)
+{
+    Q_D(QSGVisualDataModel);
+    if (!d->m_delegate)
+        return;
+    emit itemsChanged(index, count);
+}
+
+void QSGVisualDataModel::_q_itemsInserted(int index, int count)
+{
+    Q_D(QSGVisualDataModel);
+    if (!d->m_delegate)
+        return;
+
+    // XXX - highly inefficient
+    QHash<int,QSGVisualDataModelPrivate::ObjectRef> items;
+    for (QHash<int,QSGVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin();
+        iter != d->m_cache.end(); ) {
+
+        if (iter.key() >= index) {
+            QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
+            int index = iter.key() + count;
+            iter = d->m_cache.erase(iter);
+
+            items.insert(index, objRef);
+        } else {
+            ++iter;
+        }
+    }
+    d->m_cache.unite(items);
+
+    emit itemsInserted(index, count);
+    emit countChanged();
+}
+
+void QSGVisualDataModel::_q_itemsRemoved(int index, int count)
+{
+    Q_D(QSGVisualDataModel);
+    if (!d->m_delegate)
+        return;
+        // XXX - highly inefficient
+    QHash<int, QSGVisualDataModelPrivate::ObjectRef> items;
+    for (QHash<int, QSGVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin();
+        iter != d->m_cache.end(); ) {
+        if (iter.key() >= index && iter.key() < index + count) {
+            QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
+            iter = d->m_cache.erase(iter);
+            items.insertMulti(-1, objRef); //XXX perhaps better to maintain separately
+        } else if (iter.key() >= index + count) {
+            QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
+            int index = iter.key() - count;
+            iter = d->m_cache.erase(iter);
+            items.insert(index, objRef);
+        } else {
+            ++iter;
+        }
+    }
+    d->m_cache.unite(items);
+
+    emit itemsRemoved(index, count);
+    emit countChanged();
+}
+
+void QSGVisualDataModel::_q_itemsMoved(int from, int to, int count)
+{
+    Q_D(QSGVisualDataModel);
+    if (!d->m_delegate)
+        return;
+
+    // XXX - highly inefficient
+    QHash<int,QSGVisualDataModelPrivate::ObjectRef> items;
+    for (QHash<int,QSGVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin();
+        iter != d->m_cache.end(); ) {
+        if (iter.key() >= from && iter.key() < from + count) {
+            QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
+            int index = iter.key() - from + to;
+            items.insert(index, objRef);
+            iter = d->m_cache.erase(iter);
+        } else {
+            ++iter;
+        }
+    }
+    for (QHash<int,QSGVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin();
+        iter != d->m_cache.end(); ) {
+        int diff = from > to ? count : -count;
+        if (iter.key() >= qMin(from,to) && iter.key() < qMax(from+count,to+count)) {
+            QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
+            int index = iter.key() + diff;
+            iter = d->m_cache.erase(iter);
+            items.insert(index, objRef);
+        } else {
+            ++iter;
+        }
+    }
+    d->m_cache.unite(items);
+    emit itemsMoved(from, to, count);
+}
+
+void QSGVisualDataModel::_q_modelReset(int, int)
+{
+    Q_D(QSGVisualDataModel);
+    if (!d->m_delegate)
+        return;
+    emit modelReset();
+    emit countChanged();
+}
+
+//============================================================================
+
+QSGVisualPartsModel::QSGVisualPartsModel(QSGVisualDataModel *model, const QString &part, QObject *parent)
+    : QSGVisualModel(*new QObjectPrivate, parent)
+    , m_model(model)
+    , m_part(part)
+{
+    connect(m_model, SIGNAL(modelReset()), this, SIGNAL(modelReset()));
+    connect(m_model, SIGNAL(itemsInserted(int,int)), this, SIGNAL(itemsInserted(int,int)));
+    connect(m_model, SIGNAL(itemsRemoved(int,int)), this, SIGNAL(itemsRemoved(int,int)));
+    connect(m_model, SIGNAL(itemsChanged(int,int)), this, SIGNAL(itemsChanged(int,int)));
+    connect(m_model, SIGNAL(itemsMoved(int,int,int)), this, SIGNAL(itemsMoved(int,int,int)));
+    connect(m_model, SIGNAL(createdPackage(int,QDeclarativePackage*)),
+            this, SLOT(createdPackage(int,QDeclarativePackage*)));
+    connect(m_model, SIGNAL(destroyingPackage(QDeclarativePackage*)),
+            this, SLOT(destroyingPackage(QDeclarativePackage*)));
+}
+
+QSGVisualPartsModel::~QSGVisualPartsModel()
+{
+}
+
+int QSGVisualPartsModel::count() const
+{
+    return m_model->count();
+}
+
+bool QSGVisualPartsModel::isValid() const
+{
+    return m_model->isValid();
+}
+
+QSGItem *QSGVisualPartsModel::item(int index, bool complete)
+{
+    QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
+
+    QObject *object = model->object(index, complete);
+
+    if (QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(object)) {
+        QObject *part = package->part(m_part);
+        if (!part)
+            return 0;
+        if (QSGItem *item = qobject_cast<QSGItem *>(part)) {
+            m_packaged.insertMulti(item, package);
+            return item;
+        }
+    }
+
+    if (m_model->completePending())
+        m_model->completeItem();
+    model->release(object);
+    if (!model->m_delegateValidated) {
+        qmlInfo(model->m_delegate) << tr("Delegate component must be Package type.");
+        model->m_delegateValidated = true;
+    }
+
+    return 0;
+}
+
+QSGVisualModel::ReleaseFlags QSGVisualPartsModel::release(QSGItem *item)
+{
+    QSGVisualModel::ReleaseFlags flags = 0;
+
+    QHash<QObject *, QDeclarativePackage *>::iterator it = m_packaged.find(item);
+    if (it != m_packaged.end()) {
+        QDeclarativePackage *package = *it;
+        QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
+        flags = model->release(package);
+        m_packaged.erase(it);
+        if (!m_packaged.contains(item))
+            flags &= ~Referenced;
+        if (flags & Destroyed)
+            QSGVisualDataModelPrivate::get(m_model)->emitDestroyingPackage(package);
+    }
+    return flags;
+}
+
+bool QSGVisualPartsModel::completePending() const
+{
+    return m_model->completePending();
+}
+
+void QSGVisualPartsModel::completeItem()
+{
+    m_model->completeItem();
+}
+
+QString QSGVisualPartsModel::stringValue(int index, const QString &role)
+{
+    return QSGVisualDataModelPrivate::get(m_model)->stringValue(index, role);
+}
+
+void QSGVisualPartsModel::setWatchedRoles(QList<QByteArray> roles)
+{
+    QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
+    model->m_adaptorModel->replaceWatchedRoles(m_watchedRoles, roles);
+    m_watchedRoles = roles;
+}
+
+int QSGVisualPartsModel::indexOf(QSGItem *item, QObject *) const
+{
+    const QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
+    QHash<QObject *, QDeclarativePackage *>::const_iterator it = m_packaged.find(item);
+    return it != m_packaged.end()
+            ? model->m_adaptorModel->indexOf(*it)
+            : -1;
+}
+
+void QSGVisualPartsModel::createdPackage(int index, QDeclarativePackage *package)
+{
+    if (QSGItem *item = qobject_cast<QSGItem *>(package->part(m_part)))
+        emit createdItem(index, item);
+}
+
+void QSGVisualPartsModel::destroyingPackage(QDeclarativePackage *package)
+{
+    if (QSGItem *item = qobject_cast<QSGItem *>(package->part(m_part))) {
+        Q_ASSERT(!m_packaged.contains(item));
+        emit destroyingItem(item);
+    }
+}
+
+QT_END_NAMESPACE
+
+#include <qsgvisualdatamodel.moc>
diff --git a/src/declarative/items/qsgvisualdatamodel_p.h b/src/declarative/items/qsgvisualdatamodel_p.h
new file mode 100644 (file)
index 0000000..d3f1d18
--- /dev/null
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGVISUALDATAMODEL_P_H
+#define QSGVISUALDATAMODEL_P_H
+
+#include <private/qsgvisualitemmodel_p.h>
+#include <QtCore/qabstractitemmodel.h>
+
+QT_BEGIN_HEADER
+
+Q_DECLARE_METATYPE(QModelIndex)
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Declarative)
+
+class QDeclarativeComponent;
+class QDeclarativePackage;
+class QSGVisualDataModelPrivate;
+class Q_DECLARATIVE_EXPORT QSGVisualDataModel : public QSGVisualModel
+{
+    Q_OBJECT
+    Q_DECLARE_PRIVATE(QSGVisualDataModel)
+
+    Q_PROPERTY(QVariant model READ model WRITE setModel)
+    Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate)
+    Q_PROPERTY(QObject *parts READ parts CONSTANT)
+    Q_PROPERTY(QVariant rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged)
+    Q_CLASSINFO("DefaultProperty", "delegate")
+public:
+    QSGVisualDataModel();
+    QSGVisualDataModel(QDeclarativeContext *, QObject *parent=0);
+    virtual ~QSGVisualDataModel();
+
+    QVariant model() const;
+    void setModel(const QVariant &);
+
+    QDeclarativeComponent *delegate() const;
+    void setDelegate(QDeclarativeComponent *);
+
+    QVariant rootIndex() const;
+    void setRootIndex(const QVariant &root);
+
+    Q_INVOKABLE QVariant modelIndex(int idx) const;
+    Q_INVOKABLE QVariant parentModelIndex() const;
+
+    int count() const;
+    bool isValid() const { return delegate() != 0; }
+    QSGItem *item(int index, bool complete=true);
+    ReleaseFlags release(QSGItem *item);
+    bool completePending() const;
+    void completeItem();
+    virtual QString stringValue(int index, const QString &role);
+    virtual void setWatchedRoles(QList<QByteArray> roles);
+
+    int indexOf(QSGItem *item, QObject *objectContext) const;
+
+    QObject *parts();
+
+    bool event(QEvent *);
+
+Q_SIGNALS:
+    void createdPackage(int index, QDeclarativePackage *package);
+    void destroyingPackage(QDeclarativePackage *package);
+    void rootIndexChanged();
+
+private Q_SLOTS:
+    void _q_itemsChanged(int index, int count);
+    void _q_itemsInserted(int index, int count);
+    void _q_itemsRemoved(int index, int count);
+    void _q_itemsMoved(int from, int to, int count);
+    void _q_modelReset(int oldCount, int newCount);
+private:
+    Q_DISABLE_COPY(QSGVisualDataModel)
+};
+
+QT_END_NAMESPACE
+
+QML_DECLARE_TYPE(QSGVisualDataModel)
+
+QT_END_HEADER
+
+#endif // QSGVISUALDATAMODEL_P_H
index c6e5896..fbc8a1a 100644 (file)
 #include "qsgvisualitemmodel_p.h"
 #include "qsgitem.h"
 
+#include <QtCore/qcoreapplication.h>
 #include <QtDeclarative/qdeclarativecontext.h>
 #include <QtDeclarative/qdeclarativeengine.h>
-#include <QtDeclarative/qdeclarativeexpression.h>
-#include <QtDeclarative/qdeclarativeinfo.h>
 
-#include <private/qdeclarativecontext_p.h>
-#include <private/qdeclarativepackage_p.h>
-#include <private/qdeclarativeopenmetaobject_p.h>
-#include <private/qdeclarativelistaccessor_p.h>
-#include <private/qdeclarativedata_p.h>
-#include <private/qdeclarativepropertycache_p.h>
-#include <private/qdeclarativeguard_p.h>
 #include <private/qdeclarativeglobal_p.h>
-#include <private/qlistmodelinterface_p.h>
-#include <private/qmetaobjectbuilder_p.h>
-#include <private/qdeclarativeproperty_p.h>
 #include <private/qobject_p.h>
 
 #include <QtCore/qhash.h>
@@ -247,1315 +236,5 @@ QSGVisualItemModelAttached *QSGVisualItemModel::qmlAttachedProperties(QObject *o
     return QSGVisualItemModelAttached::properties(obj);
 }
 
-//============================================================================
-
-class VDMDelegateDataType : public QDeclarativeRefCount
-{
-public:
-    VDMDelegateDataType()
-        : metaObject(0)
-        , propertyCache(0)
-        , propertyOffset(0)
-        , signalOffset(0)
-        , shared(true)
-    {
-    }
-
-    VDMDelegateDataType(const VDMDelegateDataType &type)
-        : metaObject(0)
-        , propertyCache(0)
-        , propertyOffset(type.propertyOffset)
-        , signalOffset(type.signalOffset)
-        , shared(false)
-        , builder(type.metaObject, QMetaObjectBuilder::Properties
-                | QMetaObjectBuilder::Signals
-                | QMetaObjectBuilder::SuperClass
-                | QMetaObjectBuilder::ClassName)
-    {
-        builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
-    }
-
-    ~VDMDelegateDataType()
-    {
-        if (propertyCache)
-            propertyCache->release();
-        qFree(metaObject);
-    }
-
-    QMetaObject *metaObject;
-    QDeclarativePropertyCache *propertyCache;
-    int propertyOffset;
-    int signalOffset;
-    bool shared : 1;
-    QMetaObjectBuilder builder;
-};
-
-class QSGVisualDataModelParts;
-class QSGVisualDataModelData;
-class QSGVisualDataModelDataMetaObject;
-class QSGVisualDataModelPrivate : public QObjectPrivate
-{
-    Q_DECLARE_PUBLIC(QSGVisualDataModel)
-public:
-    QSGVisualDataModelPrivate(QDeclarativeContext *);
-
-    static QSGVisualDataModelPrivate *get(QSGVisualDataModel *m) {
-        return static_cast<QSGVisualDataModelPrivate *>(QObjectPrivate::get(m));
-    }
-
-    QDeclarativeGuard<QListModelInterface> m_listModelInterface;
-    QDeclarativeGuard<QAbstractItemModel> m_abstractItemModel;
-    QDeclarativeGuard<QSGVisualDataModel> m_visualItemModel;
-    QString m_part;
-
-    QDeclarativeComponent *m_delegate;
-    QDeclarativeGuard<QDeclarativeContext> m_context;
-    QList<int> m_roles;
-    QHash<QByteArray,int> m_roleNames;
-
-    void addProperty(int role, int propertyId, const char *propertyName, const char *propertyType, bool isModelData = false);
-    template <typename T> void setModelDataType()
-    {
-        createModelData = &T::create;
-        m_delegateDataType->builder.setFlags(QMetaObjectBuilder::DynamicMetaObject);
-        m_delegateDataType->builder.setClassName(T::staticMetaObject.className());
-        m_delegateDataType->builder.setSuperClass(&T::staticMetaObject);
-        m_delegateDataType->propertyOffset = T::staticMetaObject.propertyCount();
-        m_delegateDataType->signalOffset = T::staticMetaObject.methodCount();
-    }
-    QSGVisualDataModelData *createMetaObject(int index, QSGVisualDataModel *model);
-
-    static QSGVisualDataModelData *initializeModelData(int index, QSGVisualDataModel *model) {
-        return get(model)->createMetaObject(index, model);
-    }
-
-    typedef QSGVisualDataModelData *(*CreateModelData)(int index, QSGVisualDataModel *model);
-
-    struct PropertyData {
-        int role;
-        bool isModelData : 1;
-    };
-
-    struct ObjectRef {
-        ObjectRef(QObject *object=0) : obj(object), ref(1) {}
-        QObject *obj;
-        int ref;
-    };
-    class Cache : public QHash<int, ObjectRef> {
-    public:
-        QObject *getItem(int index) {
-            QObject *item = 0;
-            QHash<int,ObjectRef>::iterator it = find(index);
-            if (it != end()) {
-                (*it).ref++;
-                item = (*it).obj;
-            }
-            return item;
-        }
-        QObject *item(int index) {
-            QObject *item = 0;
-            QHash<int, ObjectRef>::const_iterator it = find(index);
-            if (it != end())
-                item = (*it).obj;
-            return item;
-        }
-        void insertItem(int index, QObject *obj) {
-            insert(index, ObjectRef(obj));
-        }
-        bool releaseItem(QObject *obj) {
-            QHash<int, ObjectRef>::iterator it = begin();
-            for (; it != end(); ++it) {
-                ObjectRef &objRef = *it;
-                if (objRef.obj == obj) {
-                    if (--objRef.ref == 0) {
-                        erase(it);
-                        return true;
-                    }
-                    break;
-                }
-            }
-            return false;
-        }
-    };
-
-    int modelCount() const {
-        if (m_visualItemModel)
-            return m_visualItemModel->count();
-        if (m_listModelInterface)
-            return m_listModelInterface->count();
-        if (m_abstractItemModel)
-            return m_abstractItemModel->rowCount(m_root);
-        if (m_listAccessor)
-            return m_listAccessor->count();
-        return 0;
-    }
-
-    Cache m_cache;
-    QHash<QObject *, QDeclarativePackage*> m_packaged;
-
-    QSGVisualDataModelParts *m_parts;
-    friend class QSGVisualItemParts;
-
-    VDMDelegateDataType *m_delegateDataType;
-    CreateModelData createModelData;
-
-    friend class QSGVisualDataModelData;
-    bool m_delegateValidated : 1;
-    bool m_completePending : 1;
-    bool m_objectList : 1;
-
-    QSGVisualDataModelData *data(QObject *item);
-
-    QVariant m_modelVariant;
-    QDeclarativeListAccessor *m_listAccessor;
-
-    QModelIndex m_root;
-    QList<QByteArray> watchedRoles;
-    QList<int> watchedRoleIds;
-
-    QVector<PropertyData> m_propertyData;
-};
-
-class QSGVisualDataModelData : public QObject
-{
-    Q_OBJECT
-    Q_PROPERTY(int index READ index NOTIFY indexChanged)
-public:
-    QSGVisualDataModelData(int index, QSGVisualDataModel *model);
-    ~QSGVisualDataModelData();
-
-    int index() const;
-    void setIndex(int index);
-
-Q_SIGNALS:
-    void indexChanged();
-
-public:
-    int m_index;
-    QDeclarativeGuard<QSGVisualDataModel> m_model;
-};
-
-class QSGVisualDataModelDataMetaObject : public QAbstractDynamicMetaObject
-{
-public:
-    QSGVisualDataModelDataMetaObject(QSGVisualDataModelData *data, VDMDelegateDataType *type)
-        : m_data(data)
-        , m_type(type)
-    {
-        QObjectPrivate *op = QObjectPrivate::get(m_data);
-        *static_cast<QMetaObject *>(this) = *type->metaObject;
-        op->metaObject = this;
-        m_type->addref();
-    }
-
-    ~QSGVisualDataModelDataMetaObject() { m_type->release(); }
-
-    QSGVisualDataModelData *m_data;
-    VDMDelegateDataType *m_type;
-};
-
-class QSGVDMAbstractItemModelDataMetaObject : public QSGVisualDataModelDataMetaObject
-{
-public:
-    QSGVDMAbstractItemModelDataMetaObject(QSGVisualDataModelData *object, VDMDelegateDataType *type)
-        : QSGVisualDataModelDataMetaObject(object, type) {}
-
-    int metaCall(QMetaObject::Call call, int id, void **arguments)
-    {
-        if (call == QMetaObject::ReadProperty && id >= m_type->propertyOffset) {
-            QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_data->m_model);
-            if (m_data->m_index == -1 || !model->m_abstractItemModel)
-                return -1;
-            *static_cast<QVariant *>(arguments[0]) = model->m_abstractItemModel->index(
-                    m_data->m_index, 0, model->m_root).data(model->m_propertyData.at(id - m_type->propertyOffset).role);
-            return -1;
-        } else {
-            return m_data->qt_metacall(call, id, arguments);
-        }
-    }
-};
-
-class QSGVDMAbstractItemModelData : public QSGVisualDataModelData
-{
-    Q_OBJECT
-    Q_PROPERTY(bool hasModelChildren READ hasModelChildren CONSTANT)
-public:
-    bool hasModelChildren() const
-    {
-        QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_model);
-        return model->m_abstractItemModel->hasChildren(model->m_abstractItemModel->index(m_index, 0, model->m_root));
-    }
-
-    static QSGVisualDataModelData *create(int index, QSGVisualDataModel *model) {
-        return new QSGVDMAbstractItemModelData(index, model); }
-private:
-    QSGVDMAbstractItemModelData(int index, QSGVisualDataModel *model)
-        : QSGVisualDataModelData(index, model)
-    {
-        new QSGVDMAbstractItemModelDataMetaObject(
-                this, QSGVisualDataModelPrivate::get(m_model)->m_delegateDataType);
-    }
-};
-
-class QSGVDMListModelInterfaceDataMetaObject : public QSGVisualDataModelDataMetaObject
-{
-public:
-    QSGVDMListModelInterfaceDataMetaObject(QSGVisualDataModelData *object, VDMDelegateDataType *type)
-        : QSGVisualDataModelDataMetaObject(object, type) {}
-
-    int metaCall(QMetaObject::Call call, int id, void **arguments)
-    {
-        if (call == QMetaObject::ReadProperty && id >= m_type->propertyOffset) {
-            QSGVisualDataModelPrivate *model = QSGVisualDataModelPrivate::get(m_data->m_model);
-            if (m_data->m_index == -1 || !model->m_listModelInterface)
-                return -1;
-            *static_cast<QVariant *>(arguments[0]) = model->m_listModelInterface->data(
-                    m_data->m_index, model->m_propertyData.at(id - m_type->propertyOffset).role);
-            return -1;
-        } else {
-            return m_data->qt_metacall(call, id, arguments);
-        }
-    }
-};
-
-class QSGVDMListModelInterfaceData : public QSGVisualDataModelData
-{
-public:
-    static QSGVisualDataModelData *create(int index, QSGVisualDataModel *model) {
-        return new QSGVDMListModelInterfaceData(index, model); }
-private:
-    QSGVDMListModelInterfaceData(int index, QSGVisualDataModel *model)
-        : QSGVisualDataModelData(index, model)
-    {
-        new QSGVDMListModelInterfaceDataMetaObject(
-                this, QSGVisualDataModelPrivate::get(m_model)->m_delegateDataType);
-    }
-};
-
-class QSGVDMListAccessorData : public QSGVisualDataModelData
-{
-    Q_OBJECT
-    Q_PROPERTY(QVariant modelData READ modelData CONSTANT)
-public:
-    QVariant modelData() const {
-        return QSGVisualDataModelPrivate::get(m_model)->m_listAccessor->at(m_index); }
-
-    static QSGVisualDataModelData *create(int index, QSGVisualDataModel *model) {
-        return new QSGVDMListAccessorData(index, model); }
-private:
-    QSGVDMListAccessorData(int index, QSGVisualDataModel *model)
-        : QSGVisualDataModelData(index, model)
-    {
-    }
-};
-
-class QSGVDMObjectDataMetaObject : public QSGVisualDataModelDataMetaObject
-{
-public:
-    QSGVDMObjectDataMetaObject(QSGVisualDataModelData *data, VDMDelegateDataType *type)
-        : QSGVisualDataModelDataMetaObject(data, type)
-        , m_object(QSGVisualDataModelPrivate::get(data->m_model)->m_listAccessor->at(data->m_index).value<QObject *>())
-    {}
-
-    int metaCall(QMetaObject::Call call, int id, void **arguments)
-    {
-        if (id >= m_type->propertyOffset
-                && (call == QMetaObject::ReadProperty
-                || call == QMetaObject::WriteProperty
-                || call == QMetaObject::ResetProperty)) {
-            if (m_object)
-                QMetaObject::metacall(m_object, call, id - m_type->propertyOffset + 1, arguments);
-            return -1;
-        } else if (id >= m_type->signalOffset && call == QMetaObject::InvokeMetaMethod) {
-            QMetaObject::activate(m_data, this, id, 0);
-            return -1;
-        } else {
-            return m_data->qt_metacall(call, id, arguments);
-        }
-    }
-
-    int createProperty(const char *name, const char *)
-    {
-        if (!m_object)
-            return -1;
-        const QMetaObject *metaObject = m_object->metaObject();
-
-        const int previousPropertyCount = propertyCount() - propertyOffset();
-        int propertyIndex = metaObject->indexOfProperty(name);
-        if (propertyIndex == -1)
-            return -1;
-        if (previousPropertyCount + 1 == metaObject->propertyCount())
-            return propertyIndex + m_type->propertyOffset - 1;
-
-        if (m_type->shared) {
-            VDMDelegateDataType *type = m_type;
-            m_type = new VDMDelegateDataType(*m_type);
-            type->release();
-        }
-
-        const int previousMethodCount = methodCount();
-        int notifierId = previousMethodCount;
-        for (int propertyId = previousPropertyCount; propertyId < metaObject->propertyCount() - 1; ++propertyId) {
-            QMetaProperty property = metaObject->property(propertyId + 1);
-            QMetaPropertyBuilder propertyBuilder;
-            if (property.hasNotifySignal()) {
-                m_type->builder.addSignal("__" + QByteArray::number(propertyId) + "()");
-                propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName(), notifierId);
-                ++notifierId;
-            } else {
-                propertyBuilder = m_type->builder.addProperty(property.name(), property.typeName());
-            }
-            propertyBuilder.setWritable(property.isWritable());
-            propertyBuilder.setResettable(property.isResettable());
-            propertyBuilder.setConstant(property.isConstant());
-        }
-
-        if (m_type->metaObject)
-            qFree(m_type->metaObject);
-        m_type->metaObject = m_type->builder.toMetaObject();
-        *static_cast<QMetaObject *>(this) = *m_type->metaObject;
-
-        notifierId = previousMethodCount;
-        for (int i = previousPropertyCount; i < metaObject->propertyCount(); ++i) {
-            QMetaProperty property = metaObject->property(i);
-            if (property.hasNotifySignal()) {
-                QDeclarativePropertyPrivate::connect(
-                        m_object, property.notifySignalIndex(), m_data, notifierId);
-                ++notifierId;
-            }
-        }
-        return propertyIndex + m_type->propertyOffset - 1;
-    }
-
-    QDeclarativeGuard<QObject> m_object;
-};
-
-class QSGVDMObjectData : public QSGVisualDataModelData
-{
-    Q_OBJECT
-    Q_PROPERTY(QObject *modelData READ modelData CONSTANT)
-public:
-    QObject *modelData() const { return m_metaObject->m_object; }
-
-    static QSGVisualDataModelData *create(int index, QSGVisualDataModel *model) {
-        return new QSGVDMObjectData(index, model); }
-
-private:
-    QSGVDMObjectData(int index, QSGVisualDataModel *model)
-        : QSGVisualDataModelData(index, model)
-        , m_metaObject(new QSGVDMObjectDataMetaObject(this, QSGVisualDataModelPrivate::get(m_model)->m_delegateDataType))
-    {
-    }
-
-    QSGVDMObjectDataMetaObject *m_metaObject;
-};
-
-void QSGVisualDataModelPrivate::addProperty(
-        int role, int propertyId, const char *propertyName, const char *propertyType, bool isModelData)
-{
-    PropertyData propertyData;
-    propertyData.role = role;
-    propertyData.isModelData = isModelData;
-    m_delegateDataType->builder.addSignal("__" + QByteArray::number(propertyId) + "()");
-    QMetaPropertyBuilder property = m_delegateDataType->builder.addProperty(
-            propertyName, propertyType, propertyId);
-    property.setWritable(false);
-
-    m_propertyData.append(propertyData);
-}
-
-QSGVisualDataModelData *QSGVisualDataModelPrivate::createMetaObject(int index, QSGVisualDataModel *model)
-{
-    Q_ASSERT(!m_delegateDataType);
-
-    m_objectList = false;
-    m_propertyData.clear();
-    if (m_listAccessor
-            && m_listAccessor->type() != QDeclarativeListAccessor::ListProperty
-            && m_listAccessor->type() != QDeclarativeListAccessor::Instance) {
-        createModelData = &QSGVDMListAccessorData::create;
-        return QSGVDMListAccessorData::create(index, model);
-    }
-
-    m_delegateDataType = new VDMDelegateDataType;
-    if (m_listModelInterface) {
-        setModelDataType<QSGVDMListModelInterfaceData>();
-        QList<int> roles = m_listModelInterface->roles();
-        for (int propertyId = 0; propertyId < roles.count(); ++propertyId) {
-            const int role = roles.at(propertyId);
-            const QByteArray propertyName = m_listModelInterface->toString(role).toUtf8();
-            addProperty(role, propertyId, propertyName, "QVariant");
-            m_roleNames.insert(propertyName, role);
-        }
-        if (m_propertyData.count() == 1)
-            addProperty(roles.first(), 1, "modelData", "QVariant", true);
-    } else if (m_abstractItemModel) {
-        setModelDataType<QSGVDMAbstractItemModelData>();
-        QHash<int, QByteArray> roleNames = m_abstractItemModel->roleNames();
-        for (QHash<int, QByteArray>::const_iterator it = roleNames.begin(); it != roleNames.end(); ++it) {
-            addProperty(it.key(), m_propertyData.count(), it.value(), "QVariant");
-            m_roleNames.insert(it.value(), it.key());
-        }
-        if (m_propertyData.count() == 1)
-            addProperty(roleNames.begin().key(), 1, "modelData", "QVariant", true);
-    } else if (m_listAccessor) {
-        setModelDataType<QSGVDMObjectData>();
-        m_objectList = true;
-    } else {
-        Q_ASSERT(!"No model set on VisualDataModel");
-        return 0;
-    }
-    m_delegateDataType->metaObject = m_delegateDataType->builder.toMetaObject();
-    if (!m_objectList) {
-        m_delegateDataType->propertyCache = new QDeclarativePropertyCache(
-                m_context ? m_context->engine() : qmlEngine(q_func()), m_delegateDataType->metaObject);
-    }
-    return createModelData(index, model);
-}
-
-QSGVisualDataModelData::QSGVisualDataModelData(int index, QSGVisualDataModel *model)
-    : m_index(index)
-    , m_model(model)
-{
-}
-
-QSGVisualDataModelData::~QSGVisualDataModelData()
-{
-}
-
-int QSGVisualDataModelData::index() const
-{
-    return m_index;
-}
-
-// This is internal only - it should not be set from qml
-void QSGVisualDataModelData::setIndex(int index)
-{
-    m_index = index;
-    emit indexChanged();
-}
-
-//---------------------------------------------------------------------------
-
-class QSGVisualDataModelPartsMetaObject : public QDeclarativeOpenMetaObject
-{
-public:
-    QSGVisualDataModelPartsMetaObject(QObject *parent)
-    : QDeclarativeOpenMetaObject(parent) {}
-
-    virtual void propertyCreated(int, QMetaPropertyBuilder &);
-    virtual QVariant initialValue(int);
-};
-
-class QSGVisualDataModelParts : public QObject
-{
-Q_OBJECT
-public:
-    QSGVisualDataModelParts(QSGVisualDataModel *parent);
-
-private:
-    friend class QSGVisualDataModelPartsMetaObject;
-    QSGVisualDataModel *model;
-};
-
-void QSGVisualDataModelPartsMetaObject::propertyCreated(int, QMetaPropertyBuilder &prop)
-{
-    prop.setWritable(false);
-}
-
-QVariant QSGVisualDataModelPartsMetaObject::initialValue(int id)
-{
-    QSGVisualDataModel *m = new QSGVisualDataModel;
-    m->setParent(object());
-    m->setPart(QString::fromUtf8(name(id)));
-    m->setModel(QVariant::fromValue(static_cast<QSGVisualDataModelParts *>(object())->model));
-
-    QVariant var = QVariant::fromValue((QObject *)m);
-    return var;
-}
-
-QSGVisualDataModelParts::QSGVisualDataModelParts(QSGVisualDataModel *parent)
-: QObject(parent), model(parent)
-{
-    new QSGVisualDataModelPartsMetaObject(this);
-}
-
-QSGVisualDataModelPrivate::QSGVisualDataModelPrivate(QDeclarativeContext *ctxt)
-: m_listModelInterface(0), m_abstractItemModel(0), m_visualItemModel(0), m_delegate(0)
-, m_context(ctxt), m_parts(0), m_delegateDataType(0), createModelData(&initializeModelData)
-, m_delegateValidated(false), m_completePending(false), m_objectList(false), m_listAccessor(0)
-{
-}
-
-QSGVisualDataModelData *QSGVisualDataModelPrivate::data(QObject *item)
-{
-    QSGVisualDataModelData *dataItem =
-        item->findChild<QSGVisualDataModelData *>();
-    Q_ASSERT(dataItem);
-    return dataItem;
-}
-
-//---------------------------------------------------------------------------
-
-/*!
-    \qmlclass VisualDataModel QSGVisualDataModel
-    \inqmlmodule QtQuick 2
-    \ingroup qml-working-with-data
-    \brief The VisualDataModel encapsulates a model and delegate
-
-    A VisualDataModel encapsulates a model and the delegate that will
-    be instantiated for items in the model.
-
-    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.
-
-    \snippet doc/src/snippets/declarative/visualdatamodel.qml 0
-*/
-
-QSGVisualDataModel::QSGVisualDataModel()
-: QSGVisualModel(*(new QSGVisualDataModelPrivate(0)))
-{
-}
-
-QSGVisualDataModel::QSGVisualDataModel(QDeclarativeContext *ctxt, QObject *parent)
-: QSGVisualModel(*(new QSGVisualDataModelPrivate(ctxt)), parent)
-{
-}
-
-QSGVisualDataModel::~QSGVisualDataModel()
-{
-    Q_D(QSGVisualDataModel);
-    if (d->m_listAccessor)
-        delete d->m_listAccessor;
-    if (d->m_delegateDataType)
-        d->m_delegateDataType->release();
-}
-
-/*!
-    \qmlproperty model QtQuick2::VisualDataModel::model
-    This property holds the model providing data for the VisualDataModel.
-
-    The model provides a set of data that is used to create the items
-    for a view.  For large or dynamic datasets the model is usually
-    provided by a C++ model object.  The C++ model object must be a \l
-    {QAbstractItemModel} subclass or a simple list.
-
-    Models can also be created directly in QML, using a \l{ListModel} or
-    \l{XmlListModel}.
-
-    \sa {qmlmodels}{Data Models}
-*/
-QVariant QSGVisualDataModel::model() const
-{
-    Q_D(const QSGVisualDataModel);
-    return d->m_modelVariant;
-}
-
-void QSGVisualDataModel::setModel(const QVariant &model)
-{
-    Q_D(QSGVisualDataModel);
-    delete d->m_listAccessor;
-    d->m_listAccessor = 0;
-    d->m_modelVariant = model;
-    if (d->m_listModelInterface) {
-        // Assume caller has released all items.
-        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsChanged(int,int,QList<int>)),
-                this, SLOT(_q_itemsChanged(int,int,QList<int>)));
-        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsInserted(int,int)),
-                this, SLOT(_q_itemsInserted(int,int)));
-        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsRemoved(int,int)),
-                this, SLOT(_q_itemsRemoved(int,int)));
-        QObject::disconnect(d->m_listModelInterface, SIGNAL(itemsMoved(int,int,int)),
-                this, SLOT(_q_itemsMoved(int,int,int)));
-        d->m_listModelInterface = 0;
-    } else if (d->m_abstractItemModel) {
-        QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
-                            this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
-        QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
-                            this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
-        QObject::disconnect(d->m_abstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
-                            this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
-        QObject::disconnect(d->m_abstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
-                            this, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
-        QObject::disconnect(d->m_abstractItemModel, SIGNAL(modelReset()), this, SLOT(_q_modelReset()));
-        QObject::disconnect(d->m_abstractItemModel, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
-        d->m_abstractItemModel = 0;
-    } else if (d->m_visualItemModel) {
-        QObject::disconnect(d->m_visualItemModel, SIGNAL(itemsInserted(int,int)),
-                         this, SIGNAL(itemsInserted(int,int)));
-        QObject::disconnect(d->m_visualItemModel, SIGNAL(itemsRemoved(int,int)),
-                         this, SIGNAL(itemsRemoved(int,int)));
-        QObject::disconnect(d->m_visualItemModel, SIGNAL(itemsMoved(int,int,int)),
-                         this, SIGNAL(itemsMoved(int,int,int)));
-        QObject::disconnect(d->m_visualItemModel, SIGNAL(createdPackage(int,QDeclarativePackage*)),
-                         this, SLOT(_q_createdPackage(int,QDeclarativePackage*)));
-        QObject::disconnect(d->m_visualItemModel, SIGNAL(destroyingPackage(QDeclarativePackage*)),
-                         this, SLOT(_q_destroyingPackage(QDeclarativePackage*)));
-        d->m_visualItemModel = 0;
-    }
-
-    d->m_roles.clear();
-    d->m_roleNames.clear();
-    if (d->m_delegateDataType)
-        d->m_delegateDataType->release();
-    d->m_delegateDataType = 0;
-    d->createModelData = &QSGVisualDataModelPrivate::initializeModelData;
-
-    QObject *object = qvariant_cast<QObject *>(model);
-    if (object && (d->m_listModelInterface = qobject_cast<QListModelInterface *>(object))) {
-        QObject::connect(d->m_listModelInterface, SIGNAL(itemsChanged(int,int,QList<int>)),
-                         this, SLOT(_q_itemsChanged(int,int,QList<int>)));
-        QObject::connect(d->m_listModelInterface, SIGNAL(itemsInserted(int,int)),
-                         this, SLOT(_q_itemsInserted(int,int)));
-        QObject::connect(d->m_listModelInterface, SIGNAL(itemsRemoved(int,int)),
-                         this, SLOT(_q_itemsRemoved(int,int)));
-        QObject::connect(d->m_listModelInterface, SIGNAL(itemsMoved(int,int,int)),
-                         this, SLOT(_q_itemsMoved(int,int,int)));
-        if (d->m_delegate && d->m_listModelInterface->count())
-            emit itemsInserted(0, d->m_listModelInterface->count());
-        return;
-    } else if (object && (d->m_abstractItemModel = qobject_cast<QAbstractItemModel *>(object))) {
-        QObject::connect(d->m_abstractItemModel, SIGNAL(rowsInserted(QModelIndex,int,int)),
-                            this, SLOT(_q_rowsInserted(QModelIndex,int,int)));
-        QObject::connect(d->m_abstractItemModel, SIGNAL(rowsRemoved(QModelIndex,int,int)),
-                            this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
-        QObject::connect(d->m_abstractItemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
-                            this, SLOT(_q_dataChanged(QModelIndex,QModelIndex)));
-        QObject::connect(d->m_abstractItemModel, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int)),
-                            this, SLOT(_q_rowsMoved(QModelIndex,int,int,QModelIndex,int)));
-        QObject::connect(d->m_abstractItemModel, SIGNAL(modelReset()), this, SLOT(_q_modelReset()));
-        QObject::connect(d->m_abstractItemModel, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
-        if (d->m_abstractItemModel->canFetchMore(d->m_root))
-            d->m_abstractItemModel->fetchMore(d->m_root);
-        return;
-    }
-    if ((d->m_visualItemModel = qvariant_cast<QSGVisualDataModel *>(model))) {
-        QObject::connect(d->m_visualItemModel, SIGNAL(countChanged()),
-                         this, SIGNAL(countChanged()));
-        QObject::connect(d->m_visualItemModel, SIGNAL(itemsInserted(int,int)),
-                         this, SIGNAL(itemsInserted(int,int)));
-        QObject::connect(d->m_visualItemModel, SIGNAL(itemsRemoved(int,int)),
-                         this, SIGNAL(itemsRemoved(int,int)));
-        QObject::connect(d->m_visualItemModel, SIGNAL(itemsMoved(int,int,int)),
-                         this, SIGNAL(itemsMoved(int,int,int)));
-        QObject::connect(d->m_visualItemModel, SIGNAL(createdPackage(int,QDeclarativePackage*)),
-                         this, SLOT(_q_createdPackage(int,QDeclarativePackage*)));
-        QObject::connect(d->m_visualItemModel, SIGNAL(destroyingPackage(QDeclarativePackage*)),
-                         this, SLOT(_q_destroyingPackage(QDeclarativePackage*)));
-        return;
-    }
-    d->m_listAccessor = new QDeclarativeListAccessor;
-    d->m_listAccessor->setList(model, d->m_context?d->m_context->engine():qmlEngine(this));
-    if (d->m_listAccessor->type() != QDeclarativeListAccessor::ListProperty)
-    if (d->m_delegate && d->modelCount()) {
-        emit itemsInserted(0, d->modelCount());
-        emit countChanged();
-    }
-}
-
-/*!
-    \qmlproperty Component QtQuick2::VisualDataModel::delegate
-
-    The delegate provides a template defining each item instantiated by a view.
-    The index is exposed as an accessible \c index property.  Properties of the
-    model are also available depending upon the type of \l {qmlmodels}{Data Model}.
-*/
-QDeclarativeComponent *QSGVisualDataModel::delegate() const
-{
-    Q_D(const QSGVisualDataModel);
-    if (d->m_visualItemModel)
-        return d->m_visualItemModel->delegate();
-    return d->m_delegate;
-}
-
-void QSGVisualDataModel::setDelegate(QDeclarativeComponent *delegate)
-{
-    Q_D(QSGVisualDataModel);
-    bool wasValid = d->m_delegate != 0;
-    d->m_delegate = delegate;
-    d->m_delegateValidated = false;
-    if (!wasValid && d->modelCount() && d->m_delegate) {
-        emit itemsInserted(0, d->modelCount());
-        emit countChanged();
-    }
-    if (wasValid && !d->m_delegate && d->modelCount()) {
-        _q_itemsRemoved(0, d->modelCount());
-        emit countChanged();
-    }
-}
-
-/*!
-    \qmlproperty QModelIndex QtQuick2::VisualDataModel::rootIndex
-
-    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 that
-    are hierarchical (e.g, a tree model).
-
-    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.
-
-    \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
-
-    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()
-*/
-QVariant QSGVisualDataModel::rootIndex() const
-{
-    Q_D(const QSGVisualDataModel);
-    return QVariant::fromValue(d->m_root);
-}
-
-void QSGVisualDataModel::setRootIndex(const QVariant &root)
-{
-    Q_D(QSGVisualDataModel);
-    QModelIndex modelIndex = qvariant_cast<QModelIndex>(root);
-    if (d->m_root != modelIndex) {
-        int oldCount = d->modelCount();
-        d->m_root = modelIndex;
-        if (d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(modelIndex))
-            d->m_abstractItemModel->fetchMore(modelIndex);
-        int newCount = d->modelCount();
-        if (d->m_delegate && oldCount)
-            _q_itemsRemoved(0, oldCount);
-        if (d->m_delegate && newCount)
-            emit itemsInserted(0, newCount);
-        if (newCount != oldCount)
-            emit countChanged();
-        emit rootIndexChanged();
-    }
-}
-
-/*!
-    \qmlmethod QModelIndex QtQuick2::VisualDataModel::modelIndex(int index)
-
-    QAbstractItemModel provides a hierarchical tree of data, whereas
-    QML only operates on list data.  This function assists in using
-    tree models in QML.
-
-    Returns a QModelIndex for the specified index.
-    This value can be assigned to rootIndex.
-
-    \sa rootIndex
-*/
-QVariant QSGVisualDataModel::modelIndex(int idx) const
-{
-    Q_D(const QSGVisualDataModel);
-    if (d->m_abstractItemModel)
-        return QVariant::fromValue(d->m_abstractItemModel->index(idx, 0, d->m_root));
-    return QVariant::fromValue(QModelIndex());
-}
-
-/*!
-    \qmlmethod QModelIndex QtQuick2::VisualDataModel::parentModelIndex()
-
-    QAbstractItemModel provides a hierarchical tree of data, whereas
-    QML only operates on list data.  This function assists in using
-    tree models in QML.
-
-    Returns a QModelIndex for the parent of the current rootIndex.
-    This value can be assigned to rootIndex.
-
-    \sa rootIndex
-*/
-QVariant QSGVisualDataModel::parentModelIndex() const
-{
-    Q_D(const QSGVisualDataModel);
-    if (d->m_abstractItemModel)
-        return QVariant::fromValue(d->m_abstractItemModel->parent(d->m_root));
-    return QVariant::fromValue(QModelIndex());
-}
-
-/*!
-    \qmlproperty object QtQuick2::VisualDataModel::parts
-
-    The \a parts property selects a VisualDataModel which creates
-    delegates from the part named.  This is used in conjunction with
-    the \l Package element.
-
-    For example, the code below selects a model which creates
-    delegates named \e list from a \l Package:
-
-    \code
-    VisualDataModel {
-        id: visualModel
-        delegate: Package {
-            Item { Package.name: "list" }
-        }
-        model: myModel
-    }
-
-    ListView {
-        width: 200; height:200
-        model: visualModel.parts.list
-    }
-    \endcode
-
-    \sa Package
-*/
-QString QSGVisualDataModel::part() const
-{
-    Q_D(const QSGVisualDataModel);
-    return d->m_part;
-}
-
-void QSGVisualDataModel::setPart(const QString &part)
-{
-    Q_D(QSGVisualDataModel);
-    d->m_part = part;
-}
-
-int QSGVisualDataModel::count() const
-{
-    Q_D(const QSGVisualDataModel);
-    if (d->m_visualItemModel)
-        return d->m_visualItemModel->count();
-    if (!d->m_delegate)
-        return 0;
-    return d->modelCount();
-}
-
-QSGItem *QSGVisualDataModel::item(int index, bool complete)
-{
-    Q_D(QSGVisualDataModel);
-    if (d->m_visualItemModel)
-        return d->m_visualItemModel->item(index, d->m_part.toUtf8(), complete);
-    return item(index, QByteArray(), complete);
-}
-
-/*
-  Returns ReleaseStatus flags.
-*/
-QSGVisualDataModel::ReleaseFlags QSGVisualDataModel::release(QSGItem *item)
-{
-    Q_D(QSGVisualDataModel);
-    if (d->m_visualItemModel)
-        return d->m_visualItemModel->release(item);
-
-    ReleaseFlags stat = 0;
-    QObject *obj = item;
-    bool inPackage = false;
-
-    QHash<QObject*,QDeclarativePackage*>::iterator it = d->m_packaged.find(item);
-    if (it != d->m_packaged.end()) {
-        QDeclarativePackage *package = *it;
-        d->m_packaged.erase(it);
-        if (d->m_packaged.contains(item))
-            stat |= Referenced;
-        inPackage = true;
-        obj = package; // fall through and delete
-    }
-
-    if (d->m_cache.releaseItem(obj)) {
-        // Remove any bindings to avoid warnings due to parent change.
-        QObjectPrivate *p = QObjectPrivate::get(obj);
-        Q_ASSERT(p->declarativeData);
-        QDeclarativeData *d = static_cast<QDeclarativeData*>(p->declarativeData);
-        if (d->ownContext && d->context)
-            d->context->clearContext();
-
-        if (inPackage) {
-            emit destroyingPackage(qobject_cast<QDeclarativePackage*>(obj));
-        } else {
-            // XXX todo - the original did item->scene()->removeItem().  Why?
-            item->setParentItem(0);
-        }
-        stat |= Destroyed;
-        obj->deleteLater();
-    } else if (!inPackage) {
-        stat |= Referenced;
-    }
-
-    return stat;
-}
-
-QObject *QSGVisualDataModel::parts()
-{
-    Q_D(QSGVisualDataModel);
-    if (!d->m_parts)
-        d->m_parts = new QSGVisualDataModelParts(this);
-    return d->m_parts;
-}
-
-QSGItem *QSGVisualDataModel::item(int index, const QByteArray &viewId, bool complete)
-{
-    Q_D(QSGVisualDataModel);
-    if (d->m_visualItemModel)
-        return d->m_visualItemModel->item(index, viewId, complete);
-
-    if (d->modelCount() <= 0 || !d->m_delegate)
-        return 0;
-    QObject *nobj = d->m_cache.getItem(index);
-    bool needComplete = false;
-    if (!nobj) {
-        QDeclarativeContext *ccontext = d->m_context;
-        if (!ccontext) ccontext = qmlContext(this);
-        QDeclarativeContext *ctxt = new QDeclarativeContext(ccontext);
-        if (d->m_objectList) {
-            ctxt->setContextObject(d->m_listAccessor->at(index).value<QObject *>());
-            ctxt = new QDeclarativeContext(ctxt);
-        }
-        QSGVisualDataModelData *data = d->createModelData(index, this);
-        ctxt->setContextProperty(QLatin1String("model"), data);
-        ctxt->setContextObject(data);
-        d->m_completePending = false;
-        nobj = d->m_delegate->beginCreate(ctxt);
-        if (complete) {
-            d->m_delegate->completeCreate();
-        } else {
-            d->m_completePending = true;
-            needComplete = true;
-        }
-        if (nobj) {
-            QDeclarative_setParent_noEvent(ctxt, nobj);
-            QDeclarative_setParent_noEvent(data, nobj);
-            d->m_cache.insertItem(index, nobj);
-            if (QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(nobj))
-                emit createdPackage(index, package);
-        } else {
-            delete data;
-            delete ctxt;
-            qmlInfo(this, d->m_delegate->errors()) << "Error creating delegate";
-        }
-    }
-    QSGItem *item = qobject_cast<QSGItem *>(nobj);
-    if (!item) {
-        QDeclarativePackage *package = qobject_cast<QDeclarativePackage *>(nobj);
-        if (package) {
-            QObject *o = package->part(QString::fromUtf8(viewId));
-            item = qobject_cast<QSGItem *>(o);
-            if (item)
-                d->m_packaged.insertMulti(item, package);
-        }
-    }
-    if (!item) {
-        if (needComplete)
-            d->m_delegate->completeCreate();
-        d->m_cache.releaseItem(nobj);
-        if (!d->m_delegateValidated) {
-            qmlInfo(d->m_delegate) << QSGVisualDataModel::tr("Delegate component must be Item type.");
-            d->m_delegateValidated = true;
-        }
-    }
-    if (d->modelCount()-1 == index && d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(d->m_root))
-        d->m_abstractItemModel->fetchMore(d->m_root);
-
-    return item;
-}
-
-bool QSGVisualDataModel::completePending() const
-{
-    Q_D(const QSGVisualDataModel);
-    if (d->m_visualItemModel)
-        return d->m_visualItemModel->completePending();
-    return d->m_completePending;
-}
-
-void QSGVisualDataModel::completeItem()
-{
-    Q_D(QSGVisualDataModel);
-    if (d->m_visualItemModel) {
-        d->m_visualItemModel->completeItem();
-        return;
-    }
-
-    d->m_delegate->completeCreate();
-    d->m_completePending = false;
-}
-
-QString QSGVisualDataModel::stringValue(int index, const QString &name)
-{
-    Q_D(QSGVisualDataModel);
-    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();
-
-    QString val;
-    QObject *data = 0;
-    bool tempData = false;
-
-    if (QObject *nobj = d->m_cache.item(index))
-        data = d->data(nobj);
-    if (!data) {
-        data = d->createModelData(index, this);
-        tempData = true;
-    }
-
-    QDeclarativeData *ddata = QDeclarativeData::get(data);
-    if (ddata && ddata->propertyCache) {
-        QDeclarativePropertyCache::Data *prop = ddata->propertyCache->property(name);
-        if (prop) {
-            if (prop->propType == QVariant::String) {
-                void *args[] = { &val, 0 };
-                QMetaObject::metacall(data, QMetaObject::ReadProperty, prop->coreIndex, args);
-            } else if (prop->propType == qMetaTypeId<QVariant>()) {
-                QVariant v;
-                void *args[] = { &v, 0 };
-                QMetaObject::metacall(data, QMetaObject::ReadProperty, prop->coreIndex, args);
-                val = v.toString();
-            }
-        } else {
-            val = data->property(name.toUtf8()).toString();
-        }
-    } else {
-        val = data->property(name.toUtf8()).toString();
-    }
-
-    if (tempData)
-        delete data;
-
-    return val;
-}
-
-int QSGVisualDataModel::indexOf(QSGItem *item, QObject *) const
-{
-    QVariant val = QDeclarativeEngine::contextForObject(item)->contextProperty(QLatin1String("index"));
-        return val.toInt();
-    return -1;
-}
-
-void QSGVisualDataModel::setWatchedRoles(QList<QByteArray> roles)
-{
-    Q_D(QSGVisualDataModel);
-    d->watchedRoles = roles;
-    d->watchedRoleIds.clear();
-}
-
-void QSGVisualDataModel::_q_itemsChanged(int index, int count,
-                                         const QList<int> &roles)
-{
-    Q_D(QSGVisualDataModel);
-    bool changed = false;
-    if (!d->watchedRoles.isEmpty() && d->watchedRoleIds.isEmpty()) {
-        foreach (QByteArray r, d->watchedRoles) {
-            if (d->m_roleNames.contains(r))
-                d->watchedRoleIds << d->m_roleNames.value(r);
-        }
-    }
-
-    QVector<int> signalIndexes;
-    for (int i = 0; i < roles.count(); ++i) {
-        const int role = roles.at(i);
-        if (!changed && d->watchedRoleIds.contains(role))
-            changed = true;
-        for (int propertyId = 0; propertyId < d->m_propertyData.count(); ++propertyId) {
-            if (d->m_propertyData.at(propertyId).role == role)
-                signalIndexes.append(propertyId + d->m_delegateDataType->signalOffset);
-        }
-    }
-    if (roles.isEmpty()) {
-        for (int propertyId = 0; propertyId < d->m_propertyData.count(); ++propertyId)
-            signalIndexes.append(propertyId + d->m_delegateDataType->signalOffset);
-    }
-
-    for (QHash<int,QSGVisualDataModelPrivate::ObjectRef>::ConstIterator iter = d->m_cache.begin();
-        iter != d->m_cache.end(); ++iter) {
-        const int idx = iter.key();
-
-        if (idx >= index && idx < index+count) {
-            QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
-            QSGVisualDataModelData *data = d->data(objRef.obj);
-            for (int i = 0; i < signalIndexes.count(); ++i)
-                QMetaObject::activate(data, signalIndexes.at(i), 0);
-        }
-    }
-    if (changed)
-        emit itemsChanged(index, count);
-}
-
-void QSGVisualDataModel::_q_itemsInserted(int index, int count)
-{
-    Q_D(QSGVisualDataModel);
-    if (!count)
-        return;
-    // XXX - highly inefficient
-    QHash<int,QSGVisualDataModelPrivate::ObjectRef> items;
-    for (QHash<int,QSGVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin();
-        iter != d->m_cache.end(); ) {
-
-        if (iter.key() >= index) {
-            QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
-            int index = iter.key() + count;
-            iter = d->m_cache.erase(iter);
-
-            items.insert(index, objRef);
-
-            QSGVisualDataModelData *data = d->data(objRef.obj);
-            data->setIndex(index);
-        } else {
-            ++iter;
-        }
-    }
-    d->m_cache.unite(items);
-
-    emit itemsInserted(index, count);
-    emit countChanged();
-}
-
-void QSGVisualDataModel::_q_itemsRemoved(int index, int count)
-{
-    Q_D(QSGVisualDataModel);
-    if (!count)
-        return;
-    // XXX - highly inefficient
-    QHash<int, QSGVisualDataModelPrivate::ObjectRef> items;
-    for (QHash<int, QSGVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin();
-        iter != d->m_cache.end(); ) {
-        if (iter.key() >= index && iter.key() < index + count) {
-            QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
-            iter = d->m_cache.erase(iter);
-            items.insertMulti(-1, objRef); //XXX perhaps better to maintain separately
-            QSGVisualDataModelData *data = d->data(objRef.obj);
-            data->setIndex(-1);
-        } else if (iter.key() >= index + count) {
-            QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
-            int index = iter.key() - count;
-            iter = d->m_cache.erase(iter);
-            items.insert(index, objRef);
-            QSGVisualDataModelData *data = d->data(objRef.obj);
-            data->setIndex(index);
-        } else {
-            ++iter;
-        }
-    }
-
-    d->m_cache.unite(items);
-    emit itemsRemoved(index, count);
-    emit countChanged();
-}
-
-void QSGVisualDataModel::_q_itemsMoved(int from, int to, int count)
-{
-    Q_D(QSGVisualDataModel);
-    // XXX - highly inefficient
-    QHash<int,QSGVisualDataModelPrivate::ObjectRef> items;
-    for (QHash<int,QSGVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin();
-        iter != d->m_cache.end(); ) {
-
-        if (iter.key() >= from && iter.key() < from + count) {
-            QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
-            int index = iter.key() - from + to;
-            iter = d->m_cache.erase(iter);
-
-            items.insert(index, objRef);
-
-            QSGVisualDataModelData *data = d->data(objRef.obj);
-            data->setIndex(index);
-        } else {
-            ++iter;
-        }
-    }
-    for (QHash<int,QSGVisualDataModelPrivate::ObjectRef>::Iterator iter = d->m_cache.begin();
-        iter != d->m_cache.end(); ) {
-
-        int diff = from > to ? count : -count;
-        if (iter.key() >= qMin(from,to) && iter.key() < qMax(from+count,to+count)) {
-            QSGVisualDataModelPrivate::ObjectRef objRef = *iter;
-            int index = iter.key() + diff;
-            iter = d->m_cache.erase(iter);
-
-            items.insert(index, objRef);
-
-            QSGVisualDataModelData *data = d->data(objRef.obj);
-            data->setIndex(index);
-        } else {
-            ++iter;
-        }
-    }
-    d->m_cache.unite(items);
-
-    emit itemsMoved(from, to, count);
-}
-
-void QSGVisualDataModel::_q_rowsInserted(const QModelIndex &parent, int begin, int end)
-{
-    Q_D(QSGVisualDataModel);
-    if (parent == d->m_root)
-        _q_itemsInserted(begin, end - begin + 1);
-}
-
-void QSGVisualDataModel::_q_rowsRemoved(const QModelIndex &parent, int begin, int end)
-{
-    Q_D(QSGVisualDataModel);
-    if (parent == d->m_root)
-        _q_itemsRemoved(begin, end - begin + 1);
-}
-
-void QSGVisualDataModel::_q_rowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destinationParent, int destinationRow)
-{
-    Q_D(QSGVisualDataModel);
-    const int count = sourceEnd - sourceStart + 1;
-    if (destinationParent == d->m_root && sourceParent == d->m_root) {
-        _q_itemsMoved(sourceStart, sourceStart > destinationRow ? destinationRow : destinationRow-count, count);
-    } else if (sourceParent == d->m_root) {
-        _q_itemsRemoved(sourceStart, count);
-    } else if (destinationParent == d->m_root) {
-        _q_itemsInserted(destinationRow, count);
-    }
-}
-
-void QSGVisualDataModel::_q_dataChanged(const QModelIndex &begin, const QModelIndex &end)
-{
-    Q_D(QSGVisualDataModel);
-    if (begin.parent() == d->m_root)
-        _q_itemsChanged(begin.row(), end.row() - begin.row() + 1, d->m_roles);
-}
-
-void QSGVisualDataModel::_q_layoutChanged()
-{
-    Q_D(QSGVisualDataModel);
-    _q_itemsChanged(0, count(), d->m_roles);
-}
-
-void QSGVisualDataModel::_q_modelReset()
-{
-    Q_D(QSGVisualDataModel);
-    d->m_root = QModelIndex();
-    emit modelReset();
-    emit rootIndexChanged();
-    if (d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(d->m_root))
-        d->m_abstractItemModel->fetchMore(d->m_root);
-}
-
-void QSGVisualDataModel::_q_createdPackage(int index, QDeclarativePackage *package)
-{
-    Q_D(QSGVisualDataModel);
-    emit createdItem(index, qobject_cast<QSGItem*>(package->part(d->m_part)));
-}
-
-void QSGVisualDataModel::_q_destroyingPackage(QDeclarativePackage *package)
-{
-    Q_D(QSGVisualDataModel);
-    emit destroyingItem(qobject_cast<QSGItem*>(package->part(d->m_part)));
-}
-
 QT_END_NAMESPACE
 
-QML_DECLARE_TYPE(QListModelInterface)
-
-#include <qsgvisualitemmodel.moc>
index 9acaab6..2eeff3c 100644 (file)
 
 #include <QtDeclarative/qdeclarative.h>
 #include <QtCore/qobject.h>
-#include <QtCore/qabstractitemmodel.h>
 
 QT_BEGIN_HEADER
 
-Q_DECLARE_METATYPE(QModelIndex)
-
 QT_BEGIN_NAMESPACE
 
 QT_MODULE(Declarative)
 
 class QSGItem;
-class QDeclarativeComponent;
-class QDeclarativePackage;
-class QSGVisualDataModelPrivate;
 
 class Q_DECLARATIVE_EXPORT QSGVisualModel : public QObject
 {
@@ -137,75 +131,6 @@ private:
     Q_DISABLE_COPY(QSGVisualItemModel)
 };
 
-
-class Q_DECLARATIVE_EXPORT QSGVisualDataModel : public QSGVisualModel
-{
-    Q_OBJECT
-    Q_DECLARE_PRIVATE(QSGVisualDataModel)
-
-    Q_PROPERTY(QVariant model READ model WRITE setModel)
-    Q_PROPERTY(QDeclarativeComponent *delegate READ delegate WRITE setDelegate)
-    Q_PROPERTY(QString part READ part WRITE setPart)
-    Q_PROPERTY(QObject *parts READ parts CONSTANT)
-    Q_PROPERTY(QVariant rootIndex READ rootIndex WRITE setRootIndex NOTIFY rootIndexChanged)
-    Q_CLASSINFO("DefaultProperty", "delegate")
-public:
-    QSGVisualDataModel();
-    QSGVisualDataModel(QDeclarativeContext *, QObject *parent=0);
-    virtual ~QSGVisualDataModel();
-
-    QVariant model() const;
-    void setModel(const QVariant &);
-
-    QDeclarativeComponent *delegate() const;
-    void setDelegate(QDeclarativeComponent *);
-
-    QVariant rootIndex() const;
-    void setRootIndex(const QVariant &root);
-
-    Q_INVOKABLE QVariant modelIndex(int idx) const;
-    Q_INVOKABLE QVariant parentModelIndex() const;
-
-    QString part() const;
-    void setPart(const QString &);
-
-    int count() const;
-    bool isValid() const { return delegate() != 0; }
-    QSGItem *item(int index, bool complete=true);
-    QSGItem *item(int index, const QByteArray &, bool complete=true);
-    ReleaseFlags release(QSGItem *item);
-    bool completePending() const;
-    void completeItem();
-    virtual QString stringValue(int index, const QString &role);
-    virtual void setWatchedRoles(QList<QByteArray> roles);
-
-    int indexOf(QSGItem *item, QObject *objectContext) const;
-
-    QObject *parts();
-
-Q_SIGNALS:
-    void createdPackage(int index, QDeclarativePackage *package);
-    void destroyingPackage(QDeclarativePackage *package);
-    void rootIndexChanged();
-
-private Q_SLOTS:
-    void _q_itemsChanged(int, int, const QList<int> &);
-    void _q_itemsInserted(int index, int count);
-    void _q_itemsRemoved(int index, int count);
-    void _q_itemsMoved(int from, int to, int count);
-    void _q_rowsInserted(const QModelIndex &,int,int);
-    void _q_rowsRemoved(const QModelIndex &,int,int);
-    void _q_rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int);
-    void _q_dataChanged(const QModelIndex&,const QModelIndex&);
-    void _q_layoutChanged();
-    void _q_modelReset();
-    void _q_createdPackage(int index, QDeclarativePackage *package);
-    void _q_destroyingPackage(QDeclarativePackage *package);
-
-private:
-    Q_DISABLE_COPY(QSGVisualDataModel)
-};
-
 class QSGVisualItemModelAttached : public QObject
 {
     Q_OBJECT
@@ -250,7 +175,6 @@ QT_END_NAMESPACE
 QML_DECLARE_TYPE(QSGVisualModel)
 QML_DECLARE_TYPE(QSGVisualItemModel)
 QML_DECLARE_TYPEINFO(QSGVisualItemModel, QML_HAS_ATTACHED_PROPERTIES)
-QML_DECLARE_TYPE(QSGVisualDataModel)
 
 QT_END_HEADER
 
index 0bb5cd1..0d4d9e2 100644 (file)
@@ -8,4 +8,5 @@ VisualDataModel {
         rootIndex = parentModelIndex();
     }
     model: myModel
+    delegate: Item {}
 }
index 61a6314..a2e6d95 100644 (file)
@@ -49,7 +49,7 @@
 #include <QtDeclarative/qsgview.h>
 #include <private/qsglistview_p.h>
 #include <private/qsgtext_p.h>
-#include <private/qsgvisualitemmodel_p.h>
+#include <private/qsgvisualdatamodel_p.h>
 #include <private/qdeclarativevaluetype_p.h>
 #include <math.h>
 #include <QtOpenGL/QGLShaderProgram>