forked from qt-creator/qt-creator
QmlDesigner: Fix QML for bindings/properties
* 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 <henning.gruendl@qt.io> Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
This commit is contained in:
@@ -2,12 +2,38 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
PopupDialog {
|
PopupDialog {
|
||||||
property alias backend: form.backend
|
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 {
|
BindingsDialogForm {
|
||||||
id: form
|
id: form
|
||||||
y: 32
|
y: 32
|
||||||
|
height: 160
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,74 +3,58 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Controls
|
import QtQuick.Controls
|
||||||
import StudioControls
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
Item {
|
Column {
|
||||||
width: 400
|
id: root
|
||||||
height: 800
|
|
||||||
|
readonly property real horizontalSpacing: 10
|
||||||
|
readonly property real verticalSpacing: 16
|
||||||
|
readonly property real columnWidth: (root.width - root.horizontalSpacing) / 2
|
||||||
|
|
||||||
property var backend
|
property var backend
|
||||||
|
|
||||||
PopupLabel {
|
y: StudioTheme.Values.popupMargin
|
||||||
x: 10
|
width: parent.width
|
||||||
y: 25
|
spacing: root.verticalSpacing
|
||||||
text: qsTr("Target")
|
|
||||||
|
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 {
|
Row {
|
||||||
id: text111
|
spacing: root.horizontalSpacing
|
||||||
x: 80
|
|
||||||
y: 25
|
|
||||||
text: backend.targetNode
|
|
||||||
font.pixelSize: 15
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelComboBox {
|
StudioControls.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
|
|
||||||
}
|
|
||||||
|
|
||||||
PopupLabel {
|
|
||||||
x: 13
|
|
||||||
y: 111
|
|
||||||
text: qsTr("Source Propety")
|
|
||||||
}
|
|
||||||
|
|
||||||
TopLevelComboBox {
|
|
||||||
id: sourceNode
|
id: sourceNode
|
||||||
x: 135
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
y: 98
|
width: root.columnWidth
|
||||||
width: 156
|
|
||||||
|
|
||||||
model: backend.sourceNode.model ?? []
|
model: backend.sourceNode.model ?? []
|
||||||
|
|
||||||
onModelChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
onModelChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
||||||
|
|
||||||
onActivated: backend.sourceNode.activateIndex(sourceNode.currentIndex)
|
onActivated: backend.sourceNode.activateIndex(sourceNode.currentIndex)
|
||||||
property int currentTypeIndex: backend.sourceNode.currentIndex ?? 0
|
property int currentTypeIndex: backend.sourceNode.currentIndex ?? 0
|
||||||
onCurrentTypeIndexChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
onCurrentTypeIndexChanged: sourceNode.currentIndex = sourceNode.currentTypeIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupLabel {
|
PopupLabel {
|
||||||
x: 13
|
width: root.columnWidth
|
||||||
y: 88
|
text: backend.targetNode
|
||||||
text: qsTr("Source Node")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TopLevelComboBox {
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
spacing: root.horizontalSpacing
|
||||||
|
|
||||||
|
StudioControls.TopLevelComboBox {
|
||||||
id: sourceProperty
|
id: sourceProperty
|
||||||
x: 140
|
style: StudioTheme.Values.connectionPopupControlStyle
|
||||||
y: 121
|
width: root.columnWidth
|
||||||
width: 156
|
|
||||||
|
|
||||||
model: backend.sourceProperty.model ?? []
|
model: backend.sourceProperty.model ?? []
|
||||||
onModelChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
onModelChanged: sourceProperty.currentIndex = sourceProperty.currentTypeIndex
|
||||||
@@ -81,8 +65,9 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PopupLabel {
|
PopupLabel {
|
||||||
x: 10
|
width: root.columnWidth
|
||||||
y: 55
|
text: backend.property.currentText
|
||||||
text: qsTr("Property")
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,12 +2,38 @@
|
|||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import StudioTheme 1.0 as StudioTheme
|
||||||
|
|
||||||
PopupDialog {
|
PopupDialog {
|
||||||
property alias backend: form.backend
|
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 {
|
PropertiesDialogForm {
|
||||||
id: form
|
id: form
|
||||||
y: 32
|
y: 32
|
||||||
|
height: 180
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,68 +1,73 @@
|
|||||||
// Copyright (C) 2023 The Qt Company Ltd.
|
// Copyright (C) 2023 The Qt Company Ltd.
|
||||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||||
|
|
||||||
import QtQuick 2.15
|
import QtQuick
|
||||||
import QtQuick.Controls 2.15
|
import QtQuick.Controls
|
||||||
|
import StudioControls as StudioControls
|
||||||
|
import StudioTheme as StudioTheme
|
||||||
|
|
||||||
import StudioControls
|
Column {
|
||||||
|
id: root
|
||||||
|
|
||||||
Item {
|
readonly property real horizontalSpacing: 10
|
||||||
width: 400
|
readonly property real verticalSpacing: 16
|
||||||
height: 800
|
readonly property real columnWidth: (root.width - root.horizontalSpacing) / 2
|
||||||
|
|
||||||
property var backend
|
property var backend
|
||||||
|
|
||||||
|
y: StudioTheme.Values.popupMargin
|
||||||
|
width: parent.width
|
||||||
|
spacing: root.verticalSpacing
|
||||||
|
|
||||||
PopupLabel {
|
PopupLabel {
|
||||||
x: 10
|
text: qsTr("Type")
|
||||||
y: 25
|
tooltip: qsTr("The type of the property")
|
||||||
|
|
||||||
text: qsTr("Type:")
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
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 ?? []
|
model: backend.type.model ?? []
|
||||||
onActivated: backend.type.activateIndex(target.currentIndex)
|
onActivated: backend.type.activateIndex(type.currentIndex)
|
||||||
property int currentTypeIndex: backend.type.currentIndex ?? 0
|
property int currentTypeIndex: backend.type.currentIndex ?? 0
|
||||||
onCurrentTypeIndexChanged: target.currentIndex = target.currentTypeIndex
|
onCurrentTypeIndexChanged: type.currentIndex = type.currentTypeIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
PopupLabel {
|
Row {
|
||||||
x: 10
|
spacing: root.horizontalSpacing
|
||||||
y: 131
|
|
||||||
text: qsTr("Name")
|
PopupLabel { text: qsTr("Name") ; tooltip: qsTr("The name of the property.")}
|
||||||
|
PopupLabel { text: qsTr("Value"); tooltip: qsTr("The value of the property.") }
|
||||||
}
|
}
|
||||||
|
|
||||||
TextInput {
|
Row {
|
||||||
|
spacing: root.horizontalSpacing
|
||||||
|
StudioControls.TextField {
|
||||||
id: name
|
id: name
|
||||||
x: 70
|
|
||||||
y: 131
|
width: root.columnWidth
|
||||||
width: 156
|
actionIndicatorVisible: false
|
||||||
|
translationIndicatorVisible: false
|
||||||
|
|
||||||
text: backend.name.text ?? ""
|
text: backend.name.text ?? ""
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
backend.name.activateText(name.text)
|
backend.name.activateText(name.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
StudioControls.TextField {
|
||||||
PopupLabel {
|
|
||||||
x: 10
|
|
||||||
y: 81
|
|
||||||
text: qsTr("Value")
|
|
||||||
}
|
|
||||||
|
|
||||||
TextInput {
|
|
||||||
id: value
|
id: value
|
||||||
x: 70
|
|
||||||
y: 81
|
width: root.columnWidth
|
||||||
width: 156
|
actionIndicatorVisible: false
|
||||||
|
translationIndicatorVisible: false
|
||||||
|
|
||||||
|
|
||||||
text: backend.value.text ?? ""
|
text: backend.value.text ?? ""
|
||||||
onEditingFinished: {
|
onEditingFinished: {
|
||||||
backend.value.activateText(value.text)
|
backend.value.activateText(value.text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -553,12 +553,16 @@ void BindingModelBackendDelegate::setCurrentRow(int i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::sort(sourceNodes.begin(), sourceNodes.end());
|
std::sort(sourceNodes.begin(), sourceNodes.end());
|
||||||
m_sourceNode.setModel(sourceNodes);
|
|
||||||
|
|
||||||
QString sourceNodeName;
|
QString sourceNodeName;
|
||||||
QString sourcePropertyName;
|
QString sourcePropertyName;
|
||||||
model->getExpressionStrings(bindingProperty, &sourceNodeName, &sourcePropertyName);
|
model->getExpressionStrings(bindingProperty, &sourceNodeName, &sourcePropertyName);
|
||||||
|
|
||||||
|
if (!sourceNodes.contains(sourceNodeName))
|
||||||
|
sourceNodes.append(sourceNodeName);
|
||||||
|
|
||||||
|
m_sourceNode.setModel(sourceNodes);
|
||||||
|
|
||||||
m_sourceNode.setCurrentText(sourceNodeName);
|
m_sourceNode.setCurrentText(sourceNodeName);
|
||||||
|
|
||||||
m_sourceNodeProperty.setModel(model->possibleSourceProperties(bindingProperty));
|
m_sourceNodeProperty.setModel(model->possibleSourceProperties(bindingProperty));
|
||||||
|
@@ -1022,6 +1022,10 @@ void DynamicPropertiesModelBackendDelegate::setCurrentRow(int i)
|
|||||||
m_value.setText(property.toVariantProperty().value().toString());
|
m_value.setText(property.toVariantProperty().value().toString());
|
||||||
else if (property.isBindingProperty())
|
else if (property.isBindingProperty())
|
||||||
m_value.setText(property.toBindingProperty().expression());
|
m_value.setText(property.toBindingProperty().expression());
|
||||||
|
|
||||||
|
m_targetNode = property.parentModelNode().id();
|
||||||
|
|
||||||
|
emit targetNodeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DynamicPropertiesModelBackendDelegate::handleTypeChanged()
|
void DynamicPropertiesModelBackendDelegate::handleTypeChanged()
|
||||||
@@ -1077,9 +1081,10 @@ void DynamicPropertiesModelBackendDelegate::handleNameChanged()
|
|||||||
const QString expression = bindingProperty.expression();
|
const QString expression = bindingProperty.expression();
|
||||||
const PropertyName dynamicPropertyType = bindingProperty.dynamicTypeName();
|
const PropertyName dynamicPropertyType = bindingProperty.dynamicTypeName();
|
||||||
|
|
||||||
|
targetNode.removeProperty(bindingProperty.name());
|
||||||
|
|
||||||
targetNode.bindingProperty(newName).setDynamicTypeNameAndExpression(dynamicPropertyType,
|
targetNode.bindingProperty(newName).setDynamicTypeNameAndExpression(dynamicPropertyType,
|
||||||
expression);
|
expression);
|
||||||
targetNode.removeProperty(bindingProperty.name());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -1093,9 +1098,10 @@ void DynamicPropertiesModelBackendDelegate::handleNameChanged()
|
|||||||
ModelNode targetNode = variantProperty.parentModelNode();
|
ModelNode targetNode = variantProperty.parentModelNode();
|
||||||
|
|
||||||
model->view()->executeInTransaction(__FUNCTION__, [=]() {
|
model->view()->executeInTransaction(__FUNCTION__, [=]() {
|
||||||
|
targetNode.removeProperty(variantProperty.name());
|
||||||
|
|
||||||
targetNode.variantProperty(newName).setDynamicTypeNameAndValue(dynamicPropertyType,
|
targetNode.variantProperty(newName).setDynamicTypeNameAndValue(dynamicPropertyType,
|
||||||
value);
|
value);
|
||||||
targetNode.removeProperty(variantProperty.name());
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1167,6 +1173,11 @@ QVariant DynamicPropertiesModelBackendDelegate::variantValue() const
|
|||||||
return m_value.text();
|
return m_value.text();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString DynamicPropertiesModelBackendDelegate::targetNode() const
|
||||||
|
{
|
||||||
|
return m_targetNode;
|
||||||
|
}
|
||||||
|
|
||||||
StudioQmlComboBoxBackend *DynamicPropertiesModelBackendDelegate::type()
|
StudioQmlComboBoxBackend *DynamicPropertiesModelBackendDelegate::type()
|
||||||
{
|
{
|
||||||
return &m_type;
|
return &m_type;
|
||||||
|
@@ -135,6 +135,7 @@ class DynamicPropertiesModelBackendDelegate : public QObject
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QString targetNode READ targetNode NOTIFY targetNodeChanged)
|
||||||
Q_PROPERTY(StudioQmlComboBoxBackend *type READ type CONSTANT)
|
Q_PROPERTY(StudioQmlComboBoxBackend *type READ type CONSTANT)
|
||||||
Q_PROPERTY(int currentRow READ currentRow WRITE setCurrentRow NOTIFY currentRowChanged)
|
Q_PROPERTY(int currentRow READ currentRow WRITE setCurrentRow NOTIFY currentRowChanged)
|
||||||
Q_PROPERTY(StudioQmlTextBackend *name READ name CONSTANT)
|
Q_PROPERTY(StudioQmlTextBackend *name READ name CONSTANT)
|
||||||
@@ -148,6 +149,7 @@ signals:
|
|||||||
void currentRowChanged();
|
void currentRowChanged();
|
||||||
void nameChanged();
|
void nameChanged();
|
||||||
void valueChanged();
|
void valueChanged();
|
||||||
|
void targetNodeChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int currentRow() const;
|
int currentRow() const;
|
||||||
@@ -157,6 +159,7 @@ private:
|
|||||||
void handleValueChanged();
|
void handleValueChanged();
|
||||||
void handleException();
|
void handleException();
|
||||||
QVariant variantValue() const;
|
QVariant variantValue() const;
|
||||||
|
QString targetNode() const;
|
||||||
|
|
||||||
StudioQmlComboBoxBackend *type();
|
StudioQmlComboBoxBackend *type();
|
||||||
|
|
||||||
@@ -168,6 +171,7 @@ private:
|
|||||||
StudioQmlTextBackend m_value;
|
StudioQmlTextBackend m_value;
|
||||||
int m_currentRow = -1;
|
int m_currentRow = -1;
|
||||||
QString m_exceptionError;
|
QString m_exceptionError;
|
||||||
|
QString m_targetNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
Reference in New Issue
Block a user