diff options
-rw-r--r-- | src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp | 47 | ||||
-rw-r--r-- | src/declarative/util/qmlopenmetaobject.cpp | 181 | ||||
-rw-r--r-- | src/declarative/util/qmlopenmetaobject_p.h | 18 |
3 files changed, 174 insertions, 72 deletions
diff --git a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp index a6c40c5..7530c43 100644 --- a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp @@ -341,6 +341,9 @@ public: QmlGraphicsVisualDataModelParts *m_parts; friend class QmlGraphicsVisualItemParts; + QmlOpenMetaObjectType *m_delegateDataType; + friend class QmlGraphicsVisualDataModelData; + QmlGraphicsVisualDataModelData *data(QObject *item); QVariant m_modelVariant; @@ -362,10 +365,11 @@ public: class QmlGraphicsVisualDataModelDataMetaObject : public QmlOpenMetaObject { public: - QmlGraphicsVisualDataModelDataMetaObject(QObject *parent) - : QmlOpenMetaObject(parent) {} + QmlGraphicsVisualDataModelDataMetaObject(QObject *parent, QmlOpenMetaObjectType *type) + : QmlOpenMetaObject(parent, type) {} - virtual QVariant propertyCreated(int, QMetaPropertyBuilder &); + virtual void propertyCreated(int, QMetaPropertyBuilder &); + virtual QVariant initialValue(int); virtual int createProperty(const char *, const char *); private: @@ -442,20 +446,22 @@ int QmlGraphicsVisualDataModelDataMetaObject::createProperty(const char *name, c return -1; } -QVariant -QmlGraphicsVisualDataModelDataMetaObject::propertyCreated(int, QMetaPropertyBuilder &prop) +void QmlGraphicsVisualDataModelDataMetaObject::propertyCreated(int, QMetaPropertyBuilder &prop) { prop.setWritable(false); +} +QVariant QmlGraphicsVisualDataModelDataMetaObject::initialValue(int propId) +{ QmlGraphicsVisualDataModelData *data = static_cast<QmlGraphicsVisualDataModelData *>(object()); Q_ASSERT(data->m_model); QmlGraphicsVisualDataModelPrivate *model = QmlGraphicsVisualDataModelPrivate::get(data->m_model); - QString name = QString::fromUtf8(prop.name()); + QString strName = QString::fromUtf8(name(propId)); if ((!model->m_listModelInterface || !model->m_abstractItemModel) && model->m_listAccessor) { - if (name == QLatin1String("modelData")) { + if (strName == QLatin1String("modelData")) { if (model->m_listAccessor->type() == QmlListAccessor::Instance) { QObject *object = model->m_listAccessor->at(0).value<QObject*>(); return object->metaObject()->property(1).read(object); // the first property after objectName @@ -464,11 +470,11 @@ QmlGraphicsVisualDataModelDataMetaObject::propertyCreated(int, QMetaPropertyBuil } else { // return any property of a single object instance. QObject *object = model->m_listAccessor->at(data->m_index).value<QObject*>(); - return object->property(prop.name()); + return object->property(name(propId)); } } else if (model->m_listModelInterface) { model->ensureRoles(); - QHash<QString,int>::const_iterator it = model->m_roleNames.find(name); + QHash<QString,int>::const_iterator it = model->m_roleNames.find(strName); if (it != model->m_roleNames.end()) { roles.append(*it); QHash<int,QVariant> values = model->m_listModelInterface->data(data->m_index, QList<int>() << *it); @@ -476,7 +482,7 @@ QmlGraphicsVisualDataModelDataMetaObject::propertyCreated(int, QMetaPropertyBuil return QVariant(); else return values.value(*it); - } else if (model->m_roles.count() == 1 && name == QLatin1String("modelData")) { + } else if (model->m_roles.count() == 1 && strName == QLatin1String("modelData")) { //for compatability with other lists, assign modelData if there is only a single role QHash<int,QVariant> values = model->m_listModelInterface->data(data->m_index, QList<int>() << model->m_roles.first()); if (values.isEmpty()) @@ -486,7 +492,7 @@ QmlGraphicsVisualDataModelDataMetaObject::propertyCreated(int, QMetaPropertyBuil } } else if (model->m_abstractItemModel) { model->ensureRoles(); - QHash<QString,int>::const_iterator it = model->m_roleNames.find(name); + QHash<QString,int>::const_iterator it = model->m_roleNames.find(strName); if (it != model->m_roleNames.end()) { roles.append(*it); QModelIndex index = model->m_abstractItemModel->index(data->m_index, 0); @@ -500,7 +506,7 @@ QmlGraphicsVisualDataModelDataMetaObject::propertyCreated(int, QMetaPropertyBuil QmlGraphicsVisualDataModelData::QmlGraphicsVisualDataModelData(int index, QmlGraphicsVisualDataModel *model) : m_index(index), m_model(model), - m_meta(new QmlGraphicsVisualDataModelDataMetaObject(this)) +m_meta(new QmlGraphicsVisualDataModelDataMetaObject(this, QmlGraphicsVisualDataModelPrivate::get(model)->m_delegateDataType)) { } @@ -526,7 +532,8 @@ public: QmlGraphicsVisualDataModelPartsMetaObject(QObject *parent) : QmlOpenMetaObject(parent) {} - virtual QVariant propertyCreated(int, QMetaPropertyBuilder &); + virtual void propertyCreated(int, QMetaPropertyBuilder &); + virtual QVariant initialValue(int); }; class QmlGraphicsVisualDataModelParts : public QObject @@ -540,14 +547,16 @@ private: QmlGraphicsVisualDataModel *model; }; -QVariant -QmlGraphicsVisualDataModelPartsMetaObject::propertyCreated(int, QMetaPropertyBuilder &prop) +void QmlGraphicsVisualDataModelPartsMetaObject::propertyCreated(int, QMetaPropertyBuilder &prop) { prop.setWritable(false); +} +QVariant QmlGraphicsVisualDataModelPartsMetaObject::initialValue(int id) +{ QmlGraphicsVisualDataModel *m = new QmlGraphicsVisualDataModel; m->setParent(object()); - m->setPart(QString::fromUtf8(prop.name())); + m->setPart(QString::fromUtf8(property(id).name())); m->setModel(QVariant::fromValue(static_cast<QmlGraphicsVisualDataModelParts *>(object())->model)); QVariant var = QVariant::fromValue((QObject *)m); @@ -562,7 +571,7 @@ QmlGraphicsVisualDataModelParts::QmlGraphicsVisualDataModelParts(QmlGraphicsVisu QmlGraphicsVisualDataModelPrivate::QmlGraphicsVisualDataModelPrivate(QmlContext *ctxt) : m_listModelInterface(0), m_abstractItemModel(0), m_visualItemModel(0), m_delegate(0) -, m_context(ctxt), m_parts(0), m_listAccessor(0) +, m_context(ctxt), m_parts(0), m_delegateDataType(0), m_listAccessor(0) { } @@ -639,6 +648,8 @@ void QmlGraphicsVisualDataModel::setModel(const QVariant &model) d->m_roles.clear(); d->m_roleNames.clear(); + delete d->m_delegateDataType; + d->m_delegateDataType = new QmlOpenMetaObjectType(d->m_context->engine()); QObject *object = qvariant_cast<QObject *>(model); if (object && (d->m_listModelInterface = qobject_cast<QListModelInterface *>(object))) { @@ -761,7 +772,7 @@ QmlGraphicsVisualDataModel::ReleaseFlags QmlGraphicsVisualDataModel::release(Qml if (inPackage) emit destroyingPackage(qobject_cast<QmlPackage*>(obj)); stat |= Destroyed; - delete obj; + obj->deleteLater(); } else if (!inPackage) { stat |= Referenced; } diff --git a/src/declarative/util/qmlopenmetaobject.cpp b/src/declarative/util/qmlopenmetaobject.cpp index 04cd8a5..30457f9 100644 --- a/src/declarative/util/qmlopenmetaobject.cpp +++ b/src/declarative/util/qmlopenmetaobject.cpp @@ -40,70 +40,141 @@ ****************************************************************************/ #include "qmlopenmetaobject_p.h" - +#include "qmlpropertycache_p.h" +#include "qmldeclarativedata_p.h" #include <qmetaobjectbuilder_p.h> #include <QDebug> QT_BEGIN_NAMESPACE -class QmlOpenMetaObjectPrivate + +class QmlOpenMetaObjectTypePrivate { public: - QmlOpenMetaObjectPrivate() : parent(0), mem(0) {} + QmlOpenMetaObjectTypePrivate() : mem(0), engine(0) {} + + void init(QObject *obj); - bool autoCreate; - QAbstractDynamicMetaObject *parent; int propertyOffset; int signalOffset; - QList<QVariant> data; QHash<QByteArray, int> names; QMetaObjectBuilder mob; QMetaObject *mem; + QmlEngine *engine; +}; + +QmlOpenMetaObjectType::QmlOpenMetaObjectType(QmlEngine *engine) + : d(new QmlOpenMetaObjectTypePrivate) +{ + d->engine = engine; +} + +QmlOpenMetaObjectType::~QmlOpenMetaObjectType() +{ + qFree(d->mem); +} + +void QmlOpenMetaObjectTypePrivate::init(QObject *obj) +{ + if (!mem) { + mob.setSuperClass(obj->metaObject()); + mob.setClassName(obj->metaObject()->className()); + mob.setFlags(QMetaObjectBuilder::DynamicMetaObject); + + QObjectPrivate *op = QObjectPrivate::get(obj); + if (op->metaObject) + mob.setSuperClass(op->metaObject); + mem = mob.toMetaObject(); + + propertyOffset = mem->propertyOffset(); + signalOffset = mem->methodOffset(); + } +} + +class QmlOpenMetaObjectPrivate +{ +public: + QmlOpenMetaObjectPrivate(QmlOpenMetaObject *_q) : q(_q), parent(0), type(0), ownType(false) {} + + inline QVariant &getData(int idx) { + while (data.count() <= idx) + data << QPair<QVariant, bool>(QVariant(), false); + QPair<QVariant, bool> &prop = data[idx]; + if (!prop.second) { + prop.first = q->initialValue(idx); + prop.second = true; + } + return prop.first; + } + + inline void writeData(int idx, const QVariant &value) { + while (data.count() <= idx) + data << QPair<QVariant, bool>(QVariant(), false); + QPair<QVariant, bool> &prop = data[idx]; + prop.first = value; + prop.second = true; + } + + bool autoCreate; + QmlOpenMetaObject *q; + QAbstractDynamicMetaObject *parent; + QList<QPair<QVariant, bool> > data; QObject *object; + QmlOpenMetaObjectType *type; + bool ownType; }; QmlOpenMetaObject::QmlOpenMetaObject(QObject *obj, bool automatic) -: d(new QmlOpenMetaObjectPrivate) +: d(new QmlOpenMetaObjectPrivate(this)) { d->autoCreate = automatic; d->object = obj; - d->mob.setSuperClass(obj->metaObject()); - d->mob.setClassName(obj->metaObject()->className()); - d->mob.setFlags(QMetaObjectBuilder::DynamicMetaObject); + d->type = new QmlOpenMetaObjectType(0); + d->ownType = true; + d->type->d->init(obj); QObjectPrivate *op = QObjectPrivate::get(obj); - if (op->metaObject) - d->mob.setSuperClass(op->metaObject); + *static_cast<QMetaObject *>(this) = *d->type->d->mem; + op->metaObject = this; +} + +QmlOpenMetaObject::QmlOpenMetaObject(QObject *obj, QmlOpenMetaObjectType *type, bool automatic) +: d(new QmlOpenMetaObjectPrivate(this)) +{ + d->autoCreate = automatic; + d->object = obj; - d->mem = d->mob.toMetaObject(); - *static_cast<QMetaObject *>(this) = *d->mem; + d->type = type; + d->type->d->init(obj); + + QObjectPrivate *op = QObjectPrivate::get(obj); + *static_cast<QMetaObject *>(this) = *d->type->d->mem; op->metaObject = this; - d->propertyOffset = propertyOffset(); - d->signalOffset = methodOffset(); } QmlOpenMetaObject::~QmlOpenMetaObject() { if (d->parent) delete d->parent; - qFree(d->mem); + if (d->ownType) + delete d->type; delete d; } int QmlOpenMetaObject::metaCall(QMetaObject::Call c, int id, void **a) { if (( c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty) - && id >= d->propertyOffset) { - int propId = id - d->propertyOffset; + && id >= d->type->d->propertyOffset) { + int propId = id - d->type->d->propertyOffset; if (c == QMetaObject::ReadProperty) { propertyRead(propId); - *reinterpret_cast<QVariant *>(a[0]) = d->data[propId]; + *reinterpret_cast<QVariant *>(a[0]) = d->getData(propId); } else if (c == QMetaObject::WriteProperty) { - if (d->data[propId] != *reinterpret_cast<QVariant *>(a[0])) { + if (d->data[propId].first != *reinterpret_cast<QVariant *>(a[0])) { propertyWrite(propId); - d->data[propId] = *reinterpret_cast<QVariant *>(a[0]); - activate(d->object, d->signalOffset + propId, 0); + d->writeData(propId, *reinterpret_cast<QVariant *>(a[0])); + activate(d->object, d->type->d->signalOffset + propId, 0); } } return -1; @@ -117,50 +188,49 @@ int QmlOpenMetaObject::metaCall(QMetaObject::Call c, int id, void **a) QVariant QmlOpenMetaObject::value(int id) const { - Q_ASSERT(id >= 0 && id < d->data.count()); - return d->data.at(id); + return d->getData(id); } void QmlOpenMetaObject::setValue(int id, const QVariant &value) { - Q_ASSERT(id >= 0 && id < d->data.count()); - d->data[id] = value; - activate(d->object, id + d->signalOffset, 0); + d->writeData(id, value); + activate(d->object, id + d->type->d->signalOffset, 0); } QVariant QmlOpenMetaObject::value(const QByteArray &name) const { - QHash<QByteArray, int>::ConstIterator iter = d->names.find(name); - if (iter == d->names.end()) + QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.find(name); + if (iter == d->type->d->names.end()) return QVariant(); - return d->data.at(*iter); + return d->getData(*iter); } QVariant &QmlOpenMetaObject::operator[](const QByteArray &name) { - QHash<QByteArray, int>::ConstIterator iter = d->names.find(name); - Q_ASSERT(iter != d->names.end()); + QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.find(name); + Q_ASSERT(iter != d->type->d->names.end()); - return d->data[*iter]; + return d->getData(*iter); } void QmlOpenMetaObject::setValue(const QByteArray &name, const QVariant &val) { - QHash<QByteArray, int>::ConstIterator iter = d->names.find(name); + QHash<QByteArray, int>::ConstIterator iter = d->type->d->names.find(name); int id = -1; - if (iter == d->names.end()) { - id = doCreateProperty(name.constData()) - d->propertyOffset; + if (iter == d->type->d->names.end()) { + id = doCreateProperty(name.constData()) - d->type->d->propertyOffset; } else { id = *iter; } - if (d->data[id] == val) + QVariant &dataVal = d->getData(id); + if (dataVal == val) return; - d->data[id] = val; - activate(d->object, id + d->signalOffset, 0); + dataVal = val; + activate(d->object, id + d->type->d->signalOffset, 0); } int QmlOpenMetaObject::createProperty(const char *name, const char *) @@ -173,17 +243,18 @@ int QmlOpenMetaObject::createProperty(const char *name, const char *) int QmlOpenMetaObject::doCreateProperty(const char *name) { - int id = d->mob.propertyCount(); - d->mob.addSignal("__" + QByteArray::number(id) + "()"); - QMetaPropertyBuilder build = d->mob.addProperty(name, "QVariant", id); + qDebug() << "doCreateProperty()" << name; + int id = d->type->d->mob.propertyCount(); + d->type->d->mob.addSignal("__" + QByteArray::number(id) + "()"); + QMetaPropertyBuilder build = d->type->d->mob.addProperty(name, "QVariant", id); build.setDynamic(true); - d->data << propertyCreated(id, build); - qFree(d->mem); - d->mem = d->mob.toMetaObject(); - *static_cast<QMetaObject *>(this) = *d->mem; - d->names.insert(name, id); + propertyCreated(id, build); + qFree(d->type->d->mem); + d->type->d->mem = d->type->d->mob.toMetaObject(); + *static_cast<QMetaObject *>(this) = *d->type->d->mem; + d->type->d->names.insert(name, id); - return d->propertyOffset + id; + return d->type->d->propertyOffset + id; } void QmlOpenMetaObject::propertyRead(int) @@ -194,21 +265,25 @@ void QmlOpenMetaObject::propertyWrite(int) { } -QVariant QmlOpenMetaObject::propertyCreated(int, QMetaPropertyBuilder &) +void QmlOpenMetaObject::propertyCreated(int id, QMetaPropertyBuilder &) +{ +} + +QVariant QmlOpenMetaObject::initialValue(int) { return QVariant(); } int QmlOpenMetaObject::count() const { - return d->data.count(); + return d->type->d->names.count(); } QByteArray QmlOpenMetaObject::name(int idx) const { - Q_ASSERT(idx >= 0 && idx < d->data.count()); + Q_ASSERT(idx >= 0 && idx < d->type->d->names.count()); - return d->mob.property(idx).name(); + return d->type->d->mob.property(idx).name(); } QObject *QmlOpenMetaObject::object() const diff --git a/src/declarative/util/qmlopenmetaobject_p.h b/src/declarative/util/qmlopenmetaobject_p.h index 6045678..b33f99b 100644 --- a/src/declarative/util/qmlopenmetaobject_p.h +++ b/src/declarative/util/qmlopenmetaobject_p.h @@ -53,12 +53,27 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) +class QmlEngine; +class QmlOpenMetaObjectTypePrivate; +class QmlOpenMetaObjectType +{ +public: + QmlOpenMetaObjectType(QmlEngine *engine); + ~QmlOpenMetaObjectType(); + +private: + QmlOpenMetaObjectTypePrivate *d; + friend class QmlOpenMetaObject; + friend class QmlOpenMetaObjectPrivate; +}; + class QmlOpenMetaObjectPrivate; class QMetaPropertyBuilder; class Q_DECLARATIVE_EXPORT QmlOpenMetaObject : public QAbstractDynamicMetaObject { public: QmlOpenMetaObject(QObject *, bool = true); + QmlOpenMetaObject(QObject *, QmlOpenMetaObjectType *, bool = true); ~QmlOpenMetaObject(); QVariant value(const QByteArray &) const; @@ -71,13 +86,14 @@ public: QByteArray name(int) const; QObject *object() const; + virtual QVariant initialValue(int); protected: virtual int metaCall(QMetaObject::Call _c, int _id, void **_a); virtual int createProperty(const char *, const char *); virtual void propertyRead(int); virtual void propertyWrite(int); - virtual QVariant propertyCreated(int, QMetaPropertyBuilder &); + virtual void propertyCreated(int, QMetaPropertyBuilder &); private: int doCreateProperty(const char *); |