summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp156
-rw-r--r--src/declarative/qml/qmlpropertycache.cpp29
-rw-r--r--src/declarative/qml/qmlpropertycache_p.h2
-rw-r--r--src/declarative/util/qmlopenmetaobject.cpp115
-rw-r--r--src/declarative/util/qmlopenmetaobject_p.h22
5 files changed, 208 insertions, 116 deletions
diff --git a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp
index c6f790c..7c2159f 100644
--- a/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp
+++ b/src/declarative/graphicsitems/qmlgraphicsvisualitemmodel.cpp
@@ -241,6 +241,17 @@ QmlGraphicsVisualItemModelAttached *QmlGraphicsVisualItemModel::qmlAttachedPrope
return QmlGraphicsVisualItemModelAttached::properties(obj);
}
+//============================================================================
+
+class VDMDelegateDataType : public QmlOpenMetaObjectType
+{
+public:
+ VDMDelegateDataType(const QMetaObject *base, QmlEngine *engine) : QmlOpenMetaObjectType(base, engine) {}
+
+ void propertyCreated(int, QMetaPropertyBuilder &prop) {
+ prop.setWritable(false);
+ }
+};
class QmlGraphicsVisualDataModelParts;
class QmlGraphicsVisualDataModelData;
@@ -261,31 +272,31 @@ public:
QmlComponent *m_delegate;
QmlContext *m_context;
QList<int> m_roles;
- QHash<QString,int> m_roleNames;
+ QHash<QByteArray,int> m_roleNames;
void ensureRoles() {
if (m_roleNames.isEmpty()) {
if (m_listModelInterface) {
m_roles = m_listModelInterface->roles();
for (int ii = 0; ii < m_roles.count(); ++ii)
- m_roleNames.insert(m_listModelInterface->toString(m_roles.at(ii)), m_roles.at(ii));
+ m_roleNames.insert(m_listModelInterface->toString(m_roles.at(ii)).toUtf8(), m_roles.at(ii));
if (m_roles.count() == 1)
- m_roleNames.insert(QLatin1String("modelData"), m_roles.at(0));
+ m_roleNames.insert("modelData", m_roles.at(0));
} else if (m_abstractItemModel) {
for (QHash<int,QByteArray>::const_iterator it = m_abstractItemModel->roleNames().begin();
it != m_abstractItemModel->roleNames().end(); ++it) {
m_roles.append(it.key());
- m_roleNames.insert(QString::fromUtf8(*it), it.key());
+ m_roleNames.insert(*it, it.key());
}
if (m_roles.count() == 1)
- m_roleNames.insert(QLatin1String("modelData"), m_roles.at(0));
+ m_roleNames.insert("modelData", m_roles.at(0));
} else if (m_listAccessor) {
- m_roleNames.insert(QLatin1String("modelData"), 0);
+ m_roleNames.insert("modelData", 0);
if (m_listAccessor->type() == QmlListAccessor::Instance) {
if (QObject *object = m_listAccessor->at(0).value<QObject*>()) {
int count = object->metaObject()->propertyCount();
for (int ii = 1; ii < count; ++ii) {
const QMetaProperty &prop = object->metaObject()->property(ii);
- m_roleNames.insert(QString::fromUtf8(prop.name()), 0);
+ m_roleNames.insert(prop.name(), 0);
}
}
}
@@ -293,6 +304,18 @@ public:
}
}
+ void createMetaData() {
+ if (!m_metaDataCreated) {
+ ensureRoles();
+ QHash<QByteArray, int>::const_iterator it = m_roleNames.begin();
+ while (it != m_roleNames.end()) {
+ m_delegateDataType->createProperty(it.key());
+ ++it;
+ }
+ m_metaDataCreated = true;
+ }
+ }
+
struct ObjectRef {
ObjectRef(QObject *object=0) : obj(object), ref(1) {}
QObject *obj;
@@ -335,31 +358,33 @@ public:
}
};
+ int modelCount() const {
+ if (m_visualItemModel)
+ return m_visualItemModel->count();
+ if (m_listModelInterface)
+ return m_listModelInterface->count();
+ if (m_abstractItemModel)
+ return m_abstractItemModel->rowCount();
+ if (m_listAccessor)
+ return m_listAccessor->count();
+ return 0;
+ }
+
Cache m_cache;
QHash<QObject *, QmlPackage*> m_packaged;
QmlGraphicsVisualDataModelParts *m_parts;
friend class QmlGraphicsVisualItemParts;
- QmlOpenMetaObjectType *m_delegateDataType;
+ VDMDelegateDataType *m_delegateDataType;
friend class QmlGraphicsVisualDataModelData;
+ bool m_metaDataCreated;
+ bool m_metaDataCacheable;
QmlGraphicsVisualDataModelData *data(QObject *item);
QVariant m_modelVariant;
QmlListAccessor *m_listAccessor;
-
- int modelCount() const {
- if (m_visualItemModel)
- return m_visualItemModel->count();
- if (m_listModelInterface)
- return m_listModelInterface->count();
- if (m_abstractItemModel)
- return m_abstractItemModel->rowCount();
- if (m_listAccessor)
- return m_listAccessor->count();
- return 0;
- }
};
class QmlGraphicsVisualDataModelDataMetaObject : public QmlOpenMetaObject
@@ -368,13 +393,12 @@ public:
QmlGraphicsVisualDataModelDataMetaObject(QObject *parent, QmlOpenMetaObjectType *type)
: QmlOpenMetaObject(parent, type) {}
- virtual void propertyCreated(int, QMetaPropertyBuilder &);
virtual QVariant initialValue(int);
virtual int createProperty(const char *, const char *);
private:
friend class QmlGraphicsVisualDataModelData;
- QList<int> roles;
+ QHash<int,int> roleToProp;
};
class QmlGraphicsVisualDataModelData : public QObject
@@ -388,8 +412,7 @@ public:
int index() const;
void setIndex(int index);
- int count() const;
- int role(int) const;
+ int propForRole(int) const;
void setValue(int, const QVariant &);
Q_SIGNALS:
@@ -402,15 +425,12 @@ private:
QmlGraphicsVisualDataModelDataMetaObject *m_meta;
};
-int QmlGraphicsVisualDataModelData::count() const
-{
- return m_meta->count();
-}
-
-int QmlGraphicsVisualDataModelData::role(int id) const
+int QmlGraphicsVisualDataModelData::propForRole(int id) const
{
- Q_ASSERT(id >= 0 && id < count());
- return m_meta->roles.at(id);
+ QHash<int,int>::const_iterator it = m_meta->roleToProp.find(id);
+ if (it != m_meta->roleToProp.end())
+ return m_meta->roleToProp[id];
+ return -1;
}
void QmlGraphicsVisualDataModelData::setValue(int id, const QVariant &val)
@@ -429,28 +449,16 @@ int QmlGraphicsVisualDataModelDataMetaObject::createProperty(const char *name, c
QmlGraphicsVisualDataModelPrivate *model = QmlGraphicsVisualDataModelPrivate::get(data->m_model);
if ((!model->m_listModelInterface || !model->m_abstractItemModel) && model->m_listAccessor) {
- model->ensureRoles();
- if (model->m_roleNames.contains(QString::fromUtf8(name))) {
- return QmlOpenMetaObject::createProperty(name, type);
- } else if (model->m_listAccessor->type() == QmlListAccessor::QmlList) {
+ if (model->m_listAccessor->type() == QmlListAccessor::QmlList) {
+ model->ensureRoles();
QObject *object = model->m_listAccessor->at(data->m_index).value<QObject*>();
if (object && object->property(name).isValid())
return QmlOpenMetaObject::createProperty(name, type);
}
- } else {
- model->ensureRoles();
- QString sname = QString::fromUtf8(name);
- if (model->m_roleNames.contains(sname))
- return QmlOpenMetaObject::createProperty(name, type);
}
return -1;
}
-void QmlGraphicsVisualDataModelDataMetaObject::propertyCreated(int, QMetaPropertyBuilder &prop)
-{
- prop.setWritable(false);
-}
-
QVariant QmlGraphicsVisualDataModelDataMetaObject::initialValue(int propId)
{
QmlGraphicsVisualDataModelData *data =
@@ -459,9 +467,9 @@ QVariant QmlGraphicsVisualDataModelDataMetaObject::initialValue(int propId)
Q_ASSERT(data->m_model);
QmlGraphicsVisualDataModelPrivate *model = QmlGraphicsVisualDataModelPrivate::get(data->m_model);
- QString strName = QString::fromUtf8(name(propId));
+ QByteArray propName = name(propId);
if ((!model->m_listModelInterface || !model->m_abstractItemModel) && model->m_listAccessor) {
- if (strName == QLatin1String("modelData")) {
+ if (propName == "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
@@ -470,20 +478,21 @@ QVariant QmlGraphicsVisualDataModelDataMetaObject::initialValue(int propId)
} else {
// return any property of a single object instance.
QObject *object = model->m_listAccessor->at(data->m_index).value<QObject*>();
- return object->property(name(propId));
+ return object->property(propName);
}
} else if (model->m_listModelInterface) {
model->ensureRoles();
- QHash<QString,int>::const_iterator it = model->m_roleNames.find(strName);
+ QHash<QByteArray,int>::const_iterator it = model->m_roleNames.find(propName);
if (it != model->m_roleNames.end()) {
- roles.append(*it);
+ roleToProp.insert(*it, propId);
QHash<int,QVariant> values = model->m_listModelInterface->data(data->m_index, QList<int>() << *it);
if (values.isEmpty())
return QVariant();
else
return values.value(*it);
- } else if (model->m_roles.count() == 1 && strName == QLatin1String("modelData")) {
+ } else if (model->m_roles.count() == 1 && propName == "modelData") {
//for compatability with other lists, assign modelData if there is only a single role
+ roleToProp.insert(model->m_roles.first(), propId);
QHash<int,QVariant> values = model->m_listModelInterface->data(data->m_index, QList<int>() << model->m_roles.first());
if (values.isEmpty())
return QVariant();
@@ -492,9 +501,9 @@ QVariant QmlGraphicsVisualDataModelDataMetaObject::initialValue(int propId)
}
} else if (model->m_abstractItemModel) {
model->ensureRoles();
- QHash<QString,int>::const_iterator it = model->m_roleNames.find(strName);
+ QHash<QByteArray,int>::const_iterator it = model->m_roleNames.find(propName);
if (it != model->m_roleNames.end()) {
- roles.append(*it);
+ roleToProp.insert(*it, propId);
QModelIndex index = model->m_abstractItemModel->index(data->m_index, 0);
return model->m_abstractItemModel->data(index, *it);
}
@@ -508,6 +517,12 @@ QmlGraphicsVisualDataModelData::QmlGraphicsVisualDataModelData(int index,
: m_index(index), m_model(model),
m_meta(new QmlGraphicsVisualDataModelDataMetaObject(this, QmlGraphicsVisualDataModelPrivate::get(model)->m_delegateDataType))
{
+ QmlGraphicsVisualDataModelPrivate *modelPriv = QmlGraphicsVisualDataModelPrivate::get(model);
+ if (modelPriv->m_metaDataCacheable) {
+ if (!modelPriv->m_metaDataCreated)
+ modelPriv->createMetaData();
+ m_meta->setCached(true);
+ }
}
QmlGraphicsVisualDataModelData::~QmlGraphicsVisualDataModelData()
@@ -526,6 +541,8 @@ void QmlGraphicsVisualDataModelData::setIndex(int index)
emit indexChanged();
}
+//---------------------------------------------------------------------------
+
class QmlGraphicsVisualDataModelPartsMetaObject : public QmlOpenMetaObject
{
public:
@@ -571,7 +588,8 @@ 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_delegateDataType(0), m_listAccessor(0)
+, m_context(ctxt), m_parts(0), m_delegateDataType(0), m_metaDataCreated(false)
+, m_metaDataCacheable(false), m_listAccessor(0)
{
}
@@ -583,6 +601,8 @@ QmlGraphicsVisualDataModelData *QmlGraphicsVisualDataModelPrivate::data(QObject
return dataItem;
}
+//---------------------------------------------------------------------------
+
QmlGraphicsVisualDataModel::QmlGraphicsVisualDataModel()
: QmlGraphicsVisualModel(*(new QmlGraphicsVisualDataModelPrivate(0)))
{
@@ -598,6 +618,8 @@ QmlGraphicsVisualDataModel::~QmlGraphicsVisualDataModel()
Q_D(QmlGraphicsVisualDataModel);
if (d->m_listAccessor)
delete d->m_listAccessor;
+ if (d->m_delegateDataType)
+ d->m_delegateDataType->release();
}
QVariant QmlGraphicsVisualDataModel::model() const
@@ -648,8 +670,11 @@ 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?d->m_context->engine():qmlEngine(this));
+ if (d->m_delegateDataType)
+ d->m_delegateDataType->release();
+ d->m_metaDataCreated = 0;
+ d->m_metaDataCacheable = false;
+ d->m_delegateDataType = new VDMDelegateDataType(&QmlGraphicsVisualDataModelData::staticMetaObject, d->m_context?d->m_context->engine():qmlEngine(this));
QObject *object = qvariant_cast<QObject *>(model);
if (object && (d->m_listModelInterface = qobject_cast<QListModelInterface *>(object))) {
@@ -661,6 +686,7 @@ void QmlGraphicsVisualDataModel::setModel(const QVariant &model)
this, SLOT(_q_itemsRemoved(int,int)));
QObject::connect(d->m_listModelInterface, SIGNAL(itemsMoved(int,int,int)),
this, SLOT(_q_itemsMoved(int,int,int)));
+ d->m_metaDataCacheable = true;
if (d->m_delegate && d->m_listModelInterface->count())
emit itemsInserted(0, d->m_listModelInterface->count());
return;
@@ -673,6 +699,7 @@ void QmlGraphicsVisualDataModel::setModel(const QVariant &model)
this, SLOT(_q_dataChanged(const QModelIndex&,const QModelIndex&)));
QObject::connect(d->m_abstractItemModel, SIGNAL(rowsMoved(const QModelIndex&,int,int,const QModelIndex&,int)),
this, SLOT(_q_rowsMoved(const QModelIndex&,int,int,const QModelIndex&,int)));
+ d->m_metaDataCacheable = true;
return;
}
if ((d->m_visualItemModel = qvariant_cast<QmlGraphicsVisualDataModel *>(model))) {
@@ -690,6 +717,8 @@ void QmlGraphicsVisualDataModel::setModel(const QVariant &model)
}
d->m_listAccessor = new QmlListAccessor;
d->m_listAccessor->setList(model, d->m_context?d->m_context->engine():qmlEngine(this));
+ if (d->m_listAccessor->type() != QmlListAccessor::QmlList)
+ d->m_metaDataCacheable = true;
if (d->m_delegate && d->modelCount()) {
emit itemsInserted(0, d->modelCount());
emit countChanged();
@@ -903,20 +932,19 @@ void QmlGraphicsVisualDataModel::_q_itemsChanged(int index, int count,
if (QObject *item = d->m_cache.item(ii)) {
QmlGraphicsVisualDataModelData *data = d->data(item);
- for (int prop = 0; prop < data->count(); ++prop) {
-
- int role = data->role(prop);
- if (roles.contains(role)) {
+ for (int roleIdx = 0; roleIdx < roles.count(); ++roleIdx) {
+ int role = roles.at(roleIdx);
+ int propId = data->propForRole(role);
+ if (propId != -1) {
if (d->m_listModelInterface) {
- data->setValue(prop, d->m_listModelInterface->data(ii, QList<int>() << role).value(role));
+ data->setValue(propId, d->m_listModelInterface->data(ii, QList<int>() << role).value(role));
} else if (d->m_abstractItemModel) {
QModelIndex index = d->m_abstractItemModel->index(ii, 0);
- data->setValue(prop, d->m_abstractItemModel->data(index, role));
+ data->setValue(propId, d->m_abstractItemModel->data(index, role));
}
}
}
}
-
}
}
diff --git a/src/declarative/qml/qmlpropertycache.cpp b/src/declarative/qml/qmlpropertycache.cpp
index bad8ad8..6ba6028 100644
--- a/src/declarative/qml/qmlpropertycache.cpp
+++ b/src/declarative/qml/qmlpropertycache.cpp
@@ -43,6 +43,7 @@
#include "qmlengine_p.h"
#include "qmlbinding.h"
+#include "qdebug.h"
QT_BEGIN_NAMESPACE
@@ -119,7 +120,6 @@ QmlPropertyCache::Data QmlPropertyCache::create(const QMetaObject *metaObject,
Q_ASSERT(metaObject);
QmlPropertyCache::Data rv;
-
int idx = metaObject->indexOfProperty(property.toUtf8());
if (idx != -1) {
rv.load(metaObject->property(idx));
@@ -151,13 +151,22 @@ QmlPropertyCache *QmlPropertyCache::create(QmlEngine *engine, const QMetaObject
Q_ASSERT(metaObject);
QmlPropertyCache *cache = new QmlPropertyCache(engine);
+ cache->update(engine, metaObject);
+ return cache;
+}
+void QmlPropertyCache::update(QmlEngine *engine, const QMetaObject *metaObject)
+{
+ Q_ASSERT(engine);
+ Q_ASSERT(metaObject);
QmlEnginePrivate *enginePriv = QmlEnginePrivate::get(engine);
+ clear();
+
// ### The properties/methods should probably be spliced on a per-metaobject basis
int propCount = metaObject->propertyCount();
- cache->indexCache.resize(propCount);
+ indexCache.resize(propCount);
for (int ii = propCount - 1; ii >= 0; --ii) {
QMetaProperty p = metaObject->property(ii);
QString propName = QString::fromUtf8(p.name());
@@ -167,13 +176,13 @@ QmlPropertyCache *QmlPropertyCache::create(QmlEngine *engine, const QMetaObject
data->load(p);
- cache->indexCache[ii] = data;
+ indexCache[ii] = data;
- if (cache->stringCache.contains(propName))
+ if (stringCache.contains(propName))
continue;
- cache->stringCache.insert(propName, data);
- cache->identifierCache.insert(data->identifier.identifier, data);
+ stringCache.insert(propName, data);
+ identifierCache.insert(data->identifier.identifier, data);
data->addref();
data->addref();
}
@@ -187,7 +196,7 @@ QmlPropertyCache *QmlPropertyCache::create(QmlEngine *engine, const QMetaObject
Q_ASSERT(parenIdx != -1);
methodName = methodName.left(parenIdx);
- if (cache->stringCache.contains(methodName))
+ if (stringCache.contains(methodName))
continue;
RData *data = new RData;
@@ -195,12 +204,10 @@ QmlPropertyCache *QmlPropertyCache::create(QmlEngine *engine, const QMetaObject
data->load(m);
- cache->stringCache.insert(methodName, data);
- cache->identifierCache.insert(data->identifier.identifier, data);
+ stringCache.insert(methodName, data);
+ identifierCache.insert(data->identifier.identifier, data);
data->addref();
}
-
- return cache;
}
QmlPropertyCache::Data *
diff --git a/src/declarative/qml/qmlpropertycache_p.h b/src/declarative/qml/qmlpropertycache_p.h
index 7cee606..613f4dd 100644
--- a/src/declarative/qml/qmlpropertycache_p.h
+++ b/src/declarative/qml/qmlpropertycache_p.h
@@ -110,6 +110,8 @@ public:
int valueTypePropType; // The QVariant::Type of access property on the value type wrapper
};
+ void update(QmlEngine *, const QMetaObject *);
+
static QmlPropertyCache *create(QmlEngine *, const QMetaObject *);
static Data create(const QMetaObject *, const QString &);
diff --git a/src/declarative/util/qmlopenmetaobject.cpp b/src/declarative/util/qmlopenmetaobject.cpp
index 473d9d9..e66a3e7 100644
--- a/src/declarative/util/qmlopenmetaobject.cpp
+++ b/src/declarative/util/qmlopenmetaobject.cpp
@@ -43,7 +43,7 @@
#include "qmlpropertycache_p.h"
#include "qmldeclarativedata_p.h"
#include <qmetaobjectbuilder_p.h>
-#include <QDebug>
+#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -51,39 +51,69 @@ QT_BEGIN_NAMESPACE
class QmlOpenMetaObjectTypePrivate
{
public:
- QmlOpenMetaObjectTypePrivate() : mem(0), engine(0) {}
+ QmlOpenMetaObjectTypePrivate() : mem(0), cache(0), engine(0) {}
- void init(QObject *obj);
+ void init(const QMetaObject *metaObj);
int propertyOffset;
int signalOffset;
QHash<QByteArray, int> names;
QMetaObjectBuilder mob;
QMetaObject *mem;
+ QmlPropertyCache *cache;
QmlEngine *engine;
+ QSet<QmlOpenMetaObject*> referers;
};
-QmlOpenMetaObjectType::QmlOpenMetaObjectType(QmlEngine *engine)
+QmlOpenMetaObjectType::QmlOpenMetaObjectType(const QMetaObject *base, QmlEngine *engine)
: d(new QmlOpenMetaObjectTypePrivate)
{
d->engine = engine;
+ d->init(base);
}
QmlOpenMetaObjectType::~QmlOpenMetaObjectType()
{
+ if (d->mem)
+ qFree(d->mem);
+ delete d;
+}
+
+int QmlOpenMetaObjectType::createProperty(const QByteArray &name)
+{
+ int id = d->mob.propertyCount();
+ d->mob.addSignal("__" + QByteArray::number(id) + "()");
+ QMetaPropertyBuilder build = d->mob.addProperty(name, "QVariant", id);
+ build.setDynamic(true);
+ propertyCreated(id, build);
qFree(d->mem);
+ d->mem = d->mob.toMetaObject();
+ d->names.insert(name, id);
+ QSet<QmlOpenMetaObject*>::iterator it = d->referers.begin();
+ while (it != d->referers.end()) {
+ QmlOpenMetaObject *omo = *it;
+ *static_cast<QMetaObject *>(omo) = *d->mem;
+ if (d->cache)
+ d->cache->update(d->engine, omo);
+ ++it;
+ }
+
+ return d->propertyOffset + id;
}
-void QmlOpenMetaObjectTypePrivate::init(QObject *obj)
+void QmlOpenMetaObjectType::propertyCreated(int id, QMetaPropertyBuilder &builder)
+{
+ if (d->referers.count())
+ (*d->referers.begin())->propertyCreated(id, builder);
+}
+
+void QmlOpenMetaObjectTypePrivate::init(const QMetaObject *metaObj)
{
if (!mem) {
- mob.setSuperClass(obj->metaObject());
- mob.setClassName(obj->metaObject()->className());
+ mob.setSuperClass(metaObj);
+ mob.setClassName(metaObj->className());
mob.setFlags(QMetaObjectBuilder::DynamicMetaObject);
- QObjectPrivate *op = QObjectPrivate::get(obj);
- if (op->metaObject)
- mob.setSuperClass(op->metaObject);
mem = mob.toMetaObject();
propertyOffset = mem->propertyOffset();
@@ -91,10 +121,13 @@ void QmlOpenMetaObjectTypePrivate::init(QObject *obj)
}
}
+//----------------------------------------------------------------------------
+
class QmlOpenMetaObjectPrivate
{
public:
- QmlOpenMetaObjectPrivate(QmlOpenMetaObject *_q) : q(_q), parent(0), type(0), ownType(false) {}
+ QmlOpenMetaObjectPrivate(QmlOpenMetaObject *_q)
+ : q(_q), parent(0), type(0), cacheProperties(false) {}
inline QVariant &getData(int idx) {
while (data.count() <= idx)
@@ -121,7 +154,7 @@ public:
QList<QPair<QVariant, bool> > data;
QObject *object;
QmlOpenMetaObjectType *type;
- bool ownType;
+ bool cacheProperties;
};
QmlOpenMetaObject::QmlOpenMetaObject(QObject *obj, bool automatic)
@@ -130,9 +163,8 @@ QmlOpenMetaObject::QmlOpenMetaObject(QObject *obj, bool automatic)
d->autoCreate = automatic;
d->object = obj;
- d->type = new QmlOpenMetaObjectType(0);
- d->ownType = true;
- d->type->d->init(obj);
+ d->type = new QmlOpenMetaObjectType(obj->metaObject(), 0);
+ d->type->d->referers.insert(this);
QObjectPrivate *op = QObjectPrivate::get(obj);
*static_cast<QMetaObject *>(this) = *d->type->d->mem;
@@ -146,7 +178,8 @@ QmlOpenMetaObject::QmlOpenMetaObject(QObject *obj, QmlOpenMetaObjectType *type,
d->object = obj;
d->type = type;
- d->type->d->init(obj);
+ d->type->addref();
+ d->type->d->referers.insert(this);
QObjectPrivate *op = QObjectPrivate::get(obj);
*static_cast<QMetaObject *>(this) = *d->type->d->mem;
@@ -157,11 +190,16 @@ QmlOpenMetaObject::~QmlOpenMetaObject()
{
if (d->parent)
delete d->parent;
- if (d->ownType)
- delete d->type;
+ d->type->d->referers.remove(this);
+ d->type->release();
delete d;
}
+QmlOpenMetaObjectType *QmlOpenMetaObject::type() const
+{
+ return d->type;
+}
+
int QmlOpenMetaObject::metaCall(QMetaObject::Call c, int id, void **a)
{
if (( c == QMetaObject::ReadProperty || c == QMetaObject::WriteProperty)
@@ -220,7 +258,7 @@ void QmlOpenMetaObject::setValue(const QByteArray &name, const QVariant &val)
int id = -1;
if (iter == d->type->d->names.end()) {
- id = doCreateProperty(name.constData()) - d->type->d->propertyOffset;
+ id = d->type->createProperty(name.constData()) - d->type->d->propertyOffset;
} else {
id = *iter;
}
@@ -233,29 +271,34 @@ void QmlOpenMetaObject::setValue(const QByteArray &name, const QVariant &val)
activate(d->object, id + d->type->d->signalOffset, 0);
}
+void QmlOpenMetaObject::setCached(bool c)
+{
+ if (c == d->cacheProperties || !d->type->d->engine)
+ return;
+
+ d->cacheProperties = c;
+
+ QmlDeclarativeData *qmldata = QmlDeclarativeData::get(d->object, true);
+ if (d->cacheProperties) {
+ if (!d->type->d->cache)
+ d->type->d->cache = QmlPropertyCache::create(d->type->d->engine, this);
+ qmldata->propertyCache = d->type->d->cache;
+ d->type->d->cache->addref();
+ } else {
+ if (d->type->d->cache)
+ d->type->d->cache->release();
+ qmldata->propertyCache = 0;
+ }
+}
+
int QmlOpenMetaObject::createProperty(const char *name, const char *)
{
if (d->autoCreate)
- return doCreateProperty(name);
+ return d->type->createProperty(name);
else
return -1;
}
-int QmlOpenMetaObject::doCreateProperty(const char *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);
- 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->type->d->propertyOffset + id;
-}
-
void QmlOpenMetaObject::propertyRead(int)
{
}
@@ -264,7 +307,7 @@ void QmlOpenMetaObject::propertyWrite(int)
{
}
-void QmlOpenMetaObject::propertyCreated(int id, QMetaPropertyBuilder &)
+void QmlOpenMetaObject::propertyCreated(int, QMetaPropertyBuilder &)
{
}
diff --git a/src/declarative/util/qmlopenmetaobject_p.h b/src/declarative/util/qmlopenmetaobject_p.h
index b33f99b..73e3a98 100644
--- a/src/declarative/util/qmlopenmetaobject_p.h
+++ b/src/declarative/util/qmlopenmetaobject_p.h
@@ -42,6 +42,7 @@
#ifndef QMLOPENMETAOBJECT_H
#define QMLOPENMETAOBJECT_H
+#include <qmlrefcount_p.h>
#include <QtCore/QMetaObject>
#include <QtCore/QObject>
@@ -54,13 +55,19 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QmlEngine;
+class QMetaPropertyBuilder;
class QmlOpenMetaObjectTypePrivate;
-class QmlOpenMetaObjectType
+class QmlOpenMetaObjectType : public QmlRefCount
{
public:
- QmlOpenMetaObjectType(QmlEngine *engine);
+ QmlOpenMetaObjectType(const QMetaObject *base, QmlEngine *engine);
~QmlOpenMetaObjectType();
+ int createProperty(const QByteArray &name);
+
+protected:
+ virtual void propertyCreated(int, QMetaPropertyBuilder &);
+
private:
QmlOpenMetaObjectTypePrivate *d;
friend class QmlOpenMetaObject;
@@ -68,7 +75,6 @@ private:
};
class QmlOpenMetaObjectPrivate;
-class QMetaPropertyBuilder;
class Q_DECLARATIVE_EXPORT QmlOpenMetaObject : public QAbstractDynamicMetaObject
{
public:
@@ -87,6 +93,13 @@ public:
QObject *object() const;
virtual QVariant initialValue(int);
+
+ // Be careful - once setCached(true) is called createProperty() is no
+ // longer automatically called for new properties.
+ void setCached(bool);
+
+ QmlOpenMetaObjectType *type() const;
+
protected:
virtual int metaCall(QMetaObject::Call _c, int _id, void **_a);
virtual int createProperty(const char *, const char *);
@@ -96,9 +109,8 @@ protected:
virtual void propertyCreated(int, QMetaPropertyBuilder &);
private:
- int doCreateProperty(const char *);
-
QmlOpenMetaObjectPrivate *d;
+ friend class QmlOpenMetaObjectType;
};
QT_END_NAMESPACE