forked from qt-creator/qt-creator
qmlpuppet: watch changes of new dynamic properties
qmlpuppet took into account predefined properties and dynamic properties that were already defined when the instance was created. Dynamic properties created after instance creation where not considered (NodeInstanceSignalSpy wasn't watching them). With a given change, it also monitors changes of dynamic properties that are added to an existing instance, e.g. through the Property Editor. Task-number: QDS-13513 Change-Id: I50ae9c25f358378f17e08d4dd957d78db6b97b98 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -916,19 +916,16 @@ void NodeInstanceServer::setInstancePropertyBinding(const PropertyBindingContain
|
||||
const PropertyName name = bindingContainer.name();
|
||||
const QString expression = bindingContainer.expression();
|
||||
|
||||
|
||||
if (activeStateInstance().isValid() && !instance.isSubclassOf("QtQuick/PropertyChanges")) {
|
||||
bool stateBindingWasUpdated = activeStateInstance().updateStateBinding(instance, name, expression);
|
||||
if (!stateBindingWasUpdated) {
|
||||
if (bindingContainer.isDynamic())
|
||||
Internal::QmlPrivateGate::createNewDynamicProperty(instance.internalInstance()->object(), engine(),
|
||||
QString::fromUtf8(name));
|
||||
if (bindingContainer.isDynamic() && !instance.hasProperty(name))
|
||||
instance.createNewDynamicProperty(name);
|
||||
instance.setPropertyBinding(name, expression);
|
||||
}
|
||||
} else {
|
||||
if (bindingContainer.isDynamic())
|
||||
Internal::QmlPrivateGate::createNewDynamicProperty(instance.internalInstance()->object(), engine(),
|
||||
QString::fromUtf8(name));
|
||||
if (bindingContainer.isDynamic() && !instance.hasProperty(name))
|
||||
instance.createNewDynamicProperty(name);
|
||||
instance.setPropertyBinding(name, expression);
|
||||
|
||||
if (instance.instanceId() == 0 && (name == "width" || name == "height"))
|
||||
@@ -955,17 +952,13 @@ void NodeInstanceServer::setInstancePropertyVariant(const PropertyValueContainer
|
||||
if (activeStateInstance().isValid() && !instance.isSubclassOf("QtQuick/PropertyChanges")) {
|
||||
bool stateValueWasUpdated = activeStateInstance().updateStateVariant(instance, name, value);
|
||||
if (!stateValueWasUpdated) {
|
||||
if (valueContainer.isDynamic()) {
|
||||
Internal::QmlPrivateGate::createNewDynamicProperty(instance.internalInstance()->object(),
|
||||
engine(), QString::fromUtf8(name));
|
||||
}
|
||||
if (valueContainer.isDynamic() && !instance.hasProperty(name))
|
||||
instance.createNewDynamicProperty(name);
|
||||
instance.setPropertyVariant(name, value);
|
||||
}
|
||||
} else { // base state
|
||||
if (valueContainer.isDynamic()) {
|
||||
Internal::QmlPrivateGate::createNewDynamicProperty(instance.internalInstance()->object(),
|
||||
engine(), QString::fromUtf8(name));
|
||||
}
|
||||
if (valueContainer.isDynamic() && !instance.hasProperty(name))
|
||||
instance.createNewDynamicProperty(name);
|
||||
instance.setPropertyVariant(name, value);
|
||||
}
|
||||
|
||||
|
@@ -40,16 +40,21 @@ void NodeInstanceSignalSpy::registerObject(QObject *spiedObject)
|
||||
index < spiedObject->metaObject()->propertyCount();
|
||||
index++) {
|
||||
QMetaProperty metaProperty = spiedObject->metaObject()->property(index);
|
||||
|
||||
if (QmlPrivateGate::isPropertyQObject(metaProperty)) {
|
||||
registerChildObject(metaProperty, spiedObject);
|
||||
} else {
|
||||
registerProperty(metaProperty, spiedObject);
|
||||
}
|
||||
registerProperty(metaProperty, spiedObject);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeInstanceSignalSpy::registerProperty(const QMetaProperty &metaProperty, QObject *spiedObject, const PropertyName &propertyPrefix)
|
||||
void NodeInstanceSignalSpy::registerProperty(const QMetaProperty &metaProperty, QObject *spiedObject)
|
||||
{
|
||||
if (QmlPrivateGate::isPropertyQObject(metaProperty)) {
|
||||
registerChildObject(metaProperty, spiedObject);
|
||||
} else {
|
||||
registerSingleProperty(metaProperty, spiedObject);
|
||||
}
|
||||
}
|
||||
|
||||
void NodeInstanceSignalSpy::registerSingleProperty(
|
||||
const QMetaProperty &metaProperty, QObject *spiedObject, const PropertyName &propertyPrefix)
|
||||
{
|
||||
if (metaProperty.isReadable() && metaProperty.isWritable() && metaProperty.hasNotifySignal()) {
|
||||
QMetaMethod metaMethod = metaProperty.notifySignal();
|
||||
@@ -77,7 +82,7 @@ void NodeInstanceSignalSpy::registerChildObject(
|
||||
index++) {
|
||||
QMetaProperty childMetaProperty = childObject->metaObject()->property(index);
|
||||
|
||||
registerProperty(
|
||||
registerSingleProperty(
|
||||
childMetaProperty, childObject, PropertyName(metaProperty.name()) + '.');
|
||||
}
|
||||
}
|
||||
@@ -100,5 +105,23 @@ int NodeInstanceSignalSpy::qt_metacall(QMetaObject::Call call, int methodId, voi
|
||||
return QObject::qt_metacall(call, methodId, a);
|
||||
}
|
||||
|
||||
void NodeInstanceSignalSpy::registerDynamicProperty(
|
||||
const PropertyName &propertyName, QObject *spiedObject)
|
||||
{
|
||||
if (!m_registeredObjectList.contains(spiedObject)) {
|
||||
return;
|
||||
}
|
||||
if (m_indexPropertyHash.values().contains(propertyName)) {
|
||||
return;
|
||||
}
|
||||
QQmlProperty qmlProperty(
|
||||
spiedObject, QString::fromUtf8(propertyName), QQmlEngine::contextForObject(spiedObject));
|
||||
if (!qmlProperty.isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
registerProperty(qmlProperty.property(), spiedObject);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -27,9 +27,15 @@ public:
|
||||
|
||||
int qt_metacall(QMetaObject::Call, int, void **) override;
|
||||
|
||||
void registerDynamicProperty(const PropertyName &propertyName, QObject *spiedObject);
|
||||
|
||||
protected:
|
||||
void registerObject(QObject *spiedObject);
|
||||
void registerProperty(const QMetaProperty &metaProperty, QObject *spiedObject, const PropertyName &propertyPrefix = PropertyName());
|
||||
void registerProperty(const QMetaProperty &metaProperty, QObject *spiedObject);
|
||||
void registerSingleProperty(
|
||||
const QMetaProperty &metaProperty,
|
||||
QObject *spiedObject,
|
||||
const PropertyName &propertyPrefix = PropertyName());
|
||||
void registerChildObject(const QMetaProperty &metaProperty, QObject *spiedObject);
|
||||
|
||||
private:
|
||||
|
@@ -113,6 +113,11 @@ void ObjectNodeInstance::initializePropertyWatcher(const ObjectNodeInstance::Poi
|
||||
m_signalSpy.setObjectNodeInstance(objectNodeInstance);
|
||||
}
|
||||
|
||||
void ObjectNodeInstance::watchProperty(const PropertyName &name)
|
||||
{
|
||||
m_signalSpy.registerDynamicProperty(name, object());
|
||||
}
|
||||
|
||||
void ObjectNodeInstance::initialize(const ObjectNodeInstance::Pointer &objectNodeInstance,
|
||||
InstanceContainer::NodeFlags /*flags*/)
|
||||
{
|
||||
@@ -431,6 +436,11 @@ void ObjectNodeInstance::setModifiedFlag(bool b)
|
||||
m_isModified = b;
|
||||
}
|
||||
|
||||
void ObjectNodeInstance::handleNewDynamicProperty(const PropertyName &name)
|
||||
{
|
||||
watchProperty(name);
|
||||
}
|
||||
|
||||
QVariant ObjectNodeInstance::convertEnumToValue(const QVariant &value, const PropertyName &name)
|
||||
{
|
||||
Q_ASSERT(value.canConvert<Enumeration>());
|
||||
|
@@ -189,6 +189,8 @@ public:
|
||||
|
||||
void setModifiedFlag(bool b);
|
||||
|
||||
void handleNewDynamicProperty(const PropertyName &name);
|
||||
|
||||
protected:
|
||||
explicit ObjectNodeInstance(QObject *object);
|
||||
void doResetProperty(const PropertyName &propertyName);
|
||||
@@ -201,6 +203,7 @@ protected:
|
||||
static QVariant enumationValue(const Enumeration &enumeration);
|
||||
|
||||
void initializePropertyWatcher(const ObjectNodeInstance::Pointer &objectNodeInstance);
|
||||
void watchProperty(const PropertyName &name);
|
||||
void ensureVector3DDotProperties(PropertyNameList &list) const;
|
||||
void ensureValueTypeProperties(PropertyNameList &list) const;
|
||||
|
||||
|
@@ -168,6 +168,19 @@ QQuickItem *ServerNodeInstance::contentItem() const
|
||||
return m_nodeInstance->contentItem();
|
||||
}
|
||||
|
||||
bool ServerNodeInstance::hasProperty(const PropertyName &name)
|
||||
{
|
||||
return propertyNames().contains(name);
|
||||
}
|
||||
|
||||
void ServerNodeInstance::createNewDynamicProperty(const PropertyName &name)
|
||||
{
|
||||
auto nameStr = QString::fromUtf8(name);
|
||||
auto *context = QQmlEngine::contextForObject(internalObject());
|
||||
Internal::QmlPrivateGate::createNewDynamicProperty(internalObject(), context->engine(), nameStr);
|
||||
internalInstance()->handleNewDynamicProperty(name);
|
||||
}
|
||||
|
||||
void ServerNodeInstance::updateDirtyNodeRecursive()
|
||||
{
|
||||
m_nodeInstance->updateAllDirtyNodesRecursive();
|
||||
|
@@ -166,6 +166,9 @@ public:
|
||||
|
||||
QQuickItem *contentItem() const;
|
||||
|
||||
bool hasProperty(const PropertyName &name);
|
||||
void createNewDynamicProperty(const PropertyName &name);
|
||||
|
||||
private: // functions
|
||||
ServerNodeInstance(const QSharedPointer<Internal::ObjectNodeInstance> &abstractInstance);
|
||||
|
||||
|
Reference in New Issue
Block a user