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 <ci_patchbuild_bot@qt.io>
Reviewed-by: Vikas Pachdha <vikas.pachdha@qt.io>
This commit is contained in:
Marco Bubke
2023-08-04 20:16:43 +02:00
parent a4fbbb2463
commit bdd076efcd
21 changed files with 475 additions and 337 deletions

View File

@@ -54,7 +54,7 @@ public:
~AbstractProperty(); ~AbstractProperty();
AbstractProperty(const AbstractProperty &property, AbstractView *view); AbstractProperty(const AbstractProperty &property, AbstractView *view);
PropertyName name() const; const PropertyName &name() const;
bool isValid() const; bool isValid() const;
explicit operator bool() const { return isValid(); } explicit operator bool() const { return isValid(); }
@@ -125,8 +125,14 @@ public:
protected: protected:
AbstractProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view); AbstractProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view);
AbstractProperty(const Internal::InternalPropertyPointer &property, Model* model, AbstractView *view); AbstractProperty(const Internal::InternalPropertyPointer &property,
Internal::InternalNodePointer internalNode() const { return m_internalNode; } Model *model,
AbstractView *view);
Internal::InternalNode *internalNode() const { return m_internalNode.get(); }
Internal::InternalNodePointer internalNodeSharedPointer() const { return m_internalNode; }
Internal::ModelPrivate *privateModel() const; Internal::ModelPrivate *privateModel() const;
private: private:

View File

@@ -166,7 +166,10 @@ public:
using reference = ModelNode; using reference = ModelNode;
NodeListProperty(); NodeListProperty();
NodeListProperty(const NodeListProperty &nodeListProperty, AbstractView *view); NodeListProperty(const PropertyName &propertyName,
const Internal::InternalNodePointer &internalNode,
Model *model,
AbstractView *view);
QList<ModelNode> toModelNodeList() const; QList<ModelNode> toModelNodeList() const;
QList<QmlObjectNode> toQmlObjectNodeList() const; QList<QmlObjectNode> toQmlObjectNodeList() const;
void slide(int, int) const; void slide(int, int) const;
@@ -196,7 +199,6 @@ public:
const_iterator end() const; const_iterator end() const;
protected: protected:
NodeListProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view);
NodeListProperty(const Internal::InternalNodeListPropertyPointer &internalNodeListProperty, NodeListProperty(const Internal::InternalNodeListPropertyPointer &internalNodeListProperty,
Model *model, Model *model,
AbstractView *view); AbstractView *view);

View File

@@ -71,7 +71,7 @@ AbstractView *AbstractProperty::view() const
The QVariant is null if the property does not exist. The QVariant is null if the property does not exist.
*/ */
PropertyName AbstractProperty::name() const const PropertyName &AbstractProperty::name() const
{ {
return m_propertyName; return m_propertyName;
} }
@@ -126,7 +126,7 @@ VariantProperty AbstractProperty::toVariantProperty() const
if (!isValid()) if (!isValid())
return {}; return {};
VariantProperty propertyVariant(name(), internalNode(), model(), view()); VariantProperty propertyVariant(name(), internalNodeSharedPointer(), model(), view());
if (propertyVariant.isVariantProperty()) if (propertyVariant.isVariantProperty())
return propertyVariant; return propertyVariant;
@@ -139,7 +139,7 @@ NodeProperty AbstractProperty::toNodeProperty() const
if (!isValid()) if (!isValid())
return {}; return {};
NodeProperty propertyNode(name(), internalNode(), model(), view()); NodeProperty propertyNode(name(), internalNodeSharedPointer(), model(), view());
if (propertyNode.isNodeProperty()) if (propertyNode.isNodeProperty())
return propertyNode; return propertyNode;
@@ -152,7 +152,7 @@ SignalHandlerProperty AbstractProperty::toSignalHandlerProperty() const
if (!isValid()) if (!isValid())
return {}; return {};
SignalHandlerProperty propertyNode(name(), internalNode(), model(), view()); SignalHandlerProperty propertyNode(name(), internalNodeSharedPointer(), model(), view());
if (propertyNode.isSignalHandlerProperty()) if (propertyNode.isSignalHandlerProperty())
return propertyNode; return propertyNode;
@@ -165,7 +165,7 @@ SignalDeclarationProperty AbstractProperty::toSignalDeclarationProperty() const
if (!isValid()) if (!isValid())
return {}; return {};
SignalDeclarationProperty propertyNode(name(), internalNode(), model(), view()); SignalDeclarationProperty propertyNode(name(), internalNodeSharedPointer(), model(), view());
if (propertyNode.isSignalDeclarationProperty()) if (propertyNode.isSignalDeclarationProperty())
return propertyNode; return propertyNode;
@@ -178,7 +178,7 @@ NodeListProperty AbstractProperty::toNodeListProperty() const
if (!isValid()) if (!isValid())
return {}; return {};
NodeListProperty propertyNodeList(name(), internalNode(), model(), view()); NodeListProperty propertyNodeList(name(), internalNodeSharedPointer(), model(), view());
if (propertyNodeList.isNodeListProperty()) if (propertyNodeList.isNodeListProperty())
return propertyNodeList; return propertyNodeList;
@@ -191,7 +191,7 @@ NodeAbstractProperty AbstractProperty::toNodeAbstractProperty() const
if (!isValid()) if (!isValid())
return {}; return {};
NodeAbstractProperty propertyNodeAbstract(name(), internalNode(), model(), view()); NodeAbstractProperty propertyNodeAbstract(name(), internalNodeSharedPointer(), model(), view());
if (propertyNodeAbstract.isNodeAbstractProperty()) if (propertyNodeAbstract.isNodeAbstractProperty())
return propertyNodeAbstract; return propertyNodeAbstract;
@@ -204,7 +204,7 @@ BindingProperty AbstractProperty::toBindingProperty() const
if (!isValid()) if (!isValid())
return {}; return {};
BindingProperty propertyBinding(name(), internalNode(), model(), view()); BindingProperty propertyBinding(name(), internalNodeSharedPointer(), model(), view());
if (propertyBinding.isBindingProperty()) if (propertyBinding.isBindingProperty())
return propertyBinding; return propertyBinding;
@@ -217,10 +217,8 @@ bool AbstractProperty::isVariantProperty() const
if (!isValid()) if (!isValid())
return false; return false;
if (internalNode()->hasProperty(name())) { if (auto property = internalNode()->property(name()))
Q_ASSERT(internalNode()->property(name())); return property->isVariantProperty();
return internalNode()->property(name())->isVariantProperty();
}
return false; return false;
} }
@@ -230,10 +228,8 @@ bool AbstractProperty::isNodeAbstractProperty() const
if (!isValid()) if (!isValid())
return false; return false;
if (internalNode()->hasProperty(name())) { if (auto property = internalNode()->property(name()))
Q_ASSERT(internalNode()->property(name())); return property->isNodeAbstractProperty();
return internalNode()->property(name())->isNodeAbstractProperty();
}
return false; return false;
} }
@@ -243,10 +239,8 @@ bool AbstractProperty::isNodeListProperty() const
if (!isValid()) if (!isValid())
return false; return false;
if (internalNode()->hasProperty(name())) { if (auto property = internalNode()->property(name()))
Q_ASSERT(internalNode()->property(name())); return property->isNodeListProperty();
return internalNode()->property(name())->isNodeListProperty();
}
return false; return false;
} }
@@ -256,10 +250,8 @@ bool AbstractProperty::isNodeProperty() const
if (!isValid()) if (!isValid())
return false; return false;
if (internalNode()->hasProperty(name())) { if (auto property = internalNode()->property(name()))
Q_ASSERT(internalNode()->property(name())); return property->isNodeProperty();
return internalNode()->property(name())->isNodeProperty();
}
return false; return false;
} }
@@ -269,10 +261,8 @@ bool AbstractProperty::isSignalHandlerProperty() const
if (!isValid()) if (!isValid())
return false; return false;
if (internalNode()->hasProperty(name())) { if (auto property = internalNode()->property(name()))
Q_ASSERT(internalNode()->property(name())); return property->isSignalHandlerProperty();
return internalNode()->property(name())->isSignalHandlerProperty();
}
return false; return false;
} }
@@ -282,10 +272,8 @@ bool AbstractProperty::isSignalDeclarationProperty() const
if (!isValid()) if (!isValid())
return false; return false;
if (internalNode()->hasProperty(name())) { if (auto property = internalNode()->property(name()))
Q_ASSERT(internalNode()->property(name())); return property->isSignalDeclarationProperty();
return internalNode()->property(name())->isSignalDeclarationProperty();
}
return false; return false;
} }
@@ -295,8 +283,8 @@ PropertyType AbstractProperty::type() const
if (!isValid()) if (!isValid())
return PropertyType::None; return PropertyType::None;
if (internalNode()->hasProperty(name())) if (auto property = internalNode()->property(name()))
return internalNode()->property(name())->propertyType(); return property->propertyType();
return PropertyType::None; return PropertyType::None;
} }
@@ -306,10 +294,8 @@ bool AbstractProperty::isBindingProperty() const
if (!isValid()) if (!isValid())
return false; return false;
if (internalNode()->hasProperty(name())) { if (auto property = internalNode()->property(name()))
Q_ASSERT(internalNode()->property(name())); return property->isBindingProperty();
return internalNode()->property(name())->isBindingProperty();
}
return false; return false;
} }
@@ -324,8 +310,8 @@ TypeName AbstractProperty::dynamicTypeName() const
if (!isValid()) if (!isValid())
return {}; return {};
if (internalNode()->hasProperty(name())) if (auto property = internalNode()->property(name()))
return internalNode()->property(name())->dynamicTypeName(); return property->dynamicTypeName();
return TypeName(); return TypeName();
} }

View File

@@ -22,7 +22,7 @@ bool compareBindingProperties(const QmlDesigner::BindingProperty &bindingPropert
BindingProperty::BindingProperty() = default; BindingProperty::BindingProperty() = default;
BindingProperty::BindingProperty(const BindingProperty &property, AbstractView *view) 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()->removePropertyAndRelatedResources(internalProperty);
} }
privateModel()->setBindingProperty(internalNode(), name(), expression); privateModel()->setBindingProperty(internalNodeSharedPointer(), name(), expression);
} }
QString BindingProperty::expression() const QString BindingProperty::expression() const
{ {
if (isValid() && internalNode()->hasProperty(name()) if (isValid()) {
&& internalNode()->property(name())->isBindingProperty()) if (auto property = internalNode()->bindingProperty(name()))
return internalNode()->bindingProperty(name())->expression(); return property->expression();
}
return QString(); return QString();
} }
@@ -351,7 +352,7 @@ void BindingProperty::setDynamicTypeNameAndExpression(const TypeName &typeName,
privateModel()->removePropertyAndRelatedResources(internalProperty); privateModel()->removePropertyAndRelatedResources(internalProperty);
} }
privateModel()->setDynamicBindingProperty(internalNode(), name(), typeName, expression); privateModel()->setDynamicBindingProperty(internalNodeSharedPointer(), name(), typeName, expression);
} }
QDebug operator<<(QDebug debug, const BindingProperty &property) QDebug operator<<(QDebug debug, const BindingProperty &property)

View File

@@ -18,10 +18,6 @@
namespace QmlDesigner { namespace QmlDesigner {
namespace Internal { namespace Internal {
InternalNodeAbstractProperty::Pointer InternalNode::parentProperty() const
{
return m_parentProperty.lock();
}
void InternalNode::setParentProperty(const InternalNodeAbstractProperty::Pointer &parent) void InternalNode::setParentProperty(const InternalNodeAbstractProperty::Pointer &parent)
{ {
InternalNodeAbstractProperty::Pointer parentProperty = m_parentProperty.lock(); InternalNodeAbstractProperty::Pointer parentProperty = m_parentProperty.lock();
@@ -116,8 +112,7 @@ AuxiliaryDatasForType InternalNode::auxiliaryData(AuxiliaryDataType type) const
void InternalNode::removeProperty(const PropertyName &name) void InternalNode::removeProperty(const PropertyName &name)
{ {
InternalProperty::Pointer property = m_namePropertyHash.take(name); m_namePropertyHash.remove(name);
Q_ASSERT(property);
} }
PropertyNameList InternalNode::propertyNameList() const PropertyNameList InternalNode::propertyNameList() const
@@ -125,53 +120,73 @@ PropertyNameList InternalNode::propertyNameList() const
return m_namePropertyHash.keys(); 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<InternalProperty::Pointer> InternalNode::propertyList() const
{
return m_namePropertyHash.values();
}
QList<InternalNodeAbstractProperty::Pointer> InternalNode::nodeAbstractPropertyList() const
{
QList<InternalNodeAbstractProperty::Pointer> abstractPropertyList;
const QList<InternalProperty::Pointer> properties = propertyList();
for (const InternalProperty::Pointer &property : properties) {
if (property->isNodeAbstractProperty())
abstractPropertyList.append(property->toProperty<InternalNodeAbstractProperty>());
}
return abstractPropertyList;
}
QList<InternalNode::Pointer> InternalNode::allSubNodes() const QList<InternalNode::Pointer> InternalNode::allSubNodes() const
{ {
QList<InternalNode::Pointer> nodeList; QList<InternalNode::Pointer> nodes;
const QList<InternalNodeAbstractProperty::Pointer> properties = nodeAbstractPropertyList(); nodes.reserve(1024);
for (const InternalNodeAbstractProperty::Pointer &property : properties) {
nodeList.append(property->allSubNodes());
}
return nodeList; addSubNodes(nodes);
return nodes;
}
void InternalNode::addSubNodes(QList<InternalNodePointer> &nodes, const InternalProperty *property)
{
switch (property->type()) {
case PropertyType::NodeList:
property->to<PropertyType::NodeList>()->addSubNodes(nodes);
break;
case PropertyType::Node:
property->to<PropertyType::Node>()->addSubNodes(nodes);
break;
case PropertyType::Binding:
case PropertyType::None:
case PropertyType::SignalDeclaration:
case PropertyType::SignalHandler:
case PropertyType::Variant:
break;
}
}
void InternalNode::addSubNodes(QList<InternalNodePointer> &nodes) const
{
for (const InternalProperty::Pointer &property : m_namePropertyHash)
addSubNodes(nodes, property.get());
}
void InternalNode::addDirectSubNodes(QList<InternalNodePointer> &nodes) const
{
for (const InternalProperty::Pointer &property : m_namePropertyHash)
addDirectSubNodes(nodes, property.get());
}
void InternalNode::addDirectSubNodes(QList<InternalNodePointer> &nodes,
const InternalProperty *property)
{
switch (property->type()) {
case PropertyType::NodeList:
nodes.append(property->to<PropertyType::NodeList>()->nodes());
break;
case PropertyType::Node:
nodes.append(property->to<PropertyType::Node>()->node());
break;
case PropertyType::Binding:
case PropertyType::None:
case PropertyType::SignalDeclaration:
case PropertyType::SignalHandler:
case PropertyType::Variant:
break;
}
} }
QList<InternalNode::Pointer> InternalNode::allDirectSubNodes() const QList<InternalNode::Pointer> InternalNode::allDirectSubNodes() const
{ {
QList<InternalNode::Pointer> nodeList; QList<InternalNode::Pointer> nodes;
const QList<InternalNodeAbstractProperty::Pointer> properties = nodeAbstractPropertyList(); nodes.reserve(96);
for (const InternalNodeAbstractProperty::Pointer &property : properties) {
nodeList.append(property->directSubNodes());
}
return nodeList; addDirectSubNodes(nodes);
return nodes;
} }
} // namespace Internal } // namespace Internal

View File

@@ -52,7 +52,7 @@ public:
, internalId(internalId) , internalId(internalId)
{} {}
InternalNodeAbstractProperty::Pointer parentProperty() const; InternalNodeAbstractProperty::Pointer parentProperty() const { return m_parentProperty.lock(); }
// Reparent within model // Reparent within model
void setParentProperty(const InternalNodeAbstractProperty::Pointer &parent); void setParentProperty(const InternalNodeAbstractProperty::Pointer &parent);
@@ -66,18 +66,25 @@ public:
AuxiliaryDatasView auxiliaryData() const { return std::as_const(m_auxiliaryDatas); } AuxiliaryDatasView auxiliaryData() const { return std::as_const(m_auxiliaryDatas); }
template<typename Type> template<typename Type>
typename Type::Pointer property(const PropertyName &name) const Type *property(const PropertyName &name) const
{ {
auto property = m_namePropertyHash.value(name); auto propertyIter = m_namePropertyHash.find(name);
if (property && property->propertyType() == Type::type)
return std::static_pointer_cast<Type>(property); if (propertyIter != m_namePropertyHash.end()) {
if (auto property = propertyIter->get(); property && property->propertyType() == Type::type)
return static_cast<Type *>(property);
}
return {}; 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 auto bindingProperty(const PropertyName &name) const
@@ -116,60 +123,62 @@ public:
return {}; return {};
} }
InternalNodeProperty::Pointer nodeProperty(const PropertyName &name) const auto nodeProperty(const PropertyName &name) const
{ {
return property<InternalNodeProperty>(name); return property<InternalNodeProperty>(name);
} }
template<typename Type> template<typename Type>
auto &addProperty(const PropertyName &name) Type *addProperty(const PropertyName &name)
{ {
auto newProperty = std::make_shared<Type>(name, shared_from_this()); auto newProperty = std::make_shared<Type>(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<InternalBindingProperty>(name); return addProperty<InternalBindingProperty>(name);
} }
void addSignalHandlerProperty(const PropertyName &name) auto addSignalHandlerProperty(const PropertyName &name)
{ {
addProperty<InternalSignalHandlerProperty>(name); return addProperty<InternalSignalHandlerProperty>(name);
} }
void addSignalDeclarationProperty(const PropertyName &name) auto addSignalDeclarationProperty(const PropertyName &name)
{ {
addProperty<InternalSignalDeclarationProperty>(name); return addProperty<InternalSignalDeclarationProperty>(name);
} }
void addNodeListProperty(const PropertyName &name) auto addNodeListProperty(const PropertyName &name)
{ {
addProperty<InternalNodeListProperty>(name); return addProperty<InternalNodeListProperty>(name);
} }
void addVariantProperty(const PropertyName &name) auto addVariantProperty(const PropertyName &name)
{ {
addProperty<InternalVariantProperty>(name); return addProperty<InternalVariantProperty>(name);
} }
void addNodeProperty(const PropertyName &name, const TypeName &dynamicTypeName) auto addNodeProperty(const PropertyName &name, const TypeName &dynamicTypeName)
{ {
auto &property = addProperty<InternalNodeProperty>(name); auto property = addProperty<InternalNodeProperty>(name);
property.setDynamicTypeName(dynamicTypeName); property->setDynamicTypeName(dynamicTypeName);
return property;
} }
PropertyNameList propertyNameList() const; PropertyNameList propertyNameList() const;
bool hasProperties() const;
bool hasProperty(const PropertyName &name) const;
QList<InternalProperty::Pointer> propertyList() const;
QList<InternalNodeAbstractProperty::Pointer> nodeAbstractPropertyList() const;
QList<InternalNode::Pointer> allSubNodes() const; QList<InternalNode::Pointer> allSubNodes() const;
QList<InternalNode::Pointer> allDirectSubNodes() const; QList<InternalNode::Pointer> allDirectSubNodes() const;
void addSubNodes(QList<InternalNodePointer> &nodes) const;
void addDirectSubNodes(QList<InternalNodePointer> &nodes) const;
static void addSubNodes(QList<InternalNodePointer> &nodes, const InternalProperty *property);
static void addDirectSubNodes(QList<InternalNodePointer> &nodes, const InternalProperty *property);
friend bool operator<(const InternalNode::Pointer &firstNode, friend bool operator<(const InternalNode::Pointer &firstNode,
const InternalNode::Pointer &secondNode) const InternalNode::Pointer &secondNode)
@@ -185,9 +194,10 @@ public:
friend size_t qHash(const InternalNodePointer &node) { return ::qHash(node.get()); } friend size_t qHash(const InternalNodePointer &node) { return ::qHash(node.get()); }
protected:
void removeProperty(const PropertyName &name); void removeProperty(const PropertyName &name);
protected:
public: public:
TypeName typeName; TypeName typeName;
QString id; QString id;

View File

@@ -17,17 +17,12 @@ public:
using Pointer = std::shared_ptr<InternalNodeAbstractProperty>; using Pointer = std::shared_ptr<InternalNodeAbstractProperty>;
using WeakPointer = std::weak_ptr<InternalNodeAbstractProperty>; using WeakPointer = std::weak_ptr<InternalNodeAbstractProperty>;
virtual QList<InternalNodePointer> allSubNodes() const = 0;
virtual QList<InternalNodePointer> directSubNodes() const = 0;
virtual bool isEmpty() const = 0; virtual bool isEmpty() const = 0;
virtual int count() const = 0; virtual int count() const = 0;
virtual int indexOf(const InternalNodePointer &node) const = 0; virtual int indexOf(const InternalNodePointer &node) const = 0;
bool isValid() const override; bool isValid() const override;
using InternalProperty::remove; // keep the virtual remove(...) function around
protected: protected:
InternalNodeAbstractProperty(const PropertyName &name, InternalNodeAbstractProperty(const PropertyName &name,
const InternalNodePointer &propertyOwner, const InternalNodePointer &propertyOwner,

View File

@@ -60,20 +60,22 @@ void InternalNodeListProperty::slide(int from, int to)
m_nodeList.insert(to, internalNode); m_nodeList.insert(to, internalNode);
} }
QList<InternalNode::Pointer> InternalNodeListProperty::allSubNodes() const void InternalNodeListProperty::addSubNodes(QList<InternalNodePointer> &container) const
{ {
QList<InternalNode::Pointer> nodeList; for (const auto &node : std::as_const(m_nodeList)) {
for (const InternalNode::Pointer &childNode : std::as_const(m_nodeList)) { container.push_back(node);
nodeList.append(childNode->allSubNodes()); node->addSubNodes(container);
nodeList.append(childNode);
} }
return nodeList;
} }
QList<InternalNodePointer> InternalNodeListProperty::directSubNodes() const QList<InternalNode::Pointer> InternalNodeListProperty::allSubNodes() const
{ {
return nodeList(); QList<InternalNode::Pointer> nodes;
nodes.reserve(1024);
addSubNodes(nodes);
return nodes;
} }
} // namespace Internal } // namespace Internal

View File

@@ -44,14 +44,18 @@ public:
return *found; return *found;
} }
QList<InternalNodePointer> allSubNodes() const override; QList<InternalNodePointer> allSubNodes() const;
QList<InternalNodePointer> directSubNodes() const override;
const QList<InternalNodePointer> &nodeList() const; const QList<InternalNodePointer> &nodeList() const;
void slide(int from, int to); void slide(int from, int to);
void addSubNodes(QList<InternalNodePointer> &container) const;
QList<InternalNodePointer>::iterator begin() { return m_nodeList.begin(); } QList<InternalNodePointer>::iterator begin() { return m_nodeList.begin(); }
QList<InternalNodePointer>::iterator end() { return m_nodeList.end(); } QList<InternalNodePointer>::iterator end() { return m_nodeList.end(); }
const QList<InternalNodePointer> &nodes() const { return m_nodeList; }
protected: protected:
void add(const InternalNodePointer &node) override; void add(const InternalNodePointer &node) override;
void remove(const InternalNodePointer &node) override; void remove(const InternalNodePointer &node) override;

View File

@@ -39,11 +39,6 @@ bool InternalNodeProperty::isValid() const
return InternalProperty::isValid() && isNodeProperty(); return InternalProperty::isValid() && isNodeProperty();
} }
InternalNode::Pointer InternalNodeProperty::node() const
{
return m_node;
}
void InternalNodeProperty::remove([[maybe_unused]] const InternalNode::Pointer &node) void InternalNodeProperty::remove([[maybe_unused]] const InternalNode::Pointer &node)
{ {
Q_ASSERT(m_node == node); Q_ASSERT(m_node == node);
@@ -59,24 +54,18 @@ void InternalNodeProperty::add(const InternalNode::Pointer &node)
QList<InternalNode::Pointer> InternalNodeProperty::allSubNodes() const QList<InternalNode::Pointer> InternalNodeProperty::allSubNodes() const
{ {
QList<InternalNode::Pointer> nodeList; QList<InternalNode::Pointer> nodes;
nodes.reserve(1024);
if (node()) { addSubNodes(nodes);
nodeList.append(node());
nodeList.append(node()->allSubNodes());
}
return nodeList; return nodes;
} }
QList<InternalNodePointer> InternalNodeProperty::directSubNodes() const void InternalNodeProperty::addSubNodes(QList<InternalNodePointer> &container) const
{ {
QList<InternalNode::Pointer> nodeList; container.push_back(m_node);
m_node->addSubNodes(container);
if (node())
nodeList.append(node());
return nodeList;
} }
} // namespace Internal } // namespace Internal

View File

@@ -21,10 +21,10 @@ public:
int count() const override; int count() const override;
int indexOf(const InternalNodePointer &node) const override; int indexOf(const InternalNodePointer &node) const override;
QList<InternalNodePointer> allSubNodes() const override; QList<InternalNodePointer> allSubNodes() const;
QList<InternalNodePointer> directSubNodes() const override; void addSubNodes(QList<InternalNodePointer> &container) const;
InternalNodePointer node() const; const InternalNodePointer &node() const { return m_node; }
protected: protected:
void add(const InternalNodePointer &node) override; void add(const InternalNodePointer &node) override;

View File

@@ -37,17 +37,6 @@ PropertyName InternalProperty::name() const
return m_name; 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 TypeName InternalProperty::dynamicTypeName() const
{ {
return m_dynamicType; return m_dynamicType;

View File

@@ -8,6 +8,7 @@
#include <QVariant> #include <QVariant>
#include <memory> #include <memory>
#include <type_traits>
namespace QmlDesigner { namespace QmlDesigner {
@@ -24,7 +25,7 @@ class InternalNode;
using InternalNodePointer = std::shared_ptr<InternalNode>; using InternalNodePointer = std::shared_ptr<InternalNode>;
template<PropertyType propertyType> template<PropertyType... propertyType>
struct TypeLookup struct TypeLookup
{}; {};
@@ -68,6 +69,21 @@ struct TypeLookup<PropertyType::Variant>
using Type = InternalVariantProperty; using Type = InternalVariantProperty;
}; };
template<>
struct TypeLookup<PropertyType::Node, PropertyType::NodeList>
{
using Type = InternalNodeAbstractProperty;
};
template<>
struct TypeLookup<PropertyType::NodeList, PropertyType::Node>
{
using Type = InternalNodeAbstractProperty;
};
template<PropertyType... propertyType>
using type_lookup_t = typename TypeLookup<propertyType...>::Type;
class QMLDESIGNERCORE_EXPORT InternalProperty : public std::enable_shared_from_this<InternalProperty> class QMLDESIGNERCORE_EXPORT InternalProperty : public std::enable_shared_from_this<InternalProperty>
{ {
public: public:
@@ -103,24 +119,60 @@ public:
return std::static_pointer_cast<Type>(shared_from_this()); return std::static_pointer_cast<Type>(shared_from_this());
} }
template<PropertyType propertyType> template<PropertyType... propertyType>
auto to() auto toShared()
{ {
if (propertyType == m_propertyType) using Type = type_lookup_t<propertyType...>;
return std::static_pointer_cast<typename TypeLookup<propertyType>::Type>(
shared_from_this());
return std::shared_ptr<typename TypeLookup<propertyType>::Type>{}; if (((propertyType == m_propertyType) || ...))
return std::static_pointer_cast<Type>(shared_from_this());
return std::shared_ptr<Type>{};
} }
InternalNodePointer propertyOwner() const; template<PropertyType... propertyType>
auto toShared() const
{
using Type = const type_lookup_t<propertyType...>;
virtual void remove(); if (((propertyType == m_propertyType) || ...))
return std::static_pointer_cast<Type>(shared_from_this());
return std::shared_ptr<Type>{};
}
template<PropertyType... propertyType>
auto *to()
{
using Type = type_lookup_t<propertyType...>;
if (((propertyType == m_propertyType) || ...))
return static_cast<Type *>(this);
return static_cast<Type *>(nullptr);
}
template<PropertyType... propertyType>
const auto *to() const
{
using Type = const type_lookup_t<propertyType...>;
if (((propertyType == m_propertyType) || ...))
return static_cast<Type *>(this);
return static_cast<Type *>(nullptr);
}
const InternalNodePointer propertyOwner() const { return m_propertyOwner.lock(); }
InternalNodePointer propertyOwner() { return m_propertyOwner.lock(); }
TypeName dynamicTypeName() const; TypeName dynamicTypeName() const;
void resetDynamicTypeName(); void resetDynamicTypeName();
PropertyType type() const { return m_propertyType; }
protected: // functions protected: // functions
InternalProperty(const PropertyName &name, InternalProperty(const PropertyName &name,
const InternalNodePointer &propertyOwner, const InternalNodePointer &propertyOwner,

View File

@@ -426,7 +426,7 @@ void ModelPrivate::removeNode(const InternalNodePointer &node)
} }
if (oldParentProperty && oldParentProperty->isEmpty()) { if (oldParentProperty && oldParentProperty->isEmpty()) {
removePropertyWithoutNotification(oldParentProperty); removePropertyWithoutNotification(oldParentProperty.get());
propertyChangeFlags |= AbstractView::EmptyPropertiesRemoved; propertyChangeFlags |= AbstractView::EmptyPropertiesRemoved;
} }
@@ -753,8 +753,7 @@ void ModelPrivate::notifyPropertiesRemoved(const QList<PropertyPair> &propertyPa
}); });
} }
void ModelPrivate::notifyPropertiesAboutToBeRemoved( void ModelPrivate::notifyPropertiesAboutToBeRemoved(const QList<InternalProperty *> &internalPropertyList)
const QList<InternalPropertyPointer> &internalPropertyList)
{ {
bool resetModel = false; bool resetModel = false;
QString description; QString description;
@@ -762,9 +761,12 @@ void ModelPrivate::notifyPropertiesAboutToBeRemoved(
try { try {
if (rewriterView()) { if (rewriterView()) {
QList<AbstractProperty> propertyList; QList<AbstractProperty> propertyList;
for (const InternalPropertyPointer &property : internalPropertyList) { for (InternalProperty *property : internalPropertyList) {
AbstractProperty newProperty(property->name(), property->propertyOwner(), m_model, rewriterView()); AbstractProperty newProperty(property->name(),
propertyList.append(newProperty); property->propertyOwner(),
m_model,
rewriterView());
propertyList.append(newProperty);
} }
rewriterView()->propertiesAboutToBeRemoved(propertyList); rewriterView()->propertiesAboutToBeRemoved(propertyList);
@@ -777,7 +779,7 @@ void ModelPrivate::notifyPropertiesAboutToBeRemoved(
for (const QPointer<AbstractView> &view : enabledViews()) { for (const QPointer<AbstractView> &view : enabledViews()) {
QList<AbstractProperty> propertyList; QList<AbstractProperty> propertyList;
Q_ASSERT(view != nullptr); Q_ASSERT(view != nullptr);
for (const InternalPropertyPointer &property : internalPropertyList) { for (auto property : internalPropertyList) {
AbstractProperty newProperty(property->name(), property->propertyOwner(), m_model, view.data()); AbstractProperty newProperty(property->name(), property->propertyOwner(), m_model, view.data());
propertyList.append(newProperty); propertyList.append(newProperty);
} }
@@ -792,7 +794,7 @@ void ModelPrivate::notifyPropertiesAboutToBeRemoved(
if (nodeInstanceView()) { if (nodeInstanceView()) {
QList<AbstractProperty> propertyList; QList<AbstractProperty> propertyList;
for (const InternalPropertyPointer &property : internalPropertyList) { for (auto property : internalPropertyList) {
AbstractProperty newProperty(property->name(), property->propertyOwner(), m_model, nodeInstanceView()); AbstractProperty newProperty(property->name(), property->propertyOwner(), m_model, nodeInstanceView());
propertyList.append(newProperty); propertyList.append(newProperty);
} }
@@ -900,11 +902,11 @@ void ModelPrivate::notifyNodeIdChanged(const InternalNodePointer &node,
} }
void ModelPrivate::notifyBindingPropertiesAboutToBeChanged( void ModelPrivate::notifyBindingPropertiesAboutToBeChanged(
const QList<InternalBindingPropertyPointer> &internalPropertyList) const QList<InternalBindingProperty *> &internalPropertyList)
{ {
notifyNodeInstanceViewLast([&](AbstractView *view) { notifyNodeInstanceViewLast([&](AbstractView *view) {
QList<BindingProperty> propertyList; QList<BindingProperty> propertyList;
for (const InternalBindingPropertyPointer &bindingProperty : internalPropertyList) { for (auto bindingProperty : internalPropertyList) {
propertyList.append(BindingProperty(bindingProperty->name(), propertyList.append(BindingProperty(bindingProperty->name(),
bindingProperty->propertyOwner(), bindingProperty->propertyOwner(),
m_model, m_model,
@@ -914,13 +916,12 @@ void ModelPrivate::notifyBindingPropertiesAboutToBeChanged(
}); });
} }
void ModelPrivate::notifyBindingPropertiesChanged( void ModelPrivate::notifyBindingPropertiesChanged(const QList<InternalBindingProperty *> &internalPropertyList,
const QList<InternalBindingPropertyPointer> &internalPropertyList, AbstractView::PropertyChangeFlags propertyChange)
AbstractView::PropertyChangeFlags propertyChange)
{ {
notifyNodeInstanceViewLast([&](AbstractView *view) { notifyNodeInstanceViewLast([&](AbstractView *view) {
QList<BindingProperty> propertyList; QList<BindingProperty> propertyList;
for (const InternalBindingPropertyPointer &bindingProperty : internalPropertyList) { for (auto bindingProperty : internalPropertyList) {
propertyList.append(BindingProperty(bindingProperty->name(), propertyList.append(BindingProperty(bindingProperty->name(),
bindingProperty->propertyOwner(), bindingProperty->propertyOwner(),
m_model, m_model,
@@ -931,12 +932,12 @@ void ModelPrivate::notifyBindingPropertiesChanged(
} }
void ModelPrivate::notifySignalHandlerPropertiesChanged( void ModelPrivate::notifySignalHandlerPropertiesChanged(
const QVector<InternalSignalHandlerPropertyPointer> &internalPropertyList, const QVector<InternalSignalHandlerProperty *> &internalPropertyList,
AbstractView::PropertyChangeFlags propertyChange) AbstractView::PropertyChangeFlags propertyChange)
{ {
notifyNodeInstanceViewLast([&](AbstractView *view) { notifyNodeInstanceViewLast([&](AbstractView *view) {
QVector<SignalHandlerProperty> propertyList; QVector<SignalHandlerProperty> propertyList;
for (const InternalSignalHandlerPropertyPointer &signalHandlerProperty : internalPropertyList) { for (auto signalHandlerProperty : internalPropertyList) {
propertyList.append(SignalHandlerProperty(signalHandlerProperty->name(), propertyList.append(SignalHandlerProperty(signalHandlerProperty->name(),
signalHandlerProperty->propertyOwner(), signalHandlerProperty->propertyOwner(),
m_model, m_model,
@@ -947,12 +948,12 @@ void ModelPrivate::notifySignalHandlerPropertiesChanged(
} }
void ModelPrivate::notifySignalDeclarationPropertiesChanged( void ModelPrivate::notifySignalDeclarationPropertiesChanged(
const QVector<InternalSignalDeclarationPropertyPointer> &internalPropertyList, const QVector<InternalSignalDeclarationProperty *> &internalPropertyList,
AbstractView::PropertyChangeFlags propertyChange) AbstractView::PropertyChangeFlags propertyChange)
{ {
notifyNodeInstanceViewLast([&](AbstractView *view) { notifyNodeInstanceViewLast([&](AbstractView *view) {
QVector<SignalDeclarationProperty> propertyList; QVector<SignalDeclarationProperty> propertyList;
for (const InternalSignalDeclarationPropertyPointer &signalHandlerProperty : internalPropertyList) { for (auto signalHandlerProperty : internalPropertyList) {
propertyList.append(SignalDeclarationProperty(signalHandlerProperty->name(), propertyList.append(SignalDeclarationProperty(signalHandlerProperty->name(),
signalHandlerProperty->propertyOwner(), signalHandlerProperty->propertyOwner(),
m_model, m_model,
@@ -986,7 +987,7 @@ void ModelPrivate::notifyVariantPropertiesChanged(const InternalNodePointer &nod
} }
void ModelPrivate::notifyNodeAboutToBeReparent(const InternalNodePointer &node, void ModelPrivate::notifyNodeAboutToBeReparent(const InternalNodePointer &node,
const InternalNodeAbstractPropertyPointer &newPropertyParent, const InternalNodeAbstractProperty *newPropertyParent,
const InternalNodePointer &oldParent, const InternalNodePointer &oldParent,
const PropertyName &oldPropertyName, const PropertyName &oldPropertyName,
AbstractView::PropertyChangeFlags propertyChange) AbstractView::PropertyChangeFlags propertyChange)
@@ -998,8 +999,12 @@ void ModelPrivate::notifyNodeAboutToBeReparent(const InternalNodePointer &node,
if (!oldPropertyName.isEmpty() && oldParent->isValid) if (!oldPropertyName.isEmpty() && oldParent->isValid)
oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, m_model, view); oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, m_model, view);
if (newPropertyParent) if (newPropertyParent) {
newProperty = NodeAbstractProperty(newPropertyParent, m_model, view); newProperty = NodeAbstractProperty(newPropertyParent->name(),
newPropertyParent->propertyOwner(),
m_model,
view);
}
ModelNode modelNode(node, m_model, view); ModelNode modelNode(node, m_model, view);
view->nodeAboutToBeReparented(modelNode, newProperty, oldProperty, propertyChange); view->nodeAboutToBeReparented(modelNode, newProperty, oldProperty, propertyChange);
@@ -1007,7 +1012,7 @@ void ModelPrivate::notifyNodeAboutToBeReparent(const InternalNodePointer &node,
} }
void ModelPrivate::notifyNodeReparent(const InternalNodePointer &node, void ModelPrivate::notifyNodeReparent(const InternalNodePointer &node,
const InternalNodeAbstractPropertyPointer &newPropertyParent, const InternalNodeAbstractProperty *newPropertyParent,
const InternalNodePointer &oldParent, const InternalNodePointer &oldParent,
const PropertyName &oldPropertyName, const PropertyName &oldPropertyName,
AbstractView::PropertyChangeFlags propertyChange) AbstractView::PropertyChangeFlags propertyChange)
@@ -1019,28 +1024,39 @@ void ModelPrivate::notifyNodeReparent(const InternalNodePointer &node,
if (!oldPropertyName.isEmpty() && oldParent->isValid) if (!oldPropertyName.isEmpty() && oldParent->isValid)
oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, m_model, view); oldProperty = NodeAbstractProperty(oldPropertyName, oldParent, m_model, view);
if (newPropertyParent) if (newPropertyParent) {
newProperty = NodeAbstractProperty(newPropertyParent, m_model, view); newProperty = NodeAbstractProperty(newPropertyParent->name(),
newPropertyParent->propertyOwner(),
m_model,
view);
}
ModelNode modelNode(node, m_model, view); ModelNode modelNode(node, m_model, view);
view->nodeReparented(modelNode, newProperty, oldProperty, propertyChange); view->nodeReparented(modelNode, newProperty, oldProperty, propertyChange);
}); });
} }
void ModelPrivate::notifyNodeOrderChanged(const InternalNodeListPropertyPointer &internalListProperty, void ModelPrivate::notifyNodeOrderChanged(const InternalNodeListProperty *internalListProperty,
const InternalNodePointer &node, const InternalNodePointer &node,
int oldIndex) int oldIndex)
{ {
notifyNodeInstanceViewLast([&](AbstractView *view) { 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); view->nodeOrderChanged(nodeListProperty, ModelNode(node, m_model, view), oldIndex);
}); });
} }
void ModelPrivate::notifyNodeOrderChanged(const InternalNodeListPropertyPointer &internalListProperty) void ModelPrivate::notifyNodeOrderChanged(const InternalNodeListProperty *internalListProperty)
{ {
notifyNodeInstanceViewLast([&](AbstractView *view) { notifyNodeInstanceViewLast([&](AbstractView *view) {
NodeListProperty nodeListProperty(internalListProperty, m_model, view); NodeListProperty nodeListProperty(internalListProperty->name(),
internalListProperty->propertyOwner(),
m_model,
view);
view->nodeOrderChanged(nodeListProperty); view->nodeOrderChanged(nodeListProperty);
}); });
} }
@@ -1118,9 +1134,9 @@ QVector<InternalNodePointer> ModelPrivate::toInternalNodeVector(const QVector<Mo
return newNodeVector; return newNodeVector;
} }
QList<InternalPropertyPointer> ModelPrivate::toInternalProperties(const AbstractProperties &properties) QList<InternalProperty *> ModelPrivate::toInternalProperties(const AbstractProperties &properties)
{ {
QList<InternalPropertyPointer> internalProperties; QList<InternalProperty *> internalProperties;
internalProperties.reserve(properties.size()); internalProperties.reserve(properties.size());
for (const auto &property : properties) { for (const auto &property : properties) {
@@ -1133,10 +1149,10 @@ QList<InternalPropertyPointer> ModelPrivate::toInternalProperties(const Abstract
return internalProperties; return internalProperties;
} }
QList<std::tuple<InternalBindingPropertyPointer, QString>> ModelPrivate::toInternalBindingProperties( QList<std::tuple<InternalBindingProperty *, QString>> ModelPrivate::toInternalBindingProperties(
const ModelResourceSet::SetExpressions &setExpressions) const ModelResourceSet::SetExpressions &setExpressions)
{ {
QList<std::tuple<InternalBindingPropertyPointer, QString>> internalProperties; QList<std::tuple<InternalBindingProperty *, QString>> internalProperties;
internalProperties.reserve(setExpressions.size()); internalProperties.reserve(setExpressions.size());
for (const auto &setExpression : setExpressions) { for (const auto &setExpression : setExpressions) {
@@ -1195,45 +1211,48 @@ void ModelPrivate::deselectNode(const InternalNodePointer &node)
setSelectedNodes(selectedNodeList); setSelectedNodes(selectedNodeList);
} }
void ModelPrivate::removePropertyWithoutNotification(const InternalPropertyPointer &property) void ModelPrivate::removePropertyWithoutNotification(InternalProperty *property)
{ {
if (property->isNodeAbstractProperty()) { if (auto nodeListProperty = property->to<PropertyType::NodeList>()) {
const auto &&allSubNodes = property->toProperty<InternalNodeAbstractProperty>()->allSubNodes(); const auto allSubNodes = nodeListProperty->allSubNodes();
for (const InternalNodePointer &node : allSubNodes) for (const InternalNodePointer &node : allSubNodes)
removeNodeFromModel(node); removeNodeFromModel(node);
} else if (auto nodeProperty = property->to<PropertyType::Node>()) {
removeNodeFromModel({nodeProperty->node()});
} }
property->remove(); auto propertyOwner = property->propertyOwner();
propertyOwner->removeProperty(property->name());
} }
static QList<PropertyPair> toPropertyPairList(const QList<InternalPropertyPointer> &propertyList) static QList<PropertyPair> toPropertyPairList(const QList<InternalProperty *> &propertyList)
{ {
QList<PropertyPair> propertyPairList; QList<PropertyPair> propertyPairList;
propertyPairList.reserve(propertyList.size()); propertyPairList.reserve(propertyList.size());
for (const InternalPropertyPointer &property : propertyList) for (const InternalProperty *property : propertyList)
propertyPairList.append({property->propertyOwner(), property->name()}); propertyPairList.append({property->propertyOwner(), property->name()});
return propertyPairList; return propertyPairList;
} }
void ModelPrivate::removePropertyAndRelatedResources(const InternalPropertyPointer &property) void ModelPrivate::removePropertyAndRelatedResources(InternalProperty *property)
{ {
if (m_resourceManagement) { if (m_resourceManagement) {
handleResourceSet( handleResourceSet(m_resourceManagement->removeProperties(
m_resourceManagement->removeProperties({AbstractProperty{property, m_model, nullptr}}, {AbstractProperty{property->name(), property->propertyOwner(), m_model, nullptr}},
m_model)); m_model));
} else { } else {
removeProperty(property); removeProperty(property);
} }
} }
void ModelPrivate::removeProperty(const InternalPropertyPointer &property) void ModelPrivate::removeProperty(InternalProperty *property)
{ {
removeProperties({property}); removeProperties({property});
} }
void ModelPrivate::removeProperties(const QList<InternalPropertyPointer> &properties) void ModelPrivate::removeProperties(const QList<InternalProperty *> &properties)
{ {
if (properties.isEmpty()) if (properties.isEmpty())
return; return;
@@ -1242,7 +1261,7 @@ void ModelPrivate::removeProperties(const QList<InternalPropertyPointer> &proper
const QList<PropertyPair> propertyPairList = toPropertyPairList(properties); const QList<PropertyPair> propertyPairList = toPropertyPairList(properties);
for (const auto &property : properties) for (auto property : properties)
removePropertyWithoutNotification(property); removePropertyWithoutNotification(property);
notifyPropertiesRemoved(propertyPairList); notifyPropertiesRemoved(propertyPairList);
@@ -1253,12 +1272,14 @@ void ModelPrivate::setBindingProperty(const InternalNodePointer &node,
const QString &expression) const QString &expression)
{ {
AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
if (!node->hasProperty(name)) { InternalBindingProperty *bindingProperty = nullptr;
node->addBindingProperty(name); if (auto property = node->property(name)) {
bindingProperty = property->to<PropertyType::Binding>();
} else {
bindingProperty = node->addBindingProperty(name);
propertyChange = AbstractView::PropertiesAdded; propertyChange = AbstractView::PropertiesAdded;
} }
InternalBindingPropertyPointer bindingProperty = node->bindingProperty(name);
notifyBindingPropertiesAboutToBeChanged({bindingProperty}); notifyBindingPropertiesAboutToBeChanged({bindingProperty});
bindingProperty->setExpression(expression); bindingProperty->setExpression(expression);
notifyBindingPropertiesChanged({bindingProperty}, propertyChange); 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) void ModelPrivate::setSignalHandlerProperty(const InternalNodePointer &node, const PropertyName &name, const QString &source)
{ {
AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
if (!node->hasProperty(name)) { InternalSignalHandlerProperty *signalHandlerProperty = nullptr;
node->addSignalHandlerProperty(name); if (auto property = node->property(name)) {
signalHandlerProperty = property->to<PropertyType::SignalHandler>();
} else {
signalHandlerProperty = node->addSignalHandlerProperty(name);
propertyChange = AbstractView::PropertiesAdded; propertyChange = AbstractView::PropertiesAdded;
} }
InternalSignalHandlerPropertyPointer signalHandlerProperty = node->signalHandlerProperty(name);
signalHandlerProperty->setSource(source); signalHandlerProperty->setSource(source);
notifySignalHandlerPropertiesChanged({signalHandlerProperty}, propertyChange); 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) void ModelPrivate::setSignalDeclarationProperty(const InternalNodePointer &node, const PropertyName &name, const QString &signature)
{ {
AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
if (!node->hasProperty(name)) { InternalSignalDeclarationProperty *signalDeclarationProperty = nullptr;
node->addSignalDeclarationProperty(name); if (auto property = node->property(name)) {
signalDeclarationProperty = property->to<PropertyType::SignalDeclaration>();
} else {
signalDeclarationProperty = node->addSignalDeclarationProperty(name);
propertyChange = AbstractView::PropertiesAdded; propertyChange = AbstractView::PropertiesAdded;
} }
InternalSignalDeclarationPropertyPointer signalDeclarationProperty = node->signalDeclarationProperty(name);
signalDeclarationProperty->setSignature(signature); signalDeclarationProperty->setSignature(signature);
notifySignalDeclarationPropertiesChanged({signalDeclarationProperty}, propertyChange); 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) void ModelPrivate::setVariantProperty(const InternalNodePointer &node, const PropertyName &name, const QVariant &value)
{ {
AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
if (!node->hasProperty(name)) { InternalVariantProperty *variantProperty = nullptr;
node->addVariantProperty(name); if (auto property = node->property(name)) {
variantProperty = property->to<PropertyType::Variant>();
} else {
variantProperty = node->addVariantProperty(name);
propertyChange = AbstractView::PropertiesAdded; propertyChange = AbstractView::PropertiesAdded;
} }
node->variantProperty(name)->setValue(value); variantProperty->setValue(value);
node->variantProperty(name)->resetDynamicTypeName(); variantProperty->resetDynamicTypeName();
notifyVariantPropertiesChanged(node, PropertyNameList({name}), propertyChange); notifyVariantPropertiesChanged(node, PropertyNameList({name}), propertyChange);
} }
@@ -1325,12 +1353,15 @@ void ModelPrivate::setDynamicVariantProperty(const InternalNodePointer &node,
const QVariant &value) const QVariant &value)
{ {
AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
if (!node->hasProperty(name)) { InternalVariantProperty *variantProperty = nullptr;
node->addVariantProperty(name); if (auto property = node->property(name)) {
variantProperty = property->to<PropertyType::Variant>();
} else {
variantProperty = node->addVariantProperty(name);
propertyChange = AbstractView::PropertiesAdded; propertyChange = AbstractView::PropertiesAdded;
} }
node->variantProperty(name)->setDynamicValue(dynamicPropertyType, value); variantProperty->setDynamicValue(dynamicPropertyType, value);
notifyVariantPropertiesChanged(node, PropertyNameList({name}), propertyChange); notifyVariantPropertiesChanged(node, PropertyNameList({name}), propertyChange);
} }
@@ -1340,12 +1371,14 @@ void ModelPrivate::setDynamicBindingProperty(const InternalNodePointer &node,
const QString &expression) const QString &expression)
{ {
AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
if (!node->hasProperty(name)) { InternalBindingProperty *bindingProperty = nullptr;
node->addBindingProperty(name); if (auto property = node->property(name)) {
bindingProperty = property->to<PropertyType::Binding>();
} else {
bindingProperty = node->addBindingProperty(name);
propertyChange = AbstractView::PropertiesAdded; propertyChange = AbstractView::PropertiesAdded;
} }
InternalBindingPropertyPointer bindingProperty = node->bindingProperty(name);
notifyBindingPropertiesAboutToBeChanged({bindingProperty}); notifyBindingPropertiesAboutToBeChanged({bindingProperty});
bindingProperty->setDynamicExpression(dynamicPropertyType, expression); bindingProperty->setDynamicExpression(dynamicPropertyType, expression);
notifyBindingPropertiesChanged({bindingProperty}, propertyChange); notifyBindingPropertiesChanged({bindingProperty}, propertyChange);
@@ -1358,11 +1391,15 @@ void ModelPrivate::reparentNode(const InternalNodePointer &parentNode,
const TypeName &dynamicTypeName) const TypeName &dynamicTypeName)
{ {
AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges; AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
if (!parentNode->hasProperty(name)) { InternalNodeAbstractProperty *newParentProperty = nullptr;
if (auto property = parentNode->property(name)) {
newParentProperty = property->to<PropertyType::Node, PropertyType::NodeList>();
} else {
if (list) if (list)
parentNode->addNodeListProperty(name); newParentProperty = parentNode->addNodeListProperty(name);
else else
parentNode->addNodeProperty(name, dynamicTypeName); newParentProperty = parentNode->addNodeProperty(name, dynamicTypeName);
propertyChange |= AbstractView::PropertiesAdded; propertyChange |= AbstractView::PropertiesAdded;
} }
@@ -1374,16 +1411,21 @@ void ModelPrivate::reparentNode(const InternalNodePointer &parentNode,
oldParentPropertyName = childNode->parentProperty()->name(); oldParentPropertyName = childNode->parentProperty()->name();
} }
InternalNodeAbstractPropertyPointer newParentProperty(parentNode->nodeAbstractProperty(name));
Q_ASSERT(newParentProperty); Q_ASSERT(newParentProperty);
notifyNodeAboutToBeReparent(childNode, newParentProperty, oldParentNode, oldParentPropertyName, propertyChange); notifyNodeAboutToBeReparent(childNode,
newParentProperty,
oldParentNode,
oldParentPropertyName,
propertyChange);
if (newParentProperty) if (newParentProperty) {
childNode->setParentProperty(newParentProperty); childNode->setParentProperty(
newParentProperty->toShared<PropertyType::Node, PropertyType::NodeList>());
}
if (oldParentProperty && oldParentProperty->isValid() && oldParentProperty->isEmpty()) { if (oldParentProperty && oldParentProperty->isValid() && oldParentProperty->isEmpty()) {
removePropertyWithoutNotification(oldParentProperty); removePropertyWithoutNotification(oldParentProperty.get());
propertyChange |= AbstractView::EmptyPropertiesRemoved; propertyChange |= AbstractView::EmptyPropertiesRemoved;
} }
@@ -1402,7 +1444,11 @@ void ModelPrivate::clearParent(const InternalNodePointer &node)
} }
node->resetParentProperty(); 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) 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) 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); Q_ASSERT(nodeList);
nodeList->slide(from, to); nodeList->slide(from, to);
@@ -1742,7 +1788,7 @@ QString Model::generateNewId(const QString &prefixName,
isDuplicate = std::bind(&Model::hasId, this, std::placeholders::_1); isDuplicate = std::bind(&Model::hasId, this, std::placeholders::_1);
while (!ModelNode::isValidId(newId) || isDuplicate.value()(newId) while (!ModelNode::isValidId(newId) || isDuplicate.value()(newId)
|| d->rootNode()->hasProperty(newId.toUtf8())) { || d->rootNode()->property(newId.toUtf8())) {
++counter; ++counter;
newId = QString(QStringLiteral("%1%2")).arg(firstCharToLower(newBaseId)).arg(counter); newId = QString(QStringLiteral("%1%2")).arg(firstCharToLower(newBaseId)).arg(counter);
} }

View File

@@ -43,14 +43,6 @@ class InternalVariantProperty;
class InternalNodeAbstractProperty; class InternalNodeAbstractProperty;
class InternalNodeListProperty; class InternalNodeListProperty;
using InternalNodePointer = std::shared_ptr<InternalNode>;
using InternalPropertyPointer = std::shared_ptr<InternalProperty>;
using InternalBindingPropertyPointer = std::shared_ptr<InternalBindingProperty>;
using InternalSignalHandlerPropertyPointer = std::shared_ptr<InternalSignalHandlerProperty>;
using InternalSignalDeclarationPropertyPointer = std::shared_ptr<InternalSignalDeclarationProperty>;
using InternalVariantPropertyPointer = std::shared_ptr<InternalVariantProperty>;
using InternalNodeAbstractPropertyPointer = std::shared_ptr<InternalNodeAbstractProperty>;
using InternalNodeListPropertyPointer = std::shared_ptr<InternalNodeListProperty>;
using PropertyPair = QPair<InternalNodePointer, PropertyName>; using PropertyPair = QPair<InternalNodePointer, PropertyName>;
class ModelPrivate; class ModelPrivate;
@@ -156,12 +148,12 @@ public:
void notifyNodeCreated(const InternalNodePointer &newNode); void notifyNodeCreated(const InternalNodePointer &newNode);
void notifyNodeAboutToBeReparent(const InternalNodePointer &node, void notifyNodeAboutToBeReparent(const InternalNodePointer &node,
const InternalNodeAbstractPropertyPointer &newPropertyParent, const InternalNodeAbstractProperty *newPropertyParent,
const InternalNodePointer &oldParent, const InternalNodePointer &oldParent,
const PropertyName &oldPropertyName, const PropertyName &oldPropertyName,
AbstractView::PropertyChangeFlags propertyChange); AbstractView::PropertyChangeFlags propertyChange);
void notifyNodeReparent(const InternalNodePointer &node, void notifyNodeReparent(const InternalNodePointer &node,
const InternalNodeAbstractPropertyPointer &newPropertyParent, const InternalNodeAbstractProperty *newPropertyParent,
const InternalNodePointer &oldParent, const InternalNodePointer &oldParent,
const PropertyName &oldPropertyName, const PropertyName &oldPropertyName,
AbstractView::PropertyChangeFlags propertyChange); AbstractView::PropertyChangeFlags propertyChange);
@@ -174,19 +166,25 @@ public:
void notifyNodeTypeChanged(const InternalNodePointer &node, const TypeName &type, int majorVersion, int minorVersion); void notifyNodeTypeChanged(const InternalNodePointer &node, const TypeName &type, int majorVersion, int minorVersion);
void notifyPropertiesRemoved(const QList<PropertyPair> &propertyList); void notifyPropertiesRemoved(const QList<PropertyPair> &propertyList);
void notifyPropertiesAboutToBeRemoved(const QList<InternalPropertyPointer> &internalPropertyList); void notifyPropertiesAboutToBeRemoved(const QList<InternalProperty *> &internalPropertyList);
void notifyBindingPropertiesAboutToBeChanged( void notifyBindingPropertiesAboutToBeChanged(
const QList<InternalBindingPropertyPointer> &internalPropertyList); const QList<QmlDesigner::Internal::InternalBindingProperty *> &internalPropertyList);
void notifyBindingPropertiesChanged(const QList<InternalBindingPropertyPointer> &internalPropertyList, AbstractView::PropertyChangeFlags propertyChange); void notifyBindingPropertiesChanged(
void notifySignalHandlerPropertiesChanged(const QVector<InternalSignalHandlerPropertyPointer> &propertyList, AbstractView::PropertyChangeFlags propertyChange); const QList<QmlDesigner::Internal::InternalBindingProperty *> &internalPropertyList,
void notifySignalDeclarationPropertiesChanged(const QVector<InternalSignalDeclarationPropertyPointer> &propertyList, AbstractView::PropertyChangeFlags propertyChange); AbstractView::PropertyChangeFlags propertyChange);
void notifySignalHandlerPropertiesChanged(
const QVector<QmlDesigner::Internal::InternalSignalHandlerProperty *> &propertyList,
AbstractView::PropertyChangeFlags propertyChange);
void notifySignalDeclarationPropertiesChanged(
const QVector<QmlDesigner::Internal::InternalSignalDeclarationProperty *> &propertyList,
AbstractView::PropertyChangeFlags propertyChange);
void notifyVariantPropertiesChanged(const InternalNodePointer &node, const PropertyNameList &propertyNameList, AbstractView::PropertyChangeFlags propertyChange); void notifyVariantPropertiesChanged(const InternalNodePointer &node, const PropertyNameList &propertyNameList, AbstractView::PropertyChangeFlags propertyChange);
void notifyScriptFunctionsChanged(const InternalNodePointer &node, const QStringList &scriptFunctionList); void notifyScriptFunctionsChanged(const InternalNodePointer &node, const QStringList &scriptFunctionList);
void notifyNodeOrderChanged(const InternalNodeListPropertyPointer &internalListProperty, void notifyNodeOrderChanged(const QmlDesigner::Internal::InternalNodeListProperty *internalListProperty,
const InternalNodePointer &node, const InternalNodePointer &node,
int oldIndex); int oldIndex);
void notifyNodeOrderChanged(const InternalNodeListPropertyPointer &internalListProperty); void notifyNodeOrderChanged(const InternalNodeListProperty *internalListProperty);
void notifyAuxiliaryDataChanged(const InternalNodePointer &node, void notifyAuxiliaryDataChanged(const InternalNodePointer &node,
AuxiliaryDataKeyView key, AuxiliaryDataKeyView key,
const QVariant &data); const QVariant &data);
@@ -248,9 +246,9 @@ public:
//node state property manipulation //node state property manipulation
void addProperty(const InternalNodePointer &node, const PropertyName &name); void addProperty(const InternalNodePointer &node, const PropertyName &name);
void setPropertyValue(const InternalNodePointer &node,const PropertyName &name, const QVariant &value); void setPropertyValue(const InternalNodePointer &node,const PropertyName &name, const QVariant &value);
void removePropertyAndRelatedResources(const InternalPropertyPointer &property); void removePropertyAndRelatedResources(InternalProperty *property);
void removeProperty(const InternalPropertyPointer &property); void removeProperty(InternalProperty *property);
void removeProperties(const QList<InternalPropertyPointer> &properties); void removeProperties(const QList<InternalProperty *> &properties);
void setBindingProperty(const InternalNodePointer &node, void setBindingProperty(const InternalNodePointer &node,
const PropertyName &name, const PropertyName &name,
@@ -300,16 +298,16 @@ public:
} }
private: private:
void removePropertyWithoutNotification(const InternalPropertyPointer &property); void removePropertyWithoutNotification(InternalProperty *property);
void removeAllSubNodes(const InternalNodePointer &node); void removeAllSubNodes(const InternalNodePointer &node);
void removeNodeFromModel(const InternalNodePointer &node); void removeNodeFromModel(const InternalNodePointer &node);
QList<InternalNodePointer> toInternalNodeList(const QList<ModelNode> &modelNodeList) const; QList<InternalNodePointer> toInternalNodeList(const QList<ModelNode> &modelNodeList) const;
QList<ModelNode> toModelNodeList(const QList<InternalNodePointer> &nodeList, AbstractView *view) const; QList<ModelNode> toModelNodeList(const QList<InternalNodePointer> &nodeList, AbstractView *view) const;
QVector<ModelNode> toModelNodeVector(const QVector<InternalNodePointer> &nodeVector, AbstractView *view) const; QVector<ModelNode> toModelNodeVector(const QVector<InternalNodePointer> &nodeVector, AbstractView *view) const;
QVector<InternalNodePointer> toInternalNodeVector(const QVector<ModelNode> &modelNodeVector) const; QVector<InternalNodePointer> toInternalNodeVector(const QVector<ModelNode> &modelNodeVector) const;
static QList<InternalPropertyPointer> toInternalProperties(const AbstractProperties &properties); static QList<InternalProperty *> toInternalProperties(const AbstractProperties &properties);
static QList<std::tuple<InternalBindingPropertyPointer, QString>> toInternalBindingProperties( static QList<std::tuple<QmlDesigner::Internal::InternalBindingProperty *, QString>>
const ModelResourceSet::SetExpressions &setExpressions); toInternalBindingProperties(const ModelResourceSet::SetExpressions &setExpressions);
EnabledViewRange enabledViews() const; EnabledViewRange enabledViews() const;
ImportedTypeNameId importedTypeNameId(Utils::SmallStringView typeName); ImportedTypeNameId importedTypeNameId(Utils::SmallStringView typeName);
void setTypeId(InternalNode *node, Utils::SmallStringView typeName); void setTypeId(InternalNode *node, Utils::SmallStringView typeName);

View File

@@ -607,8 +607,8 @@ void ModelNode::removeProperty(const PropertyName &name) const
if (!model()->d->propertyNameIsValid(name)) if (!model()->d->propertyNameIsValid(name))
return; return;
if (m_internalNode->hasProperty(name)) if (auto property = m_internalNode->property(name))
model()->d->removePropertyAndRelatedResources(m_internalNode->property(name)); model()->d->removePropertyAndRelatedResources(property);
} }
/*! \brief removes this node from the node tree /*! \brief removes this node from the node tree
@@ -800,7 +800,7 @@ PropertyNameList ModelNode::propertyNames() const
*/ */
bool ModelNode::hasProperty(const PropertyName &name) 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 bool ModelNode::hasVariantProperty(const PropertyName &name) const

View File

@@ -18,7 +18,7 @@ namespace QmlDesigner {
NodeAbstractProperty::NodeAbstractProperty() = default; NodeAbstractProperty::NodeAbstractProperty() = default;
NodeAbstractProperty::NodeAbstractProperty(const NodeAbstractProperty &property, AbstractView *view) 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()) if (!isValid() || !modelNode.isValid())
return; return;
if (internalNode()->hasProperty(name()) reparentHere(modelNode,
&& !internalNode()->property(name())->isNodeAbstractProperty()) { parentModelNode().metaInfo().property(name()).isListProperty()
reparentHere(modelNode, isNodeListProperty()); || isDefaultProperty()); //we could use the metasystem instead?
} else {
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) 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()) if (modelNode.hasParentProperty() && modelNode.parentProperty().isDynamic())
return; return;
auto internalProperty = internalNode()->property(name()); if (auto internalProperty = internalNode()->property(name());
if (internalProperty && !internalProperty->isNodeAbstractProperty()) internalProperty && !internalProperty->isNodeAbstractProperty()) {
privateModel()->removePropertyAndRelatedResources(internalProperty); privateModel()->removePropertyAndRelatedResources(internalProperty);
}
if (modelNode.hasParentProperty()) { if (modelNode.hasParentProperty()) {
Internal::InternalNodeAbstractProperty::Pointer oldParentProperty = modelNode.internalNode()->parentProperty(); 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); Q_ASSERT(oldParentProperty);
} else { } 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<ModelNode> NodeAbstractProperty::allSubNodes() QList<ModelNode> NodeAbstractProperty::allSubNodes()
{ {
if (!internalNode() || !internalNode()->isValid || !internalNode()->hasProperty(name()) if (!internalNode() || !internalNode()->isValid)
|| !internalNode()->property(name())->isNodeAbstractProperty())
return {}; return {};
Internal::InternalNodeAbstractProperty::Pointer property = internalNode()->nodeAbstractProperty(name()); auto property = internalNode()->property(name());
return QmlDesigner::toModelNodeList(property->allSubNodes(), model(), view());
if (!property)
return {};
switch (property->type()) {
case PropertyType::Node:
return QmlDesigner::toModelNodeList({property->to<PropertyType::Node>()->allSubNodes()},
model(),
view());
case PropertyType::NodeList:
return QmlDesigner::toModelNodeList({property->to<PropertyType::NodeList>()->allSubNodes()},
model(),
view());
case PropertyType::Binding:
case PropertyType::None:
case PropertyType::SignalDeclaration:
case PropertyType::SignalHandler:
case PropertyType::Variant:
break;
}
return {};
} }
QList<ModelNode> NodeAbstractProperty::directSubNodes() const QList<ModelNode> NodeAbstractProperty::directSubNodes() const
{ {
if (!internalNode() || !internalNode()->isValid || !internalNode()->hasProperty(name()) if (!internalNode() || !internalNode()->isValid)
|| !internalNode()->property(name())->isNodeAbstractProperty())
return {}; return {};
Internal::InternalNodeAbstractProperty::Pointer property = internalNode()->nodeAbstractProperty(name()); auto property = internalNode()->property(name());
return QmlDesigner::toModelNodeList(property->directSubNodes(), model(), view());
if (!property)
return {};
switch (property->type()) {
case PropertyType::Node:
return QmlDesigner::toModelNodeList({property->to<PropertyType::Node>()->node()},
model(),
view());
case PropertyType::NodeList:
return QmlDesigner::toModelNodeList({property->to<PropertyType::NodeList>()->nodes()},
model(),
view());
case PropertyType::Binding:
case PropertyType::None:
case PropertyType::SignalDeclaration:
case PropertyType::SignalHandler:
case PropertyType::Variant:
break;
}
return {};
} }
/*! /*!

View File

@@ -23,14 +23,11 @@ Internal::NodeListPropertyIterator::value_type Internal::NodeListPropertyIterato
NodeListProperty::NodeListProperty() = default; NodeListProperty::NodeListProperty() = default;
NodeListProperty::NodeListProperty(const NodeListProperty &property, AbstractView *view) NodeListProperty::NodeListProperty(const PropertyName &propertyName,
: NodeAbstractProperty(property.name(), property.internalNode(), property.model(), view) 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) if (m_internalNodeListProperty)
return m_internalNodeListProperty; return m_internalNodeListProperty;
auto internalProperty = internalNode()->nodeListProperty(name()); auto property = internalNode()->property(name());
if (internalProperty) if (property) {
m_internalNodeListProperty = internalProperty; if (auto nodeListProperty = property->toShared<PropertyType::NodeList>())
m_internalNodeListProperty = nodeListProperty;
}
return m_internalNodeListProperty; 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) if (to < 0 || to > count() - 1 || from < 0 || from > count() - 1)
return; return;
privateModel()->changeNodeOrder(internalNode(), name(), from, to); privateModel()->changeNodeOrder(internalNodeSharedPointer(), name(), from, to);
} }
void NodeListProperty::swap(int from, int to) const 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, newFirst.m_currentIndex),
std::next(begin, last.m_currentIndex)); std::next(begin, last.m_currentIndex));
privateModel()->notifyNodeOrderChanged(m_internalNodeListProperty); privateModel()->notifyNodeOrderChanged(m_internalNodeListProperty.get());
return {iter - begin, internalNodeListProperty().get(), model(), view()}; 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)); 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<ModelNode> &nodes) void NodeListProperty::reverseModelNodes(const QList<ModelNode> &nodes)

View File

@@ -30,10 +30,13 @@ void NodeProperty::setModelNode(const ModelNode &modelNode)
return; return;
} }
if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isNodeProperty()) if (auto property = internalNode()->property(name()); !property->isNodeProperty())
privateModel()->removePropertyAndRelatedResources(internalNode()->property(name())); 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 ModelNode NodeProperty::modelNode() const

View File

@@ -11,7 +11,7 @@ namespace QmlDesigner {
SignalHandlerProperty::SignalHandlerProperty() = default; SignalHandlerProperty::SignalHandlerProperty() = default;
SignalHandlerProperty::SignalHandlerProperty(const SignalHandlerProperty &property, AbstractView *view) 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()->removePropertyAndRelatedResources(internalProperty);
} }
privateModel()->setSignalHandlerProperty(internalNode(), name(), source); privateModel()->setSignalHandlerProperty(internalNodeSharedPointer(), name(), source);
} }
QString SignalHandlerProperty::source() const QString SignalHandlerProperty::source() const
@@ -50,9 +50,8 @@ QString SignalHandlerProperty::source() const
if (!isValid()) if (!isValid())
return {}; return {};
if (internalNode()->hasProperty(name()) if (auto property = internalNode()->signalHandlerProperty(name()))
&& internalNode()->property(name())->isSignalHandlerProperty()) return property->source();
return internalNode()->signalHandlerProperty(name())->source();
return QString(); return QString();
} }
@@ -87,7 +86,7 @@ SignalDeclarationProperty::SignalDeclarationProperty() = default;
SignalDeclarationProperty::SignalDeclarationProperty(const SignalDeclarationProperty &property, SignalDeclarationProperty::SignalDeclarationProperty(const SignalDeclarationProperty &property,
AbstractView *view) AbstractView *view)
: AbstractProperty(property.name(), property.internalNode(), property.model(), view) : AbstractProperty(property.name(), property.internalNodeSharedPointer(), property.model(), view)
{} {}
SignalDeclarationProperty::SignalDeclarationProperty( SignalDeclarationProperty::SignalDeclarationProperty(
@@ -121,7 +120,7 @@ void SignalDeclarationProperty::setSignature(const QString &signature)
privateModel()->removePropertyAndRelatedResources(internalProperty); privateModel()->removePropertyAndRelatedResources(internalProperty);
} }
privateModel()->setSignalDeclarationProperty(internalNode(), name(), signature); privateModel()->setSignalDeclarationProperty(internalNodeSharedPointer(), name(), signature);
} }
QString SignalDeclarationProperty::signature() const QString SignalDeclarationProperty::signature() const
@@ -129,9 +128,8 @@ QString SignalDeclarationProperty::signature() const
if (!isValid()) if (!isValid())
return {}; return {};
if (internalNode()->hasProperty(name()) if (auto property = internalNode()->signalDeclarationProperty(name()))
&& internalNode()->property(name())->isSignalDeclarationProperty()) return property->signature();
return internalNode()->signalDeclarationProperty(name())->signature();
return QString(); return QString();
} }

View File

@@ -14,7 +14,7 @@ namespace QmlDesigner {
VariantProperty::VariantProperty() = default; VariantProperty::VariantProperty() = default;
VariantProperty::VariantProperty(const VariantProperty &property, AbstractView *view) 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()->removePropertyAndRelatedResources(internalProperty);
} }
privateModel()->setVariantProperty(internalNode(), name(), value); privateModel()->setVariantProperty(internalNodeSharedPointer(), name(), value);
} }
QVariant VariantProperty::value() const QVariant VariantProperty::value() const
@@ -99,7 +99,7 @@ void VariantProperty::setDynamicTypeNameAndValue(const TypeName &type, const QVa
privateModel()->removePropertyAndRelatedResources(internalProperty); privateModel()->removePropertyAndRelatedResources(internalProperty);
} }
privateModel()->setDynamicVariantProperty(internalNode(), name(), type, value); privateModel()->setDynamicVariantProperty(internalNodeSharedPointer(), name(), type, value);
} }
void VariantProperty::setDynamicTypeNameAndEnumeration(const TypeName &type, const EnumerationName &enumerationName) void VariantProperty::setDynamicTypeNameAndEnumeration(const TypeName &type, const EnumerationName &enumerationName)