diff --git a/src/plugins/qmldesigner/designercore/include/abstractproperty.h b/src/plugins/qmldesigner/designercore/include/abstractproperty.h index d3f8c59ffe4..6074858265a 100644 --- a/src/plugins/qmldesigner/designercore/include/abstractproperty.h +++ b/src/plugins/qmldesigner/designercore/include/abstractproperty.h @@ -79,6 +79,8 @@ public: bool isSignalHandlerProperty() const; bool isSignalDeclarationProperty() const; + PropertyType type() const; + bool isDynamic() const; TypeName dynamicTypeName() const; @@ -124,7 +126,7 @@ 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; + Internal::InternalNodePointer internalNode() const { return m_internalNode; } Internal::ModelPrivate *privateModel() const; private: diff --git a/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp b/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp index 108dea7b038..e2e5800cab3 100644 --- a/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/abstractproperty.cpp @@ -51,11 +51,6 @@ AbstractProperty::AbstractProperty(const AbstractProperty &property, AbstractVie AbstractProperty::~AbstractProperty() = default; -Internal::InternalNodePointer AbstractProperty::internalNode() const -{ - return m_internalNode; -} - Internal::ModelPrivate *AbstractProperty::privateModel() const { return m_model ? m_model->d.get() : nullptr; @@ -295,6 +290,17 @@ bool AbstractProperty::isSignalDeclarationProperty() const return false; } +PropertyType AbstractProperty::type() const +{ + if (!isValid()) + return PropertyType::None; + + if (internalNode()->hasProperty(name())) + return internalNode()->property(name())->propertyType(); + + return PropertyType::None; +} + bool AbstractProperty::isBindingProperty() const { if (!isValid()) diff --git a/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp b/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp index 5381ecf4b8e..30f8d50fd4c 100644 --- a/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/bindingproperty.cpp @@ -48,16 +48,15 @@ void BindingProperty::setExpression(const QString &expression) if (expression.isEmpty()) return; - if (internalNode()->hasProperty(name())) { //check if oldValue != value - Internal::InternalProperty::Pointer internalProperty = internalNode()->property(name()); - if (internalProperty->isBindingProperty() - && internalProperty->toBindingProperty()->expression() == expression) - + if (auto internalProperty = internalNode()->property(name())) { + auto bindingProperty = internalProperty->to(); + //check if oldValue != value + if (bindingProperty && bindingProperty->expression() == expression) return; - } - if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isBindingProperty()) - privateModel()->removePropertyAndRelatedResources(internalNode()->property(name())); + if (!bindingProperty) + privateModel()->removePropertyAndRelatedResources(internalProperty); + } privateModel()->setBindingProperty(internalNode(), name(), expression); } @@ -340,20 +339,19 @@ void BindingProperty::setDynamicTypeNameAndExpression(const TypeName &typeName, if (typeName.isEmpty()) return; - if (internalNode()->hasProperty(name())) { //check if oldValue != value - Internal::InternalProperty::Pointer internalProperty = internalNode()->property(name()); - if (internalProperty->isBindingProperty() - && internalProperty->toBindingProperty()->expression() == expression - && internalProperty->toBindingProperty()->dynamicTypeName() == typeName) { - + if (auto internalProperty = internalNode()->property(name())) { + auto bindingProperty = internalProperty->to(); + //check if oldValue != value + if (bindingProperty && bindingProperty->expression() == expression + && internalProperty->dynamicTypeName() == typeName) { return; } + + if (!bindingProperty) + privateModel()->removePropertyAndRelatedResources(internalProperty); } - if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isBindingProperty()) - privateModel()->removePropertyAndRelatedResources(internalNode()->property(name())); - - privateModel()->setDynamicBindingProperty(internalNode(), name(), typeName, expression); + privateModel()->setDynamicBindingProperty(internalNode(), name(), typeName, expression); } QDebug operator<<(QDebug debug, const BindingProperty &property) diff --git a/src/plugins/qmldesigner/designercore/model/internalbindingproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalbindingproperty.cpp index 3ac5b112bf9..6a3eee19753 100644 --- a/src/plugins/qmldesigner/designercore/model/internalbindingproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalbindingproperty.cpp @@ -6,8 +6,9 @@ namespace QmlDesigner { namespace Internal { -InternalBindingProperty::InternalBindingProperty(const PropertyName &name, const InternalNodePointer &propertyOwner) - : InternalProperty(name, propertyOwner) +InternalBindingProperty::InternalBindingProperty(const PropertyName &name, + const InternalNodePointer &propertyOwner) + : InternalProperty(name, propertyOwner, PropertyType::Binding) { } @@ -25,11 +26,6 @@ void InternalBindingProperty::setExpression(const QString &expression) m_expression = expression; } -bool InternalBindingProperty::isBindingProperty() const -{ - return true; -} - void InternalBindingProperty::setDynamicExpression(const TypeName &type, const QString &expression) { setExpression(expression); diff --git a/src/plugins/qmldesigner/designercore/model/internalbindingproperty.h b/src/plugins/qmldesigner/designercore/model/internalbindingproperty.h index 3645839eb94..9ad0e19fc9e 100644 --- a/src/plugins/qmldesigner/designercore/model/internalbindingproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalbindingproperty.h @@ -12,6 +12,8 @@ class InternalBindingProperty : public InternalProperty { public: using Pointer = std::shared_ptr; + static constexpr PropertyType type = PropertyType::Binding; + InternalBindingProperty(const PropertyName &name, const InternalNodePointer &propertyOwner); bool isValid() const override; @@ -21,8 +23,6 @@ public: void setDynamicExpression(const TypeName &type, const QString &expression); - bool isBindingProperty() const override; - protected: private: diff --git a/src/plugins/qmldesigner/designercore/model/internalnode.cpp b/src/plugins/qmldesigner/designercore/model/internalnode.cpp index 705b405a55d..0c81d2ab28f 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnode.cpp @@ -1,11 +1,14 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#include "internalbindingproperty.h" #include "internalnode_p.h" -#include "internalproperty.h" -#include "internalvariantproperty.h" -#include "internalnodeproperty.h" +#include "internalnodeabstractproperty.h" #include "internalnodelistproperty.h" +#include "internalnodeproperty.h" +#include "internalproperty.h" +#include "internalsignalhandlerproperty.h" +#include "internalvariantproperty.h" #include @@ -111,111 +114,6 @@ AuxiliaryDatasForType InternalNode::auxiliaryData(AuxiliaryDataType type) const return data; } -InternalProperty::Pointer InternalNode::property(const PropertyName &name) const -{ - return m_namePropertyHash.value(name); -} - -InternalBindingProperty::Pointer InternalNode::bindingProperty(const PropertyName &name) const -{ - InternalProperty::Pointer property = m_namePropertyHash.value(name); - if (property && property->isBindingProperty()) - return std::static_pointer_cast(property); - - return InternalBindingProperty::Pointer(); -} - -InternalSignalHandlerProperty::Pointer InternalNode::signalHandlerProperty(const PropertyName &name) const -{ - InternalProperty::Pointer property = m_namePropertyHash.value(name); - if (property->isSignalHandlerProperty()) - return std::static_pointer_cast(property); - - return InternalSignalHandlerProperty::Pointer(); -} - -InternalSignalDeclarationProperty::Pointer InternalNode::signalDeclarationProperty(const PropertyName &name) const -{ - InternalProperty::Pointer property = m_namePropertyHash.value(name); - if (property->isSignalDeclarationProperty()) - return std::static_pointer_cast(property); - - return InternalSignalDeclarationProperty::Pointer(); -} - -InternalVariantProperty::Pointer InternalNode::variantProperty(const PropertyName &name) const -{ - InternalProperty::Pointer property = m_namePropertyHash.value(name); - if (property->isVariantProperty()) - return std::static_pointer_cast(property); - - return InternalVariantProperty::Pointer(); -} - -void InternalNode::addBindingProperty(const PropertyName &name) -{ - auto newProperty = std::make_shared(name, shared_from_this()); - m_namePropertyHash.insert(name, newProperty); -} - -void InternalNode::addSignalHandlerProperty(const PropertyName &name) -{ - auto newProperty = std::make_shared(name, shared_from_this()); - m_namePropertyHash.insert(name, newProperty); -} - -void InternalNode::addSignalDeclarationProperty(const PropertyName &name) -{ - auto newProperty = std::make_shared(name, shared_from_this()); - m_namePropertyHash.insert(name, newProperty); -} - -InternalNodeListProperty::Pointer InternalNode::nodeListProperty(const PropertyName &name) const -{ - auto property = m_namePropertyHash.value(name); - if (property && property->isNodeListProperty()) - return std::static_pointer_cast(property); - - return {}; -} - -InternalNodeAbstractProperty::Pointer InternalNode::nodeAbstractProperty(const PropertyName &name) const -{ - InternalProperty::Pointer property = m_namePropertyHash.value(name); - if (property && property->isNodeAbstractProperty()) - return std::static_pointer_cast(property); - - return {}; -} - -InternalNodeProperty::Pointer InternalNode::nodeProperty(const PropertyName &name) const -{ - InternalProperty::Pointer property = m_namePropertyHash.value(name); - if (property->isNodeProperty()) - return std::static_pointer_cast(property); - - return {}; -} - -void InternalNode::addVariantProperty(const PropertyName &name) -{ - auto newProperty = std::make_shared(name, shared_from_this()); - m_namePropertyHash.insert(name, newProperty); -} - -void InternalNode::addNodeProperty(const PropertyName &name, const TypeName &dynamicTypeName) -{ - auto newProperty = std::make_shared(name, shared_from_this()); - newProperty->setDynamicTypeName(dynamicTypeName); - m_namePropertyHash.insert(name, newProperty); -} - -void InternalNode::addNodeListProperty(const PropertyName &name) -{ - auto newProperty = std::make_shared(name, shared_from_this()); - m_namePropertyHash.insert(name, newProperty); -} - void InternalNode::removeProperty(const PropertyName &name) { InternalProperty::Pointer property = m_namePropertyHash.take(name); @@ -248,13 +146,12 @@ QList InternalNode::nodeAbstractPropertyL const QList properties = propertyList(); for (const InternalProperty::Pointer &property : properties) { if (property->isNodeAbstractProperty()) - abstractPropertyList.append(property->toNodeAbstractProperty()); + abstractPropertyList.append(property->toProperty()); } return abstractPropertyList; } - QList InternalNode::allSubNodes() const { QList nodeList; @@ -278,4 +175,4 @@ QList InternalNode::allDirectSubNodes() const } } // namespace Internal -} +} // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/designercore/model/internalnode_p.h b/src/plugins/qmldesigner/designercore/model/internalnode_p.h index 7af01f5ae99..3e72296c01f 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnode_p.h +++ b/src/plugins/qmldesigner/designercore/model/internalnode_p.h @@ -44,8 +44,7 @@ public: using Pointer = std::shared_ptr; using WeakPointer = std::weak_ptr; - explicit InternalNode() = default; - + InternalNode() = default; explicit InternalNode(TypeName typeName, int majorVersion, int minorVersion, qint32 internalId) : typeName(std::move(typeName)) , majorVersion(majorVersion) @@ -67,21 +66,100 @@ public: AuxiliaryDatasForType auxiliaryData(AuxiliaryDataType type) const; AuxiliaryDatasView auxiliaryData() const { return std::as_const(m_auxiliaryDatas); } - InternalProperty::Pointer property(const PropertyName &name) const; - InternalBindingProperty::Pointer bindingProperty(const PropertyName &name) const; - InternalSignalHandlerProperty::Pointer signalHandlerProperty(const PropertyName &name) const; - InternalSignalDeclarationProperty::Pointer signalDeclarationProperty(const PropertyName &name) const; - InternalVariantProperty::Pointer variantProperty(const PropertyName &name) const; - InternalNodeListProperty::Pointer nodeListProperty(const PropertyName &name) const; - InternalNodeAbstractProperty::Pointer nodeAbstractProperty(const PropertyName &name) const; - InternalNodeProperty::Pointer nodeProperty(const PropertyName &name) const; + template + typename Type::Pointer property(const PropertyName &name) const + { + auto property = m_namePropertyHash.value(name); + if (property && property->propertyType() == Type::type) + return std::static_pointer_cast(property); - void addBindingProperty(const PropertyName &name); - void addSignalHandlerProperty(const PropertyName &name); - void addSignalDeclarationProperty(const PropertyName &name); - void addNodeListProperty(const PropertyName &name); - void addVariantProperty(const PropertyName &name); - void addNodeProperty(const PropertyName &name, const TypeName &dynamicTypeName); + return {}; + } + + InternalProperty::Pointer property(const PropertyName &name) const + { + return m_namePropertyHash.value(name); + } + + auto bindingProperty(const PropertyName &name) const + { + return property(name); + } + + auto signalHandlerProperty(const PropertyName &name) const + { + return property(name); + } + + auto signalDeclarationProperty(const PropertyName &name) const + { + return property(name); + } + + auto variantProperty(const PropertyName &name) const + { + return property(name); + } + + auto nodeListProperty(const PropertyName &name) const + { + return property(name); + } + + InternalNodeAbstractProperty::Pointer nodeAbstractProperty(const PropertyName &name) const + { + auto property = m_namePropertyHash.value(name); + if (property->propertyType() == PropertyType::NodeList + || property->propertyType() == PropertyType::Node) { + return std::static_pointer_cast(property); + } + return {}; + } + + InternalNodeProperty::Pointer nodeProperty(const PropertyName &name) const + { + return property(name); + } + + template + auto &addProperty(const PropertyName &name) + { + auto newProperty = std::make_shared(name, shared_from_this()); + auto inserted = m_namePropertyHash.insert(name, std::move(newProperty)); + + return *inserted->get(); + } + + void addBindingProperty(const PropertyName &name) + { + addProperty(name); + } + + void addSignalHandlerProperty(const PropertyName &name) + { + addProperty(name); + } + + void addSignalDeclarationProperty(const PropertyName &name) + { + addProperty(name); + } + + void addNodeListProperty(const PropertyName &name) + { + addProperty(name); + } + + void addVariantProperty(const PropertyName &name) + { + addProperty(name); + } + + void addNodeProperty(const PropertyName &name, const TypeName &dynamicTypeName) + { + auto &property = addProperty(name); + property.setDynamicTypeName(dynamicTypeName); + } PropertyNameList propertyNameList() const; @@ -105,13 +183,7 @@ public: return firstNode->internalId < secondNode->internalId; } - friend size_t qHash(const InternalNodePointer &node) - { - if (!node) - return ::qHash(-1); - - return ::qHash(node->internalId); - } + friend size_t qHash(const InternalNodePointer &node) { return ::qHash(node.get()); } protected: void removeProperty(const PropertyName &name); diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.cpp index e2b753604f7..6dff33436e4 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.cpp @@ -7,16 +7,13 @@ namespace QmlDesigner { namespace Internal { -InternalNodeAbstractProperty::InternalNodeAbstractProperty(const PropertyName &name, const InternalNode::Pointer &propertyOwner) - : InternalProperty(name, propertyOwner) +InternalNodeAbstractProperty::InternalNodeAbstractProperty(const PropertyName &name, + const InternalNode::Pointer &propertyOwner, + PropertyType propertyType) + : InternalProperty(name, propertyOwner, propertyType) { } -bool InternalNodeAbstractProperty::isNodeAbstractProperty() const -{ - return true; -} - bool InternalNodeAbstractProperty::isValid() const { return InternalProperty::isValid() && isNodeAbstractProperty(); diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h b/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h index d3320c5487d..72e01d019b2 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalnodeabstractproperty.h @@ -17,8 +17,6 @@ public: using Pointer = std::shared_ptr; using WeakPointer = std::weak_ptr; - bool isNodeAbstractProperty() const override; - virtual QList allSubNodes() const = 0; virtual QList directSubNodes() const = 0; @@ -31,7 +29,9 @@ public: using InternalProperty::remove; // keep the virtual remove(...) function around protected: - InternalNodeAbstractProperty(const PropertyName &name, const InternalNodePointer &propertyOwner); + InternalNodeAbstractProperty(const PropertyName &name, + const InternalNodePointer &propertyOwner, + PropertyType propertyType); virtual void remove(const InternalNodePointer &node) = 0; virtual void add(const InternalNodePointer &node) = 0; }; diff --git a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp index 1889145751f..8c8b1c73e59 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.cpp @@ -8,8 +8,9 @@ namespace QmlDesigner { namespace Internal { -InternalNodeListProperty::InternalNodeListProperty(const PropertyName &name, const InternalNodePointer &propertyOwner) - : InternalNodeAbstractProperty(name, propertyOwner) +InternalNodeListProperty::InternalNodeListProperty(const PropertyName &name, + const InternalNodePointer &propertyOwner) + : InternalNodeAbstractProperty(name, propertyOwner, PropertyType::NodeList) { } @@ -36,11 +37,6 @@ int InternalNodeListProperty::indexOf(const InternalNode::Pointer &node) const return m_nodeList.indexOf(node); } -bool InternalNodeListProperty::isNodeListProperty() const -{ - return true; -} - void InternalNodeListProperty::add(const InternalNode::Pointer &internalNode) { Q_ASSERT(!m_nodeList.contains(internalNode)); diff --git a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h index 8998f9c7ce7..72ab08ae74a 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalnodelistproperty.h @@ -15,6 +15,7 @@ class InternalNodeListProperty final : public InternalNodeAbstractProperty { public: using Pointer = std::shared_ptr; + static constexpr PropertyType type = PropertyType::NodeList; InternalNodeListProperty(const PropertyName &name, const InternalNodePointer &propertyOwner); @@ -43,8 +44,6 @@ public: return *found; } - bool isNodeListProperty() const override; - QList allSubNodes() const override; QList directSubNodes() const override; const QList &nodeList() const; diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp index b5811325db5..0dd286e765e 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.cpp @@ -7,8 +7,9 @@ namespace QmlDesigner { namespace Internal { -InternalNodeProperty::InternalNodeProperty(const PropertyName &name, const InternalNode::Pointer &propertyOwner) - : InternalNodeAbstractProperty(name, propertyOwner) +InternalNodeProperty::InternalNodeProperty(const PropertyName &name, + const InternalNode::Pointer &propertyOwner) + : InternalNodeAbstractProperty(name, propertyOwner, PropertyType::Node) { } @@ -38,11 +39,6 @@ bool InternalNodeProperty::isValid() const return InternalProperty::isValid() && isNodeProperty(); } -bool InternalNodeProperty::isNodeProperty() const -{ - return true; -} - InternalNode::Pointer InternalNodeProperty::node() const { return m_node; diff --git a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h index deb9ee08120..65b9b895e8a 100644 --- a/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalnodeproperty.h @@ -12,6 +12,7 @@ class InternalNodeProperty : public InternalNodeAbstractProperty { public: using Pointer = std::shared_ptr; + static constexpr PropertyType type = PropertyType::Node; InternalNodeProperty(const PropertyName &name, const InternalNodePointer &node); @@ -19,7 +20,6 @@ public: bool isEmpty() const override; int count() const override; int indexOf(const InternalNodePointer &node) const override; - bool isNodeProperty() const override; QList allSubNodes() const override; QList directSubNodes() const override; diff --git a/src/plugins/qmldesigner/designercore/model/internalproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalproperty.cpp index b382f096c73..076c14fa9b6 100644 --- a/src/plugins/qmldesigner/designercore/model/internalproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalproperty.cpp @@ -18,11 +18,13 @@ InternalProperty::InternalProperty() = default; InternalProperty::~InternalProperty() = default; -InternalProperty::InternalProperty(const PropertyName &name, const InternalNode::Pointer &propertyOwner) - : m_name(name), - m_propertyOwner(propertyOwner) +InternalProperty::InternalProperty(const PropertyName &name, + const InternalNode::Pointer &propertyOwner, + PropertyType propertyType) + : m_name(name) + , m_propertyOwner(propertyOwner) + , m_propertyType{propertyType} { - Q_ASSERT_X(!name.isEmpty(), Q_FUNC_INFO, "Name of property cannot be empty"); } bool InternalProperty::isValid() const @@ -35,90 +37,11 @@ PropertyName InternalProperty::name() const return m_name; } -bool InternalProperty::isBindingProperty() const -{ - return false; -} - -bool InternalProperty::isVariantProperty() const -{ - return false; -} - -std::shared_ptr InternalProperty::toBindingProperty() -{ - Q_ASSERT(std::dynamic_pointer_cast(shared_from_this())); - return std::static_pointer_cast(shared_from_this()); -} - - -bool InternalProperty::isNodeListProperty() const -{ - return false; -} - -bool InternalProperty::isNodeProperty() const -{ - return false; -} - -bool InternalProperty::isNodeAbstractProperty() const -{ - return false; -} - -bool InternalProperty::isSignalHandlerProperty() const -{ - return false; -} - -bool InternalProperty::isSignalDeclarationProperty() const -{ - return false; -} - -std::shared_ptr InternalProperty::toVariantProperty() - -{ - Q_ASSERT(std::dynamic_pointer_cast(shared_from_this())); - return std::static_pointer_cast(shared_from_this()); -} - InternalNode::Pointer InternalProperty::propertyOwner() const { return m_propertyOwner.lock(); } -std::shared_ptr InternalProperty::toNodeListProperty() -{ - Q_ASSERT(std::dynamic_pointer_cast(shared_from_this())); - return std::static_pointer_cast(shared_from_this()); -} - -std::shared_ptr InternalProperty::toNodeProperty() -{ - Q_ASSERT(std::dynamic_pointer_cast(shared_from_this())); - return std::static_pointer_cast(shared_from_this()); -} - -std::shared_ptr InternalProperty::toNodeAbstractProperty() -{ - Q_ASSERT(std::dynamic_pointer_cast(shared_from_this())); - return std::static_pointer_cast(shared_from_this()); -} - -std::shared_ptr InternalProperty::toSignalHandlerProperty() -{ - Q_ASSERT(std::dynamic_pointer_cast(shared_from_this())); - return std::static_pointer_cast(shared_from_this()); -} - -std::shared_ptr InternalProperty::toSignalDeclarationProperty() -{ - Q_ASSERT(std::dynamic_pointer_cast(shared_from_this())); - return std::static_pointer_cast(shared_from_this()); -} - void InternalProperty::remove() { propertyOwner()->removeProperty(name()); @@ -135,7 +58,6 @@ void InternalProperty::setDynamicTypeName(const TypeName &name) m_dynamicType = name; } - void InternalProperty::resetDynamicTypeName() { m_dynamicType.clear(); diff --git a/src/plugins/qmldesigner/designercore/model/internalproperty.h b/src/plugins/qmldesigner/designercore/model/internalproperty.h index cd9bad8847f..1f24b825093 100644 --- a/src/plugins/qmldesigner/designercore/model/internalproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalproperty.h @@ -6,7 +6,6 @@ #include "qmldesignercorelib_global.h" #include -#include #include @@ -25,9 +24,54 @@ class InternalNode; using InternalNodePointer = std::shared_ptr; +template +struct TypeLookup +{}; + +template<> +struct TypeLookup +{ + using Type = InternalBindingProperty; +}; + +template<> +struct TypeLookup +{ + using Type = InternalNodeProperty; +}; + +template<> +struct TypeLookup +{ + using Type = InternalNodeListProperty; +}; + +template<> +struct TypeLookup +{}; + +template<> +struct TypeLookup +{ + using Type = InternalSignalDeclarationProperty; +}; + +template<> +struct TypeLookup +{ + using Type = InternalSignalHandlerProperty; +}; + +template<> +struct TypeLookup +{ + using Type = InternalVariantProperty; +}; + class QMLDESIGNERCORE_EXPORT InternalProperty : public std::enable_shared_from_this { public: + friend InternalNode; using Pointer = std::shared_ptr; InternalProperty(); @@ -37,21 +81,37 @@ public: PropertyName name() const; - virtual bool isBindingProperty() const; - virtual bool isVariantProperty() const; - virtual bool isNodeListProperty() const; - virtual bool isNodeProperty() const; - virtual bool isNodeAbstractProperty() const; - virtual bool isSignalHandlerProperty() const; - virtual bool isSignalDeclarationProperty() const; + bool isBindingProperty() const { return m_propertyType == PropertyType::Binding; } + bool isVariantProperty() const { return m_propertyType == PropertyType::Variant; } + bool isNodeListProperty() const { return m_propertyType == PropertyType::NodeList; } + bool isNodeProperty() const { return m_propertyType == PropertyType::Node; } + bool isNodeAbstractProperty() const + { + return m_propertyType == PropertyType::Node || m_propertyType == PropertyType::NodeList; + } + bool isSignalHandlerProperty() const { return m_propertyType == PropertyType::SignalHandler; } + bool isSignalDeclarationProperty() const + { + return m_propertyType == PropertyType::SignalDeclaration; + } + PropertyType propertyType() const { return m_propertyType; } - std::shared_ptr toBindingProperty(); - std::shared_ptr toVariantProperty(); - std::shared_ptr toNodeListProperty(); - std::shared_ptr toNodeProperty(); - std::shared_ptr toNodeAbstractProperty(); - std::shared_ptr toSignalHandlerProperty(); - std::shared_ptr toSignalDeclarationProperty(); + template + auto toProperty() + { + Q_ASSERT(std::dynamic_pointer_cast(shared_from_this())); + return std::static_pointer_cast(shared_from_this()); + } + + template + auto to() + { + if (propertyType == m_propertyType) + return std::static_pointer_cast::Type>( + shared_from_this()); + + return std::shared_ptr::Type>{}; + } InternalNodePointer propertyOwner() const; @@ -62,12 +122,17 @@ public: void resetDynamicTypeName(); protected: // functions - InternalProperty(const PropertyName &name, const InternalNodePointer &propertyOwner); + InternalProperty(const PropertyName &name, + const InternalNodePointer &propertyOwner, + PropertyType propertyType); + void setDynamicTypeName(const TypeName &name); + private: PropertyName m_name; TypeName m_dynamicType; std::weak_ptr m_propertyOwner; + PropertyType m_propertyType = PropertyType::None; }; } // namespace Internal diff --git a/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.cpp index 96bdda06e47..70aade63a68 100644 --- a/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.cpp @@ -6,9 +6,11 @@ namespace QmlDesigner { namespace Internal { -InternalSignalHandlerProperty::InternalSignalHandlerProperty(const PropertyName &name, const InternalNodePointer &propertyOwner) - : InternalProperty(name, propertyOwner) -{} +InternalSignalHandlerProperty::InternalSignalHandlerProperty(const PropertyName &name, + const InternalNodePointer &propertyOwner) + : InternalProperty(name, propertyOwner, PropertyType::SignalHandler) +{ +} bool InternalSignalHandlerProperty::isValid() const { @@ -24,11 +26,6 @@ void InternalSignalHandlerProperty::setSource(const QString &source) m_source = source; } -bool InternalSignalHandlerProperty::isSignalHandlerProperty() const -{ - return true; -} - bool InternalSignalDeclarationProperty::isValid() const { return InternalProperty::isValid() && isSignalDeclarationProperty(); @@ -44,13 +41,9 @@ void InternalSignalDeclarationProperty::setSignature(const QString &signature) m_signature = signature; } -bool InternalSignalDeclarationProperty::isSignalDeclarationProperty() const -{ - return true; -} - -InternalSignalDeclarationProperty::InternalSignalDeclarationProperty(const PropertyName &name, const InternalNodePointer &propertyOwner) - : InternalProperty(name, propertyOwner) +InternalSignalDeclarationProperty::InternalSignalDeclarationProperty( + const PropertyName &name, const InternalNodePointer &propertyOwner) + : InternalProperty(name, propertyOwner, PropertyType::SignalDeclaration) { setDynamicTypeName("signal"); } diff --git a/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.h b/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.h index f13df86e0d1..f0d88e2d239 100644 --- a/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalsignalhandlerproperty.h @@ -12,6 +12,7 @@ class InternalSignalHandlerProperty : public InternalProperty { public: using Pointer = std::shared_ptr; + static constexpr PropertyType type = PropertyType::SignalHandler; InternalSignalHandlerProperty(const PropertyName &name, const InternalNodePointer &propertyOwner); @@ -20,9 +21,6 @@ public: QString source() const; void setSource(const QString &source); - bool isSignalHandlerProperty() const override; - - private: QString m_source; }; @@ -31,6 +29,7 @@ class InternalSignalDeclarationProperty : public InternalProperty { public: using Pointer = std::shared_ptr; + static constexpr PropertyType type = PropertyType::SignalDeclaration; InternalSignalDeclarationProperty(const PropertyName &name, const InternalNodePointer &propertyOwner); @@ -40,8 +39,6 @@ public: QString signature() const; void setSignature(const QString &source); - bool isSignalDeclarationProperty() const override; - private: QString m_signature; }; diff --git a/src/plugins/qmldesigner/designercore/model/internalvariantproperty.cpp b/src/plugins/qmldesigner/designercore/model/internalvariantproperty.cpp index 661da75630b..53a0347c173 100644 --- a/src/plugins/qmldesigner/designercore/model/internalvariantproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/internalvariantproperty.cpp @@ -6,8 +6,9 @@ namespace QmlDesigner { namespace Internal { -InternalVariantProperty::InternalVariantProperty(const PropertyName &name, const InternalNodePointer &node) - : InternalProperty(name, node) +InternalVariantProperty::InternalVariantProperty(const PropertyName &name, + const InternalNodePointer &node) + : InternalProperty(name, node, PropertyType::Variant) { } @@ -21,11 +22,6 @@ void InternalVariantProperty::setValue(const QVariant &value) m_value = value; } -bool InternalVariantProperty::isVariantProperty() const -{ - return true; -} - void InternalVariantProperty::setDynamicValue(const TypeName &type, const QVariant &value) { setValue(value); diff --git a/src/plugins/qmldesigner/designercore/model/internalvariantproperty.h b/src/plugins/qmldesigner/designercore/model/internalvariantproperty.h index 362c4bc87ca..f9bb85d38d7 100644 --- a/src/plugins/qmldesigner/designercore/model/internalvariantproperty.h +++ b/src/plugins/qmldesigner/designercore/model/internalvariantproperty.h @@ -12,6 +12,7 @@ class InternalVariantProperty : public InternalProperty { public: using Pointer = std::shared_ptr; + static constexpr PropertyType type = PropertyType::Variant; InternalVariantProperty(const PropertyName &name, const InternalNodePointer &propertyOwner); @@ -22,9 +23,6 @@ public: void setDynamicValue(const TypeName &type, const QVariant &value); - bool isVariantProperty() const override; - - private: QVariant m_value; }; diff --git a/src/plugins/qmldesigner/designercore/model/model.cpp b/src/plugins/qmldesigner/designercore/model/model.cpp index 8b5bd02ac0f..06056fd9382 100644 --- a/src/plugins/qmldesigner/designercore/model/model.cpp +++ b/src/plugins/qmldesigner/designercore/model/model.cpp @@ -8,10 +8,13 @@ #include "abstractview.h" #include "auxiliarydataproperties.h" +#include "internalbindingproperty.h" #include "internalnodeabstractproperty.h" #include "internalnodelistproperty.h" +#include "internalnodeproperty.h" #include "internalproperty.h" #include "internalsignalhandlerproperty.h" +#include "internalvariantproperty.h" #include "metainfo.h" #include "nodeinstanceview.h" #include "nodemetainfo.h" @@ -1131,7 +1134,7 @@ void ModelPrivate::deselectNode(const InternalNodePointer &node) void ModelPrivate::removePropertyWithoutNotification(const InternalPropertyPointer &property) { if (property->isNodeAbstractProperty()) { - const auto &&allSubNodes = property->toNodeAbstractProperty()->allSubNodes(); + const auto &&allSubNodes = property->toProperty()->allSubNodes(); for (const InternalNodePointer &node : allSubNodes) removeNodeFromModel(node); } diff --git a/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp index f2d3bd16d10..0688ff1c256 100644 --- a/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodeabstractproperty.cpp @@ -70,8 +70,9 @@ void NodeAbstractProperty::reparentHere(const ModelNode &modelNode, bool isNode if (modelNode.hasParentProperty() && modelNode.parentProperty().isDynamic()) return; - if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isNodeAbstractProperty()) - privateModel()->removePropertyAndRelatedResources(internalNode()->property(name())); + auto internalProperty = internalNode()->property(name()); + if (internalProperty && !internalProperty->isNodeAbstractProperty()) + privateModel()->removePropertyAndRelatedResources(internalProperty); if (modelNode.hasParentProperty()) { Internal::InternalNodeAbstractProperty::Pointer oldParentProperty = modelNode.internalNode()->parentProperty(); diff --git a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp index af7405d340d..0e1fb45b4ef 100644 --- a/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodelistproperty.cpp @@ -41,11 +41,9 @@ Internal::InternalNodeListPropertyPointer &NodeListProperty::internalNodeListPro if (m_internalNodeListProperty) return m_internalNodeListProperty; - if (internalNode()->hasProperty(name())) { - Internal::InternalProperty::Pointer internalProperty = internalNode()->property(name()); - if (internalProperty->isNodeListProperty()) - m_internalNodeListProperty = internalProperty->toNodeListProperty(); - } + auto internalProperty = internalNode()->nodeListProperty(name()); + if (internalProperty) + m_internalNodeListProperty = internalProperty; return m_internalNodeListProperty; } @@ -65,9 +63,7 @@ QList NodeListProperty::toModelNodeList() const return {}; if (internalNodeListProperty()) - return internalNodesToModelNodes(m_internalNodeListProperty->toNodeListProperty()->nodeList(), - model(), - view()); + return internalNodesToModelNodes(m_internalNodeListProperty->nodeList(), model(), view()); return QList(); } diff --git a/src/plugins/qmldesigner/designercore/model/nodeproperty.cpp b/src/plugins/qmldesigner/designercore/model/nodeproperty.cpp index 4af8428e6be..a628c96b7d2 100644 --- a/src/plugins/qmldesigner/designercore/model/nodeproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/nodeproperty.cpp @@ -24,11 +24,10 @@ void NodeProperty::setModelNode(const ModelNode &modelNode) if (!modelNode.isValid()) return; - if (internalNode()->hasProperty(name())) { //check if oldValue != value - Internal::InternalProperty::Pointer internalProperty = internalNode()->property(name()); - if (internalProperty->isNodeProperty() - && internalProperty->toNodeProperty()->node() == modelNode.internalNode()) - return; + auto internalProperty = internalNode()->nodeProperty(name()); + if (internalProperty + && internalProperty->node() == modelNode.internalNode()) { //check if oldValue != value + return; } if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isNodeProperty()) @@ -42,11 +41,9 @@ ModelNode NodeProperty::modelNode() const if (!isValid()) return {}; - if (internalNode()->hasProperty(name())) { //check if oldValue != value - Internal::InternalProperty::Pointer internalProperty = internalNode()->property(name()); - if (internalProperty->isNodeProperty()) - return ModelNode(internalProperty->toNodeProperty()->node(), model(), view()); - } + auto internalProperty = internalNode()->nodeProperty(name()); + if (internalProperty) //check if oldValue != value + return ModelNode(internalProperty->node(), model(), view()); return ModelNode(); } diff --git a/src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp b/src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp index 4690044fa61..8c8c887a660 100644 --- a/src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/signalhandlerproperty.cpp @@ -32,16 +32,15 @@ void SignalHandlerProperty::setSource(const QString &source) if (source.isEmpty()) return; - if (internalNode()->hasProperty(name())) { //check if oldValue != value - Internal::InternalProperty::Pointer internalProperty = internalNode()->property(name()); - if (internalProperty->isSignalHandlerProperty() - && internalProperty->toSignalHandlerProperty()->source() == source) - + if (auto internalProperty = internalNode()->property(name())) { + auto signalHandlerProperty = internalProperty->to(); + //check if oldValue != value + if (signalHandlerProperty && signalHandlerProperty->source() == source) return; - } - if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isSignalHandlerProperty()) - privateModel()->removePropertyAndRelatedResources(internalNode()->property(name())); + if (!signalHandlerProperty) + privateModel()->removePropertyAndRelatedResources(internalProperty); + } privateModel()->setSignalHandlerProperty(internalNode(), name(), source); } @@ -109,16 +108,15 @@ void SignalDeclarationProperty::setSignature(const QString &signature) if (signature.isEmpty()) return; - if (internalNode()->hasProperty(name())) { //check if oldValue != value - Internal::InternalProperty::Pointer internalProperty = internalNode()->property(name()); - if (internalProperty->isSignalDeclarationProperty() - && internalProperty->toSignalDeclarationProperty()->signature() == signature) - + if (auto internalProperty = internalNode()->property(name())) { + auto signalDeclarationProperty = internalProperty->to(); + //check if oldValue != value + if (signalDeclarationProperty && signalDeclarationProperty->signature() == signature) return; - } - if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isSignalDeclarationProperty()) - privateModel()->removePropertyAndRelatedResources(internalNode()->property(name())); + if (!signalDeclarationProperty) + privateModel()->removePropertyAndRelatedResources(internalProperty); + } privateModel()->setSignalDeclarationProperty(internalNode(), name(), signature); } diff --git a/src/plugins/qmldesigner/designercore/model/variantproperty.cpp b/src/plugins/qmldesigner/designercore/model/variantproperty.cpp index c879ec7a347..859bb0691ec 100644 --- a/src/plugins/qmldesigner/designercore/model/variantproperty.cpp +++ b/src/plugins/qmldesigner/designercore/model/variantproperty.cpp @@ -36,27 +36,29 @@ void VariantProperty::setValue(const QVariant &value) if (isDynamic()) qWarning() << "Calling VariantProperty::setValue on dynamic property."; + if (auto internalProperty = internalNode()->property(name())) { + auto variantProperty = internalProperty->to(); - if (internalNode()->hasProperty(name())) { //check if oldValue != value - Internal::InternalProperty::Pointer internalProperty = internalNode()->property(name()); - if (internalProperty->isVariantProperty() - && internalProperty->toVariantProperty()->value() == value - && dynamicTypeName().isEmpty()) - + //check if oldValue != value + if (variantProperty && variantProperty->value() == value + && variantProperty->dynamicTypeName().isEmpty()) { return; - } + } - if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isVariantProperty()) - privateModel()->removePropertyAndRelatedResources(internalNode()->property(name())); + if (!variantProperty) + privateModel()->removePropertyAndRelatedResources(internalProperty); + } privateModel()->setVariantProperty(internalNode(), name(), value); } QVariant VariantProperty::value() const { - if (isValid() && internalNode()->hasProperty(name()) - && internalNode()->property(name())->isVariantProperty()) - return internalNode()->variantProperty(name())->value(); + if (isValid()) { + auto property = internalNode()->variantProperty(name()); + if (property) + return property->value(); + } return QVariant(); } @@ -86,19 +88,18 @@ void VariantProperty::setDynamicTypeNameAndValue(const TypeName &type, const QVa Internal::WriteLocker locker(model()); - if (internalNode()->hasProperty(name())) { //check if oldValue != value - Internal::InternalProperty::Pointer internalProperty = internalNode()->property(name()); - if (internalProperty->isVariantProperty() - && internalProperty->toVariantProperty()->value() == value - && internalProperty->toVariantProperty()->dynamicTypeName() == type) - + //check if oldValue != value + if (auto internalProperty = internalNode()->property(name())) { + auto variantProperty = internalProperty->to(); + if (variantProperty && variantProperty->value() == value + && internalProperty->dynamicTypeName() == type) return; + + if (!variantProperty) + privateModel()->removePropertyAndRelatedResources(internalProperty); } - if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isVariantProperty()) - privateModel()->removePropertyAndRelatedResources(internalNode()->property(name())); - - privateModel()->setDynamicVariantProperty(internalNode(), name(), type, value); + privateModel()->setDynamicVariantProperty(internalNode(), name(), type, value); } void VariantProperty::setDynamicTypeNameAndEnumeration(const TypeName &type, const EnumerationName &enumerationName)