diff options
author | Andrew den Exter <andrew.den-exter@nokia.com> | 2011-12-01 14:01:13 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-23 07:23:39 +0100 |
commit | 347f84e5aca9423536cb0cd7a2eafaf836a72212 (patch) | |
tree | cdb68529b37190be7f477d7775f8011d39080b36 /src/quick/items/qquickvisualadaptormodel.cpp | |
parent | 932a195dbaae92ce87b98beca29a25c9b8d6cf5b (diff) |
Minimize the number of objects created per item in VisualDataModel.
Derive from QDeclarativeContext and reference count the context object
instead of parenting it to the context. Combined with a weak
persistent v8 handle the allows the context object to be returned by
javascript accessors instead of creating a new instance for every use.
In addition to the efficiency advantages of creating fewer objects,
routing all data access through a single object means that object can
also persist data instead of just acting as a proxy.
Change-Id: I107dc8c901f16f2a4b420ff1cbffa7a6be27de89
Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src/quick/items/qquickvisualadaptormodel.cpp')
-rw-r--r-- | src/quick/items/qquickvisualadaptormodel.cpp | 467 |
1 files changed, 280 insertions, 187 deletions
diff --git a/src/quick/items/qquickvisualadaptormodel.cpp b/src/quick/items/qquickvisualadaptormodel.cpp index 9c57d9f75f..c1402ae242 100644 --- a/src/quick/items/qquickvisualadaptormodel.cpp +++ b/src/quick/items/qquickvisualadaptormodel.cpp @@ -40,32 +40,16 @@ ****************************************************************************/ #include "qquickvisualadaptormodel_p.h" -#include "qquickitem.h" +#include "qquickvisualdatamodel_p_p.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/qdeclarativeengine_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> - -Q_DECLARE_METATYPE(QModelIndex) - QT_BEGIN_NAMESPACE class VDMDelegateDataType : public QDeclarativeRefCount @@ -109,29 +93,9 @@ public: QMetaObjectBuilder builder; }; -class QQuickVisualAdaptorModelData : public QObject -{ - Q_OBJECT - Q_PROPERTY(int index READ index NOTIFY indexChanged) -public: - QQuickVisualAdaptorModelData(int index, QQuickVisualAdaptorModel *model); - ~QQuickVisualAdaptorModelData(); - - int index() const; - void setIndex(int index); - -Q_SIGNALS: - void indexChanged(); - -public: - int m_index; - QDeclarativeGuard<QQuickVisualAdaptorModel> m_model; - QIntrusiveListNode m_cacheNode; -}; - -typedef QIntrusiveList<QQuickVisualAdaptorModelData, &QQuickVisualAdaptorModelData::m_cacheNode> QQuickVisualAdaptorModelDataCache; +typedef QIntrusiveList<QQuickVisualDataModelItem, &QQuickVisualDataModelItem::cacheNode> QQuickVisualDataModelItemCache; -class QQuickVisualAdaptorModelDataMetaObject; +class QQuickVisualDataModelItemMetaObject; class QQuickVisualAdaptorModelPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QQuickVisualAdaptorModel) @@ -140,13 +104,18 @@ public: : m_engine(0) , m_listAccessor(0) , m_delegateDataType(0) - , createModelData(&initializeModelData) + , createItem(&initializeModelData) + , stringValue(&initializeStringValue) , m_ref(0) , m_count(0) , m_objectList(false) { } + ~QQuickVisualAdaptorModelPrivate() + { + qPersistentDispose(m_constructor); + } static QQuickVisualAdaptorModelPrivate *get(QQuickVisualAdaptorModel *m) { return static_cast<QQuickVisualAdaptorModelPrivate *>(QObjectPrivate::get(m)); @@ -155,20 +124,32 @@ public: void addProperty(int role, int propertyId, const char *propertyName, const char *propertyType, bool isModelData = false); template <typename T> void setModelDataType() { - createModelData = &T::create; + createItem = &T::create; + stringValue = &T::stringValue; 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(); } - QQuickVisualAdaptorModelData *createMetaObject(int index, QQuickVisualAdaptorModel *model); - static QQuickVisualAdaptorModelData *initializeModelData(int index, QQuickVisualAdaptorModel *model) { - return get(model)->createMetaObject(index, model); + void createMetaObject(); + + static QQuickVisualDataModelItem *initializeModelData( + QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) { + QQuickVisualAdaptorModelPrivate *d = get(model); + d->createMetaObject(); + return d->createItem(metaType, model, index); + } + + static QString initializeStringValue(QQuickVisualAdaptorModel *model, int index, const QString &name) { + QQuickVisualAdaptorModelPrivate *d = get(model); + d->createMetaObject(); + return d->stringValue(model, index, name); } - typedef QQuickVisualAdaptorModelData *(*CreateModelData)(int index, QQuickVisualAdaptorModel *model); + typedef QQuickVisualDataModelItem *(*CreateModelData)(QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index); + typedef QString (*StringValue)(QQuickVisualAdaptorModel *model, int index, const QString &name); struct PropertyData { int role; @@ -190,7 +171,9 @@ public: QDeclarativeGuard<QAbstractItemModel> m_abstractItemModel; QDeclarativeListAccessor *m_listAccessor; VDMDelegateDataType *m_delegateDataType; - CreateModelData createModelData; + CreateModelData createItem; + StringValue stringValue; + v8::Persistent<v8::Function> m_constructor; int m_ref; int m_count; @@ -205,13 +188,13 @@ public: QList<QByteArray> watchedRoles; QHash<QByteArray,int> m_roleNames; QVector<PropertyData> m_propertyData; - QQuickVisualAdaptorModelDataCache m_cache; + QQuickVisualDataModelItemCache m_cache; }; -class QQuickVisualAdaptorModelDataMetaObject : public QAbstractDynamicMetaObject +class QQuickVisualDataModelItemMetaObject : public QAbstractDynamicMetaObject { public: - QQuickVisualAdaptorModelDataMetaObject(QQuickVisualAdaptorModelData *data, VDMDelegateDataType *type) + QQuickVisualDataModelItemMetaObject(QQuickVisualDataModelItem *data, VDMDelegateDataType *type) : m_data(data) , m_type(type) { @@ -221,26 +204,35 @@ public: m_type->addref(); } - ~QQuickVisualAdaptorModelDataMetaObject() { m_type->release(); } + ~QQuickVisualDataModelItemMetaObject() { m_type->release(); } + + static v8::Handle<v8::Value> get_index(v8::Local<v8::String>, const v8::AccessorInfo &info) + { + QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); + if (!data) + V8THROW_ERROR("Not a valid VisualData object"); + + return v8::Int32::New(data->index[0]); + } - QQuickVisualAdaptorModelData *m_data; + QQuickVisualDataModelItem *m_data; VDMDelegateDataType *m_type; }; -class QQuickVDMAbstractItemModelDataMetaObject : public QQuickVisualAdaptorModelDataMetaObject +class QQuickVDMAbstractItemModelDataMetaObject : public QQuickVisualDataModelItemMetaObject { public: - QQuickVDMAbstractItemModelDataMetaObject(QQuickVisualAdaptorModelData *object, VDMDelegateDataType *type) - : QQuickVisualAdaptorModelDataMetaObject(object, type) {} + QQuickVDMAbstractItemModelDataMetaObject(QQuickVisualDataModelItem *object, VDMDelegateDataType *type) + : QQuickVisualDataModelItemMetaObject(object, type) {} int metaCall(QMetaObject::Call call, int id, void **arguments) { if (call == QMetaObject::ReadProperty && id >= m_type->propertyOffset) { - QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(m_data->m_model); - if (m_data->m_index == -1 || !model->m_abstractItemModel) + QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(m_data->model); + if (m_data->index[0] == -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); + m_data->index[0], 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); @@ -248,86 +240,195 @@ public: } }; -class QQuickVDMAbstractItemModelData : public QQuickVisualAdaptorModelData +class QQuickVDMAbstractItemModelData : public QQuickVisualDataModelItem { Q_OBJECT Q_PROPERTY(bool hasModelChildren READ hasModelChildren CONSTANT) public: bool hasModelChildren() const { - QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(m_model); - return model->m_abstractItemModel->hasChildren(model->m_abstractItemModel->index(m_index, 0, model->m_root)); + QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(model); + return d->m_abstractItemModel->hasChildren(d->m_abstractItemModel->index(index[0], 0, d->m_root)); + } + + static QQuickVisualDataModelItem *create( + QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) { + return new QQuickVDMAbstractItemModelData(metaType, model, index); } + + static QString stringValue(QQuickVisualAdaptorModel *model, int index, const QString &name) + { + QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(model); + const int role = d->m_roleNames.value(name.toUtf8(), -1); + + if (role != -1) + return d->m_abstractItemModel->index(index, 0, d->m_root).data(role).toString(); + else if (name == QLatin1String("hasModelChildren")) + return QVariant(d->m_abstractItemModel->hasChildren(d->m_abstractItemModel->index(index, 0, d->m_root))).toString(); + else + return QString(); + } + + static v8::Handle<v8::Value> get_property(v8::Local<v8::String>, const v8::AccessorInfo &info) + { + QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); + if (!data) + V8THROW_ERROR("Not a valid VisualData object"); + + QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(data->model); + if (data->index[0] == -1 || !model->m_abstractItemModel) + return v8::Undefined(); + + const int role = info.Data()->Int32Value(); + const QVariant value = model->m_abstractItemModel->index(data->index[0], 0, model->m_root).data(role); + return data->engine->fromVariant(value); + } + + static v8::Handle<v8::Value> get_hasModelChildren(v8::Local<v8::String>, const v8::AccessorInfo &info) + { + QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); + if (!data) + V8THROW_ERROR("Not a valid VisualData object"); + + QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(data->model); + + return v8::Boolean::New(model->m_abstractItemModel->hasChildren( + model->m_abstractItemModel->index(data->index[0], 0, model->m_root))); + } + + v8::Handle<v8::Value> get() + { + QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(model); + + v8::Local<v8::Object> data = d->m_constructor->NewInstance(); + data->SetExternalResource(this); + return data; } - static QQuickVisualAdaptorModelData *create(int index, QQuickVisualAdaptorModel *model) { - return new QQuickVDMAbstractItemModelData(index, model); } private: - QQuickVDMAbstractItemModelData(int index, QQuickVisualAdaptorModel *model) - : QQuickVisualAdaptorModelData(index, model) + QQuickVDMAbstractItemModelData( + QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) + : QQuickVisualDataModelItem(metaType, model, index) { new QQuickVDMAbstractItemModelDataMetaObject( - this, QQuickVisualAdaptorModelPrivate::get(m_model)->m_delegateDataType); + this, QQuickVisualAdaptorModelPrivate::get(model)->m_delegateDataType); } }; -class QQuickVDMListModelInterfaceDataMetaObject : public QQuickVisualAdaptorModelDataMetaObject +class QQuickVDMListModelInterfaceDataMetaObject : public QQuickVisualDataModelItemMetaObject { public: - QQuickVDMListModelInterfaceDataMetaObject(QQuickVisualAdaptorModelData *object, VDMDelegateDataType *type) - : QQuickVisualAdaptorModelDataMetaObject(object, type) {} + QQuickVDMListModelInterfaceDataMetaObject(QQuickVisualDataModelItem *object, VDMDelegateDataType *type) + : QQuickVisualDataModelItemMetaObject(object, type) {} int metaCall(QMetaObject::Call call, int id, void **arguments) { if (call == QMetaObject::ReadProperty && id >= m_type->propertyOffset) { - QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(m_data->m_model); - if (m_data->m_index == -1 || !model->m_listModelInterface) + QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(m_data->model); + if (m_data->index[0] == -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); + m_data->index[0], model->m_propertyData.at(id - m_type->propertyOffset).role); return -1; } else { return m_data->qt_metacall(call, id, arguments); } } + }; -class QQuickVDMListModelInterfaceData : public QQuickVisualAdaptorModelData +class QQuickVDMListModelInterfaceData : public QQuickVisualDataModelItem { public: - static QQuickVisualAdaptorModelData *create(int index, QQuickVisualAdaptorModel *model) { - return new QQuickVDMListModelInterfaceData(index, model); } + static QQuickVisualDataModelItem *create( + QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) { + return new QQuickVDMListModelInterfaceData(metaType, model, index); } + + static QString stringValue(QQuickVisualAdaptorModel *model, int index, const QString &name) + { + QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(model); + const int role = d->m_roleNames.value(name.toUtf8(), -1); + return role != -1 + ? d->m_listModelInterface->data(index, role).toString() + : QString(); + } + + static v8::Handle<v8::Value> get_property(v8::Local<v8::String>, const v8::AccessorInfo &info) + { + QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); + if (!data) + V8THROW_ERROR("Not a valid VisualData object"); + + QQuickVisualAdaptorModelPrivate *model = QQuickVisualAdaptorModelPrivate::get(data->model); + if (data->index[0] == -1 || !model->m_listModelInterface) + return v8::Undefined(); + + const int role = info.Data()->Int32Value(); + const QVariant value = model->m_listModelInterface->data(data->index[0], role); + return data->engine->fromVariant(value); + } + + v8::Handle<v8::Value> get() + { + QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(model); + + v8::Local<v8::Object> data = d->m_constructor->NewInstance(); + data->SetExternalResource(this); + return data; + } + private: - QQuickVDMListModelInterfaceData(int index, QQuickVisualAdaptorModel *model) - : QQuickVisualAdaptorModelData(index, model) + QQuickVDMListModelInterfaceData(QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) + : QQuickVisualDataModelItem(metaType, model, index) { new QQuickVDMListModelInterfaceDataMetaObject( - this, QQuickVisualAdaptorModelPrivate::get(m_model)->m_delegateDataType); + this, QQuickVisualAdaptorModelPrivate::get(model)->m_delegateDataType); } }; -class QQuickVDMListAccessorData : public QQuickVisualAdaptorModelData +class QQuickVDMListAccessorData : public QQuickVisualDataModelItem { Q_OBJECT Q_PROPERTY(QVariant modelData READ modelData CONSTANT) public: QVariant modelData() const { - return QQuickVisualAdaptorModelPrivate::get(m_model)->m_listAccessor->at(m_index); } + return QQuickVisualAdaptorModelPrivate::get(model)->m_listAccessor->at(index[0]); } + + static QQuickVisualDataModelItem *create( + QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) { + return new QQuickVDMListAccessorData(metaType, model, index); } + + static QString stringValue(QQuickVisualAdaptorModel *model, int index, const QString &name) + { + return name == QLatin1String("modelData") + ? QQuickVisualAdaptorModelPrivate::get(model)->m_listAccessor->at(index).toString() + : QString(); + } + + static v8::Handle<v8::Value> get_modelData(v8::Local<v8::String>, const v8::AccessorInfo &info) + { + QQuickVisualDataModelItem *data = v8_resource_cast<QQuickVisualDataModelItem>(info.This()); + if (!data) + V8THROW_ERROR("Not a valid VisualData object"); - static QQuickVisualAdaptorModelData *create(int index, QQuickVisualAdaptorModel *model) { - return new QQuickVDMListAccessorData(index, model); } + QQuickVisualAdaptorModelPrivate *d = QQuickVisualAdaptorModelPrivate::get(data->model); + if (data->index[0] == -1 || !d->m_listAccessor) + return v8::Undefined(); + + return data->engine->fromVariant(d->m_listAccessor->at(data->index[0])); + } private: - QQuickVDMListAccessorData(int index, QQuickVisualAdaptorModel *model) - : QQuickVisualAdaptorModelData(index, model) + QQuickVDMListAccessorData(QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) + : QQuickVisualDataModelItem(metaType, model, index) { } }; -class QQuickVDMObjectDataMetaObject : public QQuickVisualAdaptorModelDataMetaObject +class QQuickVDMObjectDataMetaObject : public QQuickVisualDataModelItemMetaObject { public: - QQuickVDMObjectDataMetaObject(QQuickVisualAdaptorModelData *data, VDMDelegateDataType *type) - : QQuickVisualAdaptorModelDataMetaObject(data, type) - , m_object(QQuickVisualAdaptorModelPrivate::get(data->m_model)->m_listAccessor->at(data->m_index).value<QObject *>()) + QQuickVDMObjectDataMetaObject(QQuickVisualDataModelItem *data, VDMDelegateDataType *type) + : QQuickVisualDataModelItemMetaObject(data, type) + , m_object(QQuickVisualAdaptorModelPrivate::get(data->model)->m_listAccessor->at(data->index[0]).value<QObject *>()) {} int metaCall(QMetaObject::Call call, int id, void **arguments) @@ -405,7 +506,7 @@ public: QDeclarativeGuard<QObject> m_object; }; -class QQuickVDMObjectData : public QQuickVisualAdaptorModelData, public QQuickVisualAdaptorModelProxyInterface +class QQuickVDMObjectData : public QQuickVisualDataModelItem, public QQuickVisualAdaptorModelProxyInterface { Q_OBJECT Q_PROPERTY(QObject *modelData READ modelData CONSTANT) @@ -414,13 +515,21 @@ public: QObject *modelData() const { return m_metaObject->m_object; } QObject *proxiedObject() { return m_metaObject->m_object; } - static QQuickVisualAdaptorModelData *create(int index, QQuickVisualAdaptorModel *model) { - return new QQuickVDMObjectData(index, model); } + static QQuickVisualDataModelItem *create( + QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) { + return new QQuickVDMObjectData(metaType, model, index); } + + static QString stringValue(QQuickVisualAdaptorModel *model, int index, const QString &name) + { + if (QObject *object = QQuickVisualAdaptorModelPrivate::get(model)->m_listAccessor->at(index).value<QObject *>()) + return object->property(name.toUtf8()).toString(); + return QString(); + } private: - QQuickVDMObjectData(int index, QQuickVisualAdaptorModel *model) - : QQuickVisualAdaptorModelData(index, model) - , m_metaObject(new QQuickVDMObjectDataMetaObject(this, QQuickVisualAdaptorModelPrivate::get(m_model)->m_delegateDataType)) + QQuickVDMObjectData(QQuickVisualDataModelItemMetaType *metaType, QQuickVisualAdaptorModel *model, int index) + : QQuickVisualDataModelItem(metaType, model, index) + , m_metaObject(new QQuickVDMObjectDataMetaObject(this, QQuickVisualAdaptorModelPrivate::get(model)->m_delegateDataType)) { } @@ -441,17 +550,31 @@ void QQuickVisualAdaptorModelPrivate::addProperty( m_propertyData.append(propertyData); } -QQuickVisualAdaptorModelData *QQuickVisualAdaptorModelPrivate::createMetaObject(int index, QQuickVisualAdaptorModel *model) +void QQuickVisualAdaptorModelPrivate::createMetaObject() { Q_ASSERT(!m_delegateDataType); m_objectList = false; m_propertyData.clear(); + + QV8Engine *v8Engine = QDeclarativeEnginePrivate::getV8Engine(m_engine); + + v8::HandleScope handleScope; + v8::Context::Scope contextScope(v8Engine->context()); + v8::Local<v8::FunctionTemplate> ft = v8::FunctionTemplate::New(); + ft->InstanceTemplate()->SetHasExternalResource(true); + ft->PrototypeTemplate()->SetAccessor( + v8::String::New("index"), QQuickVisualDataModelItemMetaObject::get_index); + if (m_listAccessor && m_listAccessor->type() != QDeclarativeListAccessor::ListProperty && m_listAccessor->type() != QDeclarativeListAccessor::Instance) { - createModelData = &QQuickVDMListAccessorData::create; - return QQuickVDMListAccessorData::create(index, model); + createItem = &QQuickVDMListAccessorData::create; + stringValue = &QQuickVDMListAccessorData::stringValue; + ft->PrototypeTemplate()->SetAccessor( + v8::String::New("modelData"), QQuickVDMListAccessorData::get_modelData); + m_constructor = qPersistentNew<v8::Function>(ft->GetFunction()); + return; } m_delegateDataType = new VDMDelegateDataType; @@ -460,65 +583,63 @@ QQuickVisualAdaptorModelData *QQuickVisualAdaptorModelPrivate::createMetaObject( 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(); + const QString roleName = m_listModelInterface->toString(role); + const QByteArray propertyName = roleName.toUtf8(); addProperty(role, propertyId, propertyName, "QVariant"); + ft->PrototypeTemplate()->SetAccessor( + v8Engine->toString(roleName), + QQuickVDMListModelInterfaceData::get_property, + 0, + v8::Int32::New(role)); m_roleNames.insert(propertyName, role); } - if (m_propertyData.count() == 1) + if (m_propertyData.count() == 1) { addProperty(roles.first(), 1, "modelData", "QVariant", true); + ft->PrototypeTemplate()->SetAccessor( + v8::String::New("modelData"), + QQuickVDMListModelInterfaceData::get_property, + 0, + v8::Int32::New(roles.first())); + } } else if (m_abstractItemModel) { setModelDataType<QQuickVDMAbstractItemModelData>(); 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"); + ft->PrototypeTemplate()->SetAccessor( + v8::String::New(it.value().constData(), it.value().length()), + QQuickVDMAbstractItemModelData::get_property, + 0, + v8::Int32::New(it.key())); m_roleNames.insert(it.value(), it.key()); } - if (m_propertyData.count() == 1) + if (m_propertyData.count() == 1) { addProperty(roleNames.begin().key(), 1, "modelData", "QVariant", true); + ft->PrototypeTemplate()->SetAccessor( + v8::String::New("modelData"), + QQuickVDMAbstractItemModelData::get_property, + 0, + v8::Int32::New(roleNames.begin().key())); + } + ft->PrototypeTemplate()->SetAccessor( + v8::String::New("hasModelChildren"), + QQuickVDMAbstractItemModelData::get_hasModelChildren); } else if (m_listAccessor) { setModelDataType<QQuickVDMObjectData>(); m_objectList = true; m_flags = QQuickVisualAdaptorModel::ProxiedObject; } else { Q_ASSERT(!"No model set on VisualDataModel"); - return 0; + return; } m_delegateDataType->metaObject = m_delegateDataType->builder.toMetaObject(); if (!m_objectList) { m_delegateDataType->propertyCache = new QDeclarativePropertyCache( m_engine, m_delegateDataType->metaObject); - } - return createModelData(index, model); -} - -QQuickVisualAdaptorModelData::QQuickVisualAdaptorModelData(int index, QQuickVisualAdaptorModel *model) - : m_index(index) - , m_model(model) -{ - QQuickVisualAdaptorModelPrivate *m = QQuickVisualAdaptorModelPrivate::get(model); - if (m->m_delegateDataType && m->m_delegateDataType->propertyCache) { - QDeclarativeData *qmldata = QDeclarativeData::get(this, true); - qmldata->propertyCache = m->m_delegateDataType->propertyCache; - qmldata->propertyCache->addref(); + m_constructor = qPersistentNew<v8::Function>(ft->GetFunction()); } } -QQuickVisualAdaptorModelData::~QQuickVisualAdaptorModelData() -{ -} - -int QQuickVisualAdaptorModelData::index() const -{ - return m_index; -} - -// This is internal only - it should not be set from qml -void QQuickVisualAdaptorModelData::setIndex(int index) -{ - m_index = index; - emit indexChanged(); -} - //--------------------------------------------------------------------------- QQuickVisualAdaptorModel::QQuickVisualAdaptorModel(QObject *parent) @@ -585,7 +706,9 @@ void QQuickVisualAdaptorModel::setModel(const QVariant &model, QDeclarativeEngin if (d->m_delegateDataType) d->m_delegateDataType->release(); d->m_delegateDataType = 0; - d->createModelData = &QQuickVisualAdaptorModelPrivate::initializeModelData; + d->createItem = &QQuickVisualAdaptorModelPrivate::initializeModelData; + d->stringValue = &QQuickVisualAdaptorModelPrivate::initializeStringValue; + qPersistentDispose(d->m_constructor); if (d->m_count) emit itemsRemoved(0, d->m_count); @@ -672,55 +795,25 @@ int QQuickVisualAdaptorModel::count() const return d->modelCount(); } -QObject *QQuickVisualAdaptorModel::data(int index) +QQuickVisualDataModelItem *QQuickVisualAdaptorModel::createItem(QQuickVisualDataModelItemMetaType *metaType, int index) { Q_D(QQuickVisualAdaptorModel); - QQuickVisualAdaptorModelData *data = d->createModelData(index, this); + QQuickVisualDataModelItem *data = d->createItem(metaType, this, index); d->m_cache.insert(data); - return data; -} - -QString QQuickVisualAdaptorModel::stringValue(int index, const QString &name) -{ - Q_D(QQuickVisualAdaptorModel); - 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; - QQuickVisualAdaptorModelData *data = d->createModelData(index, this); - - QDeclarativeData *ddata = QDeclarativeData::get(data); - if (ddata && ddata->propertyCache) { - QDeclarativePropertyData *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 (d->m_delegateDataType && d->m_delegateDataType->propertyCache) { + QDeclarativeData *qmldata = QDeclarativeData::get(data, true); + qmldata->propertyCache = d->m_delegateDataType->propertyCache; + qmldata->propertyCache->addref(); } - delete data; - - return val; + return data; } -int QQuickVisualAdaptorModel::indexOf(QObject *object) const +QString QQuickVisualAdaptorModel::stringValue(int index, const QString &name) { - if (QQuickVisualAdaptorModelData *data = qobject_cast<QQuickVisualAdaptorModelData *>(object)) - return data->index(); - return -1; + Q_D(QQuickVisualAdaptorModel); + return d->stringValue(this, index, name); } bool QQuickVisualAdaptorModel::canFetchMore() const @@ -771,11 +864,11 @@ void QQuickVisualAdaptorModel::_q_itemsChanged(int index, int count, const QList signalIndexes.append(propertyId + d->m_delegateDataType->signalOffset); } - typedef QQuickVisualAdaptorModelDataCache::iterator iterator; + typedef QQuickVisualDataModelItemCache::iterator iterator; for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) { - const int idx = it->index(); + const int idx = it->modelIndex(); if (idx >= index && idx < index + count) { - QQuickVisualAdaptorModelData *data = *it; + QQuickVisualDataModelItem *data = *it; for (int i = 0; i < signalIndexes.count(); ++i) QMetaObject::activate(data, signalIndexes.at(i), 0); } @@ -791,10 +884,10 @@ void QQuickVisualAdaptorModel::_q_itemsInserted(int index, int count) return; d->m_count += count; - typedef QQuickVisualAdaptorModelDataCache::iterator iterator; + typedef QQuickVisualDataModelItemCache::iterator iterator; for (iterator it = d->m_cache.begin(); it != d->m_cache.end(); ++it) { - if (it->index() >= index) - it->setIndex(it->index() + count); + if (it->modelIndex() >= index) + it->setModelIndex(it->modelIndex() + count); } emit itemsInserted(index, count); @@ -807,12 +900,12 @@ void QQuickVisualAdaptorModel::_q_itemsRemoved(int index, int count) return; d->m_count -= count; - typedef QQuickVisualAdaptorModelDataCache::iterator iterator; + typedef QQuickVisualDataModelItemCache::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); + if (it->modelIndex() >= index + count) + it->setModelIndex(it->modelIndex() - count); + else if (it->modelIndex() >= index) + it->setModelIndex(-1); } emit itemsRemoved(index, count); @@ -825,12 +918,12 @@ void QQuickVisualAdaptorModel::_q_itemsMoved(int from, int to, int count) const int maximum = qMax(from, to) + count; const int difference = from > to ? count : -count; - typedef QQuickVisualAdaptorModelDataCache::iterator iterator; + typedef QQuickVisualDataModelItemCache::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); + if (it->modelIndex() >= from && it->modelIndex() < from + count) + it->setModelIndex(it->modelIndex() - from + to); + else if (it->modelIndex() >= minimum && it->modelIndex() < maximum) + it->setModelIndex(it->modelIndex() + difference); } emit itemsMoved(from, to, count); } |