diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.cpp index dba8c12ca3a..9d8e6e65f8e 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstanceserver.cpp @@ -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); } diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstancesignalspy.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstancesignalspy.cpp index 03165a9c1c5..345ee6a0ca4 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstancesignalspy.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstancesignalspy.cpp @@ -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 diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstancesignalspy.h b/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstancesignalspy.h index bf704f0cc1f..e97bd515aed 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstancesignalspy.h +++ b/src/tools/qmlpuppet/qmlpuppet/instances/nodeinstancesignalspy.h @@ -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: diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/objectnodeinstance.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/objectnodeinstance.cpp index 1afa8d6d3af..fb9f3cdd411 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/objectnodeinstance.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/objectnodeinstance.cpp @@ -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()); diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/objectnodeinstance.h b/src/tools/qmlpuppet/qmlpuppet/instances/objectnodeinstance.h index ab16d20729b..d5048686820 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/objectnodeinstance.h +++ b/src/tools/qmlpuppet/qmlpuppet/instances/objectnodeinstance.h @@ -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; diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/servernodeinstance.cpp b/src/tools/qmlpuppet/qmlpuppet/instances/servernodeinstance.cpp index 2796674662a..f945dd64538 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/servernodeinstance.cpp +++ b/src/tools/qmlpuppet/qmlpuppet/instances/servernodeinstance.cpp @@ -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(); diff --git a/src/tools/qmlpuppet/qmlpuppet/instances/servernodeinstance.h b/src/tools/qmlpuppet/qmlpuppet/instances/servernodeinstance.h index 49db86ed085..b654cf36df9 100644 --- a/src/tools/qmlpuppet/qmlpuppet/instances/servernodeinstance.h +++ b/src/tools/qmlpuppet/qmlpuppet/instances/servernodeinstance.h @@ -166,6 +166,9 @@ public: QQuickItem *contentItem() const; + bool hasProperty(const PropertyName &name); + void createNewDynamicProperty(const PropertyName &name); + private: // functions ServerNodeInstance(const QSharedPointer &abstractInstance);