forked from qt-creator/qt-creator
Support for QQmlVMEMetaObject and QmlPropertyCache
We have to derive NodeInstanceMetaObject from QQmlVMEMetaObject to support e. g. alias properties. The QmlEngine uses QQmlVMEMetaObject to resolve alias properties. Also we have to invalidate/recreate the QmlPropertyCache if we add dynamic properties. Change-Id: Id52dd8b380eadeb6f74b5171168f2f70c16be118 Reviewed-by: Thomas Hartmann <Thomas.Hartmann@digia.com>
This commit is contained in:
@@ -36,23 +36,167 @@
|
|||||||
#include <qnumeric.h>
|
#include <qnumeric.h>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include <private/qqmlengine_p.h>
|
||||||
|
#include <private/qqmlpropertycache_p.h>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
NodeInstanceMetaObject::NodeInstanceMetaObject(const ObjectNodeInstance::Pointer &nodeInstance, QQmlEngine *engine)
|
static QHash<QDynamicMetaObjectData *, bool> nodeInstanceMetaObjectList;
|
||||||
: QQmlOpenMetaObject(nodeInstance->object(), new QQmlOpenMetaObjectType(nodeInstance->object()->metaObject(), engine), true),
|
|
||||||
m_nodeInstance(nodeInstance),
|
struct MetaPropertyData {
|
||||||
m_context(nodeInstance->isRootNodeInstance() ? nodeInstance->context() : 0)
|
inline QPair<QVariant, bool> &getDataRef(int idx) {
|
||||||
|
while (m_data.count() <= idx)
|
||||||
|
m_data << QPair<QVariant, bool>(QVariant(), false);
|
||||||
|
return m_data[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline QVariant &getData(int idx) {
|
||||||
|
QPair<QVariant, bool> &prop = getDataRef(idx);
|
||||||
|
if (!prop.second) {
|
||||||
|
prop.first = QVariant();
|
||||||
|
prop.second = true;
|
||||||
|
}
|
||||||
|
return prop.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool hasData(int idx) const {
|
||||||
|
if (idx >= m_data.count())
|
||||||
|
return false;
|
||||||
|
return m_data[idx].second;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int count() { return m_data.count(); }
|
||||||
|
|
||||||
|
QList<QPair<QVariant, bool> > m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool constructedMetaData(const QQmlVMEMetaData* data)
|
||||||
{
|
{
|
||||||
setCached(false);
|
return data->varPropertyCount == 0
|
||||||
|
&& data->propertyCount == 0
|
||||||
|
&& data->aliasCount == 0
|
||||||
|
&& data->signalCount == 0
|
||||||
|
&& data->methodCount == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QQmlVMEMetaData* fakeMetaData()
|
||||||
|
{
|
||||||
|
QQmlVMEMetaData* data = new QQmlVMEMetaData;
|
||||||
|
data->varPropertyCount = 0;
|
||||||
|
data->propertyCount = 0;
|
||||||
|
data->aliasCount = 0;
|
||||||
|
data->signalCount = 0;
|
||||||
|
data->methodCount = 0;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const QQmlVMEMetaData* vMEMetaDataForObject(QObject *object)
|
||||||
|
{
|
||||||
|
QQmlVMEMetaObject *metaObject = QQmlVMEMetaObject::get(object);
|
||||||
|
if (metaObject)
|
||||||
|
return metaObject->metaData;
|
||||||
|
|
||||||
|
return fakeMetaData();
|
||||||
|
}
|
||||||
|
|
||||||
|
static QQmlPropertyCache *cacheForObject(QObject *object, QQmlEngine *engine)
|
||||||
|
{
|
||||||
|
QQmlVMEMetaObject *metaObject = QQmlVMEMetaObject::get(object);
|
||||||
|
if (metaObject)
|
||||||
|
return metaObject->cache;
|
||||||
|
|
||||||
|
return QQmlEnginePrivate::get(engine)->cache(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
static QAbstractDynamicMetaObject *abstractDynamicMetaObject(QObject *object)
|
||||||
|
{
|
||||||
|
QObjectPrivate *op = QObjectPrivate::get(object);
|
||||||
|
if (op->metaObject)
|
||||||
|
return static_cast<QAbstractDynamicMetaObject *>(op->metaObject);
|
||||||
|
return const_cast<QAbstractDynamicMetaObject *>(static_cast<const QAbstractDynamicMetaObject *>(object->metaObject()));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
NodeInstanceMetaObject *NodeInstanceMetaObject::createNodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QQmlEngine *engine)
|
||||||
|
{
|
||||||
|
//Avoid setting up multiple NodeInstanceMetaObjects on the same QObject
|
||||||
|
QObjectPrivate *op = QObjectPrivate::get(nodeInstance->object());
|
||||||
|
QDynamicMetaObjectData *parent = op->metaObject;
|
||||||
|
if (nodeInstanceMetaObjectList.contains(parent))
|
||||||
|
return static_cast<NodeInstanceMetaObject *>(parent);
|
||||||
|
|
||||||
|
return new NodeInstanceMetaObject(nodeInstance, engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeInstanceMetaObject *NodeInstanceMetaObject::createNodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix, QQmlEngine *engine)
|
||||||
|
{
|
||||||
|
//Avoid setting up multiple NodeInstanceMetaObjects on the same QObject
|
||||||
|
QObjectPrivate *op = QObjectPrivate::get(nodeInstance->object());
|
||||||
|
QDynamicMetaObjectData *parent = op->metaObject;
|
||||||
|
if (nodeInstanceMetaObjectList.contains(parent))
|
||||||
|
return static_cast<NodeInstanceMetaObject *>(parent);
|
||||||
|
|
||||||
|
return new NodeInstanceMetaObject(nodeInstance, object, prefix, engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeInstanceMetaObject::init(QObject *object, QQmlEngine *engine)
|
||||||
|
{
|
||||||
|
//Creating QQmlOpenMetaObjectType
|
||||||
|
m_type = new QQmlOpenMetaObjectType(metaObjectParent(), engine);
|
||||||
|
m_type->addref();
|
||||||
|
//Assigning type to this
|
||||||
|
copyTypeMetaObject();
|
||||||
|
|
||||||
|
//Assign this to object
|
||||||
|
QObjectPrivate *op = QObjectPrivate::get(object);
|
||||||
|
op->metaObject = this;
|
||||||
|
|
||||||
|
//create cache
|
||||||
|
cache = m_cache = QQmlEnginePrivate::get(engine)->cache(this);
|
||||||
|
|
||||||
|
//If our parent is not a VMEMetaObject we just se the flag to false again
|
||||||
|
if (constructedMetaData(metaData))
|
||||||
|
QQmlData::get(object)->hasVMEMetaObject = false;
|
||||||
|
|
||||||
|
nodeInstanceMetaObjectList.insert(this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeInstanceMetaObject::NodeInstanceMetaObject(const ObjectNodeInstance::Pointer &nodeInstance, QQmlEngine *engine)
|
||||||
|
: QQmlVMEMetaObject(nodeInstance->object(), cacheForObject(nodeInstance->object(), engine), vMEMetaDataForObject(nodeInstance->object())),
|
||||||
|
m_nodeInstance(nodeInstance),
|
||||||
|
m_context(engine->contextForObject(nodeInstance->object())),
|
||||||
|
m_data(new MetaPropertyData),
|
||||||
|
m_cache(0)
|
||||||
|
{
|
||||||
|
init(nodeInstance->object(), engine);
|
||||||
|
|
||||||
|
QQmlData *ddata = QQmlData::get(nodeInstance->object(), false);
|
||||||
|
|
||||||
|
//Assign cache to object
|
||||||
|
if (ddata && ddata->propertyCache) {
|
||||||
|
ddata->propertyCache = m_cache;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeInstanceMetaObject::NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix, QQmlEngine *engine)
|
NodeInstanceMetaObject::NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix, QQmlEngine *engine)
|
||||||
: QQmlOpenMetaObject(object, new QQmlOpenMetaObjectType(object->metaObject(), engine), true),
|
: QQmlVMEMetaObject(object, cacheForObject(object, engine), vMEMetaDataForObject(object)),
|
||||||
m_nodeInstance(nodeInstance),
|
m_nodeInstance(nodeInstance),
|
||||||
m_prefix(prefix)
|
m_context(engine->contextForObject(object)),
|
||||||
|
m_prefix(prefix),
|
||||||
|
|
||||||
|
m_data(new MetaPropertyData),
|
||||||
|
m_cache(0)
|
||||||
{
|
{
|
||||||
setCached(false);
|
init(object, engine);
|
||||||
|
}
|
||||||
|
|
||||||
|
NodeInstanceMetaObject::~NodeInstanceMetaObject()
|
||||||
|
{
|
||||||
|
m_type->release();
|
||||||
|
|
||||||
|
nodeInstanceMetaObjectList.remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeInstanceMetaObject::createNewProperty(const QString &name)
|
void NodeInstanceMetaObject::createNewProperty(const QString &name)
|
||||||
@@ -60,55 +204,114 @@ void NodeInstanceMetaObject::createNewProperty(const QString &name)
|
|||||||
int id = createProperty(name.toLatin1(), 0);
|
int id = createProperty(name.toLatin1(), 0);
|
||||||
setValue(id, QVariant());
|
setValue(id, QVariant());
|
||||||
Q_ASSERT(id >= 0);
|
Q_ASSERT(id >= 0);
|
||||||
Q_UNUSED(id)
|
Q_UNUSED(id);
|
||||||
|
|
||||||
|
|
||||||
|
//Updating cache
|
||||||
|
QQmlEnginePrivate::get(m_context->engine())->cache(this)->invalidate(m_context->engine(), this);
|
||||||
|
|
||||||
|
QQmlProperty property(myObject(), name, m_context);
|
||||||
|
Q_ASSERT(property.isValid());
|
||||||
|
}
|
||||||
|
|
||||||
|
int NodeInstanceMetaObject::createProperty(const char *name, const char *)
|
||||||
|
{
|
||||||
|
int id = m_type->createProperty(name);
|
||||||
|
copyTypeMetaObject();
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeInstanceMetaObject::setValue(int id, const QVariant &value)
|
||||||
|
{
|
||||||
|
QPair<QVariant, bool> &prop = m_data->getDataRef(id);
|
||||||
|
prop.first = propertyWriteValue(id, value);
|
||||||
|
prop.second = true;
|
||||||
|
QMetaObject::activate(myObject(), id + m_type->signalOffset(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant NodeInstanceMetaObject::propertyWriteValue(int, const QVariant &value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int NodeInstanceMetaObject::openMetaCall(QMetaObject::Call call, int id, void **a)
|
||||||
|
{
|
||||||
|
if ((call == QMetaObject::ReadProperty || call == QMetaObject::WriteProperty)
|
||||||
|
&& id >= m_type->propertyOffset()) {
|
||||||
|
int propId = id - m_type->propertyOffset();
|
||||||
|
if (call == QMetaObject::ReadProperty) {
|
||||||
|
//propertyRead(propId);
|
||||||
|
*reinterpret_cast<QVariant *>(a[0]) = m_data->getData(propId);
|
||||||
|
} else if (call == QMetaObject::WriteProperty) {
|
||||||
|
if (propId <= m_data->count() || m_data->m_data[propId].first != *reinterpret_cast<QVariant *>(a[0])) {
|
||||||
|
//propertyWrite(propId);
|
||||||
|
QPair<QVariant, bool> &prop = m_data->getDataRef(propId);
|
||||||
|
prop.first = propertyWriteValue(propId, *reinterpret_cast<QVariant *>(a[0]));
|
||||||
|
prop.second = true;
|
||||||
|
//propertyWritten(propId);
|
||||||
|
activate(myObject(), m_type->signalOffset() + propId, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
QAbstractDynamicMetaObject *directParent = parent();
|
||||||
|
if (directParent)
|
||||||
|
return directParent->metaCall(call, id, a);
|
||||||
|
else
|
||||||
|
return myObject()->qt_metacall(call, id, a);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int NodeInstanceMetaObject::metaCall(QMetaObject::Call call, int id, void **a)
|
int NodeInstanceMetaObject::metaCall(QMetaObject::Call call, int id, void **a)
|
||||||
{
|
{
|
||||||
int metaCallReturnValue = -1;
|
int metaCallReturnValue = -1;
|
||||||
|
|
||||||
|
const QMetaProperty propertyById = QQmlVMEMetaObject::property(id);
|
||||||
|
|
||||||
if (call == QMetaObject::WriteProperty
|
if (call == QMetaObject::WriteProperty
|
||||||
&& property(id).userType() == QMetaType::QVariant
|
&& propertyById.userType() == QMetaType::QVariant
|
||||||
&& reinterpret_cast<QVariant *>(a[0])->type() == QVariant::Double
|
&& reinterpret_cast<QVariant *>(a[0])->type() == QVariant::Double
|
||||||
&& qIsNaN(reinterpret_cast<QVariant *>(a[0])->toDouble())) {
|
&& qIsNaN(reinterpret_cast<QVariant *>(a[0])->toDouble())) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call == QMetaObject::WriteProperty
|
if (call == QMetaObject::WriteProperty
|
||||||
&& property(id).userType() == QMetaType::Double
|
&& propertyById.userType() == QMetaType::Double
|
||||||
&& qIsNaN(*reinterpret_cast<double*>(a[0]))) {
|
&& qIsNaN(*reinterpret_cast<double*>(a[0]))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (call == QMetaObject::WriteProperty
|
if (call == QMetaObject::WriteProperty
|
||||||
&& property(id).userType() == QMetaType::Float
|
&& propertyById.userType() == QMetaType::Float
|
||||||
&& qIsNaN(*reinterpret_cast<float*>(a[0]))) {
|
&& qIsNaN(*reinterpret_cast<float*>(a[0]))) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant oldValue;
|
QVariant oldValue;
|
||||||
|
|
||||||
if (call == QMetaObject::WriteProperty && !property(id).hasNotifySignal())
|
if (call == QMetaObject::WriteProperty && !propertyById.hasNotifySignal())
|
||||||
{
|
{
|
||||||
oldValue = property(id).read(object());
|
oldValue = propertyById.read(myObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectNodeInstance::Pointer objectNodeInstance = m_nodeInstance.toStrongRef();
|
ObjectNodeInstance::Pointer objectNodeInstance = m_nodeInstance.toStrongRef();
|
||||||
|
|
||||||
if (parent() && id < parent()->propertyOffset()) {
|
QAbstractDynamicMetaObject *directParent = parent();
|
||||||
metaCallReturnValue = parent()->metaCall(call, id, a);
|
if (directParent && id < directParent->propertyOffset()) {
|
||||||
|
metaCallReturnValue = directParent->metaCall(call, id, a);
|
||||||
} else {
|
} else {
|
||||||
metaCallReturnValue = QQmlOpenMetaObject::metaCall(call, id, a);
|
openMetaCall(call, id, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((call == QMetaObject::WriteProperty || call == QMetaObject::ReadProperty) && metaCallReturnValue < 0) {
|
if ((call == QMetaObject::WriteProperty || call == QMetaObject::ReadProperty) && metaCallReturnValue < 0) {
|
||||||
if (objectNodeInstance
|
if (objectNodeInstance
|
||||||
&& objectNodeInstance->nodeInstanceServer()
|
&& objectNodeInstance->nodeInstanceServer()
|
||||||
&& objectNodeInstance->nodeInstanceServer()->dummyContextObject()
|
&& objectNodeInstance->nodeInstanceServer()->dummyContextObject()
|
||||||
&& !(objectNodeInstance && !objectNodeInstance->isRootNodeInstance() && property(id).name() == QLatin1String("parent"))) {
|
&& !(objectNodeInstance && !objectNodeInstance->isRootNodeInstance()
|
||||||
|
&& property(id).name() == QLatin1String("parent"))) {
|
||||||
|
|
||||||
QObject *contextDummyObject = objectNodeInstance->nodeInstanceServer()->dummyContextObject();
|
QObject *contextDummyObject = objectNodeInstance->nodeInstanceServer()->dummyContextObject();
|
||||||
int properyIndex = contextDummyObject->metaObject()->indexOfProperty(property(id).name());
|
int properyIndex = contextDummyObject->metaObject()->indexOfProperty(propertyById.name());
|
||||||
if (properyIndex >= 0)
|
if (properyIndex >= 0)
|
||||||
metaCallReturnValue = contextDummyObject->qt_metacall(call, properyIndex, a);
|
metaCallReturnValue = contextDummyObject->qt_metacall(call, properyIndex, a);
|
||||||
}
|
}
|
||||||
@@ -116,8 +319,8 @@ int NodeInstanceMetaObject::metaCall(QMetaObject::Call call, int id, void **a)
|
|||||||
|
|
||||||
if (metaCallReturnValue >= 0
|
if (metaCallReturnValue >= 0
|
||||||
&& call == QMetaObject::WriteProperty
|
&& call == QMetaObject::WriteProperty
|
||||||
&& !property(id).hasNotifySignal()
|
&& !propertyById.hasNotifySignal()
|
||||||
&& oldValue != property(id).read(object()))
|
&& oldValue != propertyById.read(myObject()))
|
||||||
notifyPropertyChange(id);
|
notifyPropertyChange(id);
|
||||||
|
|
||||||
return metaCallReturnValue;
|
return metaCallReturnValue;
|
||||||
@@ -126,15 +329,31 @@ int NodeInstanceMetaObject::metaCall(QMetaObject::Call call, int id, void **a)
|
|||||||
void NodeInstanceMetaObject::notifyPropertyChange(int id)
|
void NodeInstanceMetaObject::notifyPropertyChange(int id)
|
||||||
{
|
{
|
||||||
ObjectNodeInstance::Pointer objectNodeInstance = m_nodeInstance.toStrongRef();
|
ObjectNodeInstance::Pointer objectNodeInstance = m_nodeInstance.toStrongRef();
|
||||||
|
const QMetaProperty propertyById = property(id);
|
||||||
|
|
||||||
if (objectNodeInstance && objectNodeInstance->nodeInstanceServer()) {
|
if (objectNodeInstance && objectNodeInstance->nodeInstanceServer()) {
|
||||||
if (id < type()->propertyOffset()) {
|
if (id < propertyOffset()) {
|
||||||
objectNodeInstance->nodeInstanceServer()->notifyPropertyChange(objectNodeInstance->instanceId(), m_prefix + property(id).name());
|
objectNodeInstance->nodeInstanceServer()->notifyPropertyChange(objectNodeInstance->instanceId(), m_prefix + propertyById.name());
|
||||||
} else {
|
} else {
|
||||||
objectNodeInstance->nodeInstanceServer()->notifyPropertyChange(objectNodeInstance->instanceId(), m_prefix + name(id - type()->propertyOffset()));
|
objectNodeInstance->nodeInstanceServer()->notifyPropertyChange(objectNodeInstance->instanceId(), m_prefix + name(id - propertyOffset()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int NodeInstanceMetaObject::count() const
|
||||||
|
{
|
||||||
|
return m_type->propertyCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
QByteArray NodeInstanceMetaObject::name(int idx) const
|
||||||
|
{
|
||||||
|
return m_type->propertyName(idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeInstanceMetaObject::copyTypeMetaObject()
|
||||||
|
{
|
||||||
|
*static_cast<QMetaObject *>(this) = *m_type->metaObject();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -32,7 +32,9 @@
|
|||||||
#define NODEINSTANCEMETAOBJECT_H
|
#define NODEINSTANCEMETAOBJECT_H
|
||||||
|
|
||||||
#include <QQmlContext>
|
#include <QQmlContext>
|
||||||
|
#include <QScopedPointer>
|
||||||
#include <private/qqmlopenmetaobject_p.h>
|
#include <private/qqmlopenmetaobject_p.h>
|
||||||
|
#include <private/qqmlvmemetaobject_p.h>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
@@ -41,21 +43,63 @@ class ObjectNodeInstance;
|
|||||||
typedef QSharedPointer<ObjectNodeInstance> ObjectNodeInstancePointer;
|
typedef QSharedPointer<ObjectNodeInstance> ObjectNodeInstancePointer;
|
||||||
typedef QWeakPointer<ObjectNodeInstance> ObjectNodeInstanceWeakPointer;
|
typedef QWeakPointer<ObjectNodeInstance> ObjectNodeInstanceWeakPointer;
|
||||||
|
|
||||||
class NodeInstanceMetaObject : public QQmlOpenMetaObject
|
struct MetaPropertyData;
|
||||||
|
|
||||||
|
class NodeInstanceMetaObject : public QQmlVMEMetaObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QQmlEngine *engine);
|
static NodeInstanceMetaObject *createNodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QQmlEngine *engine);
|
||||||
NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix, QQmlEngine *engine);
|
static NodeInstanceMetaObject *createNodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix, QQmlEngine *engine);
|
||||||
|
~NodeInstanceMetaObject();
|
||||||
void createNewProperty(const QString &name);
|
void createNewProperty(const QString &name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QQmlEngine *engine);
|
||||||
|
NodeInstanceMetaObject(const ObjectNodeInstancePointer &nodeInstance, QObject *object, const QString &prefix, QQmlEngine *engine);
|
||||||
|
|
||||||
|
int openMetaCall(QMetaObject::Call _c, int _id, void **_a);
|
||||||
int metaCall(QMetaObject::Call _c, int _id, void **_a);
|
int metaCall(QMetaObject::Call _c, int _id, void **_a);
|
||||||
void notifyPropertyChange(int id);
|
void notifyPropertyChange(int id);
|
||||||
|
void setValue(int id, const QVariant &value);
|
||||||
|
int createProperty(const char *, const char *);
|
||||||
|
QVariant propertyWriteValue(int, const QVariant &);
|
||||||
|
|
||||||
|
QObject *myObject() const { return QQmlVMEMetaObject::object; }
|
||||||
|
QAbstractDynamicMetaObject *parent() const { return const_cast<QAbstractDynamicMetaObject *>(dynamicMetaObjectParent()); }
|
||||||
|
|
||||||
|
const QAbstractDynamicMetaObject *dynamicMetaObjectParent() const
|
||||||
|
{
|
||||||
|
if (QQmlVMEMetaObject::parent.isT1())
|
||||||
|
return QQmlVMEMetaObject::parent.asT1()->toDynamicMetaObject(QQmlVMEMetaObject::object);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QMetaObject *metaObjectParent() const
|
||||||
|
{
|
||||||
|
if (QQmlVMEMetaObject::parent.isT1())
|
||||||
|
return QQmlVMEMetaObject::parent.asT1()->toDynamicMetaObject(QQmlVMEMetaObject::object);
|
||||||
|
|
||||||
|
return QQmlVMEMetaObject::parent.asT2();
|
||||||
|
}
|
||||||
|
|
||||||
|
int propertyOffset() const { return cache->propertyOffset(); }
|
||||||
|
|
||||||
|
int count() const;
|
||||||
|
QByteArray name(int) const;
|
||||||
|
|
||||||
|
void copyTypeMetaObject();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void init(QObject *, QQmlEngine *engine);
|
||||||
|
|
||||||
ObjectNodeInstanceWeakPointer m_nodeInstance;
|
ObjectNodeInstanceWeakPointer m_nodeInstance;
|
||||||
QString m_prefix;
|
QString m_prefix;
|
||||||
QPointer<QQmlContext> m_context;
|
QPointer<QQmlContext> m_context;
|
||||||
|
QQmlOpenMetaObjectType *m_type;
|
||||||
|
QScopedPointer<MetaPropertyData> m_data;
|
||||||
|
//QAbstractDynamicMetaObject *m_parent;
|
||||||
|
QQmlPropertyCache *m_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -130,14 +130,15 @@ static bool hasPropertiesWitoutNotifications(const QMetaObject *metaObject)
|
|||||||
void ObjectNodeInstance::initializePropertyWatcher(const ObjectNodeInstance::Pointer &objectNodeInstance)
|
void ObjectNodeInstance::initializePropertyWatcher(const ObjectNodeInstance::Pointer &objectNodeInstance)
|
||||||
{
|
{
|
||||||
const QMetaObject *metaObject = objectNodeInstance->object()->metaObject();
|
const QMetaObject *metaObject = objectNodeInstance->object()->metaObject();
|
||||||
m_metaObject = new NodeInstanceMetaObject(objectNodeInstance, nodeInstanceServer()->engine());
|
m_metaObject = NodeInstanceMetaObject::createNodeInstanceMetaObject(objectNodeInstance, nodeInstanceServer()->engine());
|
||||||
QQmlEnginePrivate::get(engine())->cache(m_metaObject);
|
|
||||||
for (int propertyIndex = QObject::staticMetaObject.propertyCount(); propertyIndex < metaObject->propertyCount(); propertyIndex++) {
|
for (int propertyIndex = QObject::staticMetaObject.propertyCount(); propertyIndex < metaObject->propertyCount(); propertyIndex++) {
|
||||||
if (QQmlMetaType::isQObject(metaObject->property(propertyIndex).userType())) {
|
if (QQmlMetaType::isQObject(metaObject->property(propertyIndex).userType())) {
|
||||||
QObject *propertyObject = QQmlMetaType::toQObject(metaObject->property(propertyIndex).read(objectNodeInstance->object()));
|
QObject *propertyObject = QQmlMetaType::toQObject(metaObject->property(propertyIndex).read(objectNodeInstance->object()));
|
||||||
if (propertyObject && hasPropertiesWitoutNotifications(propertyObject->metaObject())) {
|
if (propertyObject && hasPropertiesWitoutNotifications(propertyObject->metaObject())) {
|
||||||
QMetaObject *childMetaObject = new NodeInstanceMetaObject(objectNodeInstance, propertyObject, metaObject->property(propertyIndex).name(), nodeInstanceServer()->engine());
|
NodeInstanceMetaObject::createNodeInstanceMetaObject(objectNodeInstance,
|
||||||
QQmlEnginePrivate::get(engine())->cache(childMetaObject);
|
propertyObject,
|
||||||
|
metaObject->property(propertyIndex).name(),
|
||||||
|
nodeInstanceServer()->engine());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user