forked from qt-creator/qt-creator
DynamicPropertiesModel: handle instance property changes
Instance property changes are now taken into account for dynamic properties. This avoids situations where the property value is cleared unintentionally. Task-number: QDS-13513 Change-Id: I2b52ae2db721bf09b2310ba7c5bd4b3e0de3fab2 Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
@@ -19,7 +19,8 @@ QHash<int, QByteArray> DynamicPropertiesItem::roleNames()
|
||||
return {{TargetNameRole, "target"},
|
||||
{PropertyNameRole, "name"},
|
||||
{PropertyTypeRole, "type"},
|
||||
{PropertyValueRole, "value"}};
|
||||
{PropertyValueRole, "value"},
|
||||
{InstancePropertyValueRole, "instanceValue"}};
|
||||
}
|
||||
|
||||
QStringList DynamicPropertiesItem::headerLabels()
|
||||
@@ -58,6 +59,9 @@ void DynamicPropertiesItem::updateProperty(const AbstractProperty &property)
|
||||
setData(property.name().toByteArray(), PropertyNameRole);
|
||||
setData(property.dynamicTypeName(), PropertyTypeRole);
|
||||
|
||||
const auto qmlObjectNode = QmlObjectNode(property.parentModelNode());
|
||||
setData(qmlObjectNode.instanceValue(property.name()), InstancePropertyValueRole);
|
||||
|
||||
if (property.isVariantProperty()) {
|
||||
if (std::optional<const QmlObjectNode> nodeInState = parentIfNotDefaultState(property))
|
||||
setData(nodeInState->modelValue(property.name()), PropertyValueRole);
|
||||
|
@@ -18,7 +18,8 @@ public:
|
||||
TargetNameRole,
|
||||
PropertyNameRole,
|
||||
PropertyTypeRole,
|
||||
PropertyValueRole
|
||||
PropertyValueRole,
|
||||
InstancePropertyValueRole
|
||||
};
|
||||
|
||||
static QHash<int, QByteArray> roleNames();
|
||||
|
@@ -355,6 +355,21 @@ void DynamicPropertiesModel::dispatchPropertyChanges(const AbstractProperty &abs
|
||||
}
|
||||
}
|
||||
|
||||
void DynamicPropertiesModel::handleInstancePropertyChanged(const ModelNode &modelNode,
|
||||
PropertyNameView propertyName)
|
||||
{
|
||||
if (modelNode != singleSelectedNode())
|
||||
return;
|
||||
|
||||
QmlObjectNode qmlObjectNode(modelNode);
|
||||
if (qmlObjectNode.isValid() && qmlObjectNode.currentState().isValid()) {
|
||||
const AbstractProperty property = modelNode.property(propertyName);
|
||||
if (property.isDynamic()) {
|
||||
updateItem(property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QList<ModelNode> DynamicPropertiesModel::selectedNodes() const
|
||||
{
|
||||
if (m_explicitSelection)
|
||||
|
@@ -57,6 +57,8 @@ public:
|
||||
|
||||
void dispatchPropertyChanges(const AbstractProperty &abstractProperty);
|
||||
|
||||
void handleInstancePropertyChanged(const ModelNode &modelNode, PropertyNameView propertyName);
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
|
@@ -71,8 +71,10 @@ void DynamicPropertiesProxyModel::initModel(DynamicPropertiesModel *model)
|
||||
connect(m_model, &QAbstractItemModel::rowsInserted,
|
||||
this, &QAbstractItemModel::rowsInserted);
|
||||
|
||||
connect(m_model, &QAbstractItemModel::dataChanged,
|
||||
this, [this](const QModelIndex &topLeft, const QModelIndex &, const QList<int> &) {
|
||||
connect(m_model,
|
||||
&QAbstractItemModel::dataChanged,
|
||||
this,
|
||||
[this](const QModelIndex &topLeft, const QModelIndex &, const QList<int> &) {
|
||||
emit dataChanged(index(topLeft.row(), 0),
|
||||
index(topLeft.row(), 0),
|
||||
{ propertyNameRole, propertyTypeRole,
|
||||
@@ -302,19 +304,28 @@ void DynamicPropertyRow::setupBackendValue()
|
||||
if (node != m_backendValue->modelNode())
|
||||
m_backendValue->setModelNode(node);
|
||||
|
||||
QVariant modelValue = QmlObjectNode{property.parentModelNode()}.modelValue(property.name());
|
||||
|
||||
const bool isBound = QmlObjectNode{property.parentModelNode()}.hasBindingProperty(property.name());
|
||||
|
||||
if (modelValue != m_backendValue->value()) {
|
||||
m_backendValue->setValue({});
|
||||
m_backendValue->setValue(modelValue);
|
||||
}
|
||||
|
||||
if (isBound) {
|
||||
QString expression = QmlObjectNode{property.parentModelNode()}.expression(property.name());
|
||||
if (m_backendValue->expression() != expression)
|
||||
m_backendValue->setExpression(expression);
|
||||
auto qmlObjectNode = QmlObjectNode{property.parentModelNode()};
|
||||
auto propertyName = property.name();
|
||||
|
||||
if (qmlObjectNode.propertyAffectedByCurrentState(propertyName)
|
||||
&& !(qmlObjectNode.hasBindingProperty(propertyName))) {
|
||||
m_backendValue->setValue(qmlObjectNode.modelValue(propertyName));
|
||||
} else
|
||||
m_backendValue->setValue(qmlObjectNode.instanceValue(propertyName));
|
||||
|
||||
if (qmlObjectNode.currentState().isBaseState()
|
||||
&& qmlObjectNode.modelNode().property(propertyName).isBindingProperty()) {
|
||||
m_backendValue->setExpression(
|
||||
qmlObjectNode.modelNode().bindingProperty(propertyName).expression());
|
||||
} else {
|
||||
if (qmlObjectNode.hasBindingProperty(propertyName)
|
||||
&& !qmlObjectNode.expression(propertyName).isEmpty()) {
|
||||
m_backendValue->setExpression(qmlObjectNode.expression(propertyName));
|
||||
} else {
|
||||
m_backendValue->setExpression(qmlObjectNode.instanceValue(propertyName).toString());
|
||||
}
|
||||
}
|
||||
|
||||
emit m_backendValue->isBoundChanged();
|
||||
@@ -342,23 +353,26 @@ void DynamicPropertyRow::commitValue(const QVariant &value)
|
||||
|
||||
auto view = propertiesModel->view();
|
||||
RewriterTransaction transaction = view->beginRewriterTransaction(__FUNCTION__);
|
||||
|
||||
try {
|
||||
QmlObjectNode objectNode = property.parentModelNode();
|
||||
if (QmlModelState::isBaseState(view->currentStateNode())
|
||||
&& !(objectNode.timelineIsActive() && objectNode.currentTimeline().isRecording())) {
|
||||
if (property.isBindingProperty()) {
|
||||
convertBindingToVariantProperty(property.toBindingProperty(), value);
|
||||
} else if (property.isVariantProperty()) {
|
||||
VariantProperty variantProperty = property.toVariantProperty();
|
||||
QmlObjectNode objectNode = variantProperty.parentModelNode();
|
||||
if (QmlModelState::isBaseState(view->currentStateNode())
|
||||
&& !(objectNode.timelineIsActive() && objectNode.currentTimeline().isRecording())) {
|
||||
if (variantProperty.value() != value)
|
||||
variantProperty.setDynamicTypeNameAndValue(variantProperty.dynamicTypeName(), value);
|
||||
if (variantProperty.value() != value) {
|
||||
variantProperty.setDynamicTypeNameAndValue(variantProperty.dynamicTypeName(),
|
||||
value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
QTC_CHECK(objectNode.isValid());
|
||||
PropertyNameView name = variantProperty.name();
|
||||
PropertyNameView name = property.name();
|
||||
if (objectNode.isValid() && objectNode.modelValue(name) != value)
|
||||
objectNode.setVariantProperty(name, value);
|
||||
}
|
||||
}
|
||||
transaction.commit(); // committing in the try block
|
||||
} catch (Exception &e) {
|
||||
e.showException();
|
||||
|
@@ -1093,6 +1093,8 @@ void PropertyEditorView::instancePropertyChanged(const QList<QPair<ModelNode, Pr
|
||||
setValue(modelNode, property.name(), qmlObjectNode.modelValue(property.name()));
|
||||
changed = true;
|
||||
}
|
||||
|
||||
m_dynamicPropertiesModel->handleInstancePropertyChanged(modelNode, propertyName);
|
||||
}
|
||||
|
||||
if (changed)
|
||||
|
Reference in New Issue
Block a user