forked from qt-creator/qt-creator
Connection Editor: ConnectionModelBackendDelegate refactoring
ConnectionModelBackendDelegate refactoring to extract logic responsible for generating scripts to a reusable backend component. ScriptEditorBackend can be used in the property editor to handle script creation in scripting components (such as ScriptAction or StateChangeScript) and as a base for ConnectionModelBackendDelegate. Task-number: QDS-10449 Change-Id: Ie83f413f42bc1134ebb866aa6e7ea9d6b37da49b Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -6,6 +6,7 @@ import QtQuick.Controls
|
|||||||
import HelperWidgets as HelperWidgets
|
import HelperWidgets as HelperWidgets
|
||||||
import StudioControls as StudioControls
|
import StudioControls as StudioControls
|
||||||
import StudioTheme as StudioTheme
|
import StudioTheme as StudioTheme
|
||||||
|
import ScriptEditorBackend
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: root
|
id: root
|
||||||
@@ -71,32 +72,32 @@ Column {
|
|||||||
|
|
||||||
model: ListModel {
|
model: ListModel {
|
||||||
ListElement {
|
ListElement {
|
||||||
value: ConnectionModelStatementDelegate.CallFunction
|
value: StatementDelegate.CallFunction
|
||||||
text: qsTr("Call Function")
|
text: qsTr("Call Function")
|
||||||
enabled: true
|
enabled: true
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
value: ConnectionModelStatementDelegate.Assign
|
value: StatementDelegate.Assign
|
||||||
text: qsTr("Assign")
|
text: qsTr("Assign")
|
||||||
enabled: true
|
enabled: true
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
value: ConnectionModelStatementDelegate.ChangeState
|
value: StatementDelegate.ChangeState
|
||||||
text: qsTr("Change State")
|
text: qsTr("Change State")
|
||||||
enabled: true
|
enabled: true
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
value: ConnectionModelStatementDelegate.SetProperty
|
value: StatementDelegate.SetProperty
|
||||||
text: qsTr("Set Property")
|
text: qsTr("Set Property")
|
||||||
enabled: true
|
enabled: true
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
value: ConnectionModelStatementDelegate.PrintMessage
|
value: StatementDelegate.PrintMessage
|
||||||
text: qsTr("Print Message")
|
text: qsTr("Print Message")
|
||||||
enabled: true
|
enabled: true
|
||||||
}
|
}
|
||||||
ListElement {
|
ListElement {
|
||||||
value: ConnectionModelStatementDelegate.Custom
|
value: StatementDelegate.Custom
|
||||||
text: qsTr("Custom")
|
text: qsTr("Custom")
|
||||||
enabled: false
|
enabled: false
|
||||||
}
|
}
|
||||||
@@ -106,7 +107,7 @@ Column {
|
|||||||
|
|
||||||
StatementEditor {
|
StatementEditor {
|
||||||
width: root.width
|
width: root.width
|
||||||
actionType: action.currentValue ?? ConnectionModelStatementDelegate.Custom
|
actionType: action.currentValue ?? StatementDelegate.Custom
|
||||||
horizontalSpacing: root.horizontalSpacing
|
horizontalSpacing: root.horizontalSpacing
|
||||||
columnWidth: root.columnWidth
|
columnWidth: root.columnWidth
|
||||||
statement: backend.okStatement
|
statement: backend.okStatement
|
||||||
@@ -122,7 +123,7 @@ Column {
|
|||||||
iconSize: StudioTheme.Values.baseFontSize
|
iconSize: StudioTheme.Values.baseFontSize
|
||||||
iconFontFamily: StudioTheme.Constants.font.family
|
iconFontFamily: StudioTheme.Constants.font.family
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && !backend.hasCondition
|
visible: action.currentValue !== StatementDelegate.Custom && !backend.hasCondition
|
||||||
|
|
||||||
onClicked: backend.addCondition()
|
onClicked: backend.addCondition()
|
||||||
}
|
}
|
||||||
@@ -135,7 +136,7 @@ Column {
|
|||||||
iconSize: StudioTheme.Values.baseFontSize
|
iconSize: StudioTheme.Values.baseFontSize
|
||||||
iconFontFamily: StudioTheme.Constants.font.family
|
iconFontFamily: StudioTheme.Constants.font.family
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && backend.hasCondition
|
visible: action.currentValue !== StatementDelegate.Custom && backend.hasCondition
|
||||||
|
|
||||||
onClicked: backend.removeCondition()
|
onClicked: backend.removeCondition()
|
||||||
}
|
}
|
||||||
@@ -186,7 +187,7 @@ Column {
|
|||||||
iconSize: StudioTheme.Values.baseFontSize
|
iconSize: StudioTheme.Values.baseFontSize
|
||||||
iconFontFamily: StudioTheme.Constants.font.family
|
iconFontFamily: StudioTheme.Constants.font.family
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom
|
visible: action.currentValue !== StatementDelegate.Custom
|
||||||
&& backend.hasCondition && !backend.hasElse
|
&& backend.hasCondition && !backend.hasElse
|
||||||
|
|
||||||
onClicked: backend.addElse()
|
onClicked: backend.addElse()
|
||||||
@@ -200,7 +201,7 @@ Column {
|
|||||||
iconSize: StudioTheme.Values.baseFontSize
|
iconSize: StudioTheme.Values.baseFontSize
|
||||||
iconFontFamily: StudioTheme.Constants.font.family
|
iconFontFamily: StudioTheme.Constants.font.family
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom
|
visible: action.currentValue !== StatementDelegate.Custom
|
||||||
&& backend.hasCondition && backend.hasElse
|
&& backend.hasCondition && backend.hasElse
|
||||||
|
|
||||||
onClicked: backend.removeElse()
|
onClicked: backend.removeElse()
|
||||||
@@ -209,13 +210,13 @@ Column {
|
|||||||
//Else Statement
|
//Else Statement
|
||||||
StatementEditor {
|
StatementEditor {
|
||||||
width: root.width
|
width: root.width
|
||||||
actionType: action.currentValue ?? ConnectionModelStatementDelegate.Custom
|
actionType: action.currentValue ?? StatementDelegate.Custom
|
||||||
horizontalSpacing: root.horizontalSpacing
|
horizontalSpacing: root.horizontalSpacing
|
||||||
columnWidth: root.columnWidth
|
columnWidth: root.columnWidth
|
||||||
statement: backend.koStatement
|
statement: backend.koStatement
|
||||||
backend: root.backend
|
backend: root.backend
|
||||||
spacing: root.verticalSpacing
|
spacing: root.verticalSpacing
|
||||||
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom
|
visible: action.currentValue !== StatementDelegate.Custom
|
||||||
&& backend.hasCondition && backend.hasElse
|
&& backend.hasCondition && backend.hasElse
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -7,6 +7,7 @@ import HelperWidgets as HelperWidgets
|
|||||||
import StudioControls as StudioControls
|
import StudioControls as StudioControls
|
||||||
import StudioTheme as StudioTheme
|
import StudioTheme as StudioTheme
|
||||||
import ConnectionsEditorEditorBackend
|
import ConnectionsEditorEditorBackend
|
||||||
|
import ScriptEditorBackend
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: root
|
id: root
|
||||||
@@ -22,7 +23,7 @@ Column {
|
|||||||
|
|
||||||
// Call Function
|
// Call Function
|
||||||
Row {
|
Row {
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.CallFunction
|
visible: root.actionType === StatementDelegate.CallFunction
|
||||||
spacing: root.horizontalSpacing
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
PopupLabel {
|
PopupLabel {
|
||||||
@@ -39,7 +40,7 @@ Column {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.CallFunction
|
visible: root.actionType === StatementDelegate.CallFunction
|
||||||
spacing: root.horizontalSpacing
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
StudioControls.TopLevelComboBox {
|
StudioControls.TopLevelComboBox {
|
||||||
@@ -68,7 +69,7 @@ Column {
|
|||||||
|
|
||||||
// Assign
|
// Assign
|
||||||
Row {
|
Row {
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.Assign
|
visible: root.actionType === StatementDelegate.Assign
|
||||||
spacing: root.horizontalSpacing
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
PopupLabel {
|
PopupLabel {
|
||||||
@@ -84,7 +85,7 @@ Column {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.Assign
|
visible: root.actionType === StatementDelegate.Assign
|
||||||
spacing: root.horizontalSpacing
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
StudioControls.TopLevelComboBox {
|
StudioControls.TopLevelComboBox {
|
||||||
@@ -114,7 +115,7 @@ Column {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.Assign
|
visible: root.actionType === StatementDelegate.Assign
|
||||||
spacing: root.horizontalSpacing
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
StudioControls.TopLevelComboBox {
|
StudioControls.TopLevelComboBox {
|
||||||
@@ -145,7 +146,7 @@ Column {
|
|||||||
|
|
||||||
// Change State
|
// Change State
|
||||||
Row {
|
Row {
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.ChangeState
|
visible: root.actionType === StatementDelegate.ChangeState
|
||||||
spacing: root.horizontalSpacing
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
PopupLabel {
|
PopupLabel {
|
||||||
@@ -162,7 +163,7 @@ Column {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.ChangeState
|
visible: root.actionType === StatementDelegate.ChangeState
|
||||||
spacing: root.horizontalSpacing
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
StudioControls.TopLevelComboBox {
|
StudioControls.TopLevelComboBox {
|
||||||
@@ -191,7 +192,7 @@ Column {
|
|||||||
|
|
||||||
// Set Property
|
// Set Property
|
||||||
Row {
|
Row {
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.SetProperty
|
visible: root.actionType === StatementDelegate.SetProperty
|
||||||
spacing: root.horizontalSpacing
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
PopupLabel {
|
PopupLabel {
|
||||||
@@ -208,7 +209,7 @@ Column {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.SetProperty
|
visible: root.actionType === StatementDelegate.SetProperty
|
||||||
spacing: root.horizontalSpacing
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
StudioControls.TopLevelComboBox {
|
StudioControls.TopLevelComboBox {
|
||||||
@@ -238,14 +239,14 @@ Column {
|
|||||||
|
|
||||||
PopupLabel {
|
PopupLabel {
|
||||||
width: root.columnWidth
|
width: root.columnWidth
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.SetProperty
|
visible: root.actionType === StatementDelegate.SetProperty
|
||||||
text: qsTr("Value")
|
text: qsTr("Value")
|
||||||
tooltip: qsTr("Sets the value of the property of the component that is affected by the action of the <b>Target</b> component's <b>Signal</b>.")
|
tooltip: qsTr("Sets the value of the property of the component that is affected by the action of the <b>Target</b> component's <b>Signal</b>.")
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.TextField {
|
StudioControls.TextField {
|
||||||
id: setPropertyArgument
|
id: setPropertyArgument
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.SetProperty
|
visible: root.actionType === StatementDelegate.SetProperty
|
||||||
width: root.width
|
width: root.width
|
||||||
actionIndicatorVisible: false
|
actionIndicatorVisible: false
|
||||||
translationIndicatorVisible: false
|
translationIndicatorVisible: false
|
||||||
@@ -259,14 +260,14 @@ Column {
|
|||||||
// Print Message
|
// Print Message
|
||||||
PopupLabel {
|
PopupLabel {
|
||||||
width: root.columnWidth
|
width: root.columnWidth
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.PrintMessage
|
visible: root.actionType === StatementDelegate.PrintMessage
|
||||||
text: qsTr("Message")
|
text: qsTr("Message")
|
||||||
tooltip: qsTr("Sets a text that is printed when the <b>Signal</b> of the <b>Target</b> component initiates.")
|
tooltip: qsTr("Sets a text that is printed when the <b>Signal</b> of the <b>Target</b> component initiates.")
|
||||||
}
|
}
|
||||||
|
|
||||||
StudioControls.TextField {
|
StudioControls.TextField {
|
||||||
id: messageString
|
id: messageString
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.PrintMessage
|
visible: root.actionType === StatementDelegate.PrintMessage
|
||||||
width: root.width
|
width: root.width
|
||||||
actionIndicatorVisible: false
|
actionIndicatorVisible: false
|
||||||
translationIndicatorVisible: false
|
translationIndicatorVisible: false
|
||||||
@@ -278,7 +279,7 @@ Column {
|
|||||||
|
|
||||||
// Custom
|
// Custom
|
||||||
PopupLabel {
|
PopupLabel {
|
||||||
visible: root.actionType === ConnectionModelStatementDelegate.Custom
|
visible: root.actionType === StatementDelegate.Custom
|
||||||
text: qsTr("Custom Connections can only be edited with the binding editor")
|
text: qsTr("Custom Connections can only be edited with the binding editor")
|
||||||
width: root.width
|
width: root.width
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
@@ -571,6 +571,16 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
annotationeditor.qrc
|
annotationeditor.qrc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
extend_qtc_plugin(QmlDesigner
|
||||||
|
SOURCES_PREFIX components/scripteditor
|
||||||
|
SOURCES
|
||||||
|
scripteditorstatements.cpp scripteditorstatements.h
|
||||||
|
scripteditorevaluator.cpp scripteditorevaluator.h
|
||||||
|
scripteditorutils.cpp scripteditorutils.h
|
||||||
|
propertytreemodel.cpp propertytreemodel.h
|
||||||
|
scripteditorbackend.cpp scripteditorbackend.h
|
||||||
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlDesigner
|
extend_qtc_plugin(QmlDesigner
|
||||||
SOURCES_PREFIX components/connectioneditor
|
SOURCES_PREFIX components/connectioneditor
|
||||||
SOURCES
|
SOURCES
|
||||||
@@ -578,15 +588,12 @@ extend_qtc_plugin(QmlDesigner
|
|||||||
bindingmodel.cpp bindingmodel.h
|
bindingmodel.cpp bindingmodel.h
|
||||||
bindingmodelitem.cpp bindingmodelitem.h
|
bindingmodelitem.cpp bindingmodelitem.h
|
||||||
connectioneditor.qrc
|
connectioneditor.qrc
|
||||||
connectioneditorevaluator.cpp connectioneditorevaluator.h
|
|
||||||
connectioneditorstatements.cpp connectioneditorstatements.h
|
|
||||||
connectionmodel.cpp connectionmodel.h
|
connectionmodel.cpp connectionmodel.h
|
||||||
connectionview.cpp connectionview.h
|
connectionview.cpp connectionview.h
|
||||||
dynamicpropertiesmodel.cpp dynamicpropertiesmodel.h
|
dynamicpropertiesmodel.cpp dynamicpropertiesmodel.h
|
||||||
dynamicpropertiesitem.cpp dynamicpropertiesitem.h
|
dynamicpropertiesitem.cpp dynamicpropertiesitem.h
|
||||||
connectioneditorutils.cpp connectioneditorutils.h
|
|
||||||
selectiondynamicpropertiesproxymodel.cpp selectiondynamicpropertiesproxymodel.h
|
selectiondynamicpropertiesproxymodel.cpp selectiondynamicpropertiesproxymodel.h
|
||||||
propertytreemodel.cpp propertytreemodel.h
|
connectioneditorlogging.cpp connectioneditorlogging.h
|
||||||
)
|
)
|
||||||
|
|
||||||
extend_qtc_plugin(QmlDesigner
|
extend_qtc_plugin(QmlDesigner
|
||||||
|
@@ -3,10 +3,11 @@
|
|||||||
|
|
||||||
#include "bindingmodel.h"
|
#include "bindingmodel.h"
|
||||||
#include "bindingmodelitem.h"
|
#include "bindingmodelitem.h"
|
||||||
#include "connectioneditorutils.h"
|
#include "connectioneditorlogging.h"
|
||||||
#include "connectionview.h"
|
#include "connectionview.h"
|
||||||
#include "modelfwd.h"
|
#include "modelfwd.h"
|
||||||
|
|
||||||
|
#include <scripteditorutils.h>
|
||||||
#include <bindingproperty.h>
|
#include <bindingproperty.h>
|
||||||
#include <nodemetainfo.h>
|
#include <nodemetainfo.h>
|
||||||
#include <nodeproperty.h>
|
#include <nodeproperty.h>
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#include "bindingmodelitem.h"
|
#include "bindingmodelitem.h"
|
||||||
#include "connectioneditorutils.h"
|
#include <scripteditorutils.h>
|
||||||
|
|
||||||
#include <modelnode.h>
|
#include <modelnode.h>
|
||||||
#include <qmldesignertr.h>
|
#include <qmldesignertr.h>
|
||||||
|
@@ -0,0 +1,10 @@
|
|||||||
|
// Copyright (C) 2025 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#include "connectioneditorlogging.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
Q_LOGGING_CATEGORY(ConnectionEditorLog, "qtc.qtquickdesigner.connectioneditor", QtWarningMsg)
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
@@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (C) 2025 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QLoggingCategory>
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(ConnectionEditorLog)
|
||||||
|
|
||||||
|
} // namespace QmlDesigner
|
File diff suppressed because it is too large
Load Diff
@@ -3,15 +3,11 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <connectioneditorstatements.h>
|
#include <scripteditorbackend.h>
|
||||||
#include <propertytreemodel.h>
|
|
||||||
#include <studioquickwidget.h>
|
#include <studioquickwidget.h>
|
||||||
|
|
||||||
#include <QAbstractListModel>
|
|
||||||
#include <QStandardItemModel>
|
#include <QStandardItemModel>
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
class AbstractProperty;
|
class AbstractProperty;
|
||||||
@@ -23,247 +19,35 @@ class VariantProperty;
|
|||||||
class ConnectionView;
|
class ConnectionView;
|
||||||
class ConnectionModel;
|
class ConnectionModel;
|
||||||
|
|
||||||
class ConditionListModel : public QAbstractListModel
|
class ConnectionModelBackendDelegate : public ScriptEditorBackend
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY(bool valid READ valid NOTIFY validChanged)
|
|
||||||
Q_PROPERTY(bool empty READ empty NOTIFY emptyChanged)
|
|
||||||
Q_PROPERTY(QString error READ error NOTIFY errorChanged)
|
|
||||||
Q_PROPERTY(int errorIndex READ errorIndex NOTIFY errorIndexChanged)
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum ConditionType { Intermediate, Invalid, Operator, Literal, Variable, Shadow };
|
|
||||||
Q_ENUM(ConditionType)
|
|
||||||
|
|
||||||
struct ConditionToken
|
|
||||||
{
|
|
||||||
ConditionType type;
|
|
||||||
QString value;
|
|
||||||
};
|
|
||||||
|
|
||||||
ConditionListModel(ConnectionModel *model);
|
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
|
||||||
|
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
|
||||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
|
||||||
|
|
||||||
void setup();
|
|
||||||
void setCondition(ConnectionEditorStatements::MatchedCondition &condition);
|
|
||||||
ConnectionEditorStatements::MatchedCondition &condition();
|
|
||||||
|
|
||||||
static ConditionToken tokenFromConditionToken(const ConnectionEditorStatements::ConditionToken &token);
|
|
||||||
|
|
||||||
static ConditionToken tokenFromComparativeStatement(
|
|
||||||
const ConnectionEditorStatements::ComparativeStatement &token);
|
|
||||||
|
|
||||||
Q_INVOKABLE void insertToken(int index, const QString &value);
|
|
||||||
Q_INVOKABLE void updateToken(int index, const QString &value);
|
|
||||||
Q_INVOKABLE void appendToken(const QString &value);
|
|
||||||
Q_INVOKABLE void removeToken(int index);
|
|
||||||
|
|
||||||
Q_INVOKABLE void insertIntermediateToken(int index, const QString &value);
|
|
||||||
Q_INVOKABLE void insertShadowToken(int index, const QString &value);
|
|
||||||
Q_INVOKABLE void setShadowToken(int index, const QString &value);
|
|
||||||
|
|
||||||
bool valid() const;
|
|
||||||
bool empty() const;
|
|
||||||
|
|
||||||
//for debugging
|
|
||||||
Q_INVOKABLE void command(const QString &string);
|
|
||||||
|
|
||||||
void setInvalid(const QString &errorMessage, int index = -1);
|
|
||||||
void setValid();
|
|
||||||
|
|
||||||
QString error() const;
|
|
||||||
int errorIndex() const;
|
|
||||||
|
|
||||||
Q_INVOKABLE bool operatorAllowed(int cursorPosition);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void validChanged();
|
|
||||||
void emptyChanged();
|
|
||||||
void conditionChanged();
|
|
||||||
void errorChanged();
|
|
||||||
void errorIndexChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void internalSetup();
|
|
||||||
ConditionToken valueToToken(const QString &value);
|
|
||||||
void resetModel();
|
|
||||||
int checkOrder() const;
|
|
||||||
void validateAndRebuildTokens();
|
|
||||||
void rebuildTokens();
|
|
||||||
|
|
||||||
ConnectionEditorStatements::ConditionToken toOperatorStatement(const ConditionToken &token);
|
|
||||||
ConnectionEditorStatements::ComparativeStatement toStatement(const ConditionToken &token);
|
|
||||||
|
|
||||||
ConnectionModel *m_connectionModel = nullptr;
|
|
||||||
ConnectionEditorStatements::MatchedCondition &m_condition;
|
|
||||||
QList<ConditionToken> m_tokens;
|
|
||||||
bool m_valid = false;
|
|
||||||
QString m_errorMessage;
|
|
||||||
int m_errorIndex = -1;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConnectionModelStatementDelegate : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit ConnectionModelStatementDelegate(ConnectionModel *model);
|
|
||||||
|
|
||||||
enum ActionType { CallFunction, Assign, ChangeState, SetProperty, PrintMessage, Custom };
|
|
||||||
|
|
||||||
Q_ENUM(ActionType)
|
|
||||||
|
|
||||||
Q_PROPERTY(ActionType actionType READ actionType NOTIFY actionTypeChanged)
|
|
||||||
|
|
||||||
Q_PROPERTY(PropertyTreeModelDelegate *function READ function CONSTANT)
|
|
||||||
Q_PROPERTY(PropertyTreeModelDelegate *lhs READ lhs CONSTANT)
|
|
||||||
Q_PROPERTY(PropertyTreeModelDelegate *rhsAssignment READ rhsAssignment CONSTANT)
|
|
||||||
Q_PROPERTY(StudioQmlTextBackend *stringArgument READ stringArgument CONSTANT)
|
|
||||||
Q_PROPERTY(StudioQmlComboBoxBackend *states READ states CONSTANT)
|
|
||||||
Q_PROPERTY(StudioQmlComboBoxBackend *stateTargets READ stateTargets CONSTANT)
|
|
||||||
|
|
||||||
void setActionType(ActionType type);
|
|
||||||
void setup();
|
|
||||||
void setStatement(ConnectionEditorStatements::MatchedStatement &statement);
|
|
||||||
ConnectionEditorStatements::MatchedStatement &statement();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void actionTypeChanged();
|
|
||||||
void statementChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
ActionType actionType() const;
|
|
||||||
PropertyTreeModelDelegate *signal();
|
|
||||||
PropertyTreeModelDelegate *function();
|
|
||||||
PropertyTreeModelDelegate *lhs();
|
|
||||||
PropertyTreeModelDelegate *rhsAssignment();
|
|
||||||
StudioQmlTextBackend *stringArgument();
|
|
||||||
StudioQmlComboBoxBackend *stateTargets();
|
|
||||||
StudioQmlComboBoxBackend *states();
|
|
||||||
|
|
||||||
void handleFunctionChanged();
|
|
||||||
void handleLhsChanged();
|
|
||||||
void handleRhsAssignmentChanged();
|
|
||||||
void handleStringArgumentChanged();
|
|
||||||
void handleStateChanged();
|
|
||||||
void handleStateTargetsChanged();
|
|
||||||
|
|
||||||
void setupAssignment();
|
|
||||||
void setupSetProperty();
|
|
||||||
void setupCallFunction();
|
|
||||||
void setupChangeState();
|
|
||||||
void setupStates();
|
|
||||||
void setupPrintMessage();
|
|
||||||
void setupPropertyType();
|
|
||||||
QString baseStateName() const;
|
|
||||||
|
|
||||||
ActionType m_actionType;
|
|
||||||
PropertyTreeModelDelegate m_functionDelegate;
|
|
||||||
PropertyTreeModelDelegate m_lhsDelegate;
|
|
||||||
PropertyTreeModelDelegate m_rhsAssignmentDelegate;
|
|
||||||
ConnectionEditorStatements::MatchedStatement &m_statement;
|
|
||||||
ConnectionModel *m_model = nullptr;
|
|
||||||
StudioQmlTextBackend m_stringArgument;
|
|
||||||
StudioQmlComboBoxBackend m_stateTargets;
|
|
||||||
StudioQmlComboBoxBackend m_states;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConnectionModelBackendDelegate : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
Q_PROPERTY(int currentRow READ currentRow WRITE setCurrentRow NOTIFY currentRowChanged)
|
Q_PROPERTY(int currentRow READ currentRow WRITE setCurrentRow NOTIFY currentRowChanged)
|
||||||
|
|
||||||
Q_PROPERTY(ActionType actionType READ actionType NOTIFY actionTypeChanged)
|
|
||||||
Q_PROPERTY(PropertyTreeModelDelegate *signal READ signal CONSTANT)
|
Q_PROPERTY(PropertyTreeModelDelegate *signal READ signal CONSTANT)
|
||||||
Q_PROPERTY(ConnectionModelStatementDelegate *okStatement READ okStatement CONSTANT)
|
|
||||||
Q_PROPERTY(ConnectionModelStatementDelegate *koStatement READ koStatement CONSTANT)
|
|
||||||
Q_PROPERTY(ConditionListModel *conditionListModel READ conditionListModel CONSTANT)
|
|
||||||
Q_PROPERTY(bool hasCondition READ hasCondition NOTIFY hasConditionChanged)
|
|
||||||
Q_PROPERTY(bool hasElse READ hasElse NOTIFY hasElseChanged)
|
|
||||||
Q_PROPERTY(QString source READ source NOTIFY sourceChanged)
|
|
||||||
Q_PROPERTY(QString indentedSource READ indentedSource NOTIFY sourceChanged)
|
|
||||||
|
|
||||||
Q_PROPERTY(PropertyTreeModel *propertyTreeModel READ propertyTreeModel CONSTANT)
|
|
||||||
Q_PROPERTY(PropertyListProxyModel *propertyListProxyModel READ propertyListProxyModel CONSTANT)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ConnectionModelBackendDelegate(ConnectionModel *model);
|
explicit ConnectionModelBackendDelegate(ConnectionModel *model);
|
||||||
|
|
||||||
using ActionType = ConnectionModelStatementDelegate::ActionType;
|
void update() override;
|
||||||
|
|
||||||
Q_INVOKABLE void changeActionType(QmlDesigner::ConnectionModelStatementDelegate::ActionType actionType);
|
|
||||||
|
|
||||||
Q_INVOKABLE void addCondition();
|
|
||||||
Q_INVOKABLE void removeCondition();
|
|
||||||
|
|
||||||
Q_INVOKABLE void addElse();
|
|
||||||
Q_INVOKABLE void removeElse();
|
|
||||||
|
|
||||||
Q_INVOKABLE void setNewSource(const QString &newSource);
|
|
||||||
|
|
||||||
void setCurrentRow(int i);
|
void setCurrentRow(int i);
|
||||||
void update();
|
|
||||||
|
|
||||||
Q_INVOKABLE void jumpToCode();
|
PropertyTreeModelDelegate *signal();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void currentRowChanged();
|
void currentRowChanged();
|
||||||
void actionTypeChanged();
|
|
||||||
void hasConditionChanged();
|
private slots:
|
||||||
void hasElseChanged();
|
void handleTargetChanged();
|
||||||
void sourceChanged();
|
|
||||||
void popupShouldClose();
|
|
||||||
void popupShouldOpen();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
AbstractProperty getSourceProperty() const override;
|
||||||
|
void setPropertySource(const QString &source) override;
|
||||||
|
|
||||||
|
SignalHandlerProperty getSignalHandlerProperty() const;
|
||||||
int currentRow() const;
|
int currentRow() const;
|
||||||
void handleException();
|
|
||||||
bool hasCondition() const;
|
|
||||||
bool hasElse() const;
|
|
||||||
void setHasCondition(bool b);
|
|
||||||
void setHasElse(bool b);
|
|
||||||
ActionType actionType() const;
|
|
||||||
PropertyTreeModelDelegate *signal();
|
|
||||||
ConnectionModelStatementDelegate *okStatement();
|
|
||||||
ConnectionModelStatementDelegate *koStatement();
|
|
||||||
ConditionListModel *conditionListModel();
|
|
||||||
QString indentedSource() const;
|
|
||||||
QString source() const;
|
|
||||||
void setSource(const QString &source);
|
|
||||||
|
|
||||||
PropertyTreeModel *propertyTreeModel();
|
|
||||||
PropertyListProxyModel *propertyListProxyModel();
|
|
||||||
|
|
||||||
void setupCondition();
|
|
||||||
void setupHandlerAndStatements();
|
|
||||||
|
|
||||||
void handleTargetChanged();
|
|
||||||
void handleOkStatementChanged();
|
|
||||||
void handleKOStatementChanged();
|
|
||||||
void handleConditionChanged();
|
|
||||||
|
|
||||||
void commitNewSource(const QString &source);
|
|
||||||
|
|
||||||
ActionType m_actionType;
|
|
||||||
QString m_exceptionError;
|
|
||||||
int m_currentRow = -1;
|
int m_currentRow = -1;
|
||||||
ConnectionEditorStatements::Handler m_handler;
|
|
||||||
PropertyTreeModelDelegate m_signalDelegate;
|
PropertyTreeModelDelegate m_signalDelegate;
|
||||||
ConnectionModelStatementDelegate m_okStatementDelegate;
|
|
||||||
ConnectionModelStatementDelegate m_koStatementDelegate;
|
|
||||||
ConditionListModel m_conditionListModel;
|
|
||||||
bool m_hasCondition = false;
|
|
||||||
bool m_hasElse = false;
|
|
||||||
QString m_source;
|
|
||||||
PropertyTreeModel m_propertyTreeModel;
|
|
||||||
PropertyListProxyModel m_propertyListProxyModel;
|
|
||||||
bool m_blockReflection = false;
|
|
||||||
QPointer<ConnectionModel> m_model = nullptr;
|
QPointer<ConnectionModel> m_model = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -83,10 +83,8 @@ public:
|
|||||||
0,
|
0,
|
||||||
"DynamicPropertiesModelBackendDelegate");
|
"DynamicPropertiesModelBackendDelegate");
|
||||||
|
|
||||||
qmlRegisterType<ConnectionModelStatementDelegate>("ConnectionsEditorEditorBackend",
|
// TODO: register in the property editor along with the ScriptEditorBackend
|
||||||
1,
|
qmlRegisterType<StatementDelegate>("ScriptEditorBackend", 1, 0, "StatementDelegate");
|
||||||
0,
|
|
||||||
"ConnectionModelStatementDelegate");
|
|
||||||
|
|
||||||
qmlRegisterType<ConditionListModel>("ConnectionsEditorEditorBackend", 1, 0, "ConditionListModel");
|
qmlRegisterType<ConditionListModel>("ConnectionsEditorEditorBackend", 1, 0, "ConditionListModel");
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#include "dynamicpropertiesitem.h"
|
#include "dynamicpropertiesitem.h"
|
||||||
#include "connectioneditorutils.h"
|
#include <scripteditorutils.h>
|
||||||
|
|
||||||
#include <abstractproperty.h>
|
#include <abstractproperty.h>
|
||||||
#include <abstractview.h>
|
#include <abstractview.h>
|
||||||
|
@@ -2,22 +2,23 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#include "dynamicpropertiesmodel.h"
|
#include "dynamicpropertiesmodel.h"
|
||||||
|
#include "connectioneditorlogging.h"
|
||||||
#include "dynamicpropertiesitem.h"
|
#include "dynamicpropertiesitem.h"
|
||||||
#include "connectioneditorutils.h"
|
|
||||||
|
|
||||||
#include <abstractproperty.h>
|
#include <abstractproperty.h>
|
||||||
#include <bindingproperty.h>
|
#include <bindingproperty.h>
|
||||||
#include <modelfwd.h>
|
#include <modelfwd.h>
|
||||||
#include <rewritertransaction.h>
|
|
||||||
#include <rewritingexception.h>
|
|
||||||
#include <utils/algorithm.h>
|
|
||||||
#include <utils/qtcassert.h>
|
|
||||||
#include <variantproperty.h>
|
|
||||||
#include <qmlchangeset.h>
|
#include <qmlchangeset.h>
|
||||||
#include <qmldesignerconstants.h>
|
#include <qmldesignerconstants.h>
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
#include <qmlobjectnode.h>
|
#include <qmlobjectnode.h>
|
||||||
#include <qmltimeline.h>
|
#include <qmltimeline.h>
|
||||||
|
#include <rewritertransaction.h>
|
||||||
|
#include <rewritingexception.h>
|
||||||
|
#include <scripteditorutils.h>
|
||||||
|
#include <utils/algorithm.h>
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
#include <variantproperty.h>
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
|
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include "bindingproperty.h"
|
#include "bindingproperty.h"
|
||||||
#include "propertyeditorvalue.h"
|
#include "propertyeditorvalue.h"
|
||||||
#include "connectioneditorutils.h"
|
#include <scripteditorutils.h>
|
||||||
|
|
||||||
#include <dynamicpropertiesmodel.h>
|
#include <dynamicpropertiesmodel.h>
|
||||||
|
|
||||||
|
@@ -163,8 +163,8 @@ std::vector<PropertyName> properityLists()
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyTreeModel::PropertyTreeModel(ConnectionView *view)
|
PropertyTreeModel::PropertyTreeModel(AbstractView *view)
|
||||||
: m_connectionView(view)
|
: m_view(view)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void PropertyTreeModel::resetModel()
|
void PropertyTreeModel::resetModel()
|
||||||
@@ -257,7 +257,7 @@ Qt::ItemFlags PropertyTreeModel::flags(const QModelIndex &) const
|
|||||||
QModelIndex PropertyTreeModel::index(int row, int column, const QModelIndex &parent) const
|
QModelIndex PropertyTreeModel::index(int row, int column, const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
auto internalId = parent.internalId();
|
auto internalId = parent.internalId();
|
||||||
if (!m_connectionView->isAttached())
|
if (!m_view->isAttached())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
if (!parent.isValid())
|
if (!parent.isValid())
|
||||||
@@ -337,7 +337,7 @@ QPersistentModelIndex PropertyTreeModel::indexForInternalIdAndRow(quintptr inter
|
|||||||
|
|
||||||
int PropertyTreeModel::rowCount(const QModelIndex &parent) const
|
int PropertyTreeModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
if (!m_connectionView->isAttached() || parent.column() > 0)
|
if (!m_view->isAttached() || parent.column() > 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (!parent.isValid())
|
if (!parent.isValid())
|
||||||
@@ -404,10 +404,10 @@ const std::vector<PropertyName> PropertyTreeModel::getProperties(const ModelNode
|
|||||||
|
|
||||||
ModelNode PropertyTreeModel::getModelNodeForId(const QString &id) const
|
ModelNode PropertyTreeModel::getModelNodeForId(const QString &id) const
|
||||||
{
|
{
|
||||||
if (!m_connectionView->isAttached())
|
if (!m_view->isAttached())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return m_connectionView->modelNodeForId(id);
|
return m_view->modelNodeForId(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
QModelIndex PropertyTreeModel::ensureModelIndex(const ModelNode &node, int row) const
|
QModelIndex PropertyTreeModel::ensureModelIndex(const ModelNode &node, int row) const
|
||||||
@@ -473,10 +473,10 @@ void PropertyTreeModel::testModel()
|
|||||||
|
|
||||||
const QList<ModelNode> PropertyTreeModel::allModelNodesWithIdsSortedByDisplayName() const
|
const QList<ModelNode> PropertyTreeModel::allModelNodesWithIdsSortedByDisplayName() const
|
||||||
{
|
{
|
||||||
if (!m_connectionView->isAttached())
|
if (!m_view->isAttached())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return Utils::sorted(ModelUtils::allModelNodesWithId(m_connectionView),
|
return Utils::sorted(ModelUtils::allModelNodesWithId(m_view),
|
||||||
[](const ModelNode &lhs, const ModelNode &rhs) {
|
[](const ModelNode &lhs, const ModelNode &rhs) {
|
||||||
return lhs.displayName() < rhs.displayName();
|
return lhs.displayName() < rhs.displayName();
|
||||||
});
|
});
|
||||||
@@ -882,7 +882,7 @@ QString PropertyListProxyModel::parentName() const
|
|||||||
return m_treeModel->data(m_parentIndex, PropertyTreeModel::UserRoles::PropertyNameRole).toString();
|
return m_treeModel->data(m_parentIndex, PropertyTreeModel::UserRoles::PropertyNameRole).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyTreeModelDelegate::PropertyTreeModelDelegate(ConnectionView *view)
|
PropertyTreeModelDelegate::PropertyTreeModelDelegate(AbstractView *view)
|
||||||
: m_model(view)
|
: m_model(view)
|
||||||
{
|
{
|
||||||
connect(&m_nameCombboBox, &StudioQmlComboBoxBackend::activated, this, [this] {
|
connect(&m_nameCombboBox, &StudioQmlComboBoxBackend::activated, this, [this] {
|
@@ -49,7 +49,8 @@ public:
|
|||||||
BoolType
|
BoolType
|
||||||
};
|
};
|
||||||
|
|
||||||
PropertyTreeModel(ConnectionView *view);
|
// PropertyTreeModel(ConnectionView *view);
|
||||||
|
PropertyTreeModel(AbstractView *view);
|
||||||
|
|
||||||
void resetModel();
|
void resetModel();
|
||||||
|
|
||||||
@@ -120,7 +121,7 @@ private:
|
|||||||
const PropertyMetaInfo &metaInfo,
|
const PropertyMetaInfo &metaInfo,
|
||||||
bool recursive) const;
|
bool recursive) const;
|
||||||
|
|
||||||
ConnectionView *m_connectionView;
|
AbstractView *m_view;
|
||||||
|
|
||||||
mutable std::set<DataCacheItem> m_indexCache;
|
mutable std::set<DataCacheItem> m_indexCache;
|
||||||
mutable std::vector<DataCacheItem> m_indexHash;
|
mutable std::vector<DataCacheItem> m_indexHash;
|
||||||
@@ -187,7 +188,7 @@ class PropertyTreeModelDelegate : public QObject
|
|||||||
Q_PROPERTY(StudioQmlComboBoxBackend *id READ idCombboBox CONSTANT)
|
Q_PROPERTY(StudioQmlComboBoxBackend *id READ idCombboBox CONSTANT)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PropertyTreeModelDelegate(ConnectionView *view);
|
explicit PropertyTreeModelDelegate(AbstractView *view);
|
||||||
void setPropertyType(PropertyTreeModel::PropertyTypes type);
|
void setPropertyType(PropertyTreeModel::PropertyTypes type);
|
||||||
void setup(const QString &id, const QString &name, bool *nameExists = nullptr);
|
void setup(const QString &id, const QString &name, bool *nameExists = nullptr);
|
||||||
void setupNameComboBox(const QString &id, const QString &name, bool *nameExists);
|
void setupNameComboBox(const QString &id, const QString &name, bool *nameExists);
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,250 @@
|
|||||||
|
// Copyright (C) 2025 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "propertytreemodel.h"
|
||||||
|
#include "scripteditorstatements.h"
|
||||||
|
|
||||||
|
namespace QmlDesigner {
|
||||||
|
|
||||||
|
class ConditionListModel : public QAbstractListModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(bool valid READ valid NOTIFY validChanged)
|
||||||
|
Q_PROPERTY(bool empty READ empty NOTIFY emptyChanged)
|
||||||
|
Q_PROPERTY(QString error READ error NOTIFY errorChanged)
|
||||||
|
Q_PROPERTY(int errorIndex READ errorIndex NOTIFY errorIndexChanged)
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum ConditionType { Intermediate, Invalid, Operator, Literal, Variable, Shadow };
|
||||||
|
Q_ENUM(ConditionType)
|
||||||
|
|
||||||
|
struct ConditionToken
|
||||||
|
{
|
||||||
|
ConditionType type;
|
||||||
|
QString value;
|
||||||
|
};
|
||||||
|
|
||||||
|
ConditionListModel(AbstractView *view);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||||
|
|
||||||
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||||
|
|
||||||
|
void setup();
|
||||||
|
void setCondition(ScriptEditorStatements::MatchedCondition &condition);
|
||||||
|
ScriptEditorStatements::MatchedCondition &condition();
|
||||||
|
|
||||||
|
static ConditionToken tokenFromConditionToken(const ScriptEditorStatements::ConditionToken &token);
|
||||||
|
|
||||||
|
static ConditionToken tokenFromComparativeStatement(
|
||||||
|
const ScriptEditorStatements::ComparativeStatement &token);
|
||||||
|
|
||||||
|
Q_INVOKABLE void insertToken(int index, const QString &value);
|
||||||
|
Q_INVOKABLE void updateToken(int index, const QString &value);
|
||||||
|
Q_INVOKABLE void appendToken(const QString &value);
|
||||||
|
Q_INVOKABLE void removeToken(int index);
|
||||||
|
|
||||||
|
Q_INVOKABLE void insertIntermediateToken(int index, const QString &value);
|
||||||
|
Q_INVOKABLE void insertShadowToken(int index, const QString &value);
|
||||||
|
Q_INVOKABLE void setShadowToken(int index, const QString &value);
|
||||||
|
|
||||||
|
bool valid() const;
|
||||||
|
bool empty() const;
|
||||||
|
|
||||||
|
//for debugging
|
||||||
|
Q_INVOKABLE void command(const QString &string);
|
||||||
|
|
||||||
|
void setInvalid(const QString &errorMessage, int index = -1);
|
||||||
|
void setValid();
|
||||||
|
|
||||||
|
QString error() const;
|
||||||
|
int errorIndex() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE bool operatorAllowed(int cursorPosition);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void validChanged();
|
||||||
|
void emptyChanged();
|
||||||
|
void conditionChanged();
|
||||||
|
void errorChanged();
|
||||||
|
void errorIndexChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void internalSetup();
|
||||||
|
ConditionToken valueToToken(const QString &value);
|
||||||
|
void resetModel();
|
||||||
|
int checkOrder() const;
|
||||||
|
void validateAndRebuildTokens();
|
||||||
|
void rebuildTokens();
|
||||||
|
|
||||||
|
ScriptEditorStatements::ConditionToken toOperatorStatement(const ConditionToken &token);
|
||||||
|
ScriptEditorStatements::ComparativeStatement toStatement(const ConditionToken &token);
|
||||||
|
|
||||||
|
AbstractView *m_view = nullptr;
|
||||||
|
ScriptEditorStatements::MatchedCondition &m_condition;
|
||||||
|
QList<ConditionToken> m_tokens;
|
||||||
|
bool m_valid = false;
|
||||||
|
QString m_errorMessage;
|
||||||
|
int m_errorIndex = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
class StatementDelegate : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit StatementDelegate(AbstractView *view);
|
||||||
|
|
||||||
|
enum ActionType { CallFunction, Assign, ChangeState, SetProperty, PrintMessage, Custom };
|
||||||
|
|
||||||
|
Q_ENUM(ActionType)
|
||||||
|
|
||||||
|
Q_PROPERTY(ActionType actionType READ actionType NOTIFY actionTypeChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(PropertyTreeModelDelegate *function READ function CONSTANT)
|
||||||
|
Q_PROPERTY(PropertyTreeModelDelegate *lhs READ lhs CONSTANT)
|
||||||
|
Q_PROPERTY(PropertyTreeModelDelegate *rhsAssignment READ rhsAssignment CONSTANT)
|
||||||
|
Q_PROPERTY(StudioQmlTextBackend *stringArgument READ stringArgument CONSTANT)
|
||||||
|
Q_PROPERTY(StudioQmlComboBoxBackend *states READ states CONSTANT)
|
||||||
|
Q_PROPERTY(StudioQmlComboBoxBackend *stateTargets READ stateTargets CONSTANT)
|
||||||
|
|
||||||
|
void setActionType(ActionType type);
|
||||||
|
void setup();
|
||||||
|
void setStatement(ScriptEditorStatements::MatchedStatement &statement);
|
||||||
|
ScriptEditorStatements::MatchedStatement &statement();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void actionTypeChanged();
|
||||||
|
void statementChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
ActionType actionType() const;
|
||||||
|
PropertyTreeModelDelegate *function();
|
||||||
|
PropertyTreeModelDelegate *lhs();
|
||||||
|
PropertyTreeModelDelegate *rhsAssignment();
|
||||||
|
StudioQmlTextBackend *stringArgument();
|
||||||
|
StudioQmlComboBoxBackend *stateTargets();
|
||||||
|
StudioQmlComboBoxBackend *states();
|
||||||
|
|
||||||
|
void handleFunctionChanged();
|
||||||
|
void handleLhsChanged();
|
||||||
|
void handleRhsAssignmentChanged();
|
||||||
|
void handleStringArgumentChanged();
|
||||||
|
void handleStateChanged();
|
||||||
|
void handleStateTargetsChanged();
|
||||||
|
|
||||||
|
void setupAssignment();
|
||||||
|
void setupSetProperty();
|
||||||
|
void setupCallFunction();
|
||||||
|
void setupChangeState();
|
||||||
|
void setupStates();
|
||||||
|
void setupPrintMessage();
|
||||||
|
void setupPropertyType();
|
||||||
|
QString baseStateName() const;
|
||||||
|
|
||||||
|
ActionType m_actionType;
|
||||||
|
PropertyTreeModelDelegate m_functionDelegate;
|
||||||
|
PropertyTreeModelDelegate m_lhsDelegate;
|
||||||
|
PropertyTreeModelDelegate m_rhsAssignmentDelegate;
|
||||||
|
ScriptEditorStatements::MatchedStatement &m_statement;
|
||||||
|
AbstractView *m_view = nullptr;
|
||||||
|
StudioQmlTextBackend m_stringArgument;
|
||||||
|
StudioQmlComboBoxBackend m_stateTargets;
|
||||||
|
StudioQmlComboBoxBackend m_states;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ScriptEditorBackend : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(ActionType actionType READ actionType NOTIFY actionTypeChanged)
|
||||||
|
Q_PROPERTY(StatementDelegate *okStatement READ okStatement CONSTANT)
|
||||||
|
Q_PROPERTY(StatementDelegate *koStatement READ koStatement CONSTANT)
|
||||||
|
Q_PROPERTY(ConditionListModel *conditionListModel READ conditionListModel CONSTANT)
|
||||||
|
Q_PROPERTY(bool hasCondition READ hasCondition NOTIFY hasConditionChanged)
|
||||||
|
Q_PROPERTY(bool hasElse READ hasElse NOTIFY hasElseChanged)
|
||||||
|
Q_PROPERTY(QString source READ source NOTIFY sourceChanged)
|
||||||
|
Q_PROPERTY(QString indentedSource READ indentedSource NOTIFY sourceChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(PropertyTreeModel *propertyTreeModel READ propertyTreeModel CONSTANT)
|
||||||
|
Q_PROPERTY(PropertyListProxyModel *propertyListProxyModel READ propertyListProxyModel CONSTANT)
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ScriptEditorBackend(AbstractView *view);
|
||||||
|
|
||||||
|
using ActionType = StatementDelegate::ActionType;
|
||||||
|
|
||||||
|
Q_INVOKABLE void changeActionType(QmlDesigner::StatementDelegate::ActionType actionType);
|
||||||
|
|
||||||
|
Q_INVOKABLE void addCondition();
|
||||||
|
Q_INVOKABLE void removeCondition();
|
||||||
|
|
||||||
|
Q_INVOKABLE void addElse();
|
||||||
|
Q_INVOKABLE void removeElse();
|
||||||
|
|
||||||
|
Q_INVOKABLE void setNewSource(const QString &newSource);
|
||||||
|
|
||||||
|
Q_INVOKABLE virtual void update();
|
||||||
|
|
||||||
|
Q_INVOKABLE void jumpToCode();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void actionTypeChanged();
|
||||||
|
void hasConditionChanged();
|
||||||
|
void hasElseChanged();
|
||||||
|
void sourceChanged();
|
||||||
|
void popupShouldClose();
|
||||||
|
void popupShouldOpen();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool blockReflection() const;
|
||||||
|
;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual AbstractProperty getSourceProperty() const;
|
||||||
|
virtual void setPropertySource(const QString &source);
|
||||||
|
|
||||||
|
BindingProperty getBindingProperty() const;
|
||||||
|
void handleException();
|
||||||
|
bool hasCondition() const;
|
||||||
|
bool hasElse() const;
|
||||||
|
void setHasCondition(bool b);
|
||||||
|
void setHasElse(bool b);
|
||||||
|
ActionType actionType() const;
|
||||||
|
StatementDelegate *okStatement();
|
||||||
|
StatementDelegate *koStatement();
|
||||||
|
ConditionListModel *conditionListModel();
|
||||||
|
QString indentedSource() const;
|
||||||
|
QString source() const;
|
||||||
|
void setSource(const QString &source);
|
||||||
|
|
||||||
|
PropertyTreeModel *propertyTreeModel();
|
||||||
|
PropertyListProxyModel *propertyListProxyModel();
|
||||||
|
|
||||||
|
void setupCondition();
|
||||||
|
void setupHandlerAndStatements();
|
||||||
|
|
||||||
|
void handleOkStatementChanged();
|
||||||
|
void handleKOStatementChanged();
|
||||||
|
void handleConditionChanged();
|
||||||
|
|
||||||
|
void commitNewSource(const QString &source);
|
||||||
|
|
||||||
|
ActionType m_actionType;
|
||||||
|
QString m_exceptionError;
|
||||||
|
ScriptEditorStatements::Handler m_handler;
|
||||||
|
StatementDelegate m_okStatementDelegate;
|
||||||
|
StatementDelegate m_koStatementDelegate;
|
||||||
|
ConditionListModel m_conditionListModel;
|
||||||
|
bool m_hasCondition = false;
|
||||||
|
bool m_hasElse = false;
|
||||||
|
QString m_source;
|
||||||
|
PropertyTreeModel m_propertyTreeModel;
|
||||||
|
PropertyListProxyModel m_propertyListProxyModel;
|
||||||
|
bool m_blockReflection = false;
|
||||||
|
QPointer<AbstractView> m_view = nullptr;
|
||||||
|
};
|
||||||
|
} // namespace QmlDesigner
|
@@ -1,10 +1,10 @@
|
|||||||
// Copyright (C) 2023 The Qt Company Ltd.
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
#include "connectioneditorevaluator.h"
|
#include "scripteditorevaluator.h"
|
||||||
#include "connectioneditorutils.h"
|
|
||||||
#include "qmljs/parser/qmljsast_p.h"
|
#include "qmljs/parser/qmljsast_p.h"
|
||||||
#include "qmljs/qmljsdocument.h"
|
#include "qmljs/qmljsdocument.h"
|
||||||
|
#include "scripteditorutils.h"
|
||||||
|
|
||||||
#include <utils/ranges.h>
|
#include <utils/ranges.h>
|
||||||
|
|
||||||
@@ -14,10 +14,10 @@ using namespace QmlDesigner;
|
|||||||
|
|
||||||
using QmlJS::AST::Node;
|
using QmlJS::AST::Node;
|
||||||
using Kind = Node::Kind;
|
using Kind = Node::Kind;
|
||||||
using ConnectionEditorStatements::ConditionalStatement;
|
using ScriptEditorStatements::ConditionalStatement;
|
||||||
using ConnectionEditorStatements::ConditionToken;
|
using ScriptEditorStatements::ConditionToken;
|
||||||
using ConnectionEditorStatements::MatchedCondition;
|
using ScriptEditorStatements::MatchedCondition;
|
||||||
using ConnectionEditorStatements::MatchedStatement;
|
using ScriptEditorStatements::MatchedStatement;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
enum class TrackingArea { No, Condition, Ok, Ko };
|
enum class TrackingArea { No, Condition, Ok, Ko };
|
||||||
@@ -255,14 +255,14 @@ protected:
|
|||||||
void throwRecursionDepthError() override
|
void throwRecursionDepthError() override
|
||||||
{
|
{
|
||||||
checkValidityAndReturn(false, "Recursion depth problem");
|
checkValidityAndReturn(false, "Recursion depth problem");
|
||||||
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "Recursion depth error";
|
qCWarning(ScriptEditorLog) << __FUNCTION__ << "Recursion depth error";
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkAndResetVariable()
|
void checkAndResetVariable()
|
||||||
{
|
{
|
||||||
if (--m_depth == 0) {
|
if (--m_depth == 0) {
|
||||||
m_condition.statements.push_back(
|
m_condition.statements.push_back(
|
||||||
ConnectionEditorStatements::Variable{m_identifier, m_fields.join(".")});
|
ScriptEditorStatements::Variable{m_identifier, m_fields.join(".")});
|
||||||
m_identifier.clear();
|
m_identifier.clear();
|
||||||
m_fields.clear();
|
m_fields.clear();
|
||||||
}
|
}
|
||||||
@@ -300,7 +300,7 @@ private:
|
|||||||
class RightHandVisitor : public QmlJS::AST::Visitor
|
class RightHandVisitor : public QmlJS::AST::Visitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConnectionEditorStatements::RightHandSide rhs() const { return m_rhs; }
|
ScriptEditorStatements::RightHandSide rhs() const { return m_rhs; }
|
||||||
|
|
||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
@@ -318,48 +318,48 @@ public:
|
|||||||
if (!isValid())
|
if (!isValid())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return ConnectionEditorStatements::isLiteralType(rhs());
|
return ScriptEditorStatements::isLiteralType(rhs());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool couldBeLHS() const
|
bool couldBeLHS() const
|
||||||
{
|
{
|
||||||
if (!isValid())
|
if (!isValid())
|
||||||
return false;
|
return false;
|
||||||
return std::holds_alternative<ConnectionEditorStatements::Variable>(m_rhs);
|
return std::holds_alternative<ScriptEditorStatements::Variable>(m_rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool couldBeVariable() const { return couldBeLHS(); }
|
inline bool couldBeVariable() const { return couldBeLHS(); }
|
||||||
|
|
||||||
ConnectionEditorStatements::Literal literal() const
|
ScriptEditorStatements::Literal literal() const
|
||||||
{
|
{
|
||||||
if (!isLiteralType())
|
if (!isLiteralType())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
return std::visit(
|
return std::visit(
|
||||||
Overload{[](const bool &var) -> ConnectionEditorStatements::Literal { return var; },
|
Overload{[](const bool &var) -> ScriptEditorStatements::Literal { return var; },
|
||||||
[](const double &var) -> ConnectionEditorStatements::Literal { return var; },
|
[](const double &var) -> ScriptEditorStatements::Literal { return var; },
|
||||||
[](const QString &var) -> ConnectionEditorStatements::Literal { return var; },
|
[](const QString &var) -> ScriptEditorStatements::Literal { return var; },
|
||||||
[](const auto &) -> ConnectionEditorStatements::Literal { return false; }},
|
[](const auto &) -> ScriptEditorStatements::Literal { return false; }},
|
||||||
m_rhs);
|
m_rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionEditorStatements::Variable lhs() const
|
ScriptEditorStatements::Variable lhs() const
|
||||||
{
|
{
|
||||||
if (!isValid())
|
if (!isValid())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
if (auto rhs = std::get_if<ConnectionEditorStatements::Variable>(&m_rhs))
|
if (auto rhs = std::get_if<ScriptEditorStatements::Variable>(&m_rhs))
|
||||||
return *rhs;
|
return *rhs;
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionEditorStatements::Variable variable() const
|
ScriptEditorStatements::Variable variable() const
|
||||||
{
|
{
|
||||||
if (!isValid())
|
if (!isValid())
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
if (auto rhs = std::get_if<ConnectionEditorStatements::Variable>(&m_rhs))
|
if (auto rhs = std::get_if<ScriptEditorStatements::Variable>(&m_rhs))
|
||||||
return *rhs;
|
return *rhs;
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
@@ -478,13 +478,13 @@ protected:
|
|||||||
void throwRecursionDepthError() override
|
void throwRecursionDepthError() override
|
||||||
{
|
{
|
||||||
setFailed();
|
setFailed();
|
||||||
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "Recursion depth error";
|
qCWarning(ScriptEditorLog) << __FUNCTION__ << "Recursion depth error";
|
||||||
}
|
}
|
||||||
|
|
||||||
void checkAndResetCal()
|
void checkAndResetCal()
|
||||||
{
|
{
|
||||||
if (--m_depth == 0) {
|
if (--m_depth == 0) {
|
||||||
m_rhs = ConnectionEditorStatements::MatchedFunction{m_identifier, m_fields.join(".")};
|
m_rhs = ScriptEditorStatements::MatchedFunction{m_identifier, m_fields.join(".")};
|
||||||
m_specified = true;
|
m_specified = true;
|
||||||
|
|
||||||
m_identifier.clear();
|
m_identifier.clear();
|
||||||
@@ -495,7 +495,7 @@ protected:
|
|||||||
void checkAndResetNonCal()
|
void checkAndResetNonCal()
|
||||||
{
|
{
|
||||||
if (--m_depth == 0) {
|
if (--m_depth == 0) {
|
||||||
m_rhs = ConnectionEditorStatements::Variable{m_identifier, m_fields.join(".")};
|
m_rhs = ScriptEditorStatements::Variable{m_identifier, m_fields.join(".")};
|
||||||
m_specified = true;
|
m_specified = true;
|
||||||
|
|
||||||
m_identifier.clear();
|
m_identifier.clear();
|
||||||
@@ -513,18 +513,19 @@ private:
|
|||||||
int m_depth = 0;
|
int m_depth = 0;
|
||||||
QString m_identifier;
|
QString m_identifier;
|
||||||
QStringList m_fields;
|
QStringList m_fields;
|
||||||
ConnectionEditorStatements::RightHandSide m_rhs;
|
ScriptEditorStatements::RightHandSide m_rhs;
|
||||||
};
|
};
|
||||||
|
|
||||||
MatchedStatement checkForStateSet(const MatchedStatement ¤tState)
|
MatchedStatement checkForStateSet(const MatchedStatement ¤tState)
|
||||||
{
|
{
|
||||||
using namespace ConnectionEditorStatements;
|
using namespace ScriptEditorStatements;
|
||||||
return std::visit(
|
return std::visit(Overload{[](const PropertySet &propertySet) -> MatchedStatement {
|
||||||
Overload{[](const PropertySet &propertySet) -> MatchedStatement {
|
if (propertySet.lhs.nodeId.size()
|
||||||
if (propertySet.lhs.nodeId.size() && propertySet.lhs.propertyName == u"state"
|
&& propertySet.lhs.propertyName == u"state"
|
||||||
&& std::holds_alternative<QString>(propertySet.rhs))
|
&& std::holds_alternative<QString>(propertySet.rhs))
|
||||||
return StateSet{propertySet.lhs.nodeId,
|
return StateSet{propertySet.lhs.nodeId,
|
||||||
ConnectionEditorStatements::toString(propertySet.rhs)};
|
ScriptEditorStatements::toString(
|
||||||
|
propertySet.rhs)};
|
||||||
return propertySet;
|
return propertySet;
|
||||||
},
|
},
|
||||||
[](const auto &pSet) -> MatchedStatement { return pSet; }},
|
[](const auto &pSet) -> MatchedStatement { return pSet; }},
|
||||||
@@ -536,9 +537,9 @@ class ConsoleLogEvaluator : public QmlJS::AST::Visitor
|
|||||||
public:
|
public:
|
||||||
bool isValid() { return m_completed; }
|
bool isValid() { return m_completed; }
|
||||||
|
|
||||||
ConnectionEditorStatements::ConsoleLog expression()
|
ScriptEditorStatements::ConsoleLog expression()
|
||||||
{
|
{
|
||||||
return ConnectionEditorStatements::ConsoleLog{m_arg};
|
return ScriptEditorStatements::ConsoleLog{m_arg};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -618,14 +619,14 @@ protected:
|
|||||||
void throwRecursionDepthError() override
|
void throwRecursionDepthError() override
|
||||||
{
|
{
|
||||||
m_failed = true;
|
m_failed = true;
|
||||||
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "Recursion depth error";
|
qCWarning(ScriptEditorLog) << __FUNCTION__ << "Recursion depth error";
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_failed = false;
|
bool m_failed = false;
|
||||||
bool m_completed = false;
|
bool m_completed = false;
|
||||||
int m_stepId = 0;
|
int m_stepId = 0;
|
||||||
ConnectionEditorStatements::RightHandSide m_arg;
|
ScriptEditorStatements::RightHandSide m_arg;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StatementReply
|
struct StatementReply
|
||||||
@@ -650,10 +651,10 @@ struct StatementReply
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class QmlDesigner::ConnectionEditorEvaluatorPrivate
|
class QmlDesigner::ScriptEditorEvaluatorPrivate
|
||||||
{
|
{
|
||||||
friend class ConnectionEditorEvaluator;
|
friend class ScriptEditorEvaluator;
|
||||||
using Status = ConnectionEditorEvaluator::Status;
|
using Status = ScriptEditorEvaluator::Status;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool checkValidityAndReturn(bool valid, const QString &parseError = {});
|
bool checkValidityAndReturn(bool valid, const QString &parseError = {});
|
||||||
@@ -731,28 +732,28 @@ private:
|
|||||||
QString m_errorString;
|
QString m_errorString;
|
||||||
Status m_checkStatus = Status::UnStarted;
|
Status m_checkStatus = Status::UnStarted;
|
||||||
QList<NodeStatus> m_nodeHierarchy;
|
QList<NodeStatus> m_nodeHierarchy;
|
||||||
ConnectionEditorStatements::Handler m_handler;
|
ScriptEditorStatements::Handler m_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
ConnectionEditorEvaluator::ConnectionEditorEvaluator()
|
ScriptEditorEvaluator::ScriptEditorEvaluator()
|
||||||
: d(std::make_unique<ConnectionEditorEvaluatorPrivate>())
|
: d(std::make_unique<ScriptEditorEvaluatorPrivate>())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ConnectionEditorEvaluator::~ConnectionEditorEvaluator() {}
|
ScriptEditorEvaluator::~ScriptEditorEvaluator() {}
|
||||||
|
|
||||||
ConnectionEditorEvaluator::Status ConnectionEditorEvaluator::status() const
|
ScriptEditorEvaluator::Status ScriptEditorEvaluator::status() const
|
||||||
{
|
{
|
||||||
return d->m_checkStatus;
|
return d->m_checkStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionEditorStatements::Handler ConnectionEditorEvaluator::resultNode() const
|
ScriptEditorStatements::Handler ScriptEditorEvaluator::resultNode() const
|
||||||
{
|
{
|
||||||
return (d->m_checkStatus == Succeeded) ? d->m_handler : ConnectionEditorStatements::EmptyBlock{};
|
return (d->m_checkStatus == Succeeded) ? d->m_handler : ScriptEditorStatements::EmptyBlock{};
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ConnectionEditorEvaluator::getDisplayStringForType(const QString &statement)
|
QString ScriptEditorEvaluator::getDisplayStringForType(const QString &statement)
|
||||||
{
|
{
|
||||||
ConnectionEditorEvaluator evaluator;
|
ScriptEditorEvaluator evaluator;
|
||||||
QmlJS::Document::MutablePtr newDoc = QmlJS::Document::create(Utils::FilePath::fromString(
|
QmlJS::Document::MutablePtr newDoc = QmlJS::Document::create(Utils::FilePath::fromString(
|
||||||
"<expression>"),
|
"<expression>"),
|
||||||
QmlJS::Dialect::JavaScript);
|
QmlJS::Dialect::JavaScript);
|
||||||
@@ -761,23 +762,23 @@ QString ConnectionEditorEvaluator::getDisplayStringForType(const QString &statem
|
|||||||
newDoc->parseJavaScript();
|
newDoc->parseJavaScript();
|
||||||
|
|
||||||
if (!newDoc->isParsedCorrectly())
|
if (!newDoc->isParsedCorrectly())
|
||||||
return ConnectionEditorStatements::CUSTOM_DISPLAY_NAME;
|
return ScriptEditorStatements::CUSTOM_DISPLAY_NAME;
|
||||||
|
|
||||||
newDoc->ast()->accept(&evaluator);
|
newDoc->ast()->accept(&evaluator);
|
||||||
|
|
||||||
const bool valid = evaluator.status() == ConnectionEditorEvaluator::Succeeded;
|
const bool valid = evaluator.status() == ScriptEditorEvaluator::Succeeded;
|
||||||
|
|
||||||
if (!valid)
|
if (!valid)
|
||||||
return ConnectionEditorStatements::CUSTOM_DISPLAY_NAME;
|
return ScriptEditorStatements::CUSTOM_DISPLAY_NAME;
|
||||||
|
|
||||||
auto result = evaluator.resultNode();
|
auto result = evaluator.resultNode();
|
||||||
|
|
||||||
return QmlDesigner::ConnectionEditorStatements::toDisplayName(result);
|
return QmlDesigner::ScriptEditorStatements::toDisplayName(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConnectionEditorStatements::Handler ConnectionEditorEvaluator::parseStatement(const QString &statement)
|
ScriptEditorStatements::Handler ScriptEditorEvaluator::parseStatement(const QString &statement)
|
||||||
{
|
{
|
||||||
ConnectionEditorEvaluator evaluator;
|
ScriptEditorEvaluator evaluator;
|
||||||
QmlJS::Document::MutablePtr newDoc = QmlJS::Document::create(Utils::FilePath::fromString(
|
QmlJS::Document::MutablePtr newDoc = QmlJS::Document::create(Utils::FilePath::fromString(
|
||||||
"<expression>"),
|
"<expression>"),
|
||||||
QmlJS::Dialect::JavaScript);
|
QmlJS::Dialect::JavaScript);
|
||||||
@@ -786,19 +787,19 @@ ConnectionEditorStatements::Handler ConnectionEditorEvaluator::parseStatement(co
|
|||||||
newDoc->parseJavaScript();
|
newDoc->parseJavaScript();
|
||||||
|
|
||||||
if (!newDoc->isParsedCorrectly())
|
if (!newDoc->isParsedCorrectly())
|
||||||
return ConnectionEditorStatements::EmptyBlock{};
|
return ScriptEditorStatements::EmptyBlock{};
|
||||||
|
|
||||||
newDoc->ast()->accept(&evaluator);
|
newDoc->ast()->accept(&evaluator);
|
||||||
|
|
||||||
const bool valid = evaluator.status() == ConnectionEditorEvaluator::Succeeded;
|
const bool valid = evaluator.status() == ScriptEditorEvaluator::Succeeded;
|
||||||
|
|
||||||
if (!valid)
|
if (!valid)
|
||||||
return ConnectionEditorStatements::EmptyBlock{};
|
return ScriptEditorStatements::EmptyBlock{};
|
||||||
|
|
||||||
return evaluator.resultNode();
|
return evaluator.resultNode();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectionEditorEvaluator::preVisit(Node *node)
|
bool ScriptEditorEvaluator::preVisit(Node *node)
|
||||||
{
|
{
|
||||||
if (d->m_nodeHierarchy.size()) {
|
if (d->m_nodeHierarchy.size()) {
|
||||||
NodeStatus &parentNode = d->m_nodeHierarchy.last();
|
NodeStatus &parentNode = d->m_nodeHierarchy.last();
|
||||||
@@ -832,7 +833,7 @@ bool ConnectionEditorEvaluator::preVisit(Node *node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionEditorEvaluator::postVisit(QmlJS::AST::Node *node)
|
void ScriptEditorEvaluator::postVisit(QmlJS::AST::Node *node)
|
||||||
{
|
{
|
||||||
if (d->m_nodeHierarchy.isEmpty()) {
|
if (d->m_nodeHierarchy.isEmpty()) {
|
||||||
d->checkValidityAndReturn(false, "Unexpected post visiting");
|
d->checkValidityAndReturn(false, "Unexpected post visiting");
|
||||||
@@ -859,18 +860,18 @@ void ConnectionEditorEvaluator::postVisit(QmlJS::AST::Node *node)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectionEditorEvaluator::visit([[maybe_unused]] QmlJS::AST::Program *program)
|
bool ScriptEditorEvaluator::visit([[maybe_unused]] QmlJS::AST::Program *program)
|
||||||
{
|
{
|
||||||
d->setStatus(UnFinished);
|
d->setStatus(UnFinished);
|
||||||
d->setTrackingArea(false, 0);
|
d->setTrackingArea(false, 0);
|
||||||
d->m_ifStatement = 0;
|
d->m_ifStatement = 0;
|
||||||
d->m_consoleLogCount = 0;
|
d->m_consoleLogCount = 0;
|
||||||
d->m_consoleIdentifierCount = 0;
|
d->m_consoleIdentifierCount = 0;
|
||||||
d->m_handler = ConnectionEditorStatements::EmptyBlock{};
|
d->m_handler = ScriptEditorStatements::EmptyBlock{};
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectionEditorEvaluator::visit([[maybe_unused]] QmlJS::AST::IfStatement *ifStatement)
|
bool ScriptEditorEvaluator::visit([[maybe_unused]] QmlJS::AST::IfStatement *ifStatement)
|
||||||
{
|
{
|
||||||
if (d->m_ifStatement++)
|
if (d->m_ifStatement++)
|
||||||
return d->checkValidityAndReturn(false, "Nested if conditions are not supported");
|
return d->checkValidityAndReturn(false, "Nested if conditions are not supported");
|
||||||
@@ -885,7 +886,7 @@ bool ConnectionEditorEvaluator::visit([[maybe_unused]] QmlJS::AST::IfStatement *
|
|||||||
return d->checkValidityAndReturn(true);
|
return d->checkValidityAndReturn(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectionEditorEvaluator::visit(QmlJS::AST::IdentifierExpression *identifier)
|
bool ScriptEditorEvaluator::visit(QmlJS::AST::IdentifierExpression *identifier)
|
||||||
{
|
{
|
||||||
if (d->parentNodeStatus() == Kind::Kind_FieldMemberExpression)
|
if (d->parentNodeStatus() == Kind::Kind_FieldMemberExpression)
|
||||||
if (d->m_consoleLogCount)
|
if (d->m_consoleLogCount)
|
||||||
@@ -896,7 +897,7 @@ bool ConnectionEditorEvaluator::visit(QmlJS::AST::IdentifierExpression *identifi
|
|||||||
return d->checkValidityAndReturn(true);
|
return d->checkValidityAndReturn(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectionEditorEvaluator::visit(QmlJS::AST::BinaryExpression *binaryExpression)
|
bool ScriptEditorEvaluator::visit(QmlJS::AST::BinaryExpression *binaryExpression)
|
||||||
{
|
{
|
||||||
if (d->isInIfCondition()) {
|
if (d->isInIfCondition()) {
|
||||||
if (binaryExpression->op == QSOperator::Assign)
|
if (binaryExpression->op == QSOperator::Assign)
|
||||||
@@ -923,7 +924,7 @@ bool ConnectionEditorEvaluator::visit(QmlJS::AST::BinaryExpression *binaryExpres
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
MatchedStatement *currentStatement = d->currentStatement();
|
MatchedStatement *currentStatement = d->currentStatement();
|
||||||
if (currentStatement && ConnectionEditorStatements::isEmptyStatement(*currentStatement)
|
if (currentStatement && ScriptEditorStatements::isEmptyStatement(*currentStatement)
|
||||||
&& d->parentNodeStatus().childId() == 0) {
|
&& d->parentNodeStatus().childId() == 0) {
|
||||||
if (binaryExpression->op == QSOperator::Assign) {
|
if (binaryExpression->op == QSOperator::Assign) {
|
||||||
RightHandVisitor variableVisitor;
|
RightHandVisitor variableVisitor;
|
||||||
@@ -932,16 +933,16 @@ bool ConnectionEditorEvaluator::visit(QmlJS::AST::BinaryExpression *binaryExpres
|
|||||||
if (!variableVisitor.couldBeLHS())
|
if (!variableVisitor.couldBeLHS())
|
||||||
return d->checkValidityAndReturn(false, "Invalid left hand.");
|
return d->checkValidityAndReturn(false, "Invalid left hand.");
|
||||||
|
|
||||||
ConnectionEditorStatements::Variable lhs = variableVisitor.lhs();
|
ScriptEditorStatements::Variable lhs = variableVisitor.lhs();
|
||||||
|
|
||||||
variableVisitor.reset();
|
variableVisitor.reset();
|
||||||
binaryExpression->right->accept(&variableVisitor);
|
binaryExpression->right->accept(&variableVisitor);
|
||||||
|
|
||||||
if (variableVisitor.couldBeLHS()) {
|
if (variableVisitor.couldBeLHS()) {
|
||||||
ConnectionEditorStatements::Assignment assignment{lhs, variableVisitor.variable()};
|
ScriptEditorStatements::Assignment assignment{lhs, variableVisitor.variable()};
|
||||||
*currentStatement = assignment;
|
*currentStatement = assignment;
|
||||||
} else if (variableVisitor.isLiteralType()) {
|
} else if (variableVisitor.isLiteralType()) {
|
||||||
ConnectionEditorStatements::PropertySet propSet{lhs, variableVisitor.literal()};
|
ScriptEditorStatements::PropertySet propSet{lhs, variableVisitor.literal()};
|
||||||
*currentStatement = propSet;
|
*currentStatement = propSet;
|
||||||
} else {
|
} else {
|
||||||
return d->checkValidityAndReturn(false, "Invalid RHS");
|
return d->checkValidityAndReturn(false, "Invalid RHS");
|
||||||
@@ -955,7 +956,7 @@ bool ConnectionEditorEvaluator::visit(QmlJS::AST::BinaryExpression *binaryExpres
|
|||||||
return d->checkValidityAndReturn(true);
|
return d->checkValidityAndReturn(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectionEditorEvaluator::visit(QmlJS::AST::FieldMemberExpression *fieldExpression)
|
bool ScriptEditorEvaluator::visit(QmlJS::AST::FieldMemberExpression *fieldExpression)
|
||||||
{
|
{
|
||||||
if (d->parentNodeStatus() == Kind::Kind_CallExpression && fieldExpression->name == u"log")
|
if (d->parentNodeStatus() == Kind::Kind_CallExpression && fieldExpression->name == u"log")
|
||||||
d->m_consoleLogCount++;
|
d->m_consoleLogCount++;
|
||||||
@@ -965,7 +966,7 @@ bool ConnectionEditorEvaluator::visit(QmlJS::AST::FieldMemberExpression *fieldEx
|
|||||||
return d->checkValidityAndReturn(true);
|
return d->checkValidityAndReturn(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectionEditorEvaluator::visit(QmlJS::AST::CallExpression *callExpression)
|
bool ScriptEditorEvaluator::visit(QmlJS::AST::CallExpression *callExpression)
|
||||||
{
|
{
|
||||||
if (d->isInIfCondition())
|
if (d->isInIfCondition())
|
||||||
return d->checkValidityAndReturn(false, "Functions are not allowd in the expressions");
|
return d->checkValidityAndReturn(false, "Functions are not allowd in the expressions");
|
||||||
@@ -974,7 +975,7 @@ bool ConnectionEditorEvaluator::visit(QmlJS::AST::CallExpression *callExpression
|
|||||||
if (!currentStatement)
|
if (!currentStatement)
|
||||||
return d->checkValidityAndReturn(false, "Invalid place to call an expression");
|
return d->checkValidityAndReturn(false, "Invalid place to call an expression");
|
||||||
|
|
||||||
if (ConnectionEditorStatements::isEmptyStatement(*currentStatement)) {
|
if (ScriptEditorStatements::isEmptyStatement(*currentStatement)) {
|
||||||
if (d->parentNodeStatus().childId() == 0) {
|
if (d->parentNodeStatus().childId() == 0) {
|
||||||
ConsoleLogEvaluator logEvaluator;
|
ConsoleLogEvaluator logEvaluator;
|
||||||
callExpression->accept(&logEvaluator);
|
callExpression->accept(&logEvaluator);
|
||||||
@@ -985,8 +986,8 @@ bool ConnectionEditorEvaluator::visit(QmlJS::AST::CallExpression *callExpression
|
|||||||
|
|
||||||
callExpression->accept(&callVisitor);
|
callExpression->accept(&callVisitor);
|
||||||
if (callVisitor.isValid()) {
|
if (callVisitor.isValid()) {
|
||||||
ConnectionEditorStatements::RightHandSide rhs = callVisitor.rhs();
|
ScriptEditorStatements::RightHandSide rhs = callVisitor.rhs();
|
||||||
if (auto rhs_ = std::get_if<ConnectionEditorStatements::MatchedFunction>(&rhs))
|
if (auto rhs_ = std::get_if<ScriptEditorStatements::MatchedFunction>(&rhs))
|
||||||
*currentStatement = *rhs_;
|
*currentStatement = *rhs_;
|
||||||
else
|
else
|
||||||
return d->checkValidityAndReturn(false, "Invalid Matched Function type.");
|
return d->checkValidityAndReturn(false, "Invalid Matched Function type.");
|
||||||
@@ -999,7 +1000,7 @@ bool ConnectionEditorEvaluator::visit(QmlJS::AST::CallExpression *callExpression
|
|||||||
return d->checkValidityAndReturn(true);
|
return d->checkValidityAndReturn(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectionEditorEvaluator::visit([[maybe_unused]] QmlJS::AST::Block *block)
|
bool ScriptEditorEvaluator::visit([[maybe_unused]] QmlJS::AST::Block *block)
|
||||||
{
|
{
|
||||||
Kind parentKind = d->parentNodeStatus();
|
Kind parentKind = d->parentNodeStatus();
|
||||||
|
|
||||||
@@ -1013,7 +1014,7 @@ bool ConnectionEditorEvaluator::visit([[maybe_unused]] QmlJS::AST::Block *block)
|
|||||||
return d->checkValidityAndReturn(false, "Block count ptoblem");
|
return d->checkValidityAndReturn(false, "Block count ptoblem");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectionEditorEvaluator::visit(QmlJS::AST::ArgumentList *arguments)
|
bool ScriptEditorEvaluator::visit(QmlJS::AST::ArgumentList *arguments)
|
||||||
{
|
{
|
||||||
if (d->trackingArea() == TrackingArea::Condition)
|
if (d->trackingArea() == TrackingArea::Condition)
|
||||||
return d->checkValidityAndReturn(false, "Arguments are not supported in if condition");
|
return d->checkValidityAndReturn(false, "Arguments are not supported in if condition");
|
||||||
@@ -1022,7 +1023,7 @@ bool ConnectionEditorEvaluator::visit(QmlJS::AST::ArgumentList *arguments)
|
|||||||
if (!currentStatement)
|
if (!currentStatement)
|
||||||
return d->checkValidityAndReturn(false, "No statement found for argument");
|
return d->checkValidityAndReturn(false, "No statement found for argument");
|
||||||
|
|
||||||
if (!ConnectionEditorStatements::isConsoleLog(*currentStatement))
|
if (!ScriptEditorStatements::isConsoleLog(*currentStatement))
|
||||||
return d->checkValidityAndReturn(false, "Arguments are only supported for console.log");
|
return d->checkValidityAndReturn(false, "Arguments are only supported for console.log");
|
||||||
|
|
||||||
if (d->m_acceptLogArgument && !arguments->next)
|
if (d->m_acceptLogArgument && !arguments->next)
|
||||||
@@ -1031,13 +1032,13 @@ bool ConnectionEditorEvaluator::visit(QmlJS::AST::ArgumentList *arguments)
|
|||||||
return d->checkValidityAndReturn(false, "The only supported argument is in console.log");
|
return d->checkValidityAndReturn(false, "The only supported argument is in console.log");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionEditorEvaluator::endVisit([[maybe_unused]] QmlJS::AST::Program *program)
|
void ScriptEditorEvaluator::endVisit([[maybe_unused]] QmlJS::AST::Program *program)
|
||||||
{
|
{
|
||||||
if (status() == UnFinished)
|
if (status() == UnFinished)
|
||||||
d->setStatus(Succeeded);
|
d->setStatus(Succeeded);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionEditorEvaluator::endVisit(QmlJS::AST::FieldMemberExpression *fieldExpression)
|
void ScriptEditorEvaluator::endVisit(QmlJS::AST::FieldMemberExpression *fieldExpression)
|
||||||
{
|
{
|
||||||
if (status() != UnFinished)
|
if (status() != UnFinished)
|
||||||
return;
|
return;
|
||||||
@@ -1053,12 +1054,12 @@ void ConnectionEditorEvaluator::endVisit(QmlJS::AST::FieldMemberExpression *fiel
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionEditorEvaluator::endVisit([[maybe_unused]] QmlJS::AST::CallExpression *callExpression)
|
void ScriptEditorEvaluator::endVisit([[maybe_unused]] QmlJS::AST::CallExpression *callExpression)
|
||||||
{
|
{
|
||||||
d->m_acceptLogArgument = false;
|
d->m_acceptLogArgument = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionEditorEvaluator::endVisit(QmlJS::AST::IfStatement * /*ifStatement*/)
|
void ScriptEditorEvaluator::endVisit(QmlJS::AST::IfStatement * /*ifStatement*/)
|
||||||
{
|
{
|
||||||
if (status() != UnFinished)
|
if (status() != UnFinished)
|
||||||
return;
|
return;
|
||||||
@@ -1071,7 +1072,7 @@ void ConnectionEditorEvaluator::endVisit(QmlJS::AST::IfStatement * /*ifStatement
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionEditorEvaluator::endVisit(QmlJS::AST::StatementList * /*statementList*/)
|
void ScriptEditorEvaluator::endVisit(QmlJS::AST::StatementList * /*statementList*/)
|
||||||
{
|
{
|
||||||
if (status() != UnFinished)
|
if (status() != UnFinished)
|
||||||
return;
|
return;
|
||||||
@@ -1080,26 +1081,26 @@ void ConnectionEditorEvaluator::endVisit(QmlJS::AST::StatementList * /*statement
|
|||||||
d->checkValidityAndReturn(false, "More than one statements are available.");
|
d->checkValidityAndReturn(false, "More than one statements are available.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConnectionEditorEvaluator::throwRecursionDepthError()
|
void ScriptEditorEvaluator::throwRecursionDepthError()
|
||||||
{
|
{
|
||||||
d->checkValidityAndReturn(false, "Recursion depth problem");
|
d->checkValidityAndReturn(false, "Recursion depth problem");
|
||||||
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "Recursion depth error";
|
qCWarning(ScriptEditorLog) << __FUNCTION__ << "Recursion depth error";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectionEditorEvaluatorPrivate::checkValidityAndReturn(bool valid, const QString &parseError)
|
bool ScriptEditorEvaluatorPrivate::checkValidityAndReturn(bool valid, const QString &parseError)
|
||||||
{
|
{
|
||||||
if (!valid) {
|
if (!valid) {
|
||||||
if (m_checkStatus != Status::Failed) {
|
if (m_checkStatus != Status::Failed) {
|
||||||
setStatus(Status::Failed);
|
setStatus(Status::Failed);
|
||||||
m_errorString = parseError;
|
m_errorString = parseError;
|
||||||
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "Parse error" << parseError;
|
qCWarning(ScriptEditorLog) << __FUNCTION__ << "Parse error" << parseError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return m_checkStatus;
|
return m_checkStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeStatus ConnectionEditorEvaluatorPrivate::nodeStatus(int reverseLevel) const
|
NodeStatus ScriptEditorEvaluatorPrivate::nodeStatus(int reverseLevel) const
|
||||||
{
|
{
|
||||||
if (m_nodeHierarchy.size() > reverseLevel)
|
if (m_nodeHierarchy.size() > reverseLevel)
|
||||||
return m_nodeHierarchy.at(m_nodeHierarchy.size() - reverseLevel - 1);
|
return m_nodeHierarchy.at(m_nodeHierarchy.size() - reverseLevel - 1);
|
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "connectioneditorstatements.h"
|
#include "scripteditorstatements.h"
|
||||||
|
|
||||||
#include "qmldesigner_global.h"
|
#include "qmldesigner_global.h"
|
||||||
|
|
||||||
@@ -11,21 +11,21 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
class ConnectionEditorEvaluatorPrivate;
|
class ScriptEditorEvaluatorPrivate;
|
||||||
|
|
||||||
class QMLDESIGNER_EXPORT ConnectionEditorEvaluator : public QmlJS::AST::Visitor
|
class QMLDESIGNER_EXPORT ScriptEditorEvaluator : public QmlJS::AST::Visitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Status { UnStarted, UnFinished, Succeeded, Failed };
|
enum Status { UnStarted, UnFinished, Succeeded, Failed };
|
||||||
|
|
||||||
ConnectionEditorEvaluator();
|
ScriptEditorEvaluator();
|
||||||
virtual ~ConnectionEditorEvaluator();
|
virtual ~ScriptEditorEvaluator();
|
||||||
|
|
||||||
Status status() const;
|
Status status() const;
|
||||||
ConnectionEditorStatements::Handler resultNode() const;
|
ScriptEditorStatements::Handler resultNode() const;
|
||||||
|
|
||||||
static QString getDisplayStringForType(const QString &statement);
|
static QString getDisplayStringForType(const QString &statement);
|
||||||
static ConnectionEditorStatements::Handler parseStatement(const QString &statement);
|
static ScriptEditorStatements::Handler parseStatement(const QString &statement);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool preVisit(QmlJS::AST::Node *node) override;
|
bool preVisit(QmlJS::AST::Node *node) override;
|
||||||
@@ -49,7 +49,7 @@ protected:
|
|||||||
void throwRecursionDepthError() override;
|
void throwRecursionDepthError() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<ConnectionEditorEvaluatorPrivate> d;
|
std::unique_ptr<ScriptEditorEvaluatorPrivate> d;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
@@ -1,11 +1,11 @@
|
|||||||
// Copyright (C) 2023 The Qt Company Ltd.
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
#include "connectioneditorstatements.h"
|
#include "scripteditorstatements.h"
|
||||||
|
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
|
||||||
using namespace QmlDesigner;
|
using namespace QmlDesigner;
|
||||||
using namespace ConnectionEditorStatements;
|
using namespace ScriptEditorStatements;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
template<typename... Ts>
|
template<typename... Ts>
|
||||||
@@ -39,31 +39,31 @@ struct StringVisitor
|
|||||||
return "Variable{" + var.nodeId + propertyName + "}";
|
return "Variable{" + var.nodeId + propertyName + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::MatchedFunction &func)
|
QString operator()(const ScriptEditorStatements::MatchedFunction &func)
|
||||||
{
|
{
|
||||||
return "MatchedFunction{" + func.nodeId + "." + func.functionName + "}";
|
return "MatchedFunction{" + func.nodeId + "." + func.functionName + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::Assignment &assignment)
|
QString operator()(const ScriptEditorStatements::Assignment &assignment)
|
||||||
{
|
{
|
||||||
return "Assignment{" + assignment.lhs.expression() + " = " + StringVisitor()(assignment.rhs)
|
return "Assignment{" + assignment.lhs.expression() + " = " + StringVisitor()(assignment.rhs)
|
||||||
+ "}";
|
+ "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::PropertySet &propertySet)
|
QString operator()(const ScriptEditorStatements::PropertySet &propertySet)
|
||||||
{
|
{
|
||||||
return "PropertySet{" + propertySet.lhs.expression() + " = "
|
return "PropertySet{" + propertySet.lhs.expression() + " = "
|
||||||
+ std::visit(StringVisitor{}, propertySet.rhs) + "}";
|
+ std::visit(StringVisitor{}, propertySet.rhs) + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::StateSet &stateSet)
|
QString operator()(const ScriptEditorStatements::StateSet &stateSet)
|
||||||
{
|
{
|
||||||
return "StateSet{" + stateSet.nodeId + ".state = " + stateSet.stateName + "}";
|
return "StateSet{" + stateSet.nodeId + ".state = " + stateSet.stateName + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::EmptyBlock &) { return "EmptyBlock{}"; }
|
QString operator()(const ScriptEditorStatements::EmptyBlock &) { return "EmptyBlock{}"; }
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::ConsoleLog &consoleLog)
|
QString operator()(const ScriptEditorStatements::ConsoleLog &consoleLog)
|
||||||
{
|
{
|
||||||
return "ConsoleLog{" + std::visit(StringVisitor{}, consoleLog.argument) + "}";
|
return "ConsoleLog{" + std::visit(StringVisitor{}, consoleLog.argument) + "}";
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ struct StringVisitor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::MatchedCondition &matched)
|
QString operator()(const ScriptEditorStatements::MatchedCondition &matched)
|
||||||
{
|
{
|
||||||
if (!matched.statements.size() && !matched.tokens.size())
|
if (!matched.statements.size() && !matched.tokens.size())
|
||||||
return "MatchedCondition{}";
|
return "MatchedCondition{}";
|
||||||
@@ -113,7 +113,7 @@ struct StringVisitor
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::ConditionalStatement &conditional)
|
QString operator()(const ScriptEditorStatements::ConditionalStatement &conditional)
|
||||||
{
|
{
|
||||||
QString value;
|
QString value;
|
||||||
value.reserve(200);
|
value.reserve(200);
|
||||||
@@ -130,7 +130,7 @@ struct StringVisitor
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::MatchedStatement &conditional)
|
QString operator()(const ScriptEditorStatements::MatchedStatement &conditional)
|
||||||
{
|
{
|
||||||
return std::visit(StringVisitor{}, conditional);
|
return std::visit(StringVisitor{}, conditional);
|
||||||
}
|
}
|
||||||
@@ -156,7 +156,7 @@ struct JSOverload
|
|||||||
return var.nodeId + propertyName;
|
return var.nodeId + propertyName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::MatchedFunction &func)
|
QString operator()(const ScriptEditorStatements::MatchedFunction &func)
|
||||||
{
|
{
|
||||||
QString funcName;
|
QString funcName;
|
||||||
if (func.functionName.size())
|
if (func.functionName.size())
|
||||||
@@ -165,31 +165,31 @@ struct JSOverload
|
|||||||
return func.nodeId + funcName + "()";
|
return func.nodeId + funcName + "()";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::Assignment &assignment)
|
QString operator()(const ScriptEditorStatements::Assignment &assignment)
|
||||||
{
|
{
|
||||||
return JSOverload()(assignment.lhs) + " = " + JSOverload()(assignment.rhs);
|
return JSOverload()(assignment.lhs) + " = " + JSOverload()(assignment.rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::PropertySet &propertySet)
|
QString operator()(const ScriptEditorStatements::PropertySet &propertySet)
|
||||||
{
|
{
|
||||||
return JSOverload()(propertySet.lhs) + " = " + std::visit(JSOverload{}, propertySet.rhs);
|
return JSOverload()(propertySet.lhs) + " = " + std::visit(JSOverload{}, propertySet.rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::StateSet &stateSet)
|
QString operator()(const ScriptEditorStatements::StateSet &stateSet)
|
||||||
{
|
{
|
||||||
return stateSet.nodeId + ".state = " + stateSet.stateName;
|
return stateSet.nodeId + ".state = " + stateSet.stateName;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::EmptyBlock &) { return "{}"; }
|
QString operator()(const ScriptEditorStatements::EmptyBlock &) { return "{}"; }
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::ConsoleLog &consoleLog)
|
QString operator()(const ScriptEditorStatements::ConsoleLog &consoleLog)
|
||||||
{
|
{
|
||||||
return "console.log(" + std::visit(JSOverload{}, consoleLog.argument) + ")";
|
return "console.log(" + std::visit(JSOverload{}, consoleLog.argument) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConditionToken &token) { return toJavascript(token); }
|
QString operator()(const ConditionToken &token) { return toJavascript(token); }
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::MatchedCondition &matched)
|
QString operator()(const ScriptEditorStatements::MatchedCondition &matched)
|
||||||
{
|
{
|
||||||
if (!matched.statements.size() && !matched.tokens.size())
|
if (!matched.statements.size() && !matched.tokens.size())
|
||||||
return {};
|
return {};
|
||||||
@@ -209,7 +209,7 @@ struct JSOverload
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::MatchedStatement &statement)
|
QString operator()(const ScriptEditorStatements::MatchedStatement &statement)
|
||||||
{
|
{
|
||||||
if (isEmptyStatement(statement))
|
if (isEmptyStatement(statement))
|
||||||
return {};
|
return {};
|
||||||
@@ -217,7 +217,7 @@ struct JSOverload
|
|||||||
return std::visit(JSOverload{}, statement);
|
return std::visit(JSOverload{}, statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString operator()(const ConnectionEditorStatements::ConditionalStatement &conditional)
|
QString operator()(const ScriptEditorStatements::ConditionalStatement &conditional)
|
||||||
{
|
{
|
||||||
QString value;
|
QString value;
|
||||||
value.reserve(200);
|
value.reserve(200);
|
||||||
@@ -240,47 +240,47 @@ struct JSOverload
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool ConnectionEditorStatements::isEmptyStatement(const MatchedStatement &stat)
|
bool ScriptEditorStatements::isEmptyStatement(const MatchedStatement &stat)
|
||||||
{
|
{
|
||||||
return std::holds_alternative<EmptyBlock>(stat);
|
return std::holds_alternative<EmptyBlock>(stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ConnectionEditorStatements::toString(const ComparativeStatement &stat)
|
QString ScriptEditorStatements::toString(const ComparativeStatement &stat)
|
||||||
{
|
{
|
||||||
return std::visit(StringVisitor{}, stat);
|
return std::visit(StringVisitor{}, stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ConnectionEditorStatements::toString(const RightHandSide &rhs)
|
QString ScriptEditorStatements::toString(const RightHandSide &rhs)
|
||||||
{
|
{
|
||||||
return std::visit(StringVisitor{}, rhs);
|
return std::visit(StringVisitor{}, rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ConnectionEditorStatements::toString(const Literal &literal)
|
QString ScriptEditorStatements::toString(const Literal &literal)
|
||||||
{
|
{
|
||||||
return std::visit(StringVisitor{}, literal);
|
return std::visit(StringVisitor{}, literal);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ConnectionEditorStatements::toString(const MatchedStatement &statement)
|
QString ScriptEditorStatements::toString(const MatchedStatement &statement)
|
||||||
{
|
{
|
||||||
return std::visit(StringVisitor{}, statement);
|
return std::visit(StringVisitor{}, statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ConnectionEditorStatements::toString(const Handler &handler)
|
QString ScriptEditorStatements::toString(const Handler &handler)
|
||||||
{
|
{
|
||||||
return std::visit(StringVisitor{}, handler);
|
return std::visit(StringVisitor{}, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ConnectionEditorStatements::toJavascript(const Handler &handler)
|
QString ScriptEditorStatements::toJavascript(const Handler &handler)
|
||||||
{
|
{
|
||||||
return std::visit(JSOverload{}, handler);
|
return std::visit(JSOverload{}, handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectionEditorStatements::isConsoleLog(const MatchedStatement &curState)
|
bool ScriptEditorStatements::isConsoleLog(const MatchedStatement &curState)
|
||||||
{
|
{
|
||||||
return std::holds_alternative<ConsoleLog>(curState);
|
return std::holds_alternative<ConsoleLog>(curState);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConnectionEditorStatements::isLiteralType(const RightHandSide &var)
|
bool ScriptEditorStatements::isLiteralType(const RightHandSide &var)
|
||||||
{
|
{
|
||||||
return std::visit(Overload{[](const double &) { return true; },
|
return std::visit(Overload{[](const double &) { return true; },
|
||||||
[](const bool &) { return true; },
|
[](const bool &) { return true; },
|
||||||
@@ -289,7 +289,7 @@ bool ConnectionEditorStatements::isLiteralType(const RightHandSide &var)
|
|||||||
var);
|
var);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ConnectionEditorStatements::toDisplayName(const MatchedStatement &statement)
|
QString ScriptEditorStatements::toDisplayName(const MatchedStatement &statement)
|
||||||
{
|
{
|
||||||
const char *displayName = std::visit(
|
const char *displayName = std::visit(
|
||||||
Overload{[](const MatchedFunction &) { return FUNCTION_DISPLAY_NAME; },
|
Overload{[](const MatchedFunction &) { return FUNCTION_DISPLAY_NAME; },
|
||||||
@@ -303,7 +303,7 @@ QString ConnectionEditorStatements::toDisplayName(const MatchedStatement &statem
|
|||||||
return QString::fromLatin1(displayName);
|
return QString::fromLatin1(displayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ConnectionEditorStatements::toDisplayName(const Handler &handler)
|
QString ScriptEditorStatements::toDisplayName(const Handler &handler)
|
||||||
{
|
{
|
||||||
const MatchedStatement &statement = std::visit(
|
const MatchedStatement &statement = std::visit(
|
||||||
Overload{[](const MatchedStatement &statement) { return statement; },
|
Overload{[](const MatchedStatement &statement) { return statement; },
|
||||||
@@ -312,51 +312,49 @@ QString ConnectionEditorStatements::toDisplayName(const Handler &handler)
|
|||||||
return toDisplayName(statement);
|
return toDisplayName(statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchedStatement &ConnectionEditorStatements::okStatement(
|
MatchedStatement &ScriptEditorStatements::okStatement(ScriptEditorStatements::Handler &handler)
|
||||||
ConnectionEditorStatements::Handler &handler)
|
|
||||||
{
|
{
|
||||||
MatchedStatement statement;
|
MatchedStatement statement;
|
||||||
|
|
||||||
return std::visit(Overload{[](ConnectionEditorStatements::MatchedStatement &var)
|
return std::visit(Overload{[](ScriptEditorStatements::MatchedStatement &var) -> MatchedStatement & {
|
||||||
-> MatchedStatement & { return var; },
|
return var;
|
||||||
[](ConnectionEditorStatements::ConditionalStatement &statement)
|
},
|
||||||
|
[](ScriptEditorStatements::ConditionalStatement &statement)
|
||||||
-> MatchedStatement & { return statement.ok; }},
|
-> MatchedStatement & { return statement.ok; }},
|
||||||
handler);
|
handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchedStatement &ConnectionEditorStatements::koStatement(
|
MatchedStatement &ScriptEditorStatements::koStatement(ScriptEditorStatements::Handler &handler)
|
||||||
ConnectionEditorStatements::Handler &handler)
|
|
||||||
{
|
{
|
||||||
static MatchedStatement block;
|
static MatchedStatement block;
|
||||||
|
|
||||||
if (auto *statement = std::get_if<ConnectionEditorStatements::ConditionalStatement>(&handler))
|
if (auto *statement = std::get_if<ScriptEditorStatements::ConditionalStatement>(&handler))
|
||||||
return statement->ko;
|
return statement->ko;
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchedCondition &ConnectionEditorStatements::matchedCondition(Handler &handler)
|
MatchedCondition &ScriptEditorStatements::matchedCondition(Handler &handler)
|
||||||
{
|
{
|
||||||
static MatchedCondition block;
|
static MatchedCondition block;
|
||||||
|
|
||||||
if (auto *statement = std::get_if<ConnectionEditorStatements::ConditionalStatement>(&handler))
|
if (auto *statement = std::get_if<ScriptEditorStatements::ConditionalStatement>(&handler))
|
||||||
return statement->condition;
|
return statement->condition;
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConditionalStatement &ConnectionEditorStatements::conditionalStatement(
|
ConditionalStatement &ScriptEditorStatements::conditionalStatement(ScriptEditorStatements::Handler &handler)
|
||||||
ConnectionEditorStatements::Handler &handler)
|
|
||||||
{
|
{
|
||||||
static ConditionalStatement block;
|
static ConditionalStatement block;
|
||||||
|
|
||||||
if (auto *statement = std::get_if<ConnectionEditorStatements::ConditionalStatement>(&handler))
|
if (auto *statement = std::get_if<ScriptEditorStatements::ConditionalStatement>(&handler))
|
||||||
return *statement;
|
return *statement;
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ConnectionEditorStatements::toJavascript(const ConditionToken &token)
|
QString ScriptEditorStatements::toJavascript(const ConditionToken &token)
|
||||||
{
|
{
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case ConditionToken::Not:
|
case ConditionToken::Not:
|
@@ -7,22 +7,22 @@
|
|||||||
#include <qmljs/parser/qmljsast_p.h>
|
#include <qmljs/parser/qmljsast_p.h>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
namespace ConnectionEditorStatements {
|
namespace ScriptEditorStatements {
|
||||||
|
|
||||||
inline constexpr char FUNCTION_DISPLAY_NAME[] = QT_TRANSLATE_NOOP(
|
inline constexpr char FUNCTION_DISPLAY_NAME[] = QT_TRANSLATE_NOOP(
|
||||||
"QmlDesigner::ConnectionEditorStatements", "Function");
|
"QmlDesigner::ScriptEditorStatements", "Function");
|
||||||
inline constexpr char ASSIGNMENT_DISPLAY_NAME[] = QT_TRANSLATE_NOOP(
|
inline constexpr char ASSIGNMENT_DISPLAY_NAME[] = QT_TRANSLATE_NOOP(
|
||||||
"QmlDesigner::ConnectionEditorStatements", "Assignment");
|
"QmlDesigner::ScriptEditorStatements", "Assignment");
|
||||||
inline constexpr char SETPROPERTY_DISPLAY_NAME[] = QT_TRANSLATE_NOOP(
|
inline constexpr char SETPROPERTY_DISPLAY_NAME[] = QT_TRANSLATE_NOOP(
|
||||||
"QmlDesigner::ConnectionEditorStatements", "Set Property");
|
"QmlDesigner::ScriptEditorStatements", "Set Property");
|
||||||
inline constexpr char SETSTATE_DISPLAY_NAME[] = QT_TRANSLATE_NOOP(
|
inline constexpr char SETSTATE_DISPLAY_NAME[] = QT_TRANSLATE_NOOP(
|
||||||
"QmlDesigner::ConnectionEditorStatements", "Set State");
|
"QmlDesigner::ScriptEditorStatements", "Set State");
|
||||||
inline constexpr char LOG_DISPLAY_NAME[] = QT_TRANSLATE_NOOP(
|
inline constexpr char LOG_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("QmlDesigner::ScriptEditorStatements",
|
||||||
"QmlDesigner::ConnectionEditorStatements", "Print");
|
"Print");
|
||||||
inline constexpr char EMPTY_DISPLAY_NAME[] = QT_TRANSLATE_NOOP(
|
inline constexpr char EMPTY_DISPLAY_NAME[] = QT_TRANSLATE_NOOP(
|
||||||
"QmlDesigner::ConnectionEditorStatements", "Empty");
|
"QmlDesigner::ScriptEditorStatements", "Empty");
|
||||||
inline constexpr char CUSTOM_DISPLAY_NAME[] = QT_TRANSLATE_NOOP(
|
inline constexpr char CUSTOM_DISPLAY_NAME[] = QT_TRANSLATE_NOOP(
|
||||||
"QmlDesigner::ConnectionEditorStatements", "Custom");
|
"QmlDesigner::ScriptEditorStatements", "Custom");
|
||||||
|
|
||||||
struct Variable;
|
struct Variable;
|
||||||
struct MatchedFunction;
|
struct MatchedFunction;
|
||||||
@@ -122,13 +122,12 @@ QMLDESIGNER_EXPORT QString toDisplayName(const MatchedStatement &statement);
|
|||||||
QMLDESIGNER_EXPORT QString toDisplayName(const Handler &handler);
|
QMLDESIGNER_EXPORT QString toDisplayName(const Handler &handler);
|
||||||
QMLDESIGNER_EXPORT QString toJavascript(const ConditionToken &token);
|
QMLDESIGNER_EXPORT QString toJavascript(const ConditionToken &token);
|
||||||
|
|
||||||
QMLDESIGNER_EXPORT MatchedStatement &okStatement(ConnectionEditorStatements::Handler &handler);
|
QMLDESIGNER_EXPORT MatchedStatement &okStatement(ScriptEditorStatements::Handler &handler);
|
||||||
QMLDESIGNER_EXPORT MatchedStatement &koStatement(ConnectionEditorStatements::Handler &handler);
|
QMLDESIGNER_EXPORT MatchedStatement &koStatement(ScriptEditorStatements::Handler &handler);
|
||||||
|
|
||||||
QMLDESIGNER_EXPORT MatchedCondition &matchedCondition(ConnectionEditorStatements::Handler &handler);
|
QMLDESIGNER_EXPORT MatchedCondition &matchedCondition(ScriptEditorStatements::Handler &handler);
|
||||||
QMLDESIGNER_EXPORT ConditionalStatement &conditionalStatement(
|
QMLDESIGNER_EXPORT ConditionalStatement &conditionalStatement(ScriptEditorStatements::Handler &handler);
|
||||||
ConnectionEditorStatements::Handler &handler);
|
|
||||||
|
|
||||||
} // namespace ConnectionEditorStatements
|
} // namespace ScriptEditorStatements
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
@@ -1,6 +1,6 @@
|
|||||||
// Copyright (C) 2023 The Qt Company Ltd.
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
#include "connectioneditorutils.h"
|
#include "scripteditorutils.h"
|
||||||
|
|
||||||
#include <abstractproperty.h>
|
#include <abstractproperty.h>
|
||||||
#include <abstractview.h>
|
#include <abstractview.h>
|
||||||
@@ -8,11 +8,11 @@
|
|||||||
#include <modelnode.h>
|
#include <modelnode.h>
|
||||||
#include <nodeabstractproperty.h>
|
#include <nodeabstractproperty.h>
|
||||||
#include <nodemetainfo.h>
|
#include <nodemetainfo.h>
|
||||||
|
#include <qmldesignertr.h>
|
||||||
#include <rewriterview.h>
|
#include <rewriterview.h>
|
||||||
#include <rewritingexception.h>
|
#include <rewritingexception.h>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <variantproperty.h>
|
#include <variantproperty.h>
|
||||||
#include <qmldesignertr.h>
|
|
||||||
|
|
||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
Q_LOGGING_CATEGORY(ConnectionEditorLog, "qtc.qtquickdesigner.connectioneditor", QtWarningMsg)
|
Q_LOGGING_CATEGORY(ScriptEditorLog, "qtc.qtquickdesigner.scripteditor", QtWarningMsg)
|
||||||
|
|
||||||
void callLater(const std::function<void()> &fun)
|
void callLater(const std::function<void()> &fun)
|
||||||
{
|
{
|
||||||
@@ -62,7 +62,7 @@ PropertyName uniquePropertyName(const PropertyName &suggestion, const ModelNode
|
|||||||
NodeMetaInfo dynamicTypeNameToNodeMetaInfo(const TypeName &typeName, Model *model)
|
NodeMetaInfo dynamicTypeNameToNodeMetaInfo(const TypeName &typeName, Model *model)
|
||||||
{
|
{
|
||||||
// Note: Uses old mechanism to create the NodeMetaInfo and supports
|
// Note: Uses old mechanism to create the NodeMetaInfo and supports
|
||||||
// only types we care about in the connection editor.
|
// only types we care about in the script editor.
|
||||||
// TODO: Support all possible AbstractProperty types and move to the
|
// TODO: Support all possible AbstractProperty types and move to the
|
||||||
// AbstractProperty class.
|
// AbstractProperty class.
|
||||||
if (typeName == "bool")
|
if (typeName == "bool")
|
||||||
@@ -80,7 +80,7 @@ NodeMetaInfo dynamicTypeNameToNodeMetaInfo(const TypeName &typeName, Model *mode
|
|||||||
else if (typeName == "var" || typeName == "variant")
|
else if (typeName == "var" || typeName == "variant")
|
||||||
return model->metaInfo("QML.variant");
|
return model->metaInfo("QML.variant");
|
||||||
else
|
else
|
||||||
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "type" << typeName << "not found";
|
qCWarning(ScriptEditorLog) << __FUNCTION__ << "type" << typeName << "not found";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -355,7 +355,7 @@ QStringList availableTargetProperties(const BindingProperty &bindingProperty)
|
|||||||
{
|
{
|
||||||
const ModelNode modelNode = bindingProperty.parentModelNode();
|
const ModelNode modelNode = bindingProperty.parentModelNode();
|
||||||
if (!modelNode.isValid()) {
|
if (!modelNode.isValid()) {
|
||||||
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "invalid model node";
|
qCWarning(ScriptEditorLog) << __FUNCTION__ << "invalid model node";
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,7 +428,7 @@ QStringList availableSourceProperties(const QString &id,
|
|||||||
} else if (auto metaInfo = targetProperty.parentModelNode().metaInfo(); metaInfo.isValid()) {
|
} else if (auto metaInfo = targetProperty.parentModelNode().metaInfo(); metaInfo.isValid()) {
|
||||||
targetType = metaInfo.property(targetProperty.name()).propertyType();
|
targetType = metaInfo.property(targetProperty.name()).propertyType();
|
||||||
} else
|
} else
|
||||||
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "no meta info for target node";
|
qCWarning(ScriptEditorLog) << __FUNCTION__ << "no meta info for target node";
|
||||||
|
|
||||||
QStringList possibleProperties;
|
QStringList possibleProperties;
|
||||||
if (!modelNode.isValid()) {
|
if (!modelNode.isValid()) {
|
||||||
@@ -450,7 +450,7 @@ QStringList availableSourceProperties(const QString &id,
|
|||||||
return possibleProperties;
|
return possibleProperties;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "invalid model node:" << id;
|
qCWarning(ScriptEditorLog) << __FUNCTION__ << "invalid model node:" << id;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,10 +476,40 @@ QStringList availableSourceProperties(const QString &id,
|
|||||||
possibleProperties.push_back(QString::fromUtf8(property.name()));
|
possibleProperties.push_back(QString::fromUtf8(property.name()));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qCWarning(ConnectionEditorLog) << __FUNCTION__ << "no meta info for source node";
|
qCWarning(ScriptEditorLog) << __FUNCTION__ << "no meta info for source node";
|
||||||
}
|
}
|
||||||
|
|
||||||
return possibleProperties;
|
return possibleProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString addOnToSignalName(const QString &signal)
|
||||||
|
{
|
||||||
|
if (signal.isEmpty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
static const QRegularExpression rx("^on[A-Z]");
|
||||||
|
if (rx.match(signal).hasMatch())
|
||||||
|
return signal;
|
||||||
|
|
||||||
|
QString ret = signal;
|
||||||
|
ret[0] = ret.at(0).toUpper();
|
||||||
|
ret.prepend("on");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString removeOnFromSignalName(const QString &signal)
|
||||||
|
{
|
||||||
|
if (signal.isEmpty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
static const QRegularExpression rx("^on[A-Z]");
|
||||||
|
if (!rx.match(signal).hasMatch())
|
||||||
|
return signal;
|
||||||
|
|
||||||
|
QString ret = signal;
|
||||||
|
ret.remove(0, 2);
|
||||||
|
ret[0] = ret.at(0).toLower();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(ConnectionEditorLog)
|
Q_DECLARE_LOGGING_CATEGORY(ScriptEditorLog)
|
||||||
|
|
||||||
class AbstractView;
|
class AbstractView;
|
||||||
class AbstractProperty;
|
class AbstractProperty;
|
||||||
@@ -26,6 +26,8 @@ void showErrorMessage(const QString &text);
|
|||||||
|
|
||||||
QString idOrTypeName(const ModelNode &modelNode);
|
QString idOrTypeName(const ModelNode &modelNode);
|
||||||
PropertyName uniquePropertyName(const PropertyName &suggestion, const ModelNode &modelNode);
|
PropertyName uniquePropertyName(const PropertyName &suggestion, const ModelNode &modelNode);
|
||||||
|
QString addOnToSignalName(const QString &signal);
|
||||||
|
QString removeOnFromSignalName(const QString &signal);
|
||||||
|
|
||||||
NodeMetaInfo dynamicTypeMetaInfo(const AbstractProperty &property);
|
NodeMetaInfo dynamicTypeMetaInfo(const AbstractProperty &property);
|
||||||
NodeMetaInfo dynamicTypeNameToNodeMetaInfo(const TypeName &typeName, Model *model);
|
NodeMetaInfo dynamicTypeNameToNodeMetaInfo(const TypeName &typeName, Model *model);
|
Reference in New Issue
Block a user