QmlDesigner: Add qml state tracing

Change-Id: I2143863c5b304f4fe3ef0f2a96ee6fa843173710
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Marco Bubke
2025-05-24 11:43:56 +02:00
parent 5ad3c9b55a
commit 9ecdfb1228
2 changed files with 264 additions and 79 deletions

View File

@@ -15,17 +15,17 @@
namespace QmlDesigner { namespace QmlDesigner {
QmlModelState::QmlModelState() static auto category = ModelTracing::category;
{
}
QmlModelState::QmlModelState(const ModelNode &modelNode) QmlPropertyChanges QmlModelState::propertyChanges(const ModelNode &node, SL sl)
: QmlModelNodeFacade(modelNode)
{ {
} using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state property changes",
category(),
keyValue("model node", *this),
keyValue("node", node),
keyValue("caller location", sl)};
QmlPropertyChanges QmlModelState::propertyChanges(const ModelNode &node)
{
if (isValid() && !isBaseState()) { if (isValid() && !isBaseState()) {
addChangeSetIfNotExists(node); addChangeSetIfNotExists(node);
@@ -42,8 +42,15 @@ QmlPropertyChanges QmlModelState::propertyChanges(const ModelNode &node)
return QmlPropertyChanges(); //not found return QmlPropertyChanges(); //not found
} }
QList<QmlModelStateOperation> QmlModelState::stateOperations(const ModelNode &node) const QList<QmlModelStateOperation> QmlModelState::stateOperations(const ModelNode &node, SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state state operations",
category(),
keyValue("model node", *this),
keyValue("node", node),
keyValue("caller location", sl)};
QList<QmlModelStateOperation> returnList; QList<QmlModelStateOperation> returnList;
if (!isBaseState() && modelNode().hasNodeListProperty("changes")) { if (!isBaseState() && modelNode().hasNodeListProperty("changes")) {
@@ -61,8 +68,14 @@ QList<QmlModelStateOperation> QmlModelState::stateOperations(const ModelNode &no
return returnList; //not found return returnList; //not found
} }
QList<QmlPropertyChanges> QmlModelState::propertyChanges() const QList<QmlPropertyChanges> QmlModelState::propertyChanges(SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state property changes",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
QList<QmlPropertyChanges> returnList; QList<QmlPropertyChanges> returnList;
if (!isBaseState() && modelNode().hasNodeListProperty("changes")) { if (!isBaseState() && modelNode().hasNodeListProperty("changes")) {
@@ -77,9 +90,15 @@ QList<QmlPropertyChanges> QmlModelState::propertyChanges() const
return returnList; return returnList;
} }
bool QmlModelState::hasPropertyChanges(const ModelNode &node, SL sl) const
bool QmlModelState::hasPropertyChanges(const ModelNode &node) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state has property changes",
category(),
keyValue("model node", *this),
keyValue("node", node),
keyValue("caller location", sl)};
if (!isBaseState() && modelNode().hasNodeListProperty("changes")) { if (!isBaseState() && modelNode().hasNodeListProperty("changes")) {
const QList<QmlPropertyChanges> changes = propertyChanges(); const QList<QmlPropertyChanges> changes = propertyChanges();
for (const QmlPropertyChanges &changeSet : changes) { for (const QmlPropertyChanges &changeSet : changes) {
@@ -91,8 +110,15 @@ bool QmlModelState::hasPropertyChanges(const ModelNode &node) const
return false; return false;
} }
bool QmlModelState::hasStateOperation(const ModelNode &node) const bool QmlModelState::hasStateOperation(const ModelNode &node, SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state has state operation",
category(),
keyValue("model node", *this),
keyValue("node", node),
keyValue("caller location", sl)};
if (!isBaseState()) { if (!isBaseState()) {
const QList<QmlModelStateOperation> operations = stateOperations(); const QList<QmlModelStateOperation> operations = stateOperations();
for (const QmlModelStateOperation &stateOperation : operations) { for (const QmlModelStateOperation &stateOperation : operations) {
@@ -103,8 +129,14 @@ bool QmlModelState::hasStateOperation(const ModelNode &node) const
return false; return false;
} }
QList<QmlModelStateOperation> QmlModelState::stateOperations() const QList<QmlModelStateOperation> QmlModelState::stateOperations(SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state state operations",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
//### exception if not valid //### exception if not valid
QList<QmlModelStateOperation> returnList; QList<QmlModelStateOperation> returnList;
@@ -120,8 +152,14 @@ QList<QmlModelStateOperation> QmlModelState::stateOperations() const
return returnList; return returnList;
} }
QList<QmlModelStateOperation> QmlModelState::allInvalidStateOperations() const QList<QmlModelStateOperation> QmlModelState::allInvalidStateOperations(SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state all invalid state operations",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
return Utils::filtered(stateOperations(), [](const QmlModelStateOperation &operation) { return Utils::filtered(stateOperations(), [](const QmlModelStateOperation &operation) {
return !operation.target().isValid(); return !operation.target().isValid();
}); });
@@ -159,9 +197,14 @@ void QmlModelState::addChangeSetIfNotExists(const ModelNode &node)
} }
} }
void QmlModelState::removePropertyChanges(const ModelNode &node) void QmlModelState::removePropertyChanges(const ModelNode &node, SL sl)
{ {
//### exception if not valid using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state remove property changes",
category(),
keyValue("model node", *this),
keyValue("node", node),
keyValue("caller location", sl)};
if (!isValid()) if (!isValid())
return; return;
@@ -178,8 +221,15 @@ void QmlModelState::removePropertyChanges(const ModelNode &node)
/*! /*!
Returns \c true if this state affects \a node. Returns \c true if this state affects \a node.
*/ */
bool QmlModelState::affectsModelNode(const ModelNode &node) const bool QmlModelState::affectsModelNode(const ModelNode &node, SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state affects model node",
category(),
keyValue("model node", *this),
keyValue("node", node),
keyValue("caller location", sl)};
if (!isValid()) if (!isValid())
return false; return false;
@@ -189,8 +239,14 @@ bool QmlModelState::affectsModelNode(const ModelNode &node) const
return !stateOperations(node).isEmpty(); return !stateOperations(node).isEmpty();
} }
QList<QmlObjectNode> QmlModelState::allAffectedNodes() const QList<QmlObjectNode> QmlModelState::allAffectedNodes(SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state all affected nodes",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
QList<QmlObjectNode> returnList; QList<QmlObjectNode> returnList;
const QList<ModelNode> nodes = modelNode().nodeListProperty("changes").toModelNodeList(); const QList<ModelNode> nodes = modelNode().nodeListProperty("changes").toModelNodeList();
@@ -203,27 +259,46 @@ QList<QmlObjectNode> QmlModelState::allAffectedNodes() const
return returnList; return returnList;
} }
QString QmlModelState::name() const QString QmlModelState::name(SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state name",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
if (isBaseState()) if (isBaseState())
return QString(); return QString();
return modelNode().variantProperty("name").value().toString(); return modelNode().variantProperty("name").value().toString();
} }
void QmlModelState::setName(const QString &name) void QmlModelState::setName(const QString &name, SL sl)
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state set name",
category(),
keyValue("model node", *this),
keyValue("name", name),
keyValue("caller location", sl)};
if ((!isBaseState()) && (modelNode().isValid())) if ((!isBaseState()) && (modelNode().isValid()))
modelNode().variantProperty("name").setValue(name); modelNode().variantProperty("name").setValue(name);
} }
bool QmlModelState::isValid() const bool QmlModelState::isValid(SL sl) const
{ {
return isValidQmlModelState(modelNode()); return isValidQmlModelState(modelNode(), sl);
} }
bool QmlModelState::isValidQmlModelState(const ModelNode &modelNode) bool QmlModelState::isValidQmlModelState(const ModelNode &modelNode, SL sl)
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"is valid qml model state",
category(),
keyValue("model node", modelNode),
keyValue("caller location", sl)};
return isValidQmlModelNodeFacade(modelNode) return isValidQmlModelNodeFacade(modelNode)
&& (modelNode.metaInfo().isQtQuickState() || isBaseState(modelNode)); && (modelNode.metaInfo().isQtQuickState() || isBaseState(modelNode));
} }
@@ -231,9 +306,14 @@ bool QmlModelState::isValidQmlModelState(const ModelNode &modelNode)
/** /**
Removes state node & all subnodes. Removes state node & all subnodes.
*/ */
void QmlModelState::destroy() void QmlModelState::destroy(SL sl)
{ {
Q_ASSERT(isValid()); using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state destroy",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
modelNode().destroy(); modelNode().destroy();
} }
@@ -241,18 +321,37 @@ void QmlModelState::destroy()
Returns \c true if this state is the base state. Returns \c true if this state is the base state.
*/ */
bool QmlModelState::isBaseState() const bool QmlModelState::isBaseState(SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state is base state",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
return isBaseState(modelNode()); return isBaseState(modelNode());
} }
bool QmlModelState::isBaseState(const ModelNode &modelNode) bool QmlModelState::isBaseState(const ModelNode &modelNode, SL sl)
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"is base state",
category(),
keyValue("model node", modelNode),
keyValue("caller location", sl)};
return !modelNode.isValid() || modelNode.isRootNode(); return !modelNode.isValid() || modelNode.isRootNode();
} }
QmlModelState QmlModelState::duplicate(const QString &name) const QmlModelState QmlModelState::duplicate(const QString &name, SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state duplicate",
category(),
keyValue("model node", *this),
keyValue("name", name),
keyValue("caller location", sl)};
if (!isValid()) if (!isValid())
return {}; return {};
@@ -289,15 +388,28 @@ QmlModelState QmlModelState::duplicate(const QString &name) const
return newState; return newState;
} }
QmlModelStateGroup QmlModelState::stateGroup() const QmlModelStateGroup QmlModelState::stateGroup(SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state state group",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
QmlObjectNode parentNode(modelNode().parentProperty().parentModelNode()); QmlObjectNode parentNode(modelNode().parentProperty().parentModelNode());
return parentNode.states(); return parentNode.states();
} }
ModelNode QmlModelState::createQmlState(AbstractView *view, const PropertyListType &propertyList) ModelNode QmlModelState::createQmlState(AbstractView *view, const PropertyListType &propertyList, SL sl)
{ {
QTC_ASSERT(view, return {}); using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state create",
category(),
keyValue("view", view),
keyValue("caller location", sl)};
if (!view)
return {};
#ifdef QDS_USE_PROJECTSTORAGE #ifdef QDS_USE_PROJECTSTORAGE
return view->createModelNode("State", propertyList); return view->createModelNode("State", propertyList);
@@ -312,15 +424,27 @@ ModelNode QmlModelState::createQmlState(AbstractView *view, const PropertyListTy
#endif #endif
} }
void QmlModelState::setAsDefault() void QmlModelState::setAsDefault(SL sl)
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state set as default",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
if ((!isBaseState()) && (modelNode().isValid())) { if ((!isBaseState()) && (modelNode().isValid())) {
stateGroup().modelNode().variantProperty("state").setValue(name()); stateGroup().modelNode().variantProperty("state").setValue(name());
} }
} }
bool QmlModelState::isDefault() const bool QmlModelState::isDefault(SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state is default",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
if ((!isBaseState()) && (modelNode().isValid())) { if ((!isBaseState()) && (modelNode().isValid())) {
if (stateGroup().modelNode().hasProperty("state")) { if (stateGroup().modelNode().hasProperty("state")) {
return (stateGroup().modelNode().variantProperty("state").value() == name()); return (stateGroup().modelNode().variantProperty("state").value() == name());
@@ -330,67 +454,123 @@ bool QmlModelState::isDefault() const
return false; return false;
} }
void QmlModelState::setAnnotation(const Annotation &annotation, const QString &id) void QmlModelState::setAnnotation(const Annotation &annotation, const QString &id, SL sl)
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state set annotation",
category(),
keyValue("model node", *this),
keyValue("id", id),
keyValue("caller location", sl)};
if (modelNode().isValid()) { if (modelNode().isValid()) {
modelNode().setCustomId(id); modelNode().setCustomId(id);
modelNode().setAnnotation(annotation); modelNode().setAnnotation(annotation);
} }
} }
Annotation QmlModelState::annotation() const Annotation QmlModelState::annotation(SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state annotation",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
if (modelNode().isValid()) if (modelNode().isValid())
return modelNode().annotation(); return modelNode().annotation();
return {}; return {};
} }
QString QmlModelState::annotationName() const QString QmlModelState::annotationName(SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state annotation name",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
if (modelNode().isValid()) if (modelNode().isValid())
return modelNode().customId(); return modelNode().customId();
return {}; return {};
} }
bool QmlModelState::hasAnnotation() const bool QmlModelState::hasAnnotation(SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state has annotation",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
if (modelNode().isValid()) if (modelNode().isValid())
return modelNode().hasAnnotation() || modelNode().hasCustomId(); return modelNode().hasAnnotation() || modelNode().hasCustomId();
return false; return false;
} }
void QmlModelState::removeAnnotation() void QmlModelState::removeAnnotation(SL sl)
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state remove annotation",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
if (modelNode().isValid()) { if (modelNode().isValid()) {
modelNode().removeCustomId(); modelNode().removeCustomId();
modelNode().removeAnnotation(); modelNode().removeAnnotation();
} }
} }
QString QmlModelState::extend() const QString QmlModelState::extend(SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state extend",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
if (isBaseState()) if (isBaseState())
return QString(); return QString();
return modelNode().variantProperty("extend").value().toString(); return modelNode().variantProperty("extend").value().toString();
} }
void QmlModelState::setExtend(const QString &name) void QmlModelState::setExtend(const QString &name, SL sl)
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state set extend",
category(),
keyValue("model node", *this),
keyValue("name", name),
keyValue("caller location", sl)};
if ((!isBaseState()) && (modelNode().isValid())) if ((!isBaseState()) && (modelNode().isValid()))
modelNode().variantProperty("extend").setValue(name); modelNode().variantProperty("extend").setValue(name);
} }
bool QmlModelState::hasExtend() const bool QmlModelState::hasExtend(SL sl) const
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state has extend",
category(),
keyValue("model node", *this),
keyValue("caller location", sl)};
if (!isBaseState() && modelNode().isValid()) if (!isBaseState() && modelNode().isValid())
return modelNode().hasVariantProperty("extend"); return modelNode().hasVariantProperty("extend");
return false; return false;
} }
QmlModelState QmlModelState::createBaseState(const AbstractView *view) QmlModelState QmlModelState::createBaseState(const AbstractView *view, SL sl)
{ {
using NanotraceHR::keyValue;
NanotraceHR::Tracer tracer{"qml model state create base state",
category(),
keyValue("view", view),
keyValue("caller location", sl)};
QmlModelState qmlModelState(view->rootModelNode()); QmlModelState qmlModelState(view->rootModelNode());
return qmlModelState; return qmlModelState;

View File

@@ -21,56 +21,61 @@ class StatesEditorView;
class QMLDESIGNER_EXPORT QmlModelState final : public QmlModelNodeFacade class QMLDESIGNER_EXPORT QmlModelState final : public QmlModelNodeFacade
{ {
friend StatesEditorView;
public: public:
QmlModelState(); QmlModelState() = default;
QmlModelState(const ModelNode &modelNode);
QmlPropertyChanges propertyChanges(const ModelNode &node); QmlModelState(const ModelNode &modelNode)
QList<QmlModelStateOperation> stateOperations(const ModelNode &node) const; : QmlModelNodeFacade(modelNode)
QList<QmlPropertyChanges> propertyChanges() const; {}
QList<QmlModelStateOperation> stateOperations() const;
QList<QmlModelStateOperation> allInvalidStateOperations() const;
bool hasPropertyChanges(const ModelNode &node) const; QmlPropertyChanges propertyChanges(const ModelNode &node, SL sl = {});
QList<QmlModelStateOperation> stateOperations(const ModelNode &node, SL sl = {}) const;
QList<QmlPropertyChanges> propertyChanges(SL sl = {}) const;
QList<QmlModelStateOperation> stateOperations(SL sl = {}) const;
QList<QmlModelStateOperation> allInvalidStateOperations(SL sl = {}) const;
bool hasStateOperation(const ModelNode &node) const; bool hasPropertyChanges(const ModelNode &node, SL sl = {}) const;
void removePropertyChanges(const ModelNode &node); bool hasStateOperation(const ModelNode &node, SL sl = {}) const;
bool affectsModelNode(const ModelNode &node) const; void removePropertyChanges(const ModelNode &node, SL sl = {});
QList<QmlObjectNode> allAffectedNodes() const;
QString name() const; bool affectsModelNode(const ModelNode &node, SL sl = {}) const;
void setName(const QString &name); QList<QmlObjectNode> allAffectedNodes(SL sl = {}) const;
bool isValid() const; QString name(SL sl = {}) const;
void setName(const QString &name, SL sl = {});
bool isValid(SL sl = {}) const;
explicit operator bool() const { return isValid(); } explicit operator bool() const { return isValid(); }
static bool isValidQmlModelState(const ModelNode &modelNode);
void destroy();
bool isBaseState() const; static bool isValidQmlModelState(const ModelNode &modelNode, SL sl = {});
static bool isBaseState(const ModelNode &modelNode); void destroy(SL sl = {});
QmlModelState duplicate(const QString &name) const;
QmlModelStateGroup stateGroup() const;
static ModelNode createQmlState(AbstractView *view, const PropertyListType &propertyList); bool isBaseState(SL sl = {}) const;
static bool isBaseState(const ModelNode &modelNode, SL sl = {});
QmlModelState duplicate(const QString &name, SL sl = {}) const;
QmlModelStateGroup stateGroup(SL sl = {}) const;
void setAsDefault(); static ModelNode createQmlState(AbstractView *view,
bool isDefault() const; const PropertyListType &propertyList,
SL sl = {});
void setAnnotation(const Annotation &annotation, const QString &id); static QmlModelState createBaseState(const AbstractView *view, SL sl = {});
Annotation annotation() const;
QString annotationName() const;
bool hasAnnotation() const;
void removeAnnotation();
QString extend() const; void setAsDefault(SL sl = {});
void setExtend(const QString &name); bool isDefault(SL sl = {}) const;
bool hasExtend() const;
protected: void setAnnotation(const Annotation &annotation, const QString &id, SL sl = {});
Annotation annotation(SL sl = {}) const;
QString annotationName(SL sl = {}) const;
bool hasAnnotation(SL sl = {}) const;
void removeAnnotation(SL sl = {});
QString extend(SL sl = {}) const;
void setExtend(const QString &name, SL sl = {});
bool hasExtend(SL sl = {}) const;
private:
void addChangeSetIfNotExists(const ModelNode &node); void addChangeSetIfNotExists(const ModelNode &node);
static QmlModelState createBaseState(const AbstractView *view);
}; };
} //QmlDesigner } //QmlDesigner