From bdd076efcdb5ac762631389df128b29cedefc784 Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Fri, 4 Aug 2023 20:16:43 +0200 Subject: [PATCH] QmlDesigner: Improve Model Make node collection a little bit more explicit. Before we created, copied and destroyed node lists. Now we send a list around where we add nodes. Use raw pointer for properties. Properties are used as internal pointer plus the property name. The repesentation as an shared pointer is a implementation detail and could be removed in the future. Use raw pointer for internal nodes if we don't handle ownership but only access member. Remove double checks for properties. One lookup is better than two or three. Change-Id: If162f365db3e8869cbc19913abfc44d57c2d8324 Reviewed-by: Qt CI Patch Build Bot Reviewed-by: Vikas Pachdha --- .../designercore/include/abstractproperty.h | 12 +- .../designercore/include/nodelistproperty.h | 6 +- .../designercore/model/abstractproperty.cpp | 66 +++--- .../designercore/model/bindingproperty.cpp | 13 +- .../designercore/model/internalnode.cpp | 105 ++++++---- .../designercore/model/internalnode_p.h | 70 ++++--- .../model/internalnodeabstractproperty.h | 5 - .../model/internalnodelistproperty.cpp | 20 +- .../model/internalnodelistproperty.h | 8 +- .../model/internalnodeproperty.cpp | 25 +-- .../designercore/model/internalnodeproperty.h | 6 +- .../designercore/model/internalproperty.cpp | 11 - .../designercore/model/internalproperty.h | 70 ++++++- .../qmldesigner/designercore/model/model.cpp | 196 +++++++++++------- .../qmldesigner/designercore/model/model_p.h | 46 ++-- .../designercore/model/modelnode.cpp | 6 +- .../model/nodeabstractproperty.cpp | 86 ++++++-- .../designercore/model/nodelistproperty.cpp | 28 ++- .../designercore/model/nodeproperty.cpp | 9 +- .../model/signalhandlerproperty.cpp | 18 +- .../designercore/model/variantproperty.cpp | 6 +- 21 files changed, 475 insertions(+), 337 deletions(-) diff --git a/src/plugins/qmldesigner/designercore/include/abstractproperty.h b/src/plugins/qmldesigner/designercore/include/abstractproperty.h index 6074858265a..7c1dab63916 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractproperty.h +++ b/src/plugins/qmldesigner/designercore/include/abstractproperty.h @@ -54,7 +54,7 @@ public: ~AbstractProperty(); AbstractProperty(const AbstractProperty &property, AbstractView *view); - PropertyName name() const; + const PropertyName &name() const; bool isValid() const; explicit operator bool() const { return isValid(); } @@ -125,8 +125,14 @@ public: protected: AbstractProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view); - AbstractProperty(const Internal::InternalPropertyPointer &property, Model* model, AbstractView *view); - Internal::InternalNodePointer internalNode() const { return m_internalNode; } + AbstractProperty(const Internal::InternalPropertyPointer &property, + Model *model, + AbstractView *view); + + Internal::InternalNode *internalNode() const { return m_internalNode.get(); } + + Internal::InternalNodePointer internalNodeSharedPointer() const { return m_internalNode; } + Internal::ModelPrivate *privateModel() const; private: diff --git a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h b/src/plugins/qmldesigner/designercore/include/nodelistproperty.h index 334a2a2758c..2f7a4423f09 100644 --- a/src/plugins/qmldesigner/designercore/include/nodelistproperty.h +++ b/src/plugins/qmldesigner/designercore/include/nodelistproperty.h @@ -166,7 +166,10 @@ public: using reference = ModelNode; NodeListProperty(); - NodeListProperty(const NodeListProperty &nodeListProperty, AbstractView *view); + NodeListProperty(const PropertyName &propertyName, + const Internal::InternalNodePointer &internalNode, + Model *model, + AbstractView *view); QList toModelNodeList() const; QList toQmlObjectNodeList() const; void slide(int, int) const; @@ -196,7 +199,6 @@ public: const_iterator end() const; protected: - NodeListProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view); NodeListProperty(const Internal::InternalNodeListPropertyPointer &internalNodeListProperty, Model *model, AbstractView *view); diff --git a/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp b/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp index e2e5800cab3..d8db3ac269d 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp @@ -71,7 +71,7 @@ AbstractView *AbstractProperty::view() const The QVariant is null if the property does not exist. */ -PropertyName AbstractProperty::name() const +const PropertyName &AbstractProperty::name() const { return m_propertyName; } @@ -126,7 +126,7 @@ VariantProperty AbstractProperty::toVariantProperty() const if (!isValid()) return {}; - VariantProperty propertyVariant(name(), internalNode(), model(), view()); + VariantProperty propertyVariant(name(), internalNodeSharedPointer(), model(), view()); if (propertyVariant.isVariantProperty()) return propertyVariant; @@ -139,7 +139,7 @@ NodeProperty AbstractProperty::toNodeProperty() const if (!isValid()) return {}; - NodeProperty propertyNode(name(), internalNode(), model(), view()); + NodeProperty propertyNode(name(), internalNodeSharedPointer(), model(), view()); if (propertyNode.isNodeProperty()) return propertyNode; @@ -152,7 +152,7 @@ SignalHandlerProperty AbstractProperty::toSignalHandlerProperty() const if (!isValid()) return {}; - SignalHandlerProperty propertyNode(name(), internalNode(), model(), view()); + SignalHandlerProperty propertyNode(name(), internalNodeSharedPointer(), model(), view()); if (propertyNode.isSignalHandlerProperty()) return propertyNode; @@ -165,7 +165,7 @@ SignalDeclarationProperty AbstractProperty::toSignalDeclarationProperty() const if (!isValid()) return {}; - SignalDeclarationProperty propertyNode(name(), internalNode(), model(), view()); + SignalDeclarationProperty propertyNode(name(), internalNodeSharedPointer(), model(), view()); if (propertyNode.isSignalDeclarationProperty()) return propertyNode; @@ -178,7 +178,7 @@ NodeListProperty AbstractProperty::toNodeListProperty() const if (!isValid()) return {}; - NodeListProperty propertyNodeList(name(), internalNode(), model(), view()); + NodeListProperty propertyNodeList(name(), internalNodeSharedPointer(), model(), view()); if (propertyNodeList.isNodeListProperty()) return propertyNodeList; @@ -191,7 +191,7 @@ NodeAbstractProperty AbstractProperty::toNodeAbstractProperty() const if (!isValid()) return {}; - NodeAbstractProperty propertyNodeAbstract(name(), internalNode(), model(), view()); + NodeAbstractProperty propertyNodeAbstract(name(), internalNodeSharedPointer(), model(), view()); if (propertyNodeAbstract.isNodeAbstractProperty()) return propertyNodeAbstract; @@ -204,7 +204,7 @@ BindingProperty AbstractProperty::toBindingProperty() const if (!isValid()) return {}; - BindingProperty propertyBinding(name(), internalNode(), model(), view()); + BindingProperty propertyBinding(name(), internalNodeSharedPointer(), model(), view()); if (propertyBinding.isBindingProperty()) return propertyBinding; @@ -217,10 +217,8 @@ bool AbstractProperty::isVariantProperty() const if (!isValid()) return false; - if (internalNode()->hasProperty(name())) { - Q_ASSERT(internalNode()->property(name())); - return internalNode()->property(name())->isVariantProperty(); - } + if (auto property = internalNode()->property(name())) + return property->isVariantProperty(); return false; } @@ -230,10 +228,8 @@ bool AbstractProperty::isNodeAbstractProperty() const if (!isValid()) return false; - if (internalNode()->hasProperty(name())) { - Q_ASSERT(internalNode()->property(name())); - return internalNode()->property(name())->isNodeAbstractProperty(); - } + if (auto property = internalNode()->property(name())) + return property->isNodeAbstractProperty(); return false; } @@ -243,10 +239,8 @@ bool AbstractProperty::isNodeListProperty() const if (!isValid()) return false; - if (internalNode()->hasProperty(name())) { - Q_ASSERT(internalNode()->property(name())); - return internalNode()->property(name())->isNodeListProperty(); - } + if (auto property = internalNode()->property(name())) + return property->isNodeListProperty(); return false; } @@ -256,10 +250,8 @@ bool AbstractProperty::isNodeProperty() const if (!isValid()) return false; - if (internalNode()->hasProperty(name())) { - Q_ASSERT(internalNode()->property(name())); - return internalNode()->property(name())->isNodeProperty(); - } + if (auto property = internalNode()->property(name())) + return property->isNodeProperty(); return false; } @@ -269,10 +261,8 @@ bool AbstractProperty::isSignalHandlerProperty() const if (!isValid()) return false; - if (internalNode()->hasProperty(name())) { - Q_ASSERT(internalNode()->property(name())); - return internalNode()->property(name())->isSignalHandlerProperty(); - } + if (auto property = internalNode()->property(name())) + return property->isSignalHandlerProperty(); return false; } @@ -282,10 +272,8 @@ bool AbstractProperty::isSignalDeclarationProperty() const if (!isValid()) return false; - if (internalNode()->hasProperty(name())) { - Q_ASSERT(internalNode()->property(name())); - return internalNode()->property(name())->isSignalDeclarationProperty(); - } + if (auto property = internalNode()->property(name())) + return property->isSignalDeclarationProperty(); return false; } @@ -295,8 +283,8 @@ PropertyType AbstractProperty::type() const if (!isValid()) return PropertyType::None; - if (internalNode()->hasProperty(name())) - return internalNode()->property(name())->propertyType(); + if (auto property = internalNode()->property(name())) + return property->propertyType(); return PropertyType::None; } @@ -306,10 +294,8 @@ bool AbstractProperty::isBindingProperty() const if (!isValid()) return false; - if (internalNode()->hasProperty(name())) { - Q_ASSERT(internalNode()->property(name())); - return internalNode()->property(name())->isBindingProperty(); - } + if (auto property = internalNode()->property(name())) + return property->isBindingProperty(); return false; } @@ -324,8 +310,8 @@ TypeName AbstractProperty::dynamicTypeName() const if (!isValid()) return {}; - if (internalNode()->hasProperty(name())) - return internalNode()->property(name())->dynamicTypeName(); + if (auto property = internalNode()->property(name())) + return property->dynamicTypeName(); return TypeName(); } diff --git a/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp b/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp index bf1dc59e155..5369884a841 100644 --- a/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp @@ -22,7 +22,7 @@ bool compareBindingProperties(const QmlDesigner::BindingProperty &bindingPropert BindingProperty::BindingProperty() = default; BindingProperty::BindingProperty(const BindingProperty &property, AbstractView *view) - : AbstractProperty(property.name(), property.internalNode(), property.model(), view) + : AbstractProperty(property.name(), property.internalNodeSharedPointer(), property.model(), view) { } @@ -58,14 +58,15 @@ void BindingProperty::setExpression(const QString &expression) privateModel()->removePropertyAndRelatedResources(internalProperty); } - privateModel()->setBindingProperty(internalNode(), name(), expression); + privateModel()->setBindingProperty(internalNodeSharedPointer(), name(), expression); } QString BindingProperty::expression() const { - if (isValid() && internalNode()->hasProperty(name()) - && internalNode()->property(name())->isBindingProperty()) - return internalNode()->bindingProperty(name())->expression(); + if (isValid()) { + if (auto property = internalNode()->bindingProperty(name())) + return property->expression(); + } return QString(); } @@ -351,7 +352,7 @@ void BindingProperty::setDynamicTypeNameAndExpression(const TypeName &typeName, privateModel()->removePropertyAndRelatedResources(internalProperty); } - privateModel()->setDynamicBindingProperty(internalNode(), name(), typeName, expression); + privateModel()->setDynamicBindingProperty(internalNodeSharedPointer(), name(), typeName, expression); } QDebug operator<<(QDebug debug, const BindingProperty &property) diff --git a/src/plugins/qmldesigner/designercore/model/internalnode.cpp b/src/plugins/qmldesigner/designercore/model/internalnode.cpp index 0c81d2ab28f..356c0a8be44 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnode.cpp @@ -18,10 +18,6 @@ namespace QmlDesigner { namespace Internal { -InternalNodeAbstractProperty::Pointer InternalNode::parentProperty() const -{ - return m_parentProperty.lock(); -} void InternalNode::setParentProperty(const InternalNodeAbstractProperty::Pointer &parent) { InternalNodeAbstractProperty::Pointer parentProperty = m_parentProperty.lock(); @@ -116,8 +112,7 @@ AuxiliaryDatasForType InternalNode::auxiliaryData(AuxiliaryDataType type) const void InternalNode::removeProperty(const PropertyName &name) { - InternalProperty::Pointer property = m_namePropertyHash.take(name); - Q_ASSERT(property); + m_namePropertyHash.remove(name); } PropertyNameList InternalNode::propertyNameList() const @@ -125,53 +120,73 @@ PropertyNameList InternalNode::propertyNameList() const return m_namePropertyHash.keys(); } -bool InternalNode::hasProperties() const -{ - return !m_namePropertyHash.isEmpty(); -} - -bool InternalNode::hasProperty(const PropertyName &name) const -{ - return m_namePropertyHash.contains(name); -} - -QList InternalNode::propertyList() const -{ - return m_namePropertyHash.values(); -} - -QList InternalNode::nodeAbstractPropertyList() const -{ - QList abstractPropertyList; - const QList properties = propertyList(); - for (const InternalProperty::Pointer &property : properties) { - if (property->isNodeAbstractProperty()) - abstractPropertyList.append(property->toProperty()); - } - - return abstractPropertyList; -} - QList InternalNode::allSubNodes() const { - QList nodeList; - const QList properties = nodeAbstractPropertyList(); - for (const InternalNodeAbstractProperty::Pointer &property : properties) { - nodeList.append(property->allSubNodes()); - } + QList nodes; + nodes.reserve(1024); - return nodeList; + addSubNodes(nodes); + + return nodes; +} + +void InternalNode::addSubNodes(QList &nodes, const InternalProperty *property) +{ + switch (property->type()) { + case PropertyType::NodeList: + property->to()->addSubNodes(nodes); + break; + case PropertyType::Node: + property->to()->addSubNodes(nodes); + break; + case PropertyType::Binding: + case PropertyType::None: + case PropertyType::SignalDeclaration: + case PropertyType::SignalHandler: + case PropertyType::Variant: + break; + } +} + +void InternalNode::addSubNodes(QList &nodes) const +{ + for (const InternalProperty::Pointer &property : m_namePropertyHash) + addSubNodes(nodes, property.get()); +} + +void InternalNode::addDirectSubNodes(QList &nodes) const +{ + for (const InternalProperty::Pointer &property : m_namePropertyHash) + addDirectSubNodes(nodes, property.get()); +} + +void InternalNode::addDirectSubNodes(QList &nodes, + const InternalProperty *property) +{ + switch (property->type()) { + case PropertyType::NodeList: + nodes.append(property->to()->nodes()); + break; + case PropertyType::Node: + nodes.append(property->to()->node()); + break; + case PropertyType::Binding: + case PropertyType::None: + case PropertyType::SignalDeclaration: + case PropertyType::SignalHandler: + case PropertyType::Variant: + break; + } } QList InternalNode::allDirectSubNodes() const { - QList nodeList; - const QList properties = nodeAbstractPropertyList(); - for (const InternalNodeAbstractProperty::Pointer &property : properties) { - nodeList.append(property->directSubNodes()); - } + QList nodes; + nodes.reserve(96); - return nodeList; + addDirectSubNodes(nodes); + + return nodes; } } // namespace Internal diff --git a/src/plugins/qmldesigner/designercore/model/internalnode_p.h b/src/plugins/qmldesigner/designercore/model/internalnode_p.h index bf8523653cf..84165b3cb8c 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode_p.h +++ b/src/plugins/qmldesigner/designercore/model/internalnode_p.h @@ -52,7 +52,7 @@ public: , internalId(internalId) {} - InternalNodeAbstractProperty::Pointer parentProperty() const; + InternalNodeAbstractProperty::Pointer parentProperty() const { return m_parentProperty.lock(); } // Reparent within model void setParentProperty(const InternalNodeAbstractProperty::Pointer &parent); @@ -66,18 +66,25 @@ public: AuxiliaryDatasView auxiliaryData() const { return std::as_const(m_auxiliaryDatas); } template - typename Type::Pointer property(const PropertyName &name) const + Type *property(const PropertyName &name) const { - auto property = m_namePropertyHash.value(name); - if (property && property->propertyType() == Type::type) - return std::static_pointer_cast(property); + auto propertyIter = m_namePropertyHash.find(name); + + if (propertyIter != m_namePropertyHash.end()) { + if (auto property = propertyIter->get(); property && property->propertyType() == Type::type) + return static_cast(property); + } return {}; } - InternalProperty::Pointer property(const PropertyName &name) const + InternalProperty *property(const PropertyName &name) const { - return m_namePropertyHash.value(name); + auto propertyIter = m_namePropertyHash.find(name); + if (propertyIter != m_namePropertyHash.end()) + return propertyIter->get(); + + return nullptr; } auto bindingProperty(const PropertyName &name) const @@ -116,60 +123,62 @@ public: return {}; } - InternalNodeProperty::Pointer nodeProperty(const PropertyName &name) const + auto nodeProperty(const PropertyName &name) const { return property(name); } template - auto &addProperty(const PropertyName &name) + Type *addProperty(const PropertyName &name) { auto newProperty = std::make_shared(name, shared_from_this()); - auto inserted = m_namePropertyHash.insert(name, std::move(newProperty)); + auto pointer = newProperty.get(); + m_namePropertyHash.insert(name, std::move(newProperty)); - return *inserted->get(); + return pointer; } - void addBindingProperty(const PropertyName &name) + auto addBindingProperty(const PropertyName &name) { - addProperty(name); + return addProperty(name); } - void addSignalHandlerProperty(const PropertyName &name) + auto addSignalHandlerProperty(const PropertyName &name) { - addProperty(name); + return addProperty(name); } - void addSignalDeclarationProperty(const PropertyName &name) + auto addSignalDeclarationProperty(const PropertyName &name) { - addProperty(name); + return addProperty(name); } - void addNodeListProperty(const PropertyName &name) + auto addNodeListProperty(const PropertyName &name) { - addProperty(name); + return addProperty(name); } - void addVariantProperty(const PropertyName &name) + auto addVariantProperty(const PropertyName &name) { - addProperty(name); + return addProperty(name); } - void addNodeProperty(const PropertyName &name, const TypeName &dynamicTypeName) + auto addNodeProperty(const PropertyName &name, const TypeName &dynamicTypeName) { - auto &property = addProperty(name); - property.setDynamicTypeName(dynamicTypeName); + auto property = addProperty(name); + property->setDynamicTypeName(dynamicTypeName); + + return property; } PropertyNameList propertyNameList() const; - bool hasProperties() const; - bool hasProperty(const PropertyName &name) const; - - QList propertyList() const; - QList nodeAbstractPropertyList() const; QList allSubNodes() const; QList allDirectSubNodes() const; + void addSubNodes(QList &nodes) const; + void addDirectSubNodes(QList &nodes) const; + static void addSubNodes(QList &nodes, const InternalProperty *property); + static void addDirectSubNodes(QList &nodes, const InternalProperty *property); friend bool operator<(const InternalNode::Pointer &firstNode, const InternalNode::Pointer &secondNode) @@ -185,9 +194,10 @@ public: friend size_t qHash(const InternalNodePointer &node) { return ::qHash(node.get()); } -protected: void removeProperty(const PropertyName &name); +protected: + public: TypeName typeName; QString id; diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h b/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h index 72e01d019b2..7205fe7377d 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h @@ -17,17 +17,12 @@ public: using Pointer = std::shared_ptr; using WeakPointer = std::weak_ptr; - virtual QList allSubNodes() const = 0; - virtual QList directSubNodes() const = 0; - virtual bool isEmpty() const = 0; virtual int count() const = 0; virtual int indexOf(const InternalNodePointer &node) const = 0; bool isValid() const override; - using InternalProperty::remove; // keep the virtual remove(...) function around - protected: InternalNodeAbstractProperty(const PropertyName &name, const InternalNodePointer &propertyOwner, diff --git a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp index f5c46627856..c5aaa8fa94a 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp @@ -60,20 +60,22 @@ void InternalNodeListProperty::slide(int from, int to) m_nodeList.insert(to, internalNode); } -QList InternalNodeListProperty::allSubNodes() const +void InternalNodeListProperty::addSubNodes(QList &container) const { - QList nodeList; - for (const InternalNode::Pointer &childNode : std::as_const(m_nodeList)) { - nodeList.append(childNode->allSubNodes()); - nodeList.append(childNode); + for (const auto &node : std::as_const(m_nodeList)) { + container.push_back(node); + node->addSubNodes(container); } - - return nodeList; } -QList InternalNodeListProperty::directSubNodes() const +QList InternalNodeListProperty::allSubNodes() const { - return nodeList(); + QList nodes; + nodes.reserve(1024); + + addSubNodes(nodes); + + return nodes; } } // namespace Internal diff --git a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h index 2e15fdf8aef..01b508b80ab 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h @@ -44,14 +44,18 @@ public: return *found; } - QList allSubNodes() const override; - QList directSubNodes() const override; + QList allSubNodes() const; const QList &nodeList() const; void slide(int from, int to); + void addSubNodes(QList &container) const; + QList::iterator begin() { return m_nodeList.begin(); } + QList::iterator end() { return m_nodeList.end(); } + const QList &nodes() const { return m_nodeList; } + protected: void add(const InternalNodePointer &node) override; void remove(const InternalNodePointer &node) override; diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp index 0dd286e765e..df9f5593725 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp @@ -39,11 +39,6 @@ bool InternalNodeProperty::isValid() const return InternalProperty::isValid() && isNodeProperty(); } -InternalNode::Pointer InternalNodeProperty::node() const -{ - return m_node; -} - void InternalNodeProperty::remove([[maybe_unused]] const InternalNode::Pointer &node) { Q_ASSERT(m_node == node); @@ -59,24 +54,18 @@ void InternalNodeProperty::add(const InternalNode::Pointer &node) QList InternalNodeProperty::allSubNodes() const { - QList nodeList; + QList nodes; + nodes.reserve(1024); - if (node()) { - nodeList.append(node()); - nodeList.append(node()->allSubNodes()); - } + addSubNodes(nodes); - return nodeList; + return nodes; } -QList InternalNodeProperty::directSubNodes() const +void InternalNodeProperty::addSubNodes(QList &container) const { - QList nodeList; - - if (node()) - nodeList.append(node()); - - return nodeList; + container.push_back(m_node); + m_node->addSubNodes(container); } } // namespace Internal diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h index 65b9b895e8a..bd4b66304e7 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h @@ -21,10 +21,10 @@ public: int count() const override; int indexOf(const InternalNodePointer &node) const override; - QList allSubNodes() const override; - QList directSubNodes() const override; + QList allSubNodes() const; + void addSubNodes(QList &container) const; - InternalNodePointer node() const; + const InternalNodePointer &node() const { return m_node; } protected: void add(const InternalNodePointer &node) override; diff --git a/src/plugins/qmldesigner/designercore/model/internalproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalproperty.cpp index 076c14fa9b6..a5735425bdb 100644 --- a/src/plugins/qmldesigner/designercore/model/internalproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalproperty.cpp @@ -37,17 +37,6 @@ PropertyName InternalProperty::name() const return m_name; } -InternalNode::Pointer InternalProperty::propertyOwner() const -{ - return m_propertyOwner.lock(); -} - -void InternalProperty::remove() -{ - propertyOwner()->removeProperty(name()); - m_propertyOwner.reset(); -} - TypeName InternalProperty::dynamicTypeName() const { return m_dynamicType; diff --git a/src/plugins/qmldesigner/designercore/model/internalproperty.h b/src/plugins/qmldesigner/designercore/model/internalproperty.h index 1f24b825093..66d0bcaa881 100644 --- a/src/plugins/qmldesigner/designercore/model/internalproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalproperty.h @@ -8,6 +8,7 @@ #include #include +#include namespace QmlDesigner { @@ -24,7 +25,7 @@ class InternalNode; using InternalNodePointer = std::shared_ptr; -template +template struct TypeLookup {}; @@ -68,6 +69,21 @@ struct TypeLookup using Type = InternalVariantProperty; }; +template<> +struct TypeLookup +{ + using Type = InternalNodeAbstractProperty; +}; + +template<> +struct TypeLookup +{ + using Type = InternalNodeAbstractProperty; +}; + +template +using type_lookup_t = typename TypeLookup::Type; + class QMLDESIGNERCORE_EXPORT InternalProperty : public std::enable_shared_from_this { public: @@ -103,24 +119,60 @@ public: return std::static_pointer_cast(shared_from_this()); } - template - auto to() + template + auto toShared() { - if (propertyType == m_propertyType) - return std::static_pointer_cast::Type>( - shared_from_this()); + using Type = type_lookup_t; - return std::shared_ptr::Type>{}; + if (((propertyType == m_propertyType) || ...)) + return std::static_pointer_cast(shared_from_this()); + + return std::shared_ptr{}; } - InternalNodePointer propertyOwner() const; + template + auto toShared() const + { + using Type = const type_lookup_t; - virtual void remove(); + if (((propertyType == m_propertyType) || ...)) + return std::static_pointer_cast(shared_from_this()); + + return std::shared_ptr{}; + } + + template + auto *to() + { + using Type = type_lookup_t; + + if (((propertyType == m_propertyType) || ...)) + return static_cast(this); + + return static_cast(nullptr); + } + + template + const auto *to() const + { + using Type = const type_lookup_t; + + if (((propertyType == m_propertyType) || ...)) + return static_cast(this); + + return static_cast(nullptr); + } + + const InternalNodePointer propertyOwner() const { return m_propertyOwner.lock(); } + + InternalNodePointer propertyOwner() { return m_propertyOwner.lock(); } TypeName dynamicTypeName() const; void resetDynamicTypeName(); + PropertyType type() const { return m_propertyType; } + protected: // functions InternalProperty(const PropertyName &name, const InternalNodePointer &propertyOwner, diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 653ffea077a..efc3a09a74e 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -426,7 +426,7 @@ void ModelPrivate::removeNode(const InternalNodePointer &node) } if (oldParentProperty && oldParentProperty->isEmpty()) { - removePropertyWithoutNotification(oldParentProperty); + removePropertyWithoutNotification(oldParentProperty.get()); propertyChangeFlags |= AbstractView::EmptyPropertiesRemoved; } @@ -753,8 +753,7 @@ void ModelPrivate::notifyPropertiesRemoved(const QList &propertyPa }); } -void ModelPrivate::notifyPropertiesAboutToBeRemoved( - const QList &internalPropertyList) +void ModelPrivate::notifyPropertiesAboutToBeRemoved(const QList &internalPropertyList) { bool resetModel = false; QString description; @@ -762,9 +761,12 @@ void ModelPrivate::notifyPropertiesAboutToBeRemoved( try { if (rewriterView()) { QList propertyList; - for (const InternalPropertyPointer &property : internalPropertyList) { - AbstractProperty newProperty(property->name(), property->propertyOwner(), m_model, rewriterView()); - propertyList.append(newProperty); + for (InternalProperty *property : internalPropertyList) { + AbstractProperty newProperty(property->name(), + property->propertyOwner(), + m_model, + rewriterView()); + propertyList.append(newProperty); } rewriterView()->propertiesAboutToBeRemoved(propertyList); @@ -777,7 +779,7 @@ void ModelPrivate::notifyPropertiesAboutToBeRemoved( for (const QPointer &view : enabledViews()) { QList propertyList; Q_ASSERT(view != nullptr); - for (const InternalPropertyPointer &property : internalPropertyList) { + for (auto property : internalPropertyList) { AbstractProperty newProperty(property->name(), property->propertyOwner(), m_model, view.data()); propertyList.append(newProperty); } @@ -792,7 +794,7 @@ void ModelPrivate::notifyPropertiesAboutToBeRemoved( if (nodeInstanceView()) { QList propertyList; - for (const InternalPropertyPointer &property : internalPropertyList) { + for (auto property : internalPropertyList) { AbstractProperty newProperty(property->name(), property->propertyOwner(), m_model, nodeInstanceView()); propertyList.append(newProperty); } @@ -900,11 +902,11 @@ void ModelPrivate::notifyNodeIdChanged(const InternalNodePointer &node, } void ModelPrivate::notifyBindingPropertiesAboutToBeChanged( - const QList &internalPropertyList) + const QList &internalPropertyList) { notifyNodeInstanceViewLast([&](AbstractView *view) { QList propertyList; - for (const InternalBindingPropertyPointer &bindingProperty : internalPropertyList) { + for (auto bindingProperty : internalPropertyList) { propertyList.append(BindingProperty(bindingProperty->name(), bindingProperty->propertyOwner(), m_model, @@ -914,13 +916,12 @@ void ModelPrivate::notifyBindingPropertiesAboutToBeChanged( }); } -void ModelPrivate::notifyBindingPropertiesChanged( - const QList &internalPropertyList, - AbstractView::PropertyChangeFlags propertyChange) +void ModelPrivate::notifyBindingPropertiesChanged(const QList &internalPropertyList, + AbstractView::PropertyChangeFlags propertyChange) { notifyNodeInstanceViewLast([&](AbstractView *view) { QList propertyList; - for (const InternalBindingPropertyPointer &bindingProperty : internalPropertyList) { + for (auto bindingProperty : internalPropertyList) { propertyList.append(BindingProperty(bindingProperty->name(), bindingProperty->propertyOwner(), m_model, @@ -931,12 +932,12 @@ void ModelPrivate::notifyBindingPropertiesChanged( } void ModelPrivate::notifySignalHandlerPropertiesChanged( - const QVector &internalPropertyList, + const QVector &internalPropertyList, AbstractView::PropertyChangeFlags propertyChange) { notifyNodeInstanceViewLast([&](AbstractView *view) { QVector propertyList; - for (const InternalSignalHandlerPropertyPointer &signalHandlerProperty : internalPropertyList) { + for (auto signalHandlerProperty : internalPropertyList) { propertyList.append(SignalHandlerProperty(signalHandlerProperty->name(), signalHandlerProperty->propertyOwner(), m_model, @@ -947,12 +948,12 @@ void ModelPrivate::notifySignalHandlerPropertiesChanged( } void ModelPrivate::notifySignalDeclarationPropertiesChanged( - const QVector &internalPropertyList, + const QVector &internalPropertyList, AbstractView::PropertyChangeFlags propertyChange) { notifyNodeInstanceViewLast([&](AbstractView *view) { QVector propertyList; - for (const InternalSignalDeclarationPropertyPointer &signalHandlerProperty : internalPropertyList) { + for (auto signalHandlerProperty : internalPropertyList) { propertyList.append(SignalDeclarationProperty(signalHandlerProperty->name(), signalHandlerProperty->propertyOwner(), m_model, @@ -986,7 +987,7 @@ void ModelPrivate::notifyVariantPropertiesChanged(const InternalNodePointer &nod } void ModelPrivate::notifyNodeAboutToBeReparent(const InternalNodePointer &node, - const InternalNodeAbstractPropertyPointer &newPropertyParent, + const InternalNodeAbstractProperty *newPropertyParent, const InternalNodePointer &oldParent, const PropertyName &oldPropertyName, AbstractView::PropertyChangeFlags propertyChange) @@ -998,8 +999,12 @@ void ModelPrivate::notifyNodeAboutToBeReparent(const InternalNodePointer &node, if (!oldPropertyName.isEmpty() && oldParent->isValid) oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, m_model, view); - if (newPropertyParent) - newProperty = NodeAbstractProperty(newPropertyParent, m_model, view); + if (newPropertyParent) { + newProperty = NodeAbstractProperty(newPropertyParent->name(), + newPropertyParent->propertyOwner(), + m_model, + view); + } ModelNode modelNode(node, m_model, view); view->nodeAboutToBeReparented(modelNode, newProperty, oldProperty, propertyChange); @@ -1007,7 +1012,7 @@ void ModelPrivate::notifyNodeAboutToBeReparent(const InternalNodePointer &node, } void ModelPrivate::notifyNodeReparent(const InternalNodePointer &node, - const InternalNodeAbstractPropertyPointer &newPropertyParent, + const InternalNodeAbstractProperty *newPropertyParent, const InternalNodePointer &oldParent, const PropertyName &oldPropertyName, AbstractView::PropertyChangeFlags propertyChange) @@ -1019,28 +1024,39 @@ void ModelPrivate::notifyNodeReparent(const InternalNodePointer &node, if (!oldPropertyName.isEmpty() && oldParent->isValid) oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, m_model, view); - if (newPropertyParent) - newProperty = NodeAbstractProperty(newPropertyParent, m_model, view); + if (newPropertyParent) { + newProperty = NodeAbstractProperty(newPropertyParent->name(), + newPropertyParent->propertyOwner(), + m_model, + view); + } + ModelNode modelNode(node, m_model, view); view->nodeReparented(modelNode, newProperty, oldProperty, propertyChange); }); } -void ModelPrivate::notifyNodeOrderChanged(const InternalNodeListPropertyPointer &internalListProperty, +void ModelPrivate::notifyNodeOrderChanged(const InternalNodeListProperty *internalListProperty, const InternalNodePointer &node, int oldIndex) { notifyNodeInstanceViewLast([&](AbstractView *view) { - NodeListProperty nodeListProperty(internalListProperty, m_model, view); + NodeListProperty nodeListProperty(internalListProperty->name(), + internalListProperty->propertyOwner(), + m_model, + view); view->nodeOrderChanged(nodeListProperty, ModelNode(node, m_model, view), oldIndex); }); } -void ModelPrivate::notifyNodeOrderChanged(const InternalNodeListPropertyPointer &internalListProperty) +void ModelPrivate::notifyNodeOrderChanged(const InternalNodeListProperty *internalListProperty) { notifyNodeInstanceViewLast([&](AbstractView *view) { - NodeListProperty nodeListProperty(internalListProperty, m_model, view); + NodeListProperty nodeListProperty(internalListProperty->name(), + internalListProperty->propertyOwner(), + m_model, + view); view->nodeOrderChanged(nodeListProperty); }); } @@ -1118,9 +1134,9 @@ QVector ModelPrivate::toInternalNodeVector(const QVector ModelPrivate::toInternalProperties(const AbstractProperties &properties) +QList ModelPrivate::toInternalProperties(const AbstractProperties &properties) { - QList internalProperties; + QList internalProperties; internalProperties.reserve(properties.size()); for (const auto &property : properties) { @@ -1133,10 +1149,10 @@ QList ModelPrivate::toInternalProperties(const Abstract return internalProperties; } -QList> ModelPrivate::toInternalBindingProperties( +QList> ModelPrivate::toInternalBindingProperties( const ModelResourceSet::SetExpressions &setExpressions) { - QList> internalProperties; + QList> internalProperties; internalProperties.reserve(setExpressions.size()); for (const auto &setExpression : setExpressions) { @@ -1195,45 +1211,48 @@ void ModelPrivate::deselectNode(const InternalNodePointer &node) setSelectedNodes(selectedNodeList); } -void ModelPrivate::removePropertyWithoutNotification(const InternalPropertyPointer &property) +void ModelPrivate::removePropertyWithoutNotification(InternalProperty *property) { - if (property->isNodeAbstractProperty()) { - const auto &&allSubNodes = property->toProperty()->allSubNodes(); + if (auto nodeListProperty = property->to()) { + const auto allSubNodes = nodeListProperty->allSubNodes(); for (const InternalNodePointer &node : allSubNodes) removeNodeFromModel(node); + } else if (auto nodeProperty = property->to()) { + removeNodeFromModel({nodeProperty->node()}); } - property->remove(); + auto propertyOwner = property->propertyOwner(); + propertyOwner->removeProperty(property->name()); } -static QList toPropertyPairList(const QList &propertyList) +static QList toPropertyPairList(const QList &propertyList) { QList propertyPairList; propertyPairList.reserve(propertyList.size()); - for (const InternalPropertyPointer &property : propertyList) + for (const InternalProperty *property : propertyList) propertyPairList.append({property->propertyOwner(), property->name()}); return propertyPairList; } -void ModelPrivate::removePropertyAndRelatedResources(const InternalPropertyPointer &property) +void ModelPrivate::removePropertyAndRelatedResources(InternalProperty *property) { if (m_resourceManagement) { - handleResourceSet( - m_resourceManagement->removeProperties({AbstractProperty{property, m_model, nullptr}}, - m_model)); + handleResourceSet(m_resourceManagement->removeProperties( + {AbstractProperty{property->name(), property->propertyOwner(), m_model, nullptr}}, + m_model)); } else { removeProperty(property); } } -void ModelPrivate::removeProperty(const InternalPropertyPointer &property) +void ModelPrivate::removeProperty(InternalProperty *property) { removeProperties({property}); } -void ModelPrivate::removeProperties(const QList &properties) +void ModelPrivate::removeProperties(const QList &properties) { if (properties.isEmpty()) return; @@ -1242,7 +1261,7 @@ void ModelPrivate::removeProperties(const QList &proper const QList propertyPairList = toPropertyPairList(properties); - for (const auto &property : properties) + for (auto property : properties) removePropertyWithoutNotification(property); notifyPropertiesRemoved(propertyPairList); @@ -1253,12 +1272,14 @@ void ModelPrivate::setBindingProperty(const InternalNodePointer &node, const QString &expression) { AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; - if (!node->hasProperty(name)) { - node->addBindingProperty(name); + InternalBindingProperty *bindingProperty = nullptr; + if (auto property = node->property(name)) { + bindingProperty = property->to(); + } else { + bindingProperty = node->addBindingProperty(name); propertyChange = AbstractView::PropertiesAdded; } - InternalBindingPropertyPointer bindingProperty = node->bindingProperty(name); notifyBindingPropertiesAboutToBeChanged({bindingProperty}); bindingProperty->setExpression(expression); notifyBindingPropertiesChanged({bindingProperty}, propertyChange); @@ -1283,12 +1304,14 @@ void ModelPrivate::setBindingProperties(const ModelResourceSet::SetExpressions & void ModelPrivate::setSignalHandlerProperty(const InternalNodePointer &node, const PropertyName &name, const QString &source) { AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; - if (!node->hasProperty(name)) { - node->addSignalHandlerProperty(name); + InternalSignalHandlerProperty *signalHandlerProperty = nullptr; + if (auto property = node->property(name)) { + signalHandlerProperty = property->to(); + } else { + signalHandlerProperty = node->addSignalHandlerProperty(name); propertyChange = AbstractView::PropertiesAdded; } - InternalSignalHandlerPropertyPointer signalHandlerProperty = node->signalHandlerProperty(name); signalHandlerProperty->setSource(source); notifySignalHandlerPropertiesChanged({signalHandlerProperty}, propertyChange); } @@ -1296,12 +1319,14 @@ void ModelPrivate::setSignalHandlerProperty(const InternalNodePointer &node, con void ModelPrivate::setSignalDeclarationProperty(const InternalNodePointer &node, const PropertyName &name, const QString &signature) { AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; - if (!node->hasProperty(name)) { - node->addSignalDeclarationProperty(name); + InternalSignalDeclarationProperty *signalDeclarationProperty = nullptr; + if (auto property = node->property(name)) { + signalDeclarationProperty = property->to(); + } else { + signalDeclarationProperty = node->addSignalDeclarationProperty(name); propertyChange = AbstractView::PropertiesAdded; } - InternalSignalDeclarationPropertyPointer signalDeclarationProperty = node->signalDeclarationProperty(name); signalDeclarationProperty->setSignature(signature); notifySignalDeclarationPropertiesChanged({signalDeclarationProperty}, propertyChange); } @@ -1309,13 +1334,16 @@ void ModelPrivate::setSignalDeclarationProperty(const InternalNodePointer &node, void ModelPrivate::setVariantProperty(const InternalNodePointer &node, const PropertyName &name, const QVariant &value) { AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; - if (!node->hasProperty(name)) { - node->addVariantProperty(name); + InternalVariantProperty *variantProperty = nullptr; + if (auto property = node->property(name)) { + variantProperty = property->to(); + } else { + variantProperty = node->addVariantProperty(name); propertyChange = AbstractView::PropertiesAdded; } - node->variantProperty(name)->setValue(value); - node->variantProperty(name)->resetDynamicTypeName(); + variantProperty->setValue(value); + variantProperty->resetDynamicTypeName(); notifyVariantPropertiesChanged(node, PropertyNameList({name}), propertyChange); } @@ -1325,12 +1353,15 @@ void ModelPrivate::setDynamicVariantProperty(const InternalNodePointer &node, const QVariant &value) { AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; - if (!node->hasProperty(name)) { - node->addVariantProperty(name); + InternalVariantProperty *variantProperty = nullptr; + if (auto property = node->property(name)) { + variantProperty = property->to(); + } else { + variantProperty = node->addVariantProperty(name); propertyChange = AbstractView::PropertiesAdded; } - node->variantProperty(name)->setDynamicValue(dynamicPropertyType, value); + variantProperty->setDynamicValue(dynamicPropertyType, value); notifyVariantPropertiesChanged(node, PropertyNameList({name}), propertyChange); } @@ -1340,12 +1371,14 @@ void ModelPrivate::setDynamicBindingProperty(const InternalNodePointer &node, const QString &expression) { AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; - if (!node->hasProperty(name)) { - node->addBindingProperty(name); + InternalBindingProperty *bindingProperty = nullptr; + if (auto property = node->property(name)) { + bindingProperty = property->to(); + } else { + bindingProperty = node->addBindingProperty(name); propertyChange = AbstractView::PropertiesAdded; } - InternalBindingPropertyPointer bindingProperty = node->bindingProperty(name); notifyBindingPropertiesAboutToBeChanged({bindingProperty}); bindingProperty->setDynamicExpression(dynamicPropertyType, expression); notifyBindingPropertiesChanged({bindingProperty}, propertyChange); @@ -1358,11 +1391,15 @@ void ModelPrivate::reparentNode(const InternalNodePointer &parentNode, const TypeName &dynamicTypeName) { AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; - if (!parentNode->hasProperty(name)) { + InternalNodeAbstractProperty *newParentProperty = nullptr; + if (auto property = parentNode->property(name)) { + newParentProperty = property->to(); + } else { if (list) - parentNode->addNodeListProperty(name); + newParentProperty = parentNode->addNodeListProperty(name); else - parentNode->addNodeProperty(name, dynamicTypeName); + newParentProperty = parentNode->addNodeProperty(name, dynamicTypeName); + propertyChange |= AbstractView::PropertiesAdded; } @@ -1374,16 +1411,21 @@ void ModelPrivate::reparentNode(const InternalNodePointer &parentNode, oldParentPropertyName = childNode->parentProperty()->name(); } - InternalNodeAbstractPropertyPointer newParentProperty(parentNode->nodeAbstractProperty(name)); Q_ASSERT(newParentProperty); - notifyNodeAboutToBeReparent(childNode, newParentProperty, oldParentNode, oldParentPropertyName, propertyChange); + notifyNodeAboutToBeReparent(childNode, + newParentProperty, + oldParentNode, + oldParentPropertyName, + propertyChange); - if (newParentProperty) - childNode->setParentProperty(newParentProperty); + if (newParentProperty) { + childNode->setParentProperty( + newParentProperty->toShared()); + } if (oldParentProperty && oldParentProperty->isValid() && oldParentProperty->isEmpty()) { - removePropertyWithoutNotification(oldParentProperty); + removePropertyWithoutNotification(oldParentProperty.get()); propertyChange |= AbstractView::EmptyPropertiesRemoved; } @@ -1402,7 +1444,11 @@ void ModelPrivate::clearParent(const InternalNodePointer &node) } node->resetParentProperty(); - notifyNodeReparent(node, InternalNodeAbstractPropertyPointer(), oldParentNode, oldParentPropertyName, AbstractView::NoAdditionalChanges); + notifyNodeReparent(node, + nullptr, + oldParentNode, + oldParentPropertyName, + AbstractView::NoAdditionalChanges); } void ModelPrivate::changeRootNodeType(const TypeName &type, int majorVersion, int minorVersion) @@ -1431,7 +1477,7 @@ void ModelPrivate::setNodeSource(const InternalNodePointer &node, const QString void ModelPrivate::changeNodeOrder(const InternalNodePointer &parentNode, const PropertyName &listPropertyName, int from, int to) { - InternalNodeListPropertyPointer nodeList(parentNode->nodeListProperty(listPropertyName)); + auto nodeList = parentNode->nodeListProperty(listPropertyName); Q_ASSERT(nodeList); nodeList->slide(from, to); @@ -1742,7 +1788,7 @@ QString Model::generateNewId(const QString &prefixName, isDuplicate = std::bind(&Model::hasId, this, std::placeholders::_1); while (!ModelNode::isValidId(newId) || isDuplicate.value()(newId) - || d->rootNode()->hasProperty(newId.toUtf8())) { + || d->rootNode()->property(newId.toUtf8())) { ++counter; newId = QString(QStringLiteral("%1%2")).arg(firstCharToLower(newBaseId)).arg(counter); } diff --git a/src/plugins/qmldesigner/designercore/model/model_p.h b/src/plugins/qmldesigner/designercore/model/model_p.h index 324df37ddb2..88f3891b505 100644 --- a/src/plugins/qmldesigner/designercore/model/model_p.h +++ b/src/plugins/qmldesigner/designercore/model/model_p.h @@ -43,14 +43,6 @@ class InternalVariantProperty; class InternalNodeAbstractProperty; class InternalNodeListProperty; -using InternalNodePointer = std::shared_ptr; -using InternalPropertyPointer = std::shared_ptr; -using InternalBindingPropertyPointer = std::shared_ptr; -using InternalSignalHandlerPropertyPointer = std::shared_ptr; -using InternalSignalDeclarationPropertyPointer = std::shared_ptr; -using InternalVariantPropertyPointer = std::shared_ptr; -using InternalNodeAbstractPropertyPointer = std::shared_ptr; -using InternalNodeListPropertyPointer = std::shared_ptr; using PropertyPair = QPair; class ModelPrivate; @@ -156,12 +148,12 @@ public: void notifyNodeCreated(const InternalNodePointer &newNode); void notifyNodeAboutToBeReparent(const InternalNodePointer &node, - const InternalNodeAbstractPropertyPointer &newPropertyParent, + const InternalNodeAbstractProperty *newPropertyParent, const InternalNodePointer &oldParent, const PropertyName &oldPropertyName, AbstractView::PropertyChangeFlags propertyChange); void notifyNodeReparent(const InternalNodePointer &node, - const InternalNodeAbstractPropertyPointer &newPropertyParent, + const InternalNodeAbstractProperty *newPropertyParent, const InternalNodePointer &oldParent, const PropertyName &oldPropertyName, AbstractView::PropertyChangeFlags propertyChange); @@ -174,19 +166,25 @@ public: void notifyNodeTypeChanged(const InternalNodePointer &node, const TypeName &type, int majorVersion, int minorVersion); void notifyPropertiesRemoved(const QList &propertyList); - void notifyPropertiesAboutToBeRemoved(const QList &internalPropertyList); + void notifyPropertiesAboutToBeRemoved(const QList &internalPropertyList); void notifyBindingPropertiesAboutToBeChanged( - const QList &internalPropertyList); - void notifyBindingPropertiesChanged(const QList &internalPropertyList, AbstractView::PropertyChangeFlags propertyChange); - void notifySignalHandlerPropertiesChanged(const QVector &propertyList, AbstractView::PropertyChangeFlags propertyChange); - void notifySignalDeclarationPropertiesChanged(const QVector &propertyList, AbstractView::PropertyChangeFlags propertyChange); + const QList &internalPropertyList); + void notifyBindingPropertiesChanged( + const QList &internalPropertyList, + AbstractView::PropertyChangeFlags propertyChange); + void notifySignalHandlerPropertiesChanged( + const QVector &propertyList, + AbstractView::PropertyChangeFlags propertyChange); + void notifySignalDeclarationPropertiesChanged( + const QVector &propertyList, + AbstractView::PropertyChangeFlags propertyChange); void notifyVariantPropertiesChanged(const InternalNodePointer &node, const PropertyNameList &propertyNameList, AbstractView::PropertyChangeFlags propertyChange); void notifyScriptFunctionsChanged(const InternalNodePointer &node, const QStringList &scriptFunctionList); - void notifyNodeOrderChanged(const InternalNodeListPropertyPointer &internalListProperty, + void notifyNodeOrderChanged(const QmlDesigner::Internal::InternalNodeListProperty *internalListProperty, const InternalNodePointer &node, int oldIndex); - void notifyNodeOrderChanged(const InternalNodeListPropertyPointer &internalListProperty); + void notifyNodeOrderChanged(const InternalNodeListProperty *internalListProperty); void notifyAuxiliaryDataChanged(const InternalNodePointer &node, AuxiliaryDataKeyView key, const QVariant &data); @@ -248,9 +246,9 @@ public: //node state property manipulation void addProperty(const InternalNodePointer &node, const PropertyName &name); void setPropertyValue(const InternalNodePointer &node,const PropertyName &name, const QVariant &value); - void removePropertyAndRelatedResources(const InternalPropertyPointer &property); - void removeProperty(const InternalPropertyPointer &property); - void removeProperties(const QList &properties); + void removePropertyAndRelatedResources(InternalProperty *property); + void removeProperty(InternalProperty *property); + void removeProperties(const QList &properties); void setBindingProperty(const InternalNodePointer &node, const PropertyName &name, @@ -300,16 +298,16 @@ public: } private: - void removePropertyWithoutNotification(const InternalPropertyPointer &property); + void removePropertyWithoutNotification(InternalProperty *property); void removeAllSubNodes(const InternalNodePointer &node); void removeNodeFromModel(const InternalNodePointer &node); QList toInternalNodeList(const QList &modelNodeList) const; QList toModelNodeList(const QList &nodeList, AbstractView *view) const; QVector toModelNodeVector(const QVector &nodeVector, AbstractView *view) const; QVector toInternalNodeVector(const QVector &modelNodeVector) const; - static QList toInternalProperties(const AbstractProperties &properties); - static QList> toInternalBindingProperties( - const ModelResourceSet::SetExpressions &setExpressions); + static QList toInternalProperties(const AbstractProperties &properties); + static QList> + toInternalBindingProperties(const ModelResourceSet::SetExpressions &setExpressions); EnabledViewRange enabledViews() const; ImportedTypeNameId importedTypeNameId(Utils::SmallStringView typeName); void setTypeId(InternalNode *node, Utils::SmallStringView typeName); diff --git a/src/plugins/qmldesigner/designercore/model/modelnode.cpp b/src/plugins/qmldesigner/designercore/model/modelnode.cpp index cb862b03431..0c289a7d579 100644 --- a/src/plugins/qmldesigner/designercore/model/modelnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/modelnode.cpp @@ -607,8 +607,8 @@ void ModelNode::removeProperty(const PropertyName &name) const if (!model()->d->propertyNameIsValid(name)) return; - if (m_internalNode->hasProperty(name)) - model()->d->removePropertyAndRelatedResources(m_internalNode->property(name)); + if (auto property = m_internalNode->property(name)) + model()->d->removePropertyAndRelatedResources(property); } /*! \brief removes this node from the node tree @@ -800,7 +800,7 @@ PropertyNameList ModelNode::propertyNames() const */ bool ModelNode::hasProperty(const PropertyName &name) const { - return isValid() && m_internalNode->hasProperty(name); + return isValid() && m_internalNode->property(name); } bool ModelNode::hasVariantProperty(const PropertyName &name) const diff --git a/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp index 0688ff1c256..f131137ae87 100644 --- a/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp @@ -18,7 +18,7 @@ namespace QmlDesigner { NodeAbstractProperty::NodeAbstractProperty() = default; NodeAbstractProperty::NodeAbstractProperty(const NodeAbstractProperty &property, AbstractView *view) - : AbstractProperty(property.name(), property.internalNode(), property.model(), view) + : AbstractProperty(property.name(), property.internalNodeSharedPointer(), property.model(), view) { } @@ -36,14 +36,9 @@ void NodeAbstractProperty::reparentHere(const ModelNode &modelNode) if (!isValid() || !modelNode.isValid()) return; - if (internalNode()->hasProperty(name()) - && !internalNode()->property(name())->isNodeAbstractProperty()) { - reparentHere(modelNode, isNodeListProperty()); - } else { - reparentHere(modelNode, - parentModelNode().metaInfo().property(name()).isListProperty() - || isDefaultProperty()); //we could use the metasystem instead? - } + reparentHere(modelNode, + parentModelNode().metaInfo().property(name()).isListProperty() + || isDefaultProperty()); //we could use the metasystem instead? } void NodeAbstractProperty::reparentHere(const ModelNode &modelNode, bool isNodeList, const TypeName &dynamicTypeName) @@ -70,19 +65,28 @@ void NodeAbstractProperty::reparentHere(const ModelNode &modelNode, bool isNode if (modelNode.hasParentProperty() && modelNode.parentProperty().isDynamic()) return; - auto internalProperty = internalNode()->property(name()); - if (internalProperty && !internalProperty->isNodeAbstractProperty()) + if (auto internalProperty = internalNode()->property(name()); + internalProperty && !internalProperty->isNodeAbstractProperty()) { privateModel()->removePropertyAndRelatedResources(internalProperty); + } if (modelNode.hasParentProperty()) { Internal::InternalNodeAbstractProperty::Pointer oldParentProperty = modelNode.internalNode()->parentProperty(); - privateModel()->reparentNode(internalNode(), name(), modelNode.internalNode(), isNodeList, dynamicTypeName); + privateModel()->reparentNode(internalNodeSharedPointer(), + name(), + modelNode.internalNode(), + isNodeList, + dynamicTypeName); Q_ASSERT(oldParentProperty); } else { - privateModel()->reparentNode(internalNode(), name(), modelNode.internalNode(), isNodeList, dynamicTypeName); + privateModel()->reparentNode(internalNodeSharedPointer(), + name(), + modelNode.internalNode(), + isNodeList, + dynamicTypeName); } } @@ -136,22 +140,62 @@ int NodeAbstractProperty::count() const QList NodeAbstractProperty::allSubNodes() { - if (!internalNode() || !internalNode()->isValid || !internalNode()->hasProperty(name()) - || !internalNode()->property(name())->isNodeAbstractProperty()) + if (!internalNode() || !internalNode()->isValid) return {}; - Internal::InternalNodeAbstractProperty::Pointer property = internalNode()->nodeAbstractProperty(name()); - return QmlDesigner::toModelNodeList(property->allSubNodes(), model(), view()); + auto property = internalNode()->property(name()); + + if (!property) + return {}; + + switch (property->type()) { + case PropertyType::Node: + return QmlDesigner::toModelNodeList({property->to()->allSubNodes()}, + model(), + view()); + case PropertyType::NodeList: + return QmlDesigner::toModelNodeList({property->to()->allSubNodes()}, + model(), + view()); + case PropertyType::Binding: + case PropertyType::None: + case PropertyType::SignalDeclaration: + case PropertyType::SignalHandler: + case PropertyType::Variant: + break; + } + + return {}; } QList NodeAbstractProperty::directSubNodes() const { - if (!internalNode() || !internalNode()->isValid || !internalNode()->hasProperty(name()) - || !internalNode()->property(name())->isNodeAbstractProperty()) + if (!internalNode() || !internalNode()->isValid) return {}; - Internal::InternalNodeAbstractProperty::Pointer property = internalNode()->nodeAbstractProperty(name()); - return QmlDesigner::toModelNodeList(property->directSubNodes(), model(), view()); + auto property = internalNode()->property(name()); + + if (!property) + return {}; + + switch (property->type()) { + case PropertyType::Node: + return QmlDesigner::toModelNodeList({property->to()->node()}, + model(), + view()); + case PropertyType::NodeList: + return QmlDesigner::toModelNodeList({property->to()->nodes()}, + model(), + view()); + case PropertyType::Binding: + case PropertyType::None: + case PropertyType::SignalDeclaration: + case PropertyType::SignalHandler: + case PropertyType::Variant: + break; + } + + return {}; } /*! diff --git a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp index 0822786467e..18100e5298f 100644 --- a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp @@ -23,14 +23,11 @@ Internal::NodeListPropertyIterator::value_type Internal::NodeListPropertyIterato NodeListProperty::NodeListProperty() = default; -NodeListProperty::NodeListProperty(const NodeListProperty &property, AbstractView *view) - : NodeAbstractProperty(property.name(), property.internalNode(), property.model(), view) -{ - -} - -NodeListProperty::NodeListProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view) : - NodeAbstractProperty(propertyName, internalNode, model, view) +NodeListProperty::NodeListProperty(const PropertyName &propertyName, + const Internal::InternalNodePointer &internalNode, + Model *model, + AbstractView *view) + : NodeAbstractProperty(propertyName, internalNode, model, view) { } @@ -44,10 +41,11 @@ Internal::InternalNodeListPropertyPointer &NodeListProperty::internalNodeListPro if (m_internalNodeListProperty) return m_internalNodeListProperty; - auto internalProperty = internalNode()->nodeListProperty(name()); - if (internalProperty) - m_internalNodeListProperty = internalProperty; - + auto property = internalNode()->property(name()); + if (property) { + if (auto nodeListProperty = property->toShared()) + m_internalNodeListProperty = nodeListProperty; + } return m_internalNodeListProperty; } @@ -94,7 +92,7 @@ void NodeListProperty::slide(int from, int to) const if (to < 0 || to > count() - 1 || from < 0 || from > count() - 1) return; - privateModel()->changeNodeOrder(internalNode(), name(), from, to); + privateModel()->changeNodeOrder(internalNodeSharedPointer(), name(), from, to); } void NodeListProperty::swap(int from, int to) const @@ -159,7 +157,7 @@ NodeListProperty::iterator NodeListProperty::rotate(NodeListProperty::iterator f std::next(begin, newFirst.m_currentIndex), std::next(begin, last.m_currentIndex)); - privateModel()->notifyNodeOrderChanged(m_internalNodeListProperty); + privateModel()->notifyNodeOrderChanged(m_internalNodeListProperty.get()); return {iter - begin, internalNodeListProperty().get(), model(), view()}; } @@ -176,7 +174,7 @@ void NodeListProperty::reverse(NodeListProperty::iterator first, NodeListPropert std::reverse(std::next(begin, first.m_currentIndex), std::next(begin, last.m_currentIndex)); - privateModel()->notifyNodeOrderChanged(m_internalNodeListProperty); + privateModel()->notifyNodeOrderChanged(m_internalNodeListProperty.get()); } void NodeListProperty::reverseModelNodes(const QList &nodes) diff --git a/src/plugins/qmldesigner/designercore/model/nodeproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodeproperty.cpp index a628c96b7d2..88983f6b4bc 100644 --- a/src/plugins/qmldesigner/designercore/model/nodeproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodeproperty.cpp @@ -30,10 +30,13 @@ void NodeProperty::setModelNode(const ModelNode &modelNode) return; } - if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isNodeProperty()) - privateModel()->removePropertyAndRelatedResources(internalNode()->property(name())); + if (auto property = internalNode()->property(name()); !property->isNodeProperty()) + privateModel()->removePropertyAndRelatedResources(property); - privateModel()->reparentNode(internalNode(), name(), modelNode.internalNode(), false); //### we have to add a flag that this is not a list + privateModel()->reparentNode(internalNodeSharedPointer(), + name(), + modelNode.internalNode(), + false); //### we have to add a flag that this is not a list } ModelNode NodeProperty::modelNode() const diff --git a/src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp b/src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp index a260a2a0ef9..fcae441e529 100644 --- a/src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp @@ -11,7 +11,7 @@ namespace QmlDesigner { SignalHandlerProperty::SignalHandlerProperty() = default; SignalHandlerProperty::SignalHandlerProperty(const SignalHandlerProperty &property, AbstractView *view) - : AbstractProperty(property.name(), property.internalNode(), property.model(), view) + : AbstractProperty(property.name(), property.internalNodeSharedPointer(), property.model(), view) { } @@ -42,7 +42,7 @@ void SignalHandlerProperty::setSource(const QString &source) privateModel()->removePropertyAndRelatedResources(internalProperty); } - privateModel()->setSignalHandlerProperty(internalNode(), name(), source); + privateModel()->setSignalHandlerProperty(internalNodeSharedPointer(), name(), source); } QString SignalHandlerProperty::source() const @@ -50,9 +50,8 @@ QString SignalHandlerProperty::source() const if (!isValid()) return {}; - if (internalNode()->hasProperty(name()) - && internalNode()->property(name())->isSignalHandlerProperty()) - return internalNode()->signalHandlerProperty(name())->source(); + if (auto property = internalNode()->signalHandlerProperty(name())) + return property->source(); return QString(); } @@ -87,7 +86,7 @@ SignalDeclarationProperty::SignalDeclarationProperty() = default; SignalDeclarationProperty::SignalDeclarationProperty(const SignalDeclarationProperty &property, AbstractView *view) - : AbstractProperty(property.name(), property.internalNode(), property.model(), view) + : AbstractProperty(property.name(), property.internalNodeSharedPointer(), property.model(), view) {} SignalDeclarationProperty::SignalDeclarationProperty( @@ -121,7 +120,7 @@ void SignalDeclarationProperty::setSignature(const QString &signature) privateModel()->removePropertyAndRelatedResources(internalProperty); } - privateModel()->setSignalDeclarationProperty(internalNode(), name(), signature); + privateModel()->setSignalDeclarationProperty(internalNodeSharedPointer(), name(), signature); } QString SignalDeclarationProperty::signature() const @@ -129,9 +128,8 @@ QString SignalDeclarationProperty::signature() const if (!isValid()) return {}; - if (internalNode()->hasProperty(name()) - && internalNode()->property(name())->isSignalDeclarationProperty()) - return internalNode()->signalDeclarationProperty(name())->signature(); + if (auto property = internalNode()->signalDeclarationProperty(name())) + return property->signature(); return QString(); } diff --git a/src/plugins/qmldesigner/designercore/model/variantproperty.cpp b/src/plugins/qmldesigner/designercore/model/variantproperty.cpp index 859bb0691ec..37d52ceb19f 100644 --- a/src/plugins/qmldesigner/designercore/model/variantproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/variantproperty.cpp @@ -14,7 +14,7 @@ namespace QmlDesigner { VariantProperty::VariantProperty() = default; VariantProperty::VariantProperty(const VariantProperty &property, AbstractView *view) - : AbstractProperty(property.name(), property.internalNode(), property.model(), view) + : AbstractProperty(property.name(), property.internalNodeSharedPointer(), property.model(), view) { } @@ -49,7 +49,7 @@ void VariantProperty::setValue(const QVariant &value) privateModel()->removePropertyAndRelatedResources(internalProperty); } - privateModel()->setVariantProperty(internalNode(), name(), value); + privateModel()->setVariantProperty(internalNodeSharedPointer(), name(), value); } QVariant VariantProperty::value() const @@ -99,7 +99,7 @@ void VariantProperty::setDynamicTypeNameAndValue(const TypeName &type, const QVa privateModel()->removePropertyAndRelatedResources(internalProperty); } - privateModel()->setDynamicVariantProperty(internalNode(), name(), type, value); + privateModel()->setDynamicVariantProperty(internalNodeSharedPointer(), name(), type, value); } void VariantProperty::setDynamicTypeNameAndEnumeration(const TypeName &type, const EnumerationName &enumerationName)