aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksei German <aleksei.german@qt.io>2021-09-10 18:06:26 +0200
committerAleksei German <aleksei.german@qt.io>2021-10-12 08:09:19 +0000
commit3ccf269f81eb7d26af1962915026ae9ce4b6d5f8 (patch)
treed995aa4d8d53976d735828d618619b6a4aea582c
parent786dbcb9e86104be12ceded01188f9b4095e47be (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>
-rw-r--r--share/qtcreator/qmldesigner/propertyEditorQmlSources/imports/HelperWidgets/ExtendedFunctionLogic.qml1
-rw-r--r--share/qtcreator/qmldesigner/statesEditorQmlSources/StatesDelegate.qml2
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.cpp9
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/abstracteditordialog.h3
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/actioneditor.cpp7
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/actioneditor.h2
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditor.cpp36
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditor.h7
-rw-r--r--src/plugins/qmldesigner/components/bindingeditor/bindingeditorwidget.cpp22
-rw-r--r--src/plugins/qmldesigner/components/connectioneditor/connectionviewwidget.cpp21
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());
});