forked from qt-creator/qt-creator
QmlDesigner: Implement support for SignalDeclarationProperty
This allows implementing a signal with a signature. e.g. signal mySignal(int i) Task-number: QDS-7319 Change-Id: I23cb000a218d709218322e7f31c86076d3ad949b Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Marco Bubke <marco.bubke@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -155,8 +155,14 @@ void AddPropertyVisitor::addInMembers(QmlJS::AST::UiObjectInitializer *initializ
|
||||
Q_ASSERT(!"unknown property type");
|
||||
}
|
||||
|
||||
if (!m_dynamicTypeName.isEmpty())
|
||||
newPropertyTemplate.prepend(QStringLiteral("property %1 ").arg(QString::fromUtf8(m_dynamicTypeName)));
|
||||
if (!m_dynamicTypeName.isEmpty()) {
|
||||
if (m_dynamicTypeName == "signal") {
|
||||
newPropertyTemplate = "signal %1%2";
|
||||
} else {
|
||||
newPropertyTemplate.prepend(
|
||||
QStringLiteral("property %1 ").arg(QString::fromUtf8(m_dynamicTypeName)));
|
||||
}
|
||||
}
|
||||
|
||||
if (isOneLiner) {
|
||||
if (needsPreceedingSemicolon)
|
||||
|
@@ -137,7 +137,14 @@ void ChangePropertyVisitor::replaceMemberValue(UiObjectMember *propertyMember, b
|
||||
startOffset = arrayBinding->lbracketToken.offset;
|
||||
endOffset = arrayBinding->rbracketToken.end();
|
||||
} else if (auto publicMember = AST::cast<UiPublicMember*>(propertyMember)) {
|
||||
if (publicMember->statement) {
|
||||
if (publicMember->type == AST::UiPublicMember::Signal) {
|
||||
startOffset = publicMember->firstSourceLocation().offset;
|
||||
if (publicMember->semicolonToken.isValid())
|
||||
endOffset = publicMember->semicolonToken.end();
|
||||
else
|
||||
endOffset = publicMember->lastSourceLocation().end();
|
||||
replacement.prepend(QStringLiteral("signal %1 ").arg(publicMember->name));
|
||||
} else if (publicMember->statement) {
|
||||
startOffset = publicMember->statement->firstSourceLocation().offset;
|
||||
if (publicMember->semicolonToken.isValid())
|
||||
endOffset = publicMember->semicolonToken.end();
|
||||
|
@@ -51,6 +51,7 @@ class QMLDESIGNERCORE_EXPORT NodeAbstractProperty;
|
||||
class QMLDESIGNERCORE_EXPORT BindingProperty;
|
||||
class QMLDESIGNERCORE_EXPORT NodeProperty;
|
||||
class QMLDESIGNERCORE_EXPORT SignalHandlerProperty;
|
||||
class QMLDESIGNERCORE_EXPORT SignalDeclarationProperty;
|
||||
class QmlObjectNode;
|
||||
|
||||
|
||||
@@ -88,6 +89,7 @@ public:
|
||||
BindingProperty toBindingProperty() const;
|
||||
NodeProperty toNodeProperty() const;
|
||||
SignalHandlerProperty toSignalHandlerProperty() const;
|
||||
SignalDeclarationProperty toSignalDeclarationProperty() const;
|
||||
|
||||
bool isVariantProperty() const;
|
||||
bool isNodeListProperty() const;
|
||||
@@ -95,6 +97,7 @@ public:
|
||||
bool isBindingProperty() const;
|
||||
bool isNodeProperty() const;
|
||||
bool isSignalHandlerProperty() const;
|
||||
bool isSignalDeclarationProperty() const;
|
||||
|
||||
bool isDynamic() const;
|
||||
TypeName dynamicTypeName() const;
|
||||
|
@@ -185,6 +185,7 @@ public:
|
||||
virtual void bindingPropertiesAboutToBeChanged(const QList<BindingProperty> &propertyList);
|
||||
virtual void bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags propertyChange);
|
||||
virtual void signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty>& propertyList, PropertyChangeFlags propertyChange);
|
||||
virtual void signalDeclarationPropertiesChanged(const QVector<SignalDeclarationProperty>& propertyList, PropertyChangeFlags propertyChange);
|
||||
virtual void rootNodeTypeChanged(const QString &type, int majorVersion, int minorVersion);
|
||||
virtual void nodeTypeChanged(const ModelNode& node, const TypeName &type, int majorVersion, int minorVersion);
|
||||
|
||||
|
@@ -51,6 +51,7 @@ class AbstractProperty;
|
||||
class BindingProperty;
|
||||
class VariantProperty;
|
||||
class SignalHandlerProperty;
|
||||
class SignalDeclarationProperty;
|
||||
class Model;
|
||||
class AbstractView;
|
||||
class NodeListProperty;
|
||||
@@ -128,6 +129,7 @@ public:
|
||||
VariantProperty variantProperty(const PropertyName &name) const;
|
||||
BindingProperty bindingProperty(const PropertyName &name) const;
|
||||
SignalHandlerProperty signalHandlerProperty(const PropertyName &name) const;
|
||||
SignalDeclarationProperty signalDeclarationProperty(const PropertyName &name) const;
|
||||
NodeListProperty nodeListProperty(const PropertyName &name) const;
|
||||
NodeProperty nodeProperty(const PropertyName &name) const;
|
||||
NodeAbstractProperty nodeAbstractProperty(const PropertyName &name) const;
|
||||
|
@@ -87,6 +87,7 @@ public:
|
||||
void variantPropertiesChanged(const QList<VariantProperty>& propertyList, PropertyChangeFlags propertyChange) override;
|
||||
void bindingPropertiesChanged(const QList<BindingProperty>& propertyList, PropertyChangeFlags propertyChange) override;
|
||||
void signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty>& propertyList,PropertyChangeFlags propertyChange) override;
|
||||
void signalDeclarationPropertiesChanged(const QVector<SignalDeclarationProperty>& propertyList, PropertyChangeFlags propertyChange) override;
|
||||
void nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent,
|
||||
const NodeAbstractProperty &oldPropertyParent,
|
||||
AbstractView::PropertyChangeFlags propertyChange) override;
|
||||
|
@@ -30,7 +30,7 @@
|
||||
|
||||
namespace QmlDesigner {
|
||||
|
||||
class QMLDESIGNERCORE_EXPORT SignalHandlerProperty : public QmlDesigner::AbstractProperty
|
||||
class QMLDESIGNERCORE_EXPORT SignalHandlerProperty : public AbstractProperty
|
||||
{
|
||||
friend ModelNode;
|
||||
friend Internal::ModelPrivate;
|
||||
@@ -50,4 +50,21 @@ protected:
|
||||
SignalHandlerProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view);
|
||||
};
|
||||
|
||||
class QMLDESIGNERCORE_EXPORT SignalDeclarationProperty : public AbstractProperty
|
||||
{
|
||||
friend ModelNode;
|
||||
friend Internal::ModelPrivate;
|
||||
friend AbstractProperty;
|
||||
|
||||
public:
|
||||
void setSignature(const QString &source);
|
||||
QString signature() const;
|
||||
|
||||
SignalDeclarationProperty();
|
||||
SignalDeclarationProperty(const SignalDeclarationProperty &property, AbstractView *view);
|
||||
|
||||
protected:
|
||||
SignalDeclarationProperty(const PropertyName &propertyName, const Internal::InternalNodePointer &internalNode, Model* model, AbstractView *view);
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -203,6 +203,19 @@ SignalHandlerProperty AbstractProperty::toSignalHandlerProperty() const
|
||||
return SignalHandlerProperty();
|
||||
}
|
||||
|
||||
SignalDeclarationProperty AbstractProperty::toSignalDeclarationProperty() const
|
||||
{
|
||||
if (!isValid())
|
||||
throw InvalidPropertyException(__LINE__, __FUNCTION__, __FILE__, m_propertyName);
|
||||
|
||||
SignalDeclarationProperty propertyNode(name(), internalNode(), model(), view());
|
||||
|
||||
if (propertyNode.isSignalDeclarationProperty())
|
||||
return propertyNode;
|
||||
|
||||
return SignalDeclarationProperty();
|
||||
}
|
||||
|
||||
NodeListProperty AbstractProperty::toNodeListProperty() const
|
||||
{
|
||||
if (!isValid())
|
||||
@@ -307,6 +320,18 @@ bool AbstractProperty::isSignalHandlerProperty() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractProperty::isSignalDeclarationProperty() const
|
||||
{
|
||||
if (!isValid())
|
||||
throw InvalidPropertyException(__LINE__, __FUNCTION__, __FILE__, m_propertyName);
|
||||
|
||||
if (internalNode()->hasProperty(name())) {
|
||||
Q_ASSERT(internalNode()->property(name()));
|
||||
return internalNode()->property(name())->isSignalDeclarationProperty();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AbstractProperty::isBindingProperty() const
|
||||
{
|
||||
|
@@ -351,6 +351,10 @@ void AbstractView::signalHandlerPropertiesChanged(const QVector<SignalHandlerPro
|
||||
{
|
||||
}
|
||||
|
||||
void AbstractView::signalDeclarationPropertiesChanged(const QVector<SignalDeclarationProperty>& /*propertyList*/, PropertyChangeFlags /*propertyChange*/)
|
||||
{
|
||||
}
|
||||
|
||||
void AbstractView::rootNodeTypeChanged(const QString &/*type*/, int /*majorVersion*/, int /*minorVersion*/)
|
||||
{
|
||||
}
|
||||
|
@@ -215,6 +215,15 @@ InternalSignalHandlerProperty::Pointer InternalNode::signalHandlerProperty(const
|
||||
return InternalSignalHandlerProperty::Pointer();
|
||||
}
|
||||
|
||||
InternalSignalDeclarationProperty::Pointer InternalNode::signalDeclarationProperty(const PropertyName &name) const
|
||||
{
|
||||
InternalProperty::Pointer property = m_namePropertyHash.value(name);
|
||||
if (property->isSignalDeclarationProperty())
|
||||
return property.staticCast<InternalSignalDeclarationProperty>();
|
||||
|
||||
return InternalSignalDeclarationProperty::Pointer();
|
||||
}
|
||||
|
||||
InternalVariantProperty::Pointer InternalNode::variantProperty(const PropertyName &name) const
|
||||
{
|
||||
InternalProperty::Pointer property = m_namePropertyHash.value(name);
|
||||
@@ -236,6 +245,12 @@ void InternalNode::addSignalHandlerProperty(const PropertyName &name)
|
||||
m_namePropertyHash.insert(name, newProperty);
|
||||
}
|
||||
|
||||
void InternalNode::addSignalDeclarationProperty(const PropertyName &name)
|
||||
{
|
||||
InternalProperty::Pointer newProperty(InternalSignalDeclarationProperty::create(name, internalPointer()));
|
||||
m_namePropertyHash.insert(name, newProperty);
|
||||
}
|
||||
|
||||
InternalNodeListProperty::Pointer InternalNode::nodeListProperty(const PropertyName &name) const
|
||||
{
|
||||
InternalProperty::Pointer property = m_namePropertyHash.value(name);
|
||||
|
@@ -92,6 +92,7 @@ public:
|
||||
InternalProperty::Pointer property(const PropertyName &name) const;
|
||||
InternalBindingProperty::Pointer bindingProperty(const PropertyName &name) const;
|
||||
InternalSignalHandlerProperty::Pointer signalHandlerProperty(const PropertyName &name) const;
|
||||
InternalSignalDeclarationProperty::Pointer signalDeclarationProperty(const PropertyName &name) const;
|
||||
InternalVariantProperty::Pointer variantProperty(const PropertyName &name) const;
|
||||
InternalNodeListProperty::Pointer nodeListProperty(const PropertyName &name) const;
|
||||
InternalNodeAbstractProperty::Pointer nodeAbstractProperty(const PropertyName &name) const;
|
||||
@@ -99,11 +100,11 @@ public:
|
||||
|
||||
void addBindingProperty(const PropertyName &name);
|
||||
void addSignalHandlerProperty(const PropertyName &name);
|
||||
void addSignalDeclarationProperty(const PropertyName &name);
|
||||
void addNodeListProperty(const PropertyName &name);
|
||||
void addVariantProperty(const PropertyName &name);
|
||||
void addNodeProperty(const PropertyName &name, const TypeName &dynamicTypeName);
|
||||
|
||||
|
||||
PropertyNameList propertyNameList() const;
|
||||
|
||||
bool hasProperties() const;
|
||||
|
@@ -107,6 +107,11 @@ bool InternalProperty::isSignalHandlerProperty() const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool InternalProperty::isSignalDeclarationProperty() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QSharedPointer<InternalVariantProperty> InternalProperty::toVariantProperty() const
|
||||
|
||||
{
|
||||
@@ -143,6 +148,12 @@ QSharedPointer<InternalSignalHandlerProperty> InternalProperty::toSignalHandlerP
|
||||
return internalPointer().staticCast<InternalSignalHandlerProperty>();
|
||||
}
|
||||
|
||||
QSharedPointer<InternalSignalDeclarationProperty> InternalProperty::toSignalDeclarationProperty() const
|
||||
{
|
||||
Q_ASSERT(internalPointer().dynamicCast<InternalSignalDeclarationProperty>());
|
||||
return internalPointer().staticCast<InternalSignalDeclarationProperty>();
|
||||
}
|
||||
|
||||
void InternalProperty::remove()
|
||||
{
|
||||
propertyOwner()->removeProperty(name());
|
||||
|
@@ -36,6 +36,7 @@ namespace Internal {
|
||||
|
||||
class InternalBindingProperty;
|
||||
class InternalSignalHandlerProperty;
|
||||
class InternalSignalDeclarationProperty;
|
||||
class InternalVariantProperty;
|
||||
class InternalNodeListProperty;
|
||||
class InternalNodeProperty;
|
||||
@@ -62,6 +63,7 @@ public:
|
||||
virtual bool isNodeProperty() const;
|
||||
virtual bool isNodeAbstractProperty() const;
|
||||
virtual bool isSignalHandlerProperty() const;
|
||||
virtual bool isSignalDeclarationProperty() const;
|
||||
|
||||
QSharedPointer<InternalBindingProperty> toBindingProperty() const;
|
||||
QSharedPointer<InternalVariantProperty> toVariantProperty() const;
|
||||
@@ -69,6 +71,7 @@ public:
|
||||
QSharedPointer<InternalNodeProperty> toNodeProperty() const;
|
||||
QSharedPointer<InternalNodeAbstractProperty> toNodeAbstractProperty() const;
|
||||
QSharedPointer<InternalSignalHandlerProperty> toSignalHandlerProperty() const;
|
||||
QSharedPointer<InternalSignalDeclarationProperty> toSignalDeclarationProperty() const;
|
||||
|
||||
InternalNodePointer propertyOwner() const;
|
||||
|
||||
|
@@ -63,5 +63,42 @@ bool InternalSignalHandlerProperty::isSignalHandlerProperty() const
|
||||
return true;
|
||||
}
|
||||
|
||||
InternalSignalDeclarationProperty::Pointer InternalSignalDeclarationProperty::create(const PropertyName &name, const InternalNodePointer &propertyOwner)
|
||||
{
|
||||
auto newPointer(new InternalSignalDeclarationProperty(name, propertyOwner));
|
||||
InternalSignalDeclarationProperty::Pointer smartPointer(newPointer);
|
||||
|
||||
newPointer->setInternalWeakPointer(smartPointer);
|
||||
|
||||
newPointer->setDynamicTypeName("signal");
|
||||
|
||||
return smartPointer;
|
||||
}
|
||||
|
||||
bool InternalSignalDeclarationProperty::isValid() const
|
||||
{
|
||||
return InternalProperty::isValid() && isSignalDeclarationProperty();
|
||||
}
|
||||
|
||||
QString InternalSignalDeclarationProperty::signature() const
|
||||
{
|
||||
return m_signature;
|
||||
}
|
||||
|
||||
void InternalSignalDeclarationProperty::setSignature(const QString &signature)
|
||||
{
|
||||
m_signature = signature;
|
||||
}
|
||||
|
||||
bool InternalSignalDeclarationProperty::isSignalDeclarationProperty() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
InternalSignalDeclarationProperty::InternalSignalDeclarationProperty(const PropertyName &name, const InternalNodePointer &propertyOwner)
|
||||
: InternalProperty(name, propertyOwner)
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -51,5 +51,26 @@ private:
|
||||
QString m_source;
|
||||
};
|
||||
|
||||
class InternalSignalDeclarationProperty : public InternalProperty
|
||||
{
|
||||
public:
|
||||
using Pointer = QSharedPointer<InternalSignalDeclarationProperty>;
|
||||
|
||||
static Pointer create(const PropertyName &name, const InternalNodePointer &propertyOwner);
|
||||
|
||||
bool isValid() const override;
|
||||
|
||||
QString signature() const;
|
||||
void setSignature(const QString &source);
|
||||
|
||||
bool isSignalDeclarationProperty() const override;
|
||||
|
||||
protected:
|
||||
InternalSignalDeclarationProperty(const PropertyName &name, const InternalNodePointer &propertyOwner);
|
||||
|
||||
private:
|
||||
QString m_signature;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -843,6 +843,22 @@ void ModelPrivate::notifySignalHandlerPropertiesChanged(
|
||||
});
|
||||
}
|
||||
|
||||
void ModelPrivate::notifySignalDeclarationPropertiesChanged(
|
||||
const QVector<InternalSignalDeclarationPropertyPointer> &internalPropertyList,
|
||||
AbstractView::PropertyChangeFlags propertyChange)
|
||||
{
|
||||
notifyNodeInstanceViewLast([&](AbstractView *view) {
|
||||
QVector<SignalDeclarationProperty> propertyList;
|
||||
for (const InternalSignalDeclarationPropertyPointer &signalHandlerProperty : internalPropertyList) {
|
||||
propertyList.append(SignalDeclarationProperty(signalHandlerProperty->name(),
|
||||
signalHandlerProperty->propertyOwner(),
|
||||
m_model,
|
||||
view));
|
||||
}
|
||||
view->signalDeclarationPropertiesChanged(propertyList, propertyChange);
|
||||
});
|
||||
}
|
||||
|
||||
void ModelPrivate::notifyScriptFunctionsChanged(const InternalNodePointer &node,
|
||||
const QStringList &scriptFunctionList)
|
||||
{
|
||||
@@ -1100,6 +1116,19 @@ void ModelPrivate::setSignalHandlerProperty(const InternalNodePointer &node, con
|
||||
notifySignalHandlerPropertiesChanged({signalHandlerProperty}, propertyChange);
|
||||
}
|
||||
|
||||
void ModelPrivate::setSignalDeclarationProperty(const InternalNodePointer &node, const PropertyName &name, const QString &signature)
|
||||
{
|
||||
AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
|
||||
if (!node->hasProperty(name)) {
|
||||
node->addSignalDeclarationProperty(name);
|
||||
propertyChange = AbstractView::PropertiesAdded;
|
||||
}
|
||||
|
||||
InternalSignalDeclarationPropertyPointer signalDeclarationProperty = node->signalDeclarationProperty(name);
|
||||
signalDeclarationProperty->setSignature(signature);
|
||||
notifySignalDeclarationPropertiesChanged({signalDeclarationProperty}, propertyChange);
|
||||
}
|
||||
|
||||
void ModelPrivate::setVariantProperty(const InternalNodePointer &node, const PropertyName &name, const QVariant &value)
|
||||
{
|
||||
AbstractView::PropertyChangeFlags propertyChange = AbstractView::NoAdditionalChanges;
|
||||
|
@@ -53,6 +53,7 @@ class InternalNode;
|
||||
class InternalProperty;
|
||||
class InternalBindingProperty;
|
||||
class InternalSignalHandlerProperty;
|
||||
class InternalSignalDeclarationProperty;
|
||||
class InternalVariantProperty;
|
||||
class InternalNodeAbstractProperty;
|
||||
class InternalNodeListProperty;
|
||||
@@ -61,6 +62,7 @@ using InternalNodePointer = QSharedPointer<InternalNode>;
|
||||
using InternalPropertyPointer = QSharedPointer<InternalProperty>;
|
||||
using InternalBindingPropertyPointer = QSharedPointer<InternalBindingProperty>;
|
||||
using InternalSignalHandlerPropertyPointer = QSharedPointer<InternalSignalHandlerProperty>;
|
||||
using InternalSignalDeclarationPropertyPointer = QSharedPointer<InternalSignalDeclarationProperty>;
|
||||
using InternalVariantPropertyPointer = QSharedPointer<InternalVariantProperty>;
|
||||
using InternalNodeAbstractPropertyPointer = QSharedPointer<InternalNodeAbstractProperty>;
|
||||
using InternalNodeListPropertyPointer = QSharedPointer<InternalNodeListProperty>;
|
||||
@@ -154,6 +156,7 @@ public:
|
||||
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);
|
||||
void notifyVariantPropertiesChanged(const InternalNodePointer &node, const PropertyNameList &propertyNameList, AbstractView::PropertyChangeFlags propertyChange);
|
||||
void notifyScriptFunctionsChanged(const InternalNodePointer &node, const QStringList &scriptFunctionList);
|
||||
|
||||
@@ -221,6 +224,7 @@ public:
|
||||
|
||||
void setBindingProperty(const InternalNodePointer &node, const PropertyName &name, const QString &expression);
|
||||
void setSignalHandlerProperty(const InternalNodePointer &node, const PropertyName &name, const QString &source);
|
||||
void setSignalDeclarationProperty(const InternalNodePointer &node, const PropertyName &name, const QString &signature);
|
||||
void setVariantProperty(const InternalNodePointer &node, const PropertyName &name, const QVariant &value);
|
||||
void setDynamicVariantProperty(const InternalNodePointer &node, const PropertyName &name, const TypeName &propertyType, const QVariant &value);
|
||||
void setDynamicBindingProperty(const InternalNodePointer &node, const PropertyName &name, const TypeName &dynamicPropertyType, const QString &expression);
|
||||
|
@@ -487,6 +487,13 @@ SignalHandlerProperty ModelNode::signalHandlerProperty(const PropertyName &name)
|
||||
return SignalHandlerProperty(name, m_internalNode, model(), view());
|
||||
}
|
||||
|
||||
SignalDeclarationProperty ModelNode::signalDeclarationProperty(const PropertyName &name) const
|
||||
{
|
||||
if (!isValid())
|
||||
throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
return SignalDeclarationProperty(name, m_internalNode, model(), view());
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Returns a NodeProperty
|
||||
|
@@ -356,6 +356,8 @@ QmlRefactoring::PropertyType ModelToTextMerger::propertyType(const AbstractPrope
|
||||
return QmlRefactoring::ObjectBinding;
|
||||
else if (property.isVariantProperty())
|
||||
return QmlRefactoring::ScriptBinding;
|
||||
else if (property.isSignalDeclarationProperty())
|
||||
return QmlRefactoring::ScriptBinding;
|
||||
|
||||
Q_ASSERT(false); //Cannot convert property type
|
||||
return QmlRefactoring::Invalid;
|
||||
|
@@ -101,6 +101,8 @@ QString QmlTextGenerator::toQml(const AbstractProperty &property, int indentDept
|
||||
return property.toBindingProperty().expression();
|
||||
} else if (property.isSignalHandlerProperty()) {
|
||||
return property.toSignalHandlerProperty().source();
|
||||
} else if (property.isSignalDeclarationProperty()) {
|
||||
return property.toSignalDeclarationProperty().signature();
|
||||
} else if (property.isNodeProperty()) {
|
||||
return toQml(property.toNodeProperty().modelNode(), indentDepth);
|
||||
} else if (property.isNodeListProperty()) {
|
||||
@@ -288,6 +290,10 @@ QString QmlTextGenerator::propertyToQml(const AbstractProperty &property, int in
|
||||
+ QString::fromUtf8(property.name())
|
||||
+ QStringLiteral(": ")
|
||||
+ toQml(property, indentDepth);
|
||||
}
|
||||
if (property.isSignalDeclarationProperty()) {
|
||||
result = m_tabSettings.indentationString(0, indentDepth, 0) + "signal" + " "
|
||||
+ QString::fromUtf8(property.name()) + " " + toQml(property, indentDepth);
|
||||
} else {
|
||||
result = m_tabSettings.indentationString(0, indentDepth, 0)
|
||||
+ QString::fromUtf8(property.name())
|
||||
|
@@ -261,6 +261,22 @@ void RewriterView::signalHandlerPropertiesChanged(const QVector<SignalHandlerPro
|
||||
applyChanges();
|
||||
}
|
||||
|
||||
void RewriterView::signalDeclarationPropertiesChanged(const QVector<SignalDeclarationProperty> &propertyList, PropertyChangeFlags propertyChange)
|
||||
{
|
||||
Q_ASSERT(textModifier());
|
||||
if (textToModelMerger()->isActive())
|
||||
return;
|
||||
|
||||
QList<AbstractProperty> usefulPropertyList;
|
||||
for (const SignalDeclarationProperty &property : propertyList)
|
||||
usefulPropertyList.append(property);
|
||||
|
||||
modelToTextMerger()->propertiesChanged(usefulPropertyList, propertyChange);
|
||||
|
||||
if (!isModificationGroupActive())
|
||||
applyChanges();
|
||||
}
|
||||
|
||||
void RewriterView::nodeReparented(const ModelNode &node, const NodeAbstractProperty &newPropertyParent, const NodeAbstractProperty &oldPropertyParent, AbstractView::PropertyChangeFlags propertyChange)
|
||||
{
|
||||
Q_ASSERT(textModifier());
|
||||
|
@@ -107,4 +107,57 @@ PropertyName SignalHandlerProperty::prefixRemoved(const PropertyName &propertyNa
|
||||
return nameAsString.toLatin1();
|
||||
}
|
||||
|
||||
SignalDeclarationProperty::SignalDeclarationProperty() = default;
|
||||
|
||||
SignalDeclarationProperty::SignalDeclarationProperty(const SignalDeclarationProperty &property,
|
||||
AbstractView *view)
|
||||
: AbstractProperty(property.name(), property.internalNode(), property.model(), view)
|
||||
{}
|
||||
|
||||
SignalDeclarationProperty::SignalDeclarationProperty(
|
||||
const PropertyName &propertyName,
|
||||
const Internal::InternalNodePointer &internalNode,
|
||||
Model *model,
|
||||
AbstractView *view)
|
||||
: AbstractProperty(propertyName, internalNode, model, view)
|
||||
{
|
||||
}
|
||||
|
||||
void SignalDeclarationProperty::setSignature(const QString &signature)
|
||||
{
|
||||
Internal::WriteLocker locker(model());
|
||||
if (!isValid())
|
||||
throw InvalidModelNodeException(__LINE__, __FUNCTION__, __FILE__);
|
||||
|
||||
if (name() == "id") { // the ID for a node is independent of the state, so it has to be set with ModelNode::setId
|
||||
throw InvalidPropertyException(__LINE__, __FUNCTION__, __FILE__, name());
|
||||
}
|
||||
|
||||
if (signature.isEmpty())
|
||||
throw InvalidArgumentException(__LINE__, __FUNCTION__, __FILE__, name());
|
||||
|
||||
if (internalNode()->hasProperty(name())) { //check if oldValue != value
|
||||
Internal::InternalProperty::Pointer internalProperty = internalNode()->property(name());
|
||||
if (internalProperty->isSignalDeclarationProperty()
|
||||
&& internalProperty->toSignalDeclarationProperty()->signature() == signature)
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (internalNode()->hasProperty(name()) && !internalNode()->property(name())->isSignalDeclarationProperty())
|
||||
privateModel()->removeProperty(internalNode()->property(name()));
|
||||
|
||||
privateModel()->setSignalDeclarationProperty(internalNode(), name(), signature);
|
||||
}
|
||||
|
||||
QString SignalDeclarationProperty::signature() const
|
||||
{
|
||||
|
||||
if (internalNode()->hasProperty(name())
|
||||
&& internalNode()->property(name())->isSignalDeclarationProperty())
|
||||
return internalNode()->signalDeclarationProperty(name())->signature();
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -1357,8 +1357,21 @@ void TextToModelMerger::syncNode(ModelNode &modelNode,
|
||||
} else if (auto script = AST::cast<AST::UiScriptBinding *>(member)) {
|
||||
modelPropertyNames.remove(syncScriptBinding(modelNode, QString(), script, context, differenceHandler));
|
||||
} else if (auto property = AST::cast<AST::UiPublicMember *>(member)) {
|
||||
if (property->type == AST::UiPublicMember::Signal)
|
||||
continue; // QML designer doesn't support this yet.
|
||||
if (property->type == AST::UiPublicMember::Signal) {
|
||||
const QStringView astName = property->name;
|
||||
AbstractProperty modelProperty = modelNode.property(astName.toUtf8());
|
||||
QString signature = "()";
|
||||
if (property->parameters) {
|
||||
signature = "("
|
||||
+ textAt(context->doc(),
|
||||
property->parameters->firstSourceLocation(),
|
||||
property->parameters->lastSourceLocation())
|
||||
+ ")";
|
||||
}
|
||||
|
||||
syncSignalDeclarationProperty(modelProperty, signature, differenceHandler);
|
||||
continue; // Done
|
||||
}
|
||||
|
||||
const QStringView astName = property->name;
|
||||
QString astValue;
|
||||
@@ -1693,6 +1706,19 @@ void TextToModelMerger::syncVariantProperty(AbstractProperty &modelProperty,
|
||||
}
|
||||
}
|
||||
|
||||
void TextToModelMerger::syncSignalDeclarationProperty(AbstractProperty &modelProperty,
|
||||
const QString &signature,
|
||||
DifferenceHandler &differenceHandler)
|
||||
{
|
||||
if (modelProperty.isSignalHandlerProperty()) {
|
||||
SignalDeclarationProperty signalHandlerProperty = modelProperty.toSignalDeclarationProperty();
|
||||
if (signalHandlerProperty.signature() != signature)
|
||||
differenceHandler.signalDeclarationSignatureDiffer(signalHandlerProperty, signature);
|
||||
} else {
|
||||
differenceHandler.shouldBeSignalDeclarationProperty(modelProperty, signature);
|
||||
}
|
||||
}
|
||||
|
||||
void TextToModelMerger::syncNodeListProperty(NodeListProperty &modelListProperty,
|
||||
const QList<AST::UiObjectMember *> arrayMembers,
|
||||
ReadingContext *context,
|
||||
@@ -1834,6 +1860,13 @@ void ModelValidator::signalHandlerSourceDiffer(SignalHandlerProperty &modelPrope
|
||||
QTC_ASSERT(compareJavaScriptExpression(modelProperty.source(), javascript), return);
|
||||
}
|
||||
|
||||
void ModelValidator::signalDeclarationSignatureDiffer(SignalDeclarationProperty &modelProperty, const QString &signature)
|
||||
{
|
||||
Q_UNUSED(modelProperty)
|
||||
Q_UNUSED(signature)
|
||||
QTC_ASSERT(compareJavaScriptExpression(modelProperty.signature(), signature), return);
|
||||
}
|
||||
|
||||
void ModelValidator::shouldBeSignalHandlerProperty(AbstractProperty &modelProperty, const QString & /*javascript*/)
|
||||
{
|
||||
Q_UNUSED(modelProperty)
|
||||
@@ -1841,6 +1874,13 @@ void ModelValidator::shouldBeSignalHandlerProperty(AbstractProperty &modelProper
|
||||
Q_ASSERT(0);
|
||||
}
|
||||
|
||||
void ModelValidator::shouldBeSignalDeclarationProperty(AbstractProperty &modelProperty, const QString & /*javascript*/)
|
||||
{
|
||||
Q_UNUSED(modelProperty)
|
||||
Q_ASSERT(modelProperty.isSignalDeclarationProperty());
|
||||
Q_ASSERT(0);
|
||||
}
|
||||
|
||||
void ModelValidator::shouldBeNodeListProperty(AbstractProperty &modelProperty,
|
||||
const QList<AST::UiObjectMember *> /*arrayMembers*/,
|
||||
ReadingContext * /*context*/)
|
||||
@@ -1989,6 +2029,11 @@ void ModelAmender::signalHandlerSourceDiffer(SignalHandlerProperty &modelPropert
|
||||
modelProperty.setSource(javascript);
|
||||
}
|
||||
|
||||
void ModelAmender::signalDeclarationSignatureDiffer(SignalDeclarationProperty &modelProperty, const QString &signature)
|
||||
{
|
||||
modelProperty.setSignature(signature);
|
||||
}
|
||||
|
||||
void ModelAmender::shouldBeSignalHandlerProperty(AbstractProperty &modelProperty, const QString &javascript)
|
||||
{
|
||||
ModelNode theNode = modelProperty.parentModelNode();
|
||||
@@ -1996,6 +2041,13 @@ void ModelAmender::shouldBeSignalHandlerProperty(AbstractProperty &modelProperty
|
||||
newModelProperty.setSource(javascript);
|
||||
}
|
||||
|
||||
void ModelAmender::shouldBeSignalDeclarationProperty(AbstractProperty &modelProperty, const QString &signature)
|
||||
{
|
||||
ModelNode theNode = modelProperty.parentModelNode();
|
||||
SignalDeclarationProperty newModelProperty = theNode.signalDeclarationProperty(modelProperty.name());
|
||||
newModelProperty.setSignature(signature);
|
||||
}
|
||||
|
||||
void ModelAmender::shouldBeNodeListProperty(AbstractProperty &modelProperty,
|
||||
const QList<AST::UiObjectMember *> arrayMembers,
|
||||
ReadingContext *context)
|
||||
|
@@ -107,6 +107,9 @@ public:
|
||||
const QList<QmlJS::AST::UiObjectMember *> &arrayMembers,
|
||||
ReadingContext *context,
|
||||
DifferenceHandler &differenceHandler);
|
||||
void syncSignalDeclarationProperty(AbstractProperty &modelProperty,
|
||||
const QString &signature,
|
||||
DifferenceHandler &differenceHandler);
|
||||
void syncVariantProperty(AbstractProperty &modelProperty,
|
||||
const QVariant &astValue,
|
||||
const TypeName &astType,
|
||||
@@ -187,11 +190,15 @@ public:
|
||||
const TypeName &astType) = 0;
|
||||
virtual void signalHandlerSourceDiffer(SignalHandlerProperty &modelProperty,
|
||||
const QString &javascript) = 0;
|
||||
virtual void signalDeclarationSignatureDiffer(SignalDeclarationProperty &modelProperty,
|
||||
const QString &signature) = 0;
|
||||
virtual void shouldBeBindingProperty(AbstractProperty &modelProperty,
|
||||
const QString &javascript,
|
||||
const TypeName &astType) = 0;
|
||||
virtual void shouldBeSignalHandlerProperty(AbstractProperty &modelProperty,
|
||||
const QString &javascript) = 0;
|
||||
virtual void shouldBeSignalDeclarationProperty(AbstractProperty &modelProperty,
|
||||
const QString &signature) = 0;
|
||||
virtual void shouldBeNodeListProperty(AbstractProperty &modelProperty,
|
||||
const QList<QmlJS::AST::UiObjectMember *> arrayMembers,
|
||||
ReadingContext *context) = 0;
|
||||
@@ -241,6 +248,10 @@ public:
|
||||
const TypeName &astType) override;
|
||||
void signalHandlerSourceDiffer(SignalHandlerProperty &modelProperty,
|
||||
const QString &javascript) override;
|
||||
void signalDeclarationSignatureDiffer(SignalDeclarationProperty &modelProperty,
|
||||
const QString &signature) override;
|
||||
void shouldBeSignalDeclarationProperty(AbstractProperty &modelProperty,
|
||||
const QString &signature) override;
|
||||
void shouldBeSignalHandlerProperty(AbstractProperty &modelProperty,
|
||||
const QString &javascript) override;
|
||||
void shouldBeNodeListProperty(AbstractProperty &modelProperty,
|
||||
@@ -290,6 +301,10 @@ public:
|
||||
const TypeName &astType) override;
|
||||
void signalHandlerSourceDiffer(SignalHandlerProperty &modelProperty,
|
||||
const QString &javascript) override;
|
||||
void signalDeclarationSignatureDiffer(SignalDeclarationProperty &modelProperty,
|
||||
const QString &signature) override;
|
||||
void shouldBeSignalDeclarationProperty(AbstractProperty &modelProperty,
|
||||
const QString &signature) override;
|
||||
void shouldBeSignalHandlerProperty(AbstractProperty &modelProperty,
|
||||
const QString &javascript) override;
|
||||
void shouldBeNodeListProperty(AbstractProperty &modelProperty,
|
||||
|
@@ -170,7 +170,8 @@ tst_TestCore::tst_TestCore()
|
||||
: QObject()
|
||||
{
|
||||
QLoggingCategory::setFilterRules(QStringLiteral("qtc.qmljs.imports=false"));
|
||||
QLoggingCategory::setFilterRules(QStringLiteral("*.info=false\n*.debug=false\n*.warning=false"));
|
||||
//QLoggingCategory::setFilterRules(QStringLiteral("*.info=false\n*.debug=false\n*.warning=false"));
|
||||
QLoggingCategory::setFilterRules(QStringLiteral("*.warning=false"));
|
||||
}
|
||||
|
||||
void tst_TestCore::initTestCase()
|
||||
@@ -1273,6 +1274,7 @@ void tst_TestCore::testRewriterBehaivours()
|
||||
testRewriterView->setTextModifier(&modifier);
|
||||
model->attachView(testRewriterView.data());
|
||||
|
||||
//qDebug() << testRewriterView->errors().first().toString();
|
||||
QVERIFY(testRewriterView->errors().isEmpty());
|
||||
|
||||
ModelNode rootModelNode = testRewriterView->rootModelNode();
|
||||
@@ -1345,6 +1347,119 @@ void tst_TestCore::testRewriterBehaivours()
|
||||
QVERIFY(!newBehavior.isValid());
|
||||
}
|
||||
|
||||
void tst_TestCore::testRewriterSignalDefinition()
|
||||
{
|
||||
const QLatin1String qmlString("\n"
|
||||
"import QtQuick 2.1\n"
|
||||
"\n"
|
||||
"Rectangle {\n"
|
||||
" id: root\n"
|
||||
" x: 10;\n"
|
||||
" y: 10;\n"
|
||||
" signal testSignal()\n"
|
||||
" signal testSignal2(float i)\n"
|
||||
" Rectangle {\n"
|
||||
" id: rectangle1\n"
|
||||
" x: 10;\n"
|
||||
" y: 10;\n"
|
||||
" signal testSignal\n"
|
||||
" }\n"
|
||||
"}");
|
||||
|
||||
|
||||
QPlainTextEdit textEdit;
|
||||
textEdit.setPlainText(qmlString);
|
||||
NotIndentingTextEditModifier modifier(&textEdit);
|
||||
|
||||
QScopedPointer<Model> model(Model::create("QtQuick.Text"));
|
||||
|
||||
QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView());
|
||||
testRewriterView->setTextModifier(&modifier);
|
||||
model->attachView(testRewriterView.data());
|
||||
|
||||
QVERIFY(testRewriterView->errors().isEmpty());
|
||||
|
||||
ModelNode rootModelNode = testRewriterView->rootModelNode();
|
||||
QVERIFY(rootModelNode.isValid());
|
||||
|
||||
QVERIFY(rootModelNode.hasProperty("testSignal"));
|
||||
QVERIFY(rootModelNode.hasProperty("testSignal2"));
|
||||
|
||||
QVERIFY(rootModelNode.property("testSignal").isSignalDeclarationProperty());
|
||||
QVERIFY(rootModelNode.signalDeclarationProperty("testSignal").isValid());
|
||||
QCOMPARE(rootModelNode.signalDeclarationProperty("testSignal").signature(), "()");
|
||||
|
||||
QVERIFY(rootModelNode.property("testSignal2").isSignalDeclarationProperty());
|
||||
QVERIFY(rootModelNode.signalDeclarationProperty("testSignal2").isValid());
|
||||
QCOMPARE(rootModelNode.signalDeclarationProperty("testSignal2").signature(), "(float i)");
|
||||
|
||||
ModelNode rectangle = testRewriterView->modelNodeForId("rectangle1");
|
||||
QVERIFY(rectangle.isValid());
|
||||
|
||||
QVERIFY(rectangle.hasProperty("testSignal"));
|
||||
|
||||
QVERIFY(rectangle.property("testSignal").isSignalDeclarationProperty());
|
||||
QVERIFY(rectangle.signalDeclarationProperty("testSignal").isValid());
|
||||
QCOMPARE(rectangle.signalDeclarationProperty("testSignal").signature(), "()");
|
||||
|
||||
rootModelNode.signalDeclarationProperty("addedSignal").setSignature("()");
|
||||
rootModelNode.signalDeclarationProperty("addedSignal").setSignature("(real i)");
|
||||
|
||||
const QLatin1String expectedQmlCode(
|
||||
"\nimport QtQuick 2.1\n\n"
|
||||
"Rectangle {\n"
|
||||
" id: root\n"
|
||||
" x: 10;\n"
|
||||
" y: 10;\n"
|
||||
" signal addedSignal (real i)\n"
|
||||
" signal testSignal()\n"
|
||||
" signal testSignal2(float i)\n"
|
||||
" Rectangle {\n"
|
||||
" id: rectangle1\n"
|
||||
" x: 10;\n"
|
||||
" y: 10;\n"
|
||||
" signal testSignal\n"
|
||||
" }\n}");
|
||||
|
||||
QCOMPARE(textEdit.toPlainText(), expectedQmlCode);
|
||||
|
||||
rootModelNode.removeProperty("addedSignal");
|
||||
|
||||
const QLatin1String expectedQmlCode2(
|
||||
"\nimport QtQuick 2.1\n\n"
|
||||
"Rectangle {\n"
|
||||
" id: root\n"
|
||||
" x: 10;\n"
|
||||
" y: 10;\n"
|
||||
" signal testSignal()\n"
|
||||
" signal testSignal2(float i)\n"
|
||||
" Rectangle {\n"
|
||||
" id: rectangle1\n"
|
||||
" x: 10;\n"
|
||||
" y: 10;\n"
|
||||
" signal testSignal\n"
|
||||
" }\n}");
|
||||
|
||||
QCOMPARE(textEdit.toPlainText(), expectedQmlCode2);
|
||||
|
||||
testRewriterView->executeInTransaction("identifer", [rectangle](){
|
||||
ModelNode newRectangle = rectangle.view()->createModelNode(rectangle.type(),
|
||||
rectangle.majorVersion(),
|
||||
rectangle.minorVersion());
|
||||
|
||||
QVERIFY(newRectangle.isValid());
|
||||
newRectangle.signalDeclarationProperty("newSignal").setSignature("()");
|
||||
newRectangle.setIdWithoutRefactoring("newRect");
|
||||
newRectangle.view()->rootModelNode().defaultNodeListProperty().reparentHere(newRectangle);
|
||||
});
|
||||
|
||||
const QString expectedQmlCode3
|
||||
= expectedQmlCode2.chopped(1)
|
||||
+ QLatin1String("\n Rectangle {\n id: newRect\n signal newSignal ()\n }\n}");
|
||||
|
||||
QCOMPARE(textEdit.toPlainText(), expectedQmlCode3);
|
||||
}
|
||||
|
||||
void tst_TestCore::testRewriterForGradientMagic()
|
||||
{
|
||||
const QLatin1String qmlString("\n"
|
||||
@@ -6891,6 +7006,29 @@ void tst_TestCore::testModelChangeType()
|
||||
QCOMPARE(textEdit.toPlainText(), expectedQmlCode2);
|
||||
}
|
||||
|
||||
void tst_TestCore::testModelSignalDefinition()
|
||||
{
|
||||
QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 2, 0));
|
||||
QVERIFY(model.data());
|
||||
|
||||
QScopedPointer<TestView> view(new TestView(model.data()));
|
||||
QVERIFY(view.data());
|
||||
model->attachView(view.data());
|
||||
|
||||
ModelNode rootModelNode(view->rootModelNode());
|
||||
QVERIFY(rootModelNode.isValid());
|
||||
|
||||
QVERIFY(!rootModelNode.hasProperty("mySignal"));
|
||||
|
||||
rootModelNode.signalDeclarationProperty("mySignal").setSignature("()");
|
||||
|
||||
QVERIFY(rootModelNode.hasProperty("mySignal"));
|
||||
|
||||
QVERIFY(rootModelNode.signalDeclarationProperty("mySignal").isValid());
|
||||
QVERIFY(rootModelNode.property("mySignal").isSignalDeclarationProperty());
|
||||
QCOMPARE(rootModelNode.signalDeclarationProperty("mySignal").signature(), "()");
|
||||
}
|
||||
|
||||
void tst_TestCore::testModelDefaultProperties()
|
||||
{
|
||||
QScopedPointer<Model> model(createModel("QtQuick.Rectangle", 2, 0));
|
||||
|
@@ -90,6 +90,7 @@ private slots:
|
||||
void testModelNodeInHierarchy();
|
||||
void testModelNodeIsAncestorOf();
|
||||
void testModelChangeType();
|
||||
void testModelSignalDefinition();
|
||||
|
||||
//
|
||||
// unit tests Rewriter
|
||||
@@ -146,6 +147,7 @@ private slots:
|
||||
void testRewriterTransactionAddingAfterReparenting();
|
||||
void testRewriterReparentToNewNode();
|
||||
void testRewriterBehaivours();
|
||||
void testRewriterSignalDefinition();
|
||||
|
||||
//
|
||||
// unit tests QmlModelNodeFacade/QmlModelState
|
||||
|
Reference in New Issue
Block a user