QmlDesigner: Add support for else statements

Change-Id: Idbb35555919cf90219c8da5ddf20a1799856f568
Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
Reviewed-by: Henning Gründl <henning.gruendl@qt.io>
This commit is contained in:
Thomas Hartmann
2023-09-01 15:48:35 +02:00
parent f4466ed7b6
commit a2d801ac0e
5 changed files with 136 additions and 49 deletions

View File

@@ -77,7 +77,6 @@ Column {
StatementEditor { StatementEditor {
actionType: action.currentValue ?? ConnectionModelStatementDelegate.Custom actionType: action.currentValue ?? ConnectionModelStatementDelegate.Custom
id: container
horizontalSpacing: root.horizontalSpacing horizontalSpacing: root.horizontalSpacing
columnWidth: root.columnWidth columnWidth: root.columnWidth
statement: backend.okStatement statement: backend.okStatement
@@ -147,6 +146,40 @@ Column {
visible: !backend.conditionListModel.valid visible: !backend.conditionListModel.valid
} }
HelperWidgets.AbstractButton {
style: StudioTheme.Values.connectionPopupButtonStyle
width: 160
buttonIcon: qsTr("Add Else Statement")
iconSize: StudioTheme.Values.baseFontSize
iconFont: StudioTheme.Constants.font
anchors.horizontalCenter: parent.horizontalCenter
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && backend.hasCondition && !backend.hasElse
onClicked: backend.addElse()
}
HelperWidgets.AbstractButton {
style: StudioTheme.Values.connectionPopupButtonStyle
width: 160
buttonIcon: qsTr("Remove Else Statement")
iconSize: StudioTheme.Values.baseFontSize
iconFont: StudioTheme.Constants.font
anchors.horizontalCenter: parent.horizontalCenter
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && backend.hasCondition && backend.hasElse
onClicked: backend.removeElse()
}
//Else Statement
StatementEditor {
actionType: action.currentValue ?? ConnectionModelStatementDelegate.Custom
horizontalSpacing: root.horizontalSpacing
columnWidth: root.columnWidth
statement: backend.koStatement
spacing: root.verticalSpacing
visible: action.currentValue !== ConnectionModelStatementDelegate.Custom && backend.hasCondition && backend.hasElse
}
// Editor // Editor
Rectangle { Rectangle {
id: editor id: editor

View File

@@ -345,6 +345,17 @@ MatchedCondition &ConnectionEditorStatements::matchedCondition(Handler &handler)
return block; return block;
} }
ConditionalStatement &ConnectionEditorStatements::conditionalStatement(
ConnectionEditorStatements::Handler &handler)
{
static ConditionalStatement block;
if (auto *statement = std::get_if<ConnectionEditorStatements::ConditionalStatement>(&handler))
return *statement;
return block;
}
QString ConnectionEditorStatements::toJavascript(const ConditionToken &token) QString ConnectionEditorStatements::toJavascript(const ConditionToken &token)
{ {
switch (token) { switch (token) {

View File

@@ -121,6 +121,8 @@ QMLDESIGNER_EXPORT MatchedStatement &okStatement(ConnectionEditorStatements::Han
QMLDESIGNER_EXPORT MatchedStatement &koStatement(ConnectionEditorStatements::Handler &handler); QMLDESIGNER_EXPORT MatchedStatement &koStatement(ConnectionEditorStatements::Handler &handler);
QMLDESIGNER_EXPORT MatchedCondition &matchedCondition(ConnectionEditorStatements::Handler &handler); QMLDESIGNER_EXPORT MatchedCondition &matchedCondition(ConnectionEditorStatements::Handler &handler);
QMLDESIGNER_EXPORT ConditionalStatement &conditionalStatement(
ConnectionEditorStatements::Handler &handler);
} // namespace ConnectionEditorStatements } // namespace ConnectionEditorStatements

View File

@@ -575,6 +575,11 @@ ConnectionModelBackendDelegate::ConnectionModelBackendDelegate(ConnectionModel *
this, this,
[this]() { handleOkStatementChanged(); }); [this]() { handleOkStatementChanged(); });
connect(&m_koStatementDelegate,
&ConnectionModelStatementDelegate::statementChanged,
this,
[this]() { handleKOStatementChanged(); });
connect(&m_conditionListModel, &ConditionListModel::conditionChanged, this, [this]() { connect(&m_conditionListModel, &ConditionListModel::conditionChanged, this, [this]() {
handleConditionChanged(); handleConditionChanged();
}); });
@@ -673,19 +678,7 @@ void ConnectionModelBackendDelegate::addCondition()
QString newSource = ConnectionEditorStatements::toJavascript(m_handler); QString newSource = ConnectionEditorStatements::toJavascript(m_handler);
ConnectionModel *model = qobject_cast<ConnectionModel *>(parent()); commitNewSource(newSource);
QTC_ASSERT(model, return );
QTC_ASSERT(model->connectionView()->isAttached(), return );
SignalHandlerProperty signalHandlerProperty = model->signalHandlerPropertyForRow(currentRow());
model->connectionView()->executeInTransaction("ConnectionModelBackendDelegate::removeCondition",
[&]() {
signalHandlerProperty.setSource(newSource);
});
setSource(signalHandlerProperty.source());
setupHandlerAndStatements(); setupHandlerAndStatements();
setupCondition(); setupCondition();
@@ -693,8 +686,6 @@ void ConnectionModelBackendDelegate::addCondition()
void ConnectionModelBackendDelegate::removeCondition() void ConnectionModelBackendDelegate::removeCondition()
{ {
qDebug() << Q_FUNC_INFO;
ConnectionEditorStatements::MatchedStatement okStatement ConnectionEditorStatements::MatchedStatement okStatement
= ConnectionEditorStatements::okStatement(m_handler); = ConnectionEditorStatements::okStatement(m_handler);
@@ -702,24 +693,42 @@ void ConnectionModelBackendDelegate::removeCondition()
QString newSource = ConnectionEditorStatements::toJavascript(m_handler); QString newSource = ConnectionEditorStatements::toJavascript(m_handler);
ConnectionModel *model = qobject_cast<ConnectionModel *>(parent()); commitNewSource(newSource);
QTC_ASSERT(model, return );
QTC_ASSERT(model->connectionView()->isAttached(), return );
SignalHandlerProperty signalHandlerProperty = model->signalHandlerPropertyForRow(currentRow());
model->connectionView()->executeInTransaction("ConnectionModelBackendDelegate::removeCondition",
[&]() {
signalHandlerProperty.setSource(newSource);
});
setSource(signalHandlerProperty.source());
setupHandlerAndStatements(); setupHandlerAndStatements();
setupCondition(); setupCondition();
} }
void ConnectionModelBackendDelegate::addElse()
{
ConnectionEditorStatements::MatchedStatement okStatement
= ConnectionEditorStatements::okStatement(m_handler);
auto &condition = ConnectionEditorStatements::conditionalStatement(m_handler);
condition.ko = condition.ok;
QString newSource = ConnectionEditorStatements::toJavascript(m_handler);
commitNewSource(newSource);
setupHandlerAndStatements();
}
void ConnectionModelBackendDelegate::removeElse()
{
ConnectionEditorStatements::MatchedStatement okStatement
= ConnectionEditorStatements::okStatement(m_handler);
auto &condition = ConnectionEditorStatements::conditionalStatement(m_handler);
condition.ko = ConnectionEditorStatements::EmptyBlock();
QString newSource = ConnectionEditorStatements::toJavascript(m_handler);
commitNewSource(newSource);
setupHandlerAndStatements();
}
int ConnectionModelBackendDelegate::currentRow() const int ConnectionModelBackendDelegate::currentRow() const
{ {
return m_currentRow; return m_currentRow;
@@ -803,6 +812,11 @@ bool ConnectionModelBackendDelegate::hasCondition() const
return m_hasCondition; return m_hasCondition;
} }
bool ConnectionModelBackendDelegate::hasElse() const
{
return m_hasElse;
}
void ConnectionModelBackendDelegate::setHasCondition(bool b) void ConnectionModelBackendDelegate::setHasCondition(bool b)
{ {
if (b == m_hasCondition) if (b == m_hasCondition)
@@ -812,6 +826,15 @@ void ConnectionModelBackendDelegate::setHasCondition(bool b)
emit hasConditionChanged(); emit hasConditionChanged();
} }
void ConnectionModelBackendDelegate::setHasElse(bool b)
{
if (b == m_hasElse)
return;
m_hasElse = b;
emit hasElseChanged();
}
ConnectionModelBackendDelegate::ActionType ConnectionModelBackendDelegate::actionType() const ConnectionModelBackendDelegate::ActionType ConnectionModelBackendDelegate::actionType() const
{ {
return m_actionType; return m_actionType;
@@ -902,6 +925,9 @@ void ConnectionModelBackendDelegate::setupHandlerAndStatements()
m_koStatementDelegate.setActionType(m_actionType); m_koStatementDelegate.setActionType(m_actionType);
} }
ConnectionEditorStatements::isEmptyStatement(koStatement);
setHasElse(!ConnectionEditorStatements::isEmptyStatement(koStatement));
emit actionTypeChanged(); emit actionTypeChanged();
} }
@@ -956,31 +982,28 @@ void ConnectionModelBackendDelegate::handleOkStatementChanged()
QString newSource = ConnectionEditorStatements::toJavascript(m_handler); QString newSource = ConnectionEditorStatements::toJavascript(m_handler);
ConnectionModel *model = qobject_cast<ConnectionModel *>(parent()); commitNewSource(newSource);
}
QTC_ASSERT(model, return ); void ConnectionModelBackendDelegate::handleKOStatementChanged()
{
ConnectionEditorStatements::MatchedStatement &koStatement
= ConnectionEditorStatements::koStatement(m_handler);
QTC_ASSERT(model->connectionView()->isAttached(), return ); koStatement = m_koStatementDelegate.statement(); //TODO why?
SignalHandlerProperty signalHandlerProperty = model->signalHandlerPropertyForRow(currentRow()); QString newSource = ConnectionEditorStatements::toJavascript(m_handler);
model->connectionView() commitNewSource(newSource);
->executeInTransaction("ConnectionModelBackendDelegate::handleOkStatementChanged",
[&]() { signalHandlerProperty.setSource(newSource); });
setSource(signalHandlerProperty.source());
} }
void ConnectionModelBackendDelegate::handleConditionChanged() void ConnectionModelBackendDelegate::handleConditionChanged()
{ {
qDebug() << Q_FUNC_INFO;
ConnectionModel *model = qobject_cast<ConnectionModel *>(parent()); ConnectionModel *model = qobject_cast<ConnectionModel *>(parent());
QTC_ASSERT(model, return ); QTC_ASSERT(model, return );
QTC_ASSERT(model->connectionView()->isAttached(), return ); QTC_ASSERT(model->connectionView()->isAttached(), return );
auto view = model->connectionView();
ConnectionEditorStatements::MatchedCondition &condition ConnectionEditorStatements::MatchedCondition &condition
= ConnectionEditorStatements::matchedCondition(m_handler); = ConnectionEditorStatements::matchedCondition(m_handler);
condition = m_conditionListModel.condition(); //why? condition = m_conditionListModel.condition(); //why?
@@ -988,16 +1011,23 @@ void ConnectionModelBackendDelegate::handleConditionChanged()
qDebug() << Q_FUNC_INFO << "new source" << newSource; qDebug() << Q_FUNC_INFO << "new source" << newSource;
commitNewSource(newSource);
}
void ConnectionModelBackendDelegate::commitNewSource(const QString &source)
{
ConnectionModel *model = qobject_cast<ConnectionModel *>(parent());
QTC_ASSERT(model, return );
QTC_ASSERT(model->connectionView()->isAttached(), return );
SignalHandlerProperty signalHandlerProperty = model->signalHandlerPropertyForRow(currentRow()); SignalHandlerProperty signalHandlerProperty = model->signalHandlerPropertyForRow(currentRow());
try { model->connectionView()->executeInTransaction("ConnectionModelBackendDelegate::commitNewSource",
RewriterTransaction transaction = view->beginRewriterTransaction( [&]() {
"ConnectionModelBackendDelegate::handleConditionChanged"); signalHandlerProperty.setSource(source);
signalHandlerProperty.setSource(newSource); });
transaction.commit();
} catch (const Exception &e) {
m_conditionListModel.setInvalid(e.description());
}
setSource(signalHandlerProperty.source()); setSource(signalHandlerProperty.source());
} }

View File

@@ -242,6 +242,7 @@ class ConnectionModelBackendDelegate : public QObject
Q_PROPERTY(ConnectionModelStatementDelegate *koStatement READ koStatement CONSTANT) Q_PROPERTY(ConnectionModelStatementDelegate *koStatement READ koStatement CONSTANT)
Q_PROPERTY(ConditionListModel *conditionListModel READ conditionListModel CONSTANT) Q_PROPERTY(ConditionListModel *conditionListModel READ conditionListModel CONSTANT)
Q_PROPERTY(bool hasCondition READ hasCondition NOTIFY hasConditionChanged) 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 source READ source NOTIFY sourceChanged)
public: public:
@@ -255,10 +256,14 @@ public:
Q_INVOKABLE void addCondition(); Q_INVOKABLE void addCondition();
Q_INVOKABLE void removeCondition(); Q_INVOKABLE void removeCondition();
Q_INVOKABLE void addElse();
Q_INVOKABLE void removeElse();
signals: signals:
void currentRowChanged(); void currentRowChanged();
void actionTypeChanged(); void actionTypeChanged();
void hasConditionChanged(); void hasConditionChanged();
void hasElseChanged();
void sourceChanged(); void sourceChanged();
private: private:
@@ -267,7 +272,9 @@ private:
void handleException(); void handleException();
bool hasCondition() const; bool hasCondition() const;
bool hasElse() const;
void setHasCondition(bool b); void setHasCondition(bool b);
void setHasElse(bool b);
ActionType actionType() const; ActionType actionType() const;
PropertyTreeModelDelegate *signal(); PropertyTreeModelDelegate *signal();
ConnectionModelStatementDelegate *okStatement(); ConnectionModelStatementDelegate *okStatement();
@@ -280,8 +287,11 @@ private:
void handleTargetChanged(); void handleTargetChanged();
void handleOkStatementChanged(); void handleOkStatementChanged();
void handleKOStatementChanged();
void handleConditionChanged(); void handleConditionChanged();
void commitNewSource(const QString &source);
ActionType m_actionType; ActionType m_actionType;
QString m_exceptionError; QString m_exceptionError;
int m_currentRow = -1; int m_currentRow = -1;
@@ -291,6 +301,7 @@ private:
ConnectionModelStatementDelegate m_koStatementDelegate; ConnectionModelStatementDelegate m_koStatementDelegate;
ConditionListModel m_conditionListModel; ConditionListModel m_conditionListModel;
bool m_hasCondition = false; bool m_hasCondition = false;
bool m_hasElse = false;
QString m_source; QString m_source;
}; };