From 5907e480a0ad3e8df96b393c78c0ded97ec5accb Mon Sep 17 00:00:00 2001 From: Thomas Hartmann Date: Fri, 1 Sep 2023 17:29:07 +0200 Subject: [PATCH] QmlDesigner: Fix QML for bindings/properties MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Ensure a "node" is added to the model if missing, for e.g. Singletons * Expose targetNode of property Change-Id: Ifbb131c1d6efaaceb15a6e630ce56023ace63311 Reviewed-by: Henning Gründl Reviewed-by: Qt CI Patch Build Bot --- .../connectionseditor/BindingsDialog.qml | 26 ++++ .../connectionseditor/BindingsDialogForm.qml | 123 ++++++++---------- .../connectionseditor/PropertiesDialog.qml | 26 ++++ .../PropertiesDialogForm.qml | 95 +++++++------- .../connectioneditor/bindingmodel.cpp | 6 +- .../dynamicpropertiesmodel.cpp | 15 ++- .../connectioneditor/dynamicpropertiesmodel.h | 4 + 7 files changed, 178 insertions(+), 117 deletions(-) diff --git a/share/qtcreator/qmldesigner/connectionseditor/BindingsDialog.qml b/share/qtcreator/qmldesigner/connectionseditor/BindingsDialog.qml index d544393a33b..65321b3b6e4 100644 --- a/share/qtcreator/qmldesigner/connectionseditor/BindingsDialog.qml +++ b/share/qtcreator/qmldesigner/connectionseditor/BindingsDialog.qml @@ -2,12 +2,38 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 import QtQuick +import StudioTheme 1.0 as StudioTheme PopupDialog { property alias backend: form.backend + titleBar: Row { + spacing: 30 // TODO + anchors.fill: parent + + Text { + color: StudioTheme.Values.themeTextColor + text: qsTr("Owner") + font.pixelSize: StudioTheme.Values.myFontSize + anchors.verticalCenter: parent.verticalCenter + ToolTipArea { + anchors.fill: parent + tooltip: qsTr("The owner of the property") + } + } + + Text { + color: StudioTheme.Values.themeTextColor + font.pixelSize: StudioTheme.Values.myFontSize + anchors.verticalCenter: parent.verticalCenter + text: form.backend.targetNode + + } + + } BindingsDialogForm { id: form y: 32 + height: 160 } } diff --git a/share/qtcreator/qmldesigner/connectionseditor/BindingsDialogForm.qml b/share/qtcreator/qmldesigner/connectionseditor/BindingsDialogForm.qml index 0d053771440..912bbad8287 100644 --- a/share/qtcreator/qmldesigner/connectionseditor/BindingsDialogForm.qml +++ b/share/qtcreator/qmldesigner/connectionseditor/BindingsDialogForm.qml @@ -3,86 +3,71 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 import QtQuick import QtQuick.Controls -import StudioControls +import StudioControls as StudioControls +import StudioTheme as StudioTheme -Item { - width: 400 - height: 800 +Column { + id: root + + readonly property real horizontalSpacing: 10 + readonly property real verticalSpacing: 16 + readonly property real columnWidth: (root.width - root.horizontalSpacing) / 2 property var backend - PopupLabel { - x: 10 - y: 25 - text: qsTr("Target") + y: StudioTheme.Values.popupMargin + width: parent.width + spacing: root.verticalSpacing + + Row { + spacing: root.horizontalSpacing + + PopupLabel { text: qsTr("From") ; tooltip: qsTr("The Property to assign from.")} + PopupLabel { text: qsTr("To"); tooltip: qsTr("The Property to assign to.") } } - PopupLabel { - id: text111 - x: 80 - y: 25 - text: backend.targetNode - font.pixelSize: 15 + Row { + spacing: root.horizontalSpacing + + StudioControls.TopLevelComboBox { + id: sourceNode + style: StudioTheme.Values.connectionPopupControlStyle + width: root.columnWidth + + model: backend.sourceNode.model ?? [] + onModelChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex + onActivated: backend.sourceNode.activateIndex(sourceNode.currentIndex) + property int currentTypeIndex: backend.sourceNode.currentIndex ?? 0 + onCurrentTypeIndexChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex + } + + PopupLabel { + width: root.columnWidth + text: backend.targetNode + } + } - TopLevelComboBox { - id: target - x: 101 - width: 210 - anchors.verticalCenter: parent.verticalCenter - anchors.verticalCenterOffset: -335 - model: backend.property.model ?? [] - enabled: false - //I see no use case to actually change the property name - //onActivated: backend.targetNode.activateIndex(target.currentIndex) - property int currentTypeIndex: backend.property.currentIndex ?? 0 - onCurrentTypeIndexChanged: target.currentIndex = target.currentTypeIndex - } + Row { + spacing: root.horizontalSpacing - PopupLabel { - x: 13 - y: 111 - text: qsTr("Source Propety") - } + StudioControls.TopLevelComboBox { + id: sourceProperty + style: StudioTheme.Values.connectionPopupControlStyle + width: root.columnWidth - TopLevelComboBox { - id: sourceNode - x: 135 - y: 98 - width: 156 + model: backend.sourceProperty.model ?? [] + onModelChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex + onActivated: backend.sourceProperty.activateIndex( + sourceProperty.currentIndex) + property int currentTypeIndex: backend.sourceProperty.currentIndex ?? 0 + onCurrentTypeIndexChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex + } - model: backend.sourceNode.model ?? [] + PopupLabel { + width: root.columnWidth + text: backend.property.currentText + } - onModelChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex - - onActivated: backend.sourceNode.activateIndex(sourceNode.currentIndex) - property int currentTypeIndex: backend.sourceNode.currentIndex ?? 0 - onCurrentTypeIndexChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex - } - - PopupLabel { - x: 13 - y: 88 - text: qsTr("Source Node") - } - - TopLevelComboBox { - id: sourceProperty - x: 140 - y: 121 - width: 156 - - model: backend.sourceProperty.model ?? [] - onModelChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex - onActivated: backend.sourceProperty.activateIndex( - sourceProperty.currentIndex) - property int currentTypeIndex: backend.sourceProperty.currentIndex ?? 0 - onCurrentTypeIndexChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex - } - - PopupLabel { - x: 10 - y: 55 - text: qsTr("Property") } } diff --git a/share/qtcreator/qmldesigner/connectionseditor/PropertiesDialog.qml b/share/qtcreator/qmldesigner/connectionseditor/PropertiesDialog.qml index cd0ae16226a..d649d6380ef 100644 --- a/share/qtcreator/qmldesigner/connectionseditor/PropertiesDialog.qml +++ b/share/qtcreator/qmldesigner/connectionseditor/PropertiesDialog.qml @@ -2,12 +2,38 @@ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 import QtQuick +import StudioTheme 1.0 as StudioTheme PopupDialog { property alias backend: form.backend + titleBar: Row { + spacing: 30 // TODO + anchors.fill: parent + + Text { + color: StudioTheme.Values.themeTextColor + text: qsTr("Owner") + font.pixelSize: StudioTheme.Values.myFontSize + anchors.verticalCenter: parent.verticalCenter + ToolTipArea { + anchors.fill: parent + tooltip: qsTr("The owner of the property") + } + } + + Text { + color: StudioTheme.Values.themeTextColor + font.pixelSize: StudioTheme.Values.myFontSize + anchors.verticalCenter: parent.verticalCenter + text: form.backend.targetNode + } + + } + PropertiesDialogForm { id: form y: 32 + height: 180 } } diff --git a/share/qtcreator/qmldesigner/connectionseditor/PropertiesDialogForm.qml b/share/qtcreator/qmldesigner/connectionseditor/PropertiesDialogForm.qml index 0936581c86f..26398e7acbb 100644 --- a/share/qtcreator/qmldesigner/connectionseditor/PropertiesDialogForm.qml +++ b/share/qtcreator/qmldesigner/connectionseditor/PropertiesDialogForm.qml @@ -1,68 +1,73 @@ // Copyright (C) 2023 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 -import QtQuick 2.15 -import QtQuick.Controls 2.15 +import QtQuick +import QtQuick.Controls +import StudioControls as StudioControls +import StudioTheme as StudioTheme -import StudioControls +Column { + id: root -Item { - width: 400 - height: 800 + readonly property real horizontalSpacing: 10 + readonly property real verticalSpacing: 16 + readonly property real columnWidth: (root.width - root.horizontalSpacing) / 2 property var backend + y: StudioTheme.Values.popupMargin + width: parent.width + spacing: root.verticalSpacing + PopupLabel { - x: 10 - y: 25 - - text: qsTr("Type:") - + text: qsTr("Type") + tooltip: qsTr("The type of the property") } + StudioControls.TopLevelComboBox { + id: type + style: StudioTheme.Values.connectionPopupControlStyle + width: root.columnWidth + //width: root.width - TopLevelComboBox { - id: target - x: 95 - width: 210 - anchors.verticalCenter: parent.verticalCenter - anchors.verticalCenterOffset: -367 model: backend.type.model ?? [] - onActivated: backend.type.activateIndex(target.currentIndex) + onActivated: backend.type.activateIndex(type.currentIndex) property int currentTypeIndex: backend.type.currentIndex ?? 0 - onCurrentTypeIndexChanged: target.currentIndex = target.currentTypeIndex + onCurrentTypeIndexChanged: type.currentIndex = type.currentTypeIndex } - PopupLabel { - x: 10 - y: 131 - text: qsTr("Name") + Row { + spacing: root.horizontalSpacing + + PopupLabel { text: qsTr("Name") ; tooltip: qsTr("The name of the property.")} + PopupLabel { text: qsTr("Value"); tooltip: qsTr("The value of the property.") } } - TextInput { - id: name - x: 70 - y: 131 - width: 156 - text: backend.name.text ?? "" - onEditingFinished: { - backend.name.activateText(name.text) + Row { + spacing: root.horizontalSpacing + StudioControls.TextField { + id: name + + width: root.columnWidth + actionIndicatorVisible: false + translationIndicatorVisible: false + + text: backend.name.text ?? "" + onEditingFinished: { + backend.name.activateText(name.text) + } } - } + StudioControls.TextField { + id: value - PopupLabel { - x: 10 - y: 81 - text: qsTr("Value") - } + width: root.columnWidth + actionIndicatorVisible: false + translationIndicatorVisible: false - TextInput { - id: value - x: 70 - y: 81 - width: 156 - text: backend.value.text ?? "" - onEditingFinished: { - backend.value.activateText(value.text) + + text: backend.value.text ?? "" + onEditingFinished: { + backend.value.activateText(value.text) + } } } } diff --git a/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp index 2b2025ed83a..4fc3b81c310 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/bindingmodel.cpp @@ -553,12 +553,16 @@ void BindingModelBackendDelegate::setCurrentRow(int i) } std::sort(sourceNodes.begin(), sourceNodes.end()); - m_sourceNode.setModel(sourceNodes); QString sourceNodeName; QString sourcePropertyName; model->getExpressionStrings(bindingProperty, &sourceNodeName, &sourcePropertyName); + if (!sourceNodes.contains(sourceNodeName)) + sourceNodes.append(sourceNodeName); + + m_sourceNode.setModel(sourceNodes); + m_sourceNode.setCurrentText(sourceNodeName); m_sourceNodeProperty.setModel(model->possibleSourceProperties(bindingProperty)); diff --git a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp index eb0976eaed9..8557ebf5cae 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp +++ b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.cpp @@ -1022,6 +1022,10 @@ void DynamicPropertiesModelBackendDelegate::setCurrentRow(int i) m_value.setText(property.toVariantProperty().value().toString()); else if (property.isBindingProperty()) m_value.setText(property.toBindingProperty().expression()); + + m_targetNode = property.parentModelNode().id(); + + emit targetNodeChanged(); } void DynamicPropertiesModelBackendDelegate::handleTypeChanged() @@ -1077,9 +1081,10 @@ void DynamicPropertiesModelBackendDelegate::handleNameChanged() const QString expression = bindingProperty.expression(); const PropertyName dynamicPropertyType = bindingProperty.dynamicTypeName(); + targetNode.removeProperty(bindingProperty.name()); + targetNode.bindingProperty(newName).setDynamicTypeNameAndExpression(dynamicPropertyType, expression); - targetNode.removeProperty(bindingProperty.name()); }); return; @@ -1093,9 +1098,10 @@ void DynamicPropertiesModelBackendDelegate::handleNameChanged() ModelNode targetNode = variantProperty.parentModelNode(); model->view()->executeInTransaction(__FUNCTION__, [=]() { + targetNode.removeProperty(variantProperty.name()); + targetNode.variantProperty(newName).setDynamicTypeNameAndValue(dynamicPropertyType, value); - targetNode.removeProperty(variantProperty.name()); }); } @@ -1167,6 +1173,11 @@ QVariant DynamicPropertiesModelBackendDelegate::variantValue() const return m_value.text(); } +QString DynamicPropertiesModelBackendDelegate::targetNode() const +{ + return m_targetNode; +} + StudioQmlComboBoxBackend *DynamicPropertiesModelBackendDelegate::type() { return &m_type; diff --git a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.h b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.h index c41875dfc09..766b4e7b87c 100644 --- a/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.h +++ b/src/plugins/qmldesigner/components/connectioneditor/dynamicpropertiesmodel.h @@ -135,6 +135,7 @@ class DynamicPropertiesModelBackendDelegate : public QObject { Q_OBJECT + Q_PROPERTY(QString targetNode READ targetNode NOTIFY targetNodeChanged) Q_PROPERTY(StudioQmlComboBoxBackend *type READ type CONSTANT) Q_PROPERTY(int currentRow READ currentRow WRITE setCurrentRow NOTIFY currentRowChanged) Q_PROPERTY(StudioQmlTextBackend *name READ name CONSTANT) @@ -148,6 +149,7 @@ signals: void currentRowChanged(); void nameChanged(); void valueChanged(); + void targetNodeChanged(); private: int currentRow() const; @@ -157,6 +159,7 @@ private: void handleValueChanged(); void handleException(); QVariant variantValue() const; + QString targetNode() const; StudioQmlComboBoxBackend *type(); @@ -168,6 +171,7 @@ private: StudioQmlTextBackend m_value; int m_currentRow = -1; QString m_exceptionError; + QString m_targetNode; }; } // namespace QmlDesigner