diff options
author | Aleksei German <aleksei.german@qt.io> | 2021-09-10 18:06:26 +0200 |
---|---|---|
committer | Aleksei German <aleksei.german@qt.io> | 2021-10-12 08:09:19 +0000 |
commit | 3ccf269f81eb7d26af1962915026ae9ce4b6d5f8 (patch) | |
tree | d995aa4d8d53976d735828d618619b6a4aea582c | |
parent | 786dbcb9e86104be12ceded01188f9b4095e47be (diff) |
QmlDesigner: Fix for Binding Editor
- Makes Binding Editor modal
- Fixes Binding Editors hotkeys and actions
- Adds Target item, property and expected type into title
Task-numbers: QDS-2819, QDS-4878
Change-Id: Ib5c5f73e6552f58828776043f9b793a24c48a1f8
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
10 files changed, 75 insertions, 35 deletions
diff --git a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml index 748f835614..bdefc13a97 100644 --- a/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml +++ b/share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml @@ -164,6 +164,7 @@ Item { bindingEditor.showWidget() bindingEditor.text = backendValue.expression bindingEditor.prepareBindings() + bindingEditor.updateWindowName() } BindingEditor { diff --git a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml index 5cbefc03d1..2deb46b212 100644 --- a/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml +++ b/share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml @@ -110,6 +110,7 @@ Rectangle { bindingEditor.showWidget() bindingEditor.text = delegateWhenConditionString bindingEditor.prepareBindings() + bindingEditor.updateWindowName() } } @@ -309,6 +310,7 @@ Rectangle { } stateModelNodeProperty: statesEditorModel.stateModelNode() + stateNameProperty: myRoot.delegateStateName onRejected: { hideWidget() diff --git a/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp b/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp index 872a004fcc..5b8a4934dd 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp @@ -46,7 +46,7 @@ AbstractEditorDialog::AbstractEditorDialog(QWidget *parent, const QString &title { setWindowFlag(Qt::Tool, true); setWindowTitle(defaultTitle()); - setModal(false); + setModal(true); setupJSEditor(); setupUIComponents(); @@ -111,11 +111,10 @@ void AbstractEditorDialog::setupJSEditor() { static BindingEditorFactory f; m_editor = qobject_cast<TextEditor::BaseTextEditor*>(f.createEditor()); - m_editorWidget = qobject_cast<BindingEditorWidget*>(m_editor->editorWidget()); + Q_ASSERT(m_editor); - Core::Context context = m_editor->context(); - context.prepend(BINDINGEDITOR_CONTEXT_ID); - m_editorWidget->m_context->setContext(context); + m_editorWidget = qobject_cast<BindingEditorWidget*>(m_editor->editorWidget()); + Q_ASSERT(m_editorWidget); auto qmlDesignerEditor = QmlDesignerPlugin::instance()->currentDesignDocument()->textEditor(); diff --git a/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.h b/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.h index ed8cdd0a13..76de79b195 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.h +++ b/src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.h @@ -26,9 +26,10 @@ #ifndef ABSTRACTEDITORDIALOG_H #define ABSTRACTEDITORDIALOG_H -#include <bindingeditor/bindingeditorwidget.h> #include <qmldesignercorelib_global.h> + #include <texteditor/texteditor.h> +#include <bindingeditor/bindingeditorwidget.h> #include <QDialog> diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp index 89364c5116..1f2a8224d3 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp @@ -286,10 +286,13 @@ void ActionEditor::prepareConnections() m_dialog->setAllConnections(connections, singletons, states); } -void ActionEditor::updateWindowName() +void ActionEditor::updateWindowName(const QString &targetName) { if (!m_dialog.isNull()) { - m_dialog->setWindowTitle(m_dialog->defaultTitle()); + if (targetName.isEmpty()) + m_dialog->setWindowTitle(m_dialog->defaultTitle()); + else + m_dialog->setWindowTitle(m_dialog->defaultTitle() + " [" + targetName + "]"); m_dialog->raise(); } } diff --git a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h index c0356e81c4..09597bc8d1 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h +++ b/src/plugins/qmldesigner/components/bindingeditor/actioneditor.h @@ -64,7 +64,7 @@ public: void prepareConnections(); - Q_INVOKABLE void updateWindowName(); + Q_INVOKABLE void updateWindowName(const QString &targetName = {}); signals: void accepted(); diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp index d28457e1f5..c1a25b0437 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp @@ -42,8 +42,6 @@ namespace QmlDesigner { -static BindingEditor *s_lastBindingEditor = nullptr; - BindingEditor::BindingEditor(QObject *) { } @@ -62,11 +60,6 @@ void BindingEditor::prepareDialog() { QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_BINDINGEDITOR_OPENED); - if (s_lastBindingEditor) - s_lastBindingEditor->hideWidget(); - - s_lastBindingEditor = this; - m_dialog = new BindingEditorDialog(Core::ICore::dialogParent()); QObject::connect(m_dialog, &AbstractEditorDialog::accepted, @@ -91,9 +84,6 @@ void BindingEditor::showWidget(int x, int y) void BindingEditor::hideWidget() { - if (s_lastBindingEditor == this) - s_lastBindingEditor = nullptr; - if (m_dialog) { m_dialog->unregisterAutoCompletion(); //we have to do it separately, otherwise we have an autocompletion action override m_dialog->close(); @@ -125,6 +115,12 @@ void BindingEditor::setBackendValue(const QVariant &backendValue) if (node.isValid()) { m_backendValueTypeName = node.metaInfo().propertyTypeName(propertyEditorValue->name()); + QString nodeId = node.id(); + if (nodeId.isEmpty()) + nodeId = node.simplifiedTypeName(); + + m_targetName = nodeId + "." + propertyEditorValue->name(); + if (m_backendValueTypeName == "alias" || m_backendValueTypeName == "unknown") if (QmlObjectNode::isValidQmlObjectNode(node)) m_backendValueTypeName = QmlObjectNode(node).instanceType(propertyEditorValue->name()); @@ -164,6 +160,12 @@ void BindingEditor::setStateModelNode(const QVariant &stateModelNode) } } +void BindingEditor::setStateName(const QString &name) +{ + m_targetName = name; + m_targetName += ".when"; +} + void BindingEditor::setModelNode(const ModelNode &modelNode) { if (modelNode.isValid()) @@ -177,6 +179,11 @@ void BindingEditor::setBackendValueTypeName(const TypeName &backendValueTypeName emit backendValueChanged(); } +void BindingEditor::setTargetName(const QString &target) +{ + m_targetName = target; +} + void BindingEditor::prepareBindings() { if (!m_modelNode.isValid() || m_backendValueTypeName.isEmpty()) @@ -279,8 +286,13 @@ void BindingEditor::prepareBindings() void BindingEditor::updateWindowName() { - if (!m_dialog.isNull() && !m_backendValueTypeName.isEmpty()) - m_dialog->setWindowTitle(m_dialog->defaultTitle() + " [" + m_backendValueTypeName + "]"); + if (!m_dialog.isNull() && !m_backendValueTypeName.isEmpty()) { + const QString targetString = " [" + + (m_targetName.isEmpty() ? QString() : (m_targetName + ": ")) + + QString::fromUtf8(m_backendValueTypeName) + "]"; + + m_dialog->setWindowTitle(m_dialog->defaultTitle() + targetString); + } } QVariant BindingEditor::backendValue() const diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h index 495462128f..f6c5c88432 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h +++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h @@ -44,6 +44,7 @@ class BindingEditor : public QObject Q_PROPERTY(QVariant backendValueProperty READ backendValue WRITE setBackendValue NOTIFY backendValueChanged) Q_PROPERTY(QVariant modelNodeBackendProperty READ modelNodeBackend WRITE setModelNodeBackend NOTIFY modelNodeBackendChanged) Q_PROPERTY(QVariant stateModelNodeProperty READ stateModelNode WRITE setStateModelNode NOTIFY stateModelNodeChanged) + Q_PROPERTY(QString stateNameProperty WRITE setStateName) public: BindingEditor(QObject *parent = nullptr); @@ -64,11 +65,14 @@ public: void setModelNodeBackend(const QVariant &modelNodeBackend); //2. modelnode (this one also sets backend value type name to bool) + //State Name is not mandatory, but used in bindingEditor dialog name void setStateModelNode(const QVariant &stateModelNode); + void setStateName(const QString &name); - //3. modelnode + backend value type name + //3. modelnode + backend value type name + optional target name void setModelNode(const ModelNode &modelNode); void setBackendValueTypeName(const TypeName &backendValueTypeName); + void setTargetName(const QString &target); Q_INVOKABLE void prepareBindings(); Q_INVOKABLE void updateWindowName(); @@ -93,6 +97,7 @@ private: QVariant m_stateModelNode; QmlDesigner::ModelNode m_modelNode; TypeName m_backendValueTypeName; + QString m_targetName; }; } diff --git a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp index 6cd810df37..5b9c54b4d4 100644 --- a/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp +++ b/src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp @@ -35,6 +35,10 @@ #include <qmljseditor/qmljseditordocument.h> #include <qmljseditor/qmljssemantichighlighter.h> #include <qmljstools/qmljsindenter.h> +#include <qmljstools/qmljstoolsconstants.h> + +#include <projectexplorer/projectexplorerconstants.h> +#include <utils/fancylineedit.h> #include <QAction> @@ -43,17 +47,19 @@ namespace QmlDesigner { BindingEditorWidget::BindingEditorWidget() : m_context(new Core::IContext(this)) { + Core::Context context(BINDINGEDITOR_CONTEXT_ID, + ProjectExplorer::Constants::QMLJS_LANGUAGE_ID); + m_context->setWidget(this); + m_context->setContext(context); Core::ICore::addContextObject(m_context); - const Core::Context context(BINDINGEDITOR_CONTEXT_ID); - /* * We have to register our own active auto completion shortcut, because the original short cut will * use the cursor position of the original editor in the editor manager. */ - m_completionAction = new QAction(tr("Trigger Completion"), this); + Core::Command *command = Core::ActionManager::registerAction( m_completionAction, TextEditor::Constants::COMPLETE_THIS, context); command->setDefaultKeySequence(QKeySequence( @@ -84,11 +90,9 @@ bool BindingEditorWidget::event(QEvent *event) { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); - if (keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) { + if ((keyEvent->key() == Qt::Key_Return || keyEvent->key() == Qt::Key_Enter) && !keyEvent->modifiers()) { emit returnKeyClicked(); return true; - } else { - return QmlJSEditor::QmlJSEditorWidget::event(event); } } return QmlJSEditor::QmlJSEditorWidget::event(event); @@ -133,8 +137,12 @@ void BindingDocument::triggerPendingUpdates() BindingEditorFactory::BindingEditorFactory() { setId(BINDINGEDITOR_CONTEXT_ID); - setDisplayName(QCoreApplication::translate("OpenWith::Editors", QmlDesigner::BINDINGEDITOR_CONTEXT_ID)); + setDisplayName(QCoreApplication::translate("OpenWith::Editors", BINDINGEDITOR_CONTEXT_ID)); setEditorActionHandlers(0); + addMimeType(BINDINGEDITOR_CONTEXT_ID); + addMimeType(QmlJSTools::Constants::QML_MIMETYPE); + addMimeType(QmlJSTools::Constants::QMLTYPES_MIMETYPE); + addMimeType(QmlJSTools::Constants::JS_MIMETYPE); setDocumentCreator([]() { return new BindingDocument; }); setEditorWidgetCreator([]() { return new BindingEditorWidget; }); diff --git a/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp b/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp index 11bfebe5e7..095b8b6262 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp @@ -159,17 +159,20 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event) QMenu menu(this); - menu.addAction(tr("Open Connection Editor"), [&]() { + menu.addAction(tr("Open Connection Editor"), this, [&]() { auto *connectionModel = qobject_cast<ConnectionModel *>(targetView->model()); const SignalHandlerProperty property = connectionModel->signalHandlerPropertyForRow(index.row()); const ModelNode node = property.parentModelNode(); + const QString targetName = index.siblingAtColumn(ConnectionModel::TargetModelNodeRow).data().toString() + + "." + property.name(); + m_connectionEditor->showWidget(); m_connectionEditor->setConnectionValue(index.data().toString()); m_connectionEditor->setModelIndex(index); m_connectionEditor->setModelNode(node); m_connectionEditor->prepareConnections(); - m_connectionEditor->updateWindowName(); + m_connectionEditor->updateWindowName(targetName); }); QMap<QString, QVariant> data; @@ -179,7 +182,7 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event) const auto actions = designerActionManager.actionsForTargetView( ActionInterface::TargetView::ConnectionEditor); - for (auto actionInterface : actions) { + for (const auto &actionInterface : actions) { auto *action = actionInterface->action(); action->setData(data); menu.addAction(action); @@ -198,7 +201,7 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event) QMenu menu(this); - menu.addAction(tr("Open Binding Editor"), [&]() { + menu.addAction(tr("Open Binding Editor"), this, [&]() { BindingModel *bindingModel = qobject_cast<BindingModel*>(targetView->model()); const BindingProperty property = bindingModel->bindingPropertyForRow(index.row()); @@ -209,10 +212,13 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event) const TypeName typeName = property.isDynamic() ? property.dynamicTypeName() : node.metaInfo().propertyTypeName(property.name()); + const QString targetName = node.displayName() + "." + property.name(); + m_bindingEditor->showWidget(); m_bindingEditor->setBindingValue(property.expression()); m_bindingEditor->setModelNode(node); m_bindingEditor->setBackendValueTypeName(typeName); + m_bindingEditor->setTargetName(targetName); m_bindingEditor->prepareBindings(); m_bindingEditor->updateWindowName(); @@ -232,7 +238,7 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event) DynamicPropertiesModel *propertiesModel = qobject_cast<DynamicPropertiesModel *>(targetView->model()); QMenu menu(this); - menu.addAction(tr("Open Binding Editor"), [&]() { + menu.addAction(tr("Open Binding Editor"), this, [&]() { AbstractProperty abstractProperty = propertiesModel->abstractPropertyForRow(index.row()); if (!abstractProperty.isValid()) return; @@ -247,17 +253,20 @@ void ConnectionViewWidget::contextMenuEvent(QContextMenuEvent *event) else return; + const QString targetName = node.displayName() + "." + abstractProperty.name(); + m_dynamicEditor->showWidget(); m_dynamicEditor->setBindingValue(newExpression); m_dynamicEditor->setModelNode(node); m_dynamicEditor->setBackendValueTypeName(abstractProperty.dynamicTypeName()); + m_dynamicEditor->setTargetName(targetName); m_dynamicEditor->prepareBindings(); m_dynamicEditor->updateWindowName(); m_dynamicIndex = index; }); - menu.addAction(tr("Reset Property"), [&]() { + menu.addAction(tr("Reset Property"), this, [&]() { propertiesModel->resetProperty(propertiesModel->abstractPropertyForRow(index.row()).name()); }); |