From 26ac6c26062066e6f97d9ab6d4784aef7bd1e8a0 Mon Sep 17 00:00:00 2001 From: Aleksei German Date: Thu, 7 Sep 2023 16:11:02 +0200 Subject: [PATCH] QmlDesigner: Integrate Editor into Connections Task-number: QDS-10530 Change-Id: I579c5e5d55b2136b96e32a448315dda8e720f2fb Reviewed-by: Thomas Hartmann Reviewed-by: Qt CI Patch Build Bot --- .../ConnectionsDialogForm.qml | 43 ++++++++++++++++++- .../bindingeditor/abstracteditordialog.cpp | 2 +- .../components/bindingeditor/actioneditor.cpp | 12 ++++++ .../components/bindingeditor/actioneditor.h | 3 ++ .../bindingeditor/actioneditordialog.cpp | 31 +++++++++++++ .../bindingeditor/actioneditordialog.h | 3 ++ .../bindingeditor/bindingeditorwidget.cpp | 34 ++++++++++++--- .../bindingeditor/bindingeditorwidget.h | 3 ++ .../connectioneditor/connectionmodel.cpp | 8 ++++ .../connectioneditor/connectionmodel.h | 2 + 10 files changed, 134 insertions(+), 7 deletions(-) diff --git a/share/qtcreator/qmldesigner/connectionseditor/ConnectionsDialogForm.qml b/share/qtcreator/qmldesigner/connectionseditor/ConnectionsDialogForm.qml index 3bd7343e49c..10b1331fa68 100644 --- a/share/qtcreator/qmldesigner/connectionseditor/ConnectionsDialogForm.qml +++ b/share/qtcreator/qmldesigner/connectionseditor/ConnectionsDialogForm.qml @@ -204,7 +204,48 @@ Column { style: StudioTheme.Values.viewBarButtonStyle buttonIcon: StudioTheme.Constants.edit_medium tooltip: qsTr("Add something.") - onClicked: console.log("OPEN EDITOR") + onClicked: { + expressionDialogLoader.show() + } + } + + Loader { + id: expressionDialogLoader + parent: editor + anchors.fill: parent + visible: false + active: visible + + function show() { + expressionDialogLoader.visible = true + } + + sourceComponent: Item { + id: bindingEditorParent + + Component.onCompleted: { + bindingEditor.showWidget() + bindingEditor.text = backend.source + bindingEditor.showControls(false) + bindingEditor.setMultilne(true) + bindingEditor.updateWindowName() + } + + ActionEditor { + id: bindingEditor + + onRejected: { + hideWidget() + expressionDialogLoader.visible = false + } + + onAccepted: { + backend.setNewSource(bindingEditor.text) + hideWidget() + expressionDialogLoader.visible = false + } + } + } } } } diff --git a/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp b/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp index 58238ad1664..8ee7ef1b9ed 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp @@ -71,7 +71,7 @@ QString AbstractEditorDialog::editorValue() const void AbstractEditorDialog::setEditorValue(const QString &text) { if (m_editorWidget) - m_editorWidget->document()->setPlainText(text); + m_editorWidget->setEditorTextWithIndentation(text); } void AbstractEditorDialog::unregisterAutoCompletion() diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp index 30c99b0f27a..0260077da86 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp @@ -83,6 +83,18 @@ void ActionEditor::hideWidget() } } +void ActionEditor::showControls(bool show) +{ + if (m_dialog) + m_dialog->showControls(show); +} + +void QmlDesigner::ActionEditor::setMultilne(bool multiline) +{ + if (m_dialog) + m_dialog->setMultiline(multiline); +} + QString ActionEditor::connectionValue() const { if (!m_dialog) diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h index 0a45e054b09..29e5b1d99a6 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h @@ -31,6 +31,9 @@ public: Q_INVOKABLE void showWidget(int x, int y); Q_INVOKABLE void hideWidget(); + Q_INVOKABLE void showControls(bool show); + Q_INVOKABLE void setMultilne(bool multiline); + QString connectionValue() const; void setConnectionValue(const QString &text); diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditordialog.cpp b/src/plugins/qmldesigner/components/bindingeditor/actioneditordialog.cpp index 8fddcb1ade8..b5bb15c30cf 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditordialog.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditordialog.cpp @@ -376,6 +376,37 @@ void ActionEditorDialog::updateComboBoxes([[maybe_unused]] int index, ComboBox t } } +void ActionEditorDialog::showControls(bool show) +{ + if (m_comboBoxType) + m_comboBoxType->setVisible(show); + + if (m_actionPlaceholder) + m_actionPlaceholder->setVisible(show); + if (m_assignmentPlaceholder) + m_assignmentPlaceholder->setVisible(show); + + if (m_actionTargetItem) + m_actionTargetItem->setVisible(show); + if (m_actionMethod) + m_actionMethod->setVisible(show); + + if (m_assignmentTargetItem) + m_assignmentTargetItem->setVisible(show); + if (m_assignmentTargetProperty) + m_assignmentTargetProperty->setVisible(show); + if (m_assignmentSourceItem) + m_assignmentSourceItem->setVisible(show); + if (m_assignmentSourceProperty) + m_assignmentSourceProperty->setVisible(show); +} + +void ActionEditorDialog::setMultiline(bool multiline) +{ + if (m_editorWidget) + m_editorWidget->m_isMultiline = multiline; +} + void ActionEditorDialog::setupUIComponents() { m_comboBoxType = new QComboBox(this); diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditordialog.h b/src/plugins/qmldesigner/components/bindingeditor/actioneditordialog.h index 06427271b38..342f0d21238 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditordialog.h +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditordialog.h @@ -96,6 +96,9 @@ public: void updateComboBoxes(int idx, ComboBox type); + void showControls(bool show); + void setMultiline(bool multiline); + private: void setupUIComponents(); diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp index 2b0b9f16e9d..da52d37a7e0 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -46,7 +47,7 @@ BindingEditorWidget::BindingEditorWidget() ? tr("Meta+Space") : tr("Ctrl+Space"))); - connect(m_completionAction, &QAction::triggered, [this]() { + connect(m_completionAction, &QAction::triggered, this, [this]() { invokeAssist(TextEditor::Completion); }); } @@ -68,8 +69,17 @@ void BindingEditorWidget::unregisterAutoCompletion() bool BindingEditorWidget::event(QEvent *event) { if (event->type() == QEvent::KeyPress) { - QKeyEvent *keyEvent = static_cast(event); - if ((keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && !keyEvent->modifiers()) { + const QKeyEvent *keyEvent = static_cast(event); + const bool returnPressed = (keyEvent->key() == Qt::Key_Return) + || (keyEvent->key() == Qt::Key_Enter); + const Qt::KeyboardModifiers mods = keyEvent->modifiers(); + constexpr Qt::KeyboardModifier submitModifier = Qt::ControlModifier; + const bool submitModed = mods.testFlag(submitModifier); + + if (!m_isMultiline && (returnPressed && !mods)) { + emit returnKeyClicked(); + return true; + } else if (m_isMultiline && (returnPressed && submitModed)) { emit returnKeyClicked(); return true; } @@ -81,8 +91,22 @@ std::unique_ptr BindingEditorWidget::createAssistIn [[maybe_unused]] TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const { return std::make_unique( - textCursor(), Utils::FilePath(), - assistReason, qmljsdocument->semanticInfo()); + textCursor(), Utils::FilePath(), assistReason, qmljsdocument->semanticInfo()); +} + +void BindingEditorWidget::setEditorTextWithIndentation(const QString &text) +{ + auto *doc = document(); + doc->setPlainText(text); + + //we don't need to indent an empty text + //but is also needed for safer text.length()-1 below + if (text.isEmpty()) + return; + + auto modifier = std::make_unique( + doc, QTextCursor{doc}); + modifier->indent(0, text.length()-1); } BindingDocument::BindingDocument() diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.h b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.h index be1da5d4ef1..5433996110a 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.h +++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.h @@ -32,6 +32,8 @@ public: std::unique_ptr createAssistInterface( TextEditor::AssistKind assistKind, TextEditor::AssistReason assistReason) const override; + void setEditorTextWithIndentation(const QString &text); + signals: void returnKeyClicked(); @@ -39,6 +41,7 @@ public: QmlJSEditor::QmlJSEditorDocument *qmljsdocument = nullptr; Core::IContext *m_context = nullptr; QAction *m_completionAction = nullptr; + bool m_isMultiline = false; }; class BindingDocument : public QmlJSEditor::QmlJSEditorDocument diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp index 15ab1341a38..60d541a940b 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.cpp @@ -758,6 +758,14 @@ void ConnectionModelBackendDelegate::removeElse() setupHandlerAndStatements(); } +void ConnectionModelBackendDelegate::setNewSource(const QString &newSource) +{ + setSource(newSource); + commitNewSource(newSource); + setupHandlerAndStatements(); + setupCondition(); +} + int ConnectionModelBackendDelegate::currentRow() const { return m_currentRow; diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.h b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.h index bef5b79637d..300fcb061a4 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.h +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionmodel.h @@ -284,6 +284,8 @@ public: Q_INVOKABLE void addElse(); Q_INVOKABLE void removeElse(); + Q_INVOKABLE void setNewSource(const QString &newSource); + void setCurrentRow(int i); void update();