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

View File

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

View File

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

View File

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

View File

@@ -18,10 +18,6 @@
namespace QmlDesigner {
namespace Internal {
InternalNodeAbstractProperty::Pointer InternalNode::parentProperty() const
{
return m_parentProperty.lock();
}
void InternalNode::setParentProperty(const InternalNodeAbstractProperty::Pointer &parent)
{
InternalNodeAbstractProperty::Pointer parentProperty = m_parentProperty.lock();
@@ -116,8 +112,7 @@ AuxiliaryDatasForType InternalNode::auxiliaryData(AuxiliaryDataType type) const
void InternalNode::removeProperty(const PropertyName &name)
{
InternalProperty::Pointer property = m_namePropertyHash.take(name);
Q_ASSERT(property);
m_namePropertyHash.remove(name);
}
PropertyNameList InternalNode::propertyNameList() const
@@ -125,53 +120,73 @@ PropertyNameList InternalNode::propertyNameList() const
return m_namePropertyHash.keys();
}
bool InternalNode::hasProperties() const
{
return !m_namePropertyHash.isEmpty();
}
bool InternalNode::hasProperty(const PropertyName &name) const
{
return m_namePropertyHash.contains(name);
}
QList<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> nodeList;
const QList<InternalNodeAbstractProperty::Pointer> properties = nodeAbstractPropertyList();
for (const InternalNodeAbstractProperty::Pointer &property : properties) {
nodeList.append(property->allSubNodes());
}
QList<InternalNode::Pointer> nodes;
nodes.reserve(1024);
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> nodeList;
const QList<InternalNodeAbstractProperty::Pointer> properties = nodeAbstractPropertyList();
for (const InternalNodeAbstractProperty::Pointer &property : properties) {
nodeList.append(property->directSubNodes());
}
QList<InternalNode::Pointer> nodes;
nodes.reserve(96);
return nodeList;
addDirectSubNodes(nodes);
return nodes;
}
} // namespace Internal

View File

@@ -52,7 +52,7 @@ public:
, internalId(internalId)
{}
InternalNodeAbstractProperty::Pointer parentProperty() const;
InternalNodeAbstractProperty::Pointer parentProperty() const { return m_parentProperty.lock(); }
// Reparent within model
void setParentProperty(const InternalNodeAbstractProperty::Pointer &parent);
@@ -66,18 +66,25 @@ public:
AuxiliaryDatasView auxiliaryData() const { return std::as_const(m_auxiliaryDatas); }
template<typename Type>
typename Type::Pointer property(const PropertyName &name) const
Type *property(const PropertyName &name) const
{
auto property = m_namePropertyHash.value(name);
if (property && property->propertyType() == Type::type)
return std::static_pointer_cast<Type>(property);
auto propertyIter = m_namePropertyHash.find(name);
if (propertyIter != m_namePropertyHash.end()) {
if (auto property = propertyIter->get(); property && property->propertyType() == Type::type)
return static_cast<Type *>(property);
}
return {};
}
InternalProperty::Pointer property(const PropertyName &name) const
InternalProperty *property(const PropertyName &name) const
{
return m_namePropertyHash.value(name);
auto propertyIter = m_namePropertyHash.find(name);
if (propertyIter != m_namePropertyHash.end())
return propertyIter->get();
return nullptr;
}
auto bindingProperty(const PropertyName &name) const
@@ -116,60 +123,62 @@ public:
return {};
}
InternalNodeProperty::Pointer nodeProperty(const PropertyName &name) const
auto nodeProperty(const PropertyName &name) const
{
return property<InternalNodeProperty>(name);
}
template<typename Type>
auto &addProperty(const PropertyName &name)
Type *addProperty(const PropertyName &name)
{
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);
property.setDynamicTypeName(dynamicTypeName);
auto property = addProperty<InternalNodeProperty>(name);
property->setDynamicTypeName(dynamicTypeName);
return property;
}
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> 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,
const InternalNode::Pointer &secondNode)
@@ -185,9 +194,10 @@ public:
friend size_t qHash(const InternalNodePointer &node) { return ::qHash(node.get()); }
protected:
void removeProperty(const PropertyName &name);
protected:
public:
TypeName typeName;
QString id;

View File

@@ -17,17 +17,12 @@ public:
using Pointer = std::shared_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 int count() const = 0;
virtual int indexOf(const InternalNodePointer &node) const = 0;
bool isValid() const override;
using InternalProperty::remove; // keep the virtual remove(...) function around
protected:
InternalNodeAbstractProperty(const PropertyName &name,
const InternalNodePointer &propertyOwner,

View File

@@ -60,20 +60,22 @@ void InternalNodeListProperty::slide(int from, int to)
m_nodeList.insert(to, internalNode);
}
QList<InternalNode::Pointer> InternalNodeListProperty::allSubNodes() const
void InternalNodeListProperty::addSubNodes(QList<InternalNodePointer> &container) const
{
QList<InternalNode::Pointer> nodeList;
for (const InternalNode::Pointer &childNode : std::as_const(m_nodeList)) {
nodeList.append(childNode->allSubNodes());
nodeList.append(childNode);
for (const auto &node : std::as_const(m_nodeList)) {
container.push_back(node);
node->addSubNodes(container);
}
return nodeList;
}
QList<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

View File

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

View File

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

View File

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

View File

@@ -37,17 +37,6 @@ PropertyName InternalProperty::name() const
return m_name;
}
InternalNode::Pointer InternalProperty::propertyOwner() const
{
return m_propertyOwner.lock();
}
void InternalProperty::remove()
{
propertyOwner()->removeProperty(name());
m_propertyOwner.reset();
}
TypeName InternalProperty::dynamicTypeName() const
{
return m_dynamicType;

View File

@@ -8,6 +8,7 @@
#include <QVariant>
#include <memory>
#include <type_traits>
namespace QmlDesigner {
@@ -24,7 +25,7 @@ class InternalNode;
using InternalNodePointer = std::shared_ptr<InternalNode>;
template<PropertyType propertyType>
template<PropertyType... propertyType>
struct TypeLookup
{};
@@ -68,6 +69,21 @@ struct TypeLookup<PropertyType::Variant>
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>
{
public:
@@ -103,24 +119,60 @@ public:
return std::static_pointer_cast<Type>(shared_from_this());
}
template<PropertyType propertyType>
auto to()
template<PropertyType... propertyType>
auto toShared()
{
if (propertyType == m_propertyType)
return std::static_pointer_cast<typename TypeLookup<propertyType>::Type>(
shared_from_this());
using Type = type_lookup_t<propertyType...>;
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;
void resetDynamicTypeName();
PropertyType type() const { return m_propertyType; }
protected: // functions
InternalProperty(const PropertyName &name,
const InternalNodePointer &propertyOwner,

View File

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

View File

@@ -43,14 +43,6 @@ class InternalVariantProperty;
class InternalNodeAbstractProperty;
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>;
class ModelPrivate;
@@ -156,12 +148,12 @@ public:
void notifyNodeCreated(const InternalNodePointer &newNode);
void notifyNodeAboutToBeReparent(const InternalNodePointer &node,
const InternalNodeAbstractPropertyPointer &newPropertyParent,
const InternalNodeAbstractProperty *newPropertyParent,
const InternalNodePointer &oldParent,
const PropertyName &oldPropertyName,
AbstractView::PropertyChangeFlags propertyChange);
void notifyNodeReparent(const InternalNodePointer &node,
const InternalNodeAbstractPropertyPointer &newPropertyParent,
const InternalNodeAbstractProperty *newPropertyParent,
const InternalNodePointer &oldParent,
const PropertyName &oldPropertyName,
AbstractView::PropertyChangeFlags propertyChange);
@@ -174,19 +166,25 @@ public:
void notifyNodeTypeChanged(const InternalNodePointer &node, const TypeName &type, int majorVersion, int minorVersion);
void notifyPropertiesRemoved(const QList<PropertyPair> &propertyList);
void notifyPropertiesAboutToBeRemoved(const QList<InternalPropertyPointer> &internalPropertyList);
void notifyPropertiesAboutToBeRemoved(const QList<InternalProperty *> &internalPropertyList);
void notifyBindingPropertiesAboutToBeChanged(
const QList<InternalBindingPropertyPointer> &internalPropertyList);
void notifyBindingPropertiesChanged(const QList<InternalBindingPropertyPointer> &internalPropertyList, AbstractView::PropertyChangeFlags propertyChange);
void notifySignalHandlerPropertiesChanged(const QVector<InternalSignalHandlerPropertyPointer> &propertyList, AbstractView::PropertyChangeFlags propertyChange);
void notifySignalDeclarationPropertiesChanged(const QVector<InternalSignalDeclarationPropertyPointer> &propertyList, AbstractView::PropertyChangeFlags propertyChange);
const QList<QmlDesigner::Internal::InternalBindingProperty *> &internalPropertyList);
void notifyBindingPropertiesChanged(
const QList<QmlDesigner::Internal::InternalBindingProperty *> &internalPropertyList,
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 notifyScriptFunctionsChanged(const InternalNodePointer &node, const QStringList &scriptFunctionList);
void notifyNodeOrderChanged(const InternalNodeListPropertyPointer &internalListProperty,
void notifyNodeOrderChanged(const QmlDesigner::Internal::InternalNodeListProperty *internalListProperty,
const InternalNodePointer &node,
int oldIndex);
void notifyNodeOrderChanged(const InternalNodeListPropertyPointer &internalListProperty);
void notifyNodeOrderChanged(const InternalNodeListProperty *internalListProperty);
void notifyAuxiliaryDataChanged(const InternalNodePointer &node,
AuxiliaryDataKeyView key,
const QVariant &data);
@@ -248,9 +246,9 @@ public:
//node state property manipulation
void addProperty(const InternalNodePointer &node, const PropertyName &name);
void setPropertyValue(const InternalNodePointer &node,const PropertyName &name, const QVariant &value);
void removePropertyAndRelatedResources(const InternalPropertyPointer &property);
void removeProperty(const InternalPropertyPointer &property);
void removeProperties(const QList<InternalPropertyPointer> &properties);
void removePropertyAndRelatedResources(InternalProperty *property);
void removeProperty(InternalProperty *property);
void removeProperties(const QList<InternalProperty *> &properties);
void setBindingProperty(const InternalNodePointer &node,
const PropertyName &name,
@@ -300,16 +298,16 @@ public:
}
private:
void removePropertyWithoutNotification(const InternalPropertyPointer &property);
void removePropertyWithoutNotification(InternalProperty *property);
void removeAllSubNodes(const InternalNodePointer &node);
void removeNodeFromModel(const InternalNodePointer &node);
QList<InternalNodePointer> toInternalNodeList(const QList<ModelNode> &modelNodeList) const;
QList<ModelNode> toModelNodeList(const QList<InternalNodePointer> &nodeList, AbstractView *view) const;
QVector<ModelNode> toModelNodeVector(const QVector<InternalNodePointer> &nodeVector, AbstractView *view) const;
QVector<InternalNodePointer> toInternalNodeVector(const QVector<ModelNode> &modelNodeVector) const;
static QList<InternalPropertyPointer> toInternalProperties(const AbstractProperties &properties);
static QList<std::tuple<InternalBindingPropertyPointer, QString>> toInternalBindingProperties(
const ModelResourceSet::SetExpressions &setExpressions);
static QList<InternalProperty *> toInternalProperties(const AbstractProperties &properties);
static QList<std::tuple<QmlDesigner::Internal::InternalBindingProperty *, QString>>
toInternalBindingProperties(const ModelResourceSet::SetExpressions &setExpressions);
EnabledViewRange enabledViews() const;
ImportedTypeNameId importedTypeNameId(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))
return;
if (m_internalNode->hasProperty(name))
model()->d->removePropertyAndRelatedResources(m_internalNode->property(name));
if (auto property = m_internalNode->property(name))
model()->d->removePropertyAndRelatedResources(property);
}
/*! \brief removes this node from the node tree
@@ -800,7 +800,7 @@ PropertyNameList ModelNode::propertyNames() const
*/
bool ModelNode::hasProperty(const PropertyName &name) const
{
return isValid() && m_internalNode->hasProperty(name);
return isValid() && m_internalNode->property(name);
}
bool ModelNode::hasVariantProperty(const PropertyName &name) const

View File

@@ -18,7 +18,7 @@ namespace QmlDesigner {
NodeAbstractProperty::NodeAbstractProperty() = default;
NodeAbstractProperty::NodeAbstractProperty(const NodeAbstractProperty &property, AbstractView *view)
: AbstractProperty(property.name(), property.internalNode(), property.model(), view)
: AbstractProperty(property.name(), property.internalNodeSharedPointer(), property.model(), view)
{
}
@@ -36,14 +36,9 @@ void NodeAbstractProperty::reparentHere(const ModelNode &modelNode)
if (!isValid() || !modelNode.isValid())
return;
if (internalNode()->hasProperty(name())
&& !internalNode()->property(name())->isNodeAbstractProperty()) {
reparentHere(modelNode, isNodeListProperty());
} else {
reparentHere(modelNode,
parentModelNode().metaInfo().property(name()).isListProperty()
|| isDefaultProperty()); //we could use the metasystem instead?
}
reparentHere(modelNode,
parentModelNode().metaInfo().property(name()).isListProperty()
|| isDefaultProperty()); //we could use the metasystem instead?
}
void NodeAbstractProperty::reparentHere(const ModelNode &modelNode, bool isNodeList, const TypeName &dynamicTypeName)
@@ -70,19 +65,28 @@ void NodeAbstractProperty::reparentHere(const ModelNode &modelNode, bool isNode
if (modelNode.hasParentProperty() && modelNode.parentProperty().isDynamic())
return;
auto internalProperty = internalNode()->property(name());
if (internalProperty && !internalProperty->isNodeAbstractProperty())
if (auto internalProperty = internalNode()->property(name());
internalProperty && !internalProperty->isNodeAbstractProperty()) {
privateModel()->removePropertyAndRelatedResources(internalProperty);
}
if (modelNode.hasParentProperty()) {
Internal::InternalNodeAbstractProperty::Pointer oldParentProperty = modelNode.internalNode()->parentProperty();
privateModel()->reparentNode(internalNode(), name(), modelNode.internalNode(), isNodeList, dynamicTypeName);
privateModel()->reparentNode(internalNodeSharedPointer(),
name(),
modelNode.internalNode(),
isNodeList,
dynamicTypeName);
Q_ASSERT(oldParentProperty);
} else {
privateModel()->reparentNode(internalNode(), name(), modelNode.internalNode(), isNodeList, dynamicTypeName);
privateModel()->reparentNode(internalNodeSharedPointer(),
name(),
modelNode.internalNode(),
isNodeList,
dynamicTypeName);
}
}
@@ -136,22 +140,62 @@ int NodeAbstractProperty::count() const
QList<ModelNode> NodeAbstractProperty::allSubNodes()
{
if (!internalNode() || !internalNode()->isValid || !internalNode()->hasProperty(name())
|| !internalNode()->property(name())->isNodeAbstractProperty())
if (!internalNode() || !internalNode()->isValid)
return {};
Internal::InternalNodeAbstractProperty::Pointer property = internalNode()->nodeAbstractProperty(name());
return QmlDesigner::toModelNodeList(property->allSubNodes(), model(), view());
auto property = internalNode()->property(name());
if (!property)
return {};
switch (property->type()) {
case PropertyType::Node:
return QmlDesigner::toModelNodeList({property->to<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
{
if (!internalNode() || !internalNode()->isValid || !internalNode()->hasProperty(name())
|| !internalNode()->property(name())->isNodeAbstractProperty())
if (!internalNode() || !internalNode()->isValid)
return {};
Internal::InternalNodeAbstractProperty::Pointer property = internalNode()->nodeAbstractProperty(name());
return QmlDesigner::toModelNodeList(property->directSubNodes(), model(), view());
auto property = internalNode()->property(name());
if (!property)
return {};
switch (property->type()) {
case PropertyType::Node:
return QmlDesigner::toModelNodeList({property->to<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(const NodeListProperty &property, AbstractView *view)
: NodeAbstractProperty(property.name(), property.internalNode(), property.model(), view)
{
}
NodeListProperty::NodeListProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view) :
NodeAbstractProperty(propertyName, internalNode, model, view)
NodeListProperty::NodeListProperty(const PropertyName &propertyName,
const Internal::InternalNodePointer &internalNode,
Model *model,
AbstractView *view)
: NodeAbstractProperty(propertyName, internalNode, model, view)
{
}
@@ -44,10 +41,11 @@ Internal::InternalNodeListPropertyPointer &NodeListProperty::internalNodeListPro
if (m_internalNodeListProperty)
return m_internalNodeListProperty;
auto internalProperty = internalNode()->nodeListProperty(name());
if (internalProperty)
m_internalNodeListProperty = internalProperty;
auto property = internalNode()->property(name());
if (property) {
if (auto nodeListProperty = property->toShared<PropertyType::NodeList>())
m_internalNodeListProperty = nodeListProperty;
}
return m_internalNodeListProperty;
}
@@ -94,7 +92,7 @@ void NodeListProperty::slide(int from, int to) const
if (to < 0 || to > count() - 1 || from < 0 || from > count() - 1)
return;
privateModel()->changeNodeOrder(internalNode(), name(), from, to);
privateModel()->changeNodeOrder(internalNodeSharedPointer(), name(), from, to);
}
void NodeListProperty::swap(int from, int to) const
@@ -159,7 +157,7 @@ NodeListProperty::iterator NodeListProperty::rotate(NodeListProperty::iterator f
std::next(begin, newFirst.m_currentIndex),
std::next(begin, last.m_currentIndex));
privateModel()->notifyNodeOrderChanged(m_internalNodeListProperty);
privateModel()->notifyNodeOrderChanged(m_internalNodeListProperty.get());
return {iter - begin, internalNodeListProperty().get(), model(), view()};
}
@@ -176,7 +174,7 @@ void NodeListProperty::reverse(NodeListProperty::iterator first, NodeListPropert
std::reverse(std::next(begin, first.m_currentIndex), std::next(begin, last.m_currentIndex));
privateModel()->notifyNodeOrderChanged(m_internalNodeListProperty);
privateModel()->notifyNodeOrderChanged(m_internalNodeListProperty.get());
}
void NodeListProperty::reverseModelNodes(const QList<ModelNode> &nodes)

View File

@@ -30,10 +30,13 @@ void NodeProperty::setModelNode(const ModelNode &modelNode)
return;
}
if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isNodeProperty())
privateModel()->removePropertyAndRelatedResources(internalNode()->property(name()));
if (auto property = internalNode()->property(name()); !property->isNodeProperty())
privateModel()->removePropertyAndRelatedResources(property);
privateModel()->reparentNode(internalNode(), name(), modelNode.internalNode(), false); //### we have to add a flag that this is not a list
privateModel()->reparentNode(internalNodeSharedPointer(),
name(),
modelNode.internalNode(),
false); //### we have to add a flag that this is not a list
}
ModelNode NodeProperty::modelNode() const

View File

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

View File

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