2022-08-19 15:59:36 +02:00
|
|
|
// Copyright (C) 2016 The Qt Company Ltd.
|
2022-12-21 10:12:09 +01:00
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
#include "dynamicpropertiesmodel.h"
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
#include "bindingproperty.h"
|
|
|
|
|
#include "nodeabstractproperty.h"
|
|
|
|
|
#include "nodemetainfo.h"
|
|
|
|
|
#include "qmlchangeset.h"
|
|
|
|
|
#include "qmldesignerconstants.h"
|
|
|
|
|
#include "qmldesignerplugin.h"
|
|
|
|
|
#include "qmlobjectnode.h"
|
|
|
|
|
#include "qmltimeline.h"
|
|
|
|
|
#include "rewritertransaction.h"
|
|
|
|
|
#include "rewritingexception.h"
|
|
|
|
|
#include "variantproperty.h"
|
2015-09-18 15:38:15 +02:00
|
|
|
|
2022-06-09 17:03:42 +02:00
|
|
|
#include <utils/algorithm.h>
|
2022-07-22 16:46:48 +02:00
|
|
|
#include <utils/qtcassert.h>
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
#include <QMessageBox>
|
|
|
|
|
#include <QTimer>
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
bool compareVariantProperties(const QmlDesigner::VariantProperty &variantProp1,
|
|
|
|
|
const QmlDesigner::VariantProperty &variantProp2)
|
2015-09-18 15:38:15 +02:00
|
|
|
{
|
2023-03-16 16:26:36 +02:00
|
|
|
if (variantProp1.parentModelNode() != variantProp2.parentModelNode())
|
2015-09-18 15:38:15 +02:00
|
|
|
return false;
|
2023-03-16 16:26:36 +02:00
|
|
|
if (variantProp1.name() != variantProp2.name())
|
2015-09-18 15:38:15 +02:00
|
|
|
return false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString idOrTypeNameForNode(const QmlDesigner::ModelNode &modelNode)
|
|
|
|
|
{
|
|
|
|
|
QString idLabel = modelNode.id();
|
|
|
|
|
if (idLabel.isEmpty())
|
2016-03-23 12:34:03 +01:00
|
|
|
idLabel = modelNode.simplifiedTypeName();
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
return idLabel;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant convertVariantForTypeName(const QVariant &variant, const QmlDesigner::TypeName &typeName)
|
|
|
|
|
{
|
|
|
|
|
QVariant returnValue = variant;
|
|
|
|
|
|
|
|
|
|
if (typeName == "int") {
|
|
|
|
|
bool ok;
|
|
|
|
|
returnValue = variant.toInt(&ok);
|
|
|
|
|
if (!ok)
|
|
|
|
|
returnValue = 0;
|
|
|
|
|
} else if (typeName == "real") {
|
|
|
|
|
bool ok;
|
|
|
|
|
returnValue = variant.toReal(&ok);
|
|
|
|
|
if (!ok)
|
|
|
|
|
returnValue = 0.0;
|
|
|
|
|
|
|
|
|
|
} else if (typeName == "string") {
|
|
|
|
|
returnValue = variant.toString();
|
|
|
|
|
|
|
|
|
|
} else if (typeName == "bool") {
|
|
|
|
|
returnValue = variant.toBool();
|
|
|
|
|
} else if (typeName == "url") {
|
|
|
|
|
returnValue = variant.toUrl();
|
|
|
|
|
} else if (typeName == "color") {
|
|
|
|
|
if (QColor::isValidColor(variant.toString())) {
|
|
|
|
|
returnValue = variant.toString();
|
|
|
|
|
} else {
|
|
|
|
|
returnValue = QColor(Qt::black);
|
|
|
|
|
}
|
2022-07-22 16:46:48 +02:00
|
|
|
} else if (typeName == "vector2d") {
|
|
|
|
|
returnValue = "Qt.vector2d(0, 0)";
|
|
|
|
|
} else if (typeName == "vector3d") {
|
|
|
|
|
returnValue = "Qt.vector3d(0, 0, 0)";
|
|
|
|
|
} else if (typeName == "vector4d") {
|
|
|
|
|
returnValue = "Qt.vector4d(0, 0, 0 ,0)";
|
|
|
|
|
} else if (typeName == "TextureInput") {
|
|
|
|
|
returnValue = "null";
|
|
|
|
|
} else if (typeName == "alias") {
|
|
|
|
|
returnValue = "null";
|
2015-09-18 15:38:15 +02:00
|
|
|
} else if (typeName == "Item") {
|
2022-09-09 10:14:04 +02:00
|
|
|
returnValue = "null";
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return returnValue;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
} // namespace
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
namespace QmlDesigner {
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
PropertyName DynamicPropertiesModel::unusedProperty(const ModelNode &modelNode)
|
2022-07-07 19:03:51 +02:00
|
|
|
{
|
2023-03-16 16:26:36 +02:00
|
|
|
PropertyName propertyName = "property";
|
2022-07-07 19:03:51 +02:00
|
|
|
int i = 0;
|
2022-09-06 09:57:20 +03:00
|
|
|
if (modelNode.isValid() && modelNode.metaInfo().isValid()) {
|
2022-07-07 19:03:51 +02:00
|
|
|
while (true) {
|
2023-03-16 16:26:36 +02:00
|
|
|
const PropertyName currentPropertyName = propertyName + QString::number(i++).toLatin1();
|
2022-07-07 19:03:51 +02:00
|
|
|
if (!modelNode.hasProperty(currentPropertyName) && !modelNode.metaInfo().hasProperty(currentPropertyName))
|
|
|
|
|
return currentPropertyName;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return propertyName;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
bool DynamicPropertiesModel::isValueType(const TypeName &type)
|
|
|
|
|
{
|
|
|
|
|
// "variant" is considered value type as it is initialized as one.
|
|
|
|
|
// This may need to change if we provide any kind of proper editor for it.
|
|
|
|
|
static const QSet<TypeName> valueTypes {"int", "real", "color", "string", "bool", "url", "variant"};
|
|
|
|
|
return valueTypes.contains(type);
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 16:33:23 +02:00
|
|
|
QVariant DynamicPropertiesModel::defaultValueForType(const TypeName &type)
|
|
|
|
|
{
|
|
|
|
|
QVariant value;
|
|
|
|
|
if (type == "int")
|
|
|
|
|
value = 0;
|
|
|
|
|
else if (type == "real")
|
|
|
|
|
value = 0.0;
|
|
|
|
|
else if (type == "color")
|
|
|
|
|
value = QColor(255, 255, 255);
|
|
|
|
|
else if (type == "string")
|
|
|
|
|
value = "This is a string";
|
|
|
|
|
else if (type == "bool")
|
|
|
|
|
value = false;
|
|
|
|
|
else if (type == "url")
|
|
|
|
|
value = "";
|
|
|
|
|
else if (type == "variant")
|
|
|
|
|
value = "";
|
|
|
|
|
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString DynamicPropertiesModel::defaultExpressionForType(const TypeName &type)
|
|
|
|
|
{
|
|
|
|
|
QString expression;
|
|
|
|
|
if (type == "alias")
|
|
|
|
|
expression = "null";
|
|
|
|
|
else if (type == "TextureInput")
|
|
|
|
|
expression = "null";
|
|
|
|
|
else if (type == "vector2d")
|
|
|
|
|
expression = "Qt.vector2d(0, 0)";
|
|
|
|
|
else if (type == "vector3d")
|
|
|
|
|
expression = "Qt.vector3d(0, 0, 0)";
|
|
|
|
|
else if (type == "vector4d")
|
|
|
|
|
expression = "Qt.vector4d(0, 0, 0 ,0)";
|
|
|
|
|
|
|
|
|
|
return expression;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-04 19:57:59 +02:00
|
|
|
void DynamicPropertiesModel::add()
|
|
|
|
|
{
|
|
|
|
|
addDynamicPropertyForCurrentNode();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::remove(int row)
|
|
|
|
|
{
|
|
|
|
|
deleteDynamicPropertyByRow(row);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int DynamicPropertiesModel::currentIndex() const
|
|
|
|
|
{
|
|
|
|
|
return m_currentIndex;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::setCurrentIndex(int i)
|
|
|
|
|
{
|
|
|
|
|
if (m_currentIndex == i)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
m_currentIndex = i;
|
|
|
|
|
|
|
|
|
|
emit currentIndexChanged();
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
DynamicPropertiesModel::DynamicPropertiesModel(bool explicitSelection, AbstractView *parent)
|
2023-07-04 19:57:59 +02:00
|
|
|
: QStandardItemModel(parent), m_view(parent), m_explicitSelection(explicitSelection),
|
|
|
|
|
m_delegate(new DynamicPropertiesModelBackendDelegate(this))
|
2015-09-18 15:38:15 +02:00
|
|
|
{
|
2016-05-18 20:54:02 +02:00
|
|
|
connect(this, &QStandardItemModel::dataChanged, this, &DynamicPropertiesModel::handleDataChanged);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::resetModel()
|
|
|
|
|
{
|
|
|
|
|
beginResetModel();
|
2023-07-04 19:57:59 +02:00
|
|
|
const int backIndex = m_currentIndex;
|
2016-05-18 20:54:02 +02:00
|
|
|
clear();
|
2023-03-16 16:26:36 +02:00
|
|
|
setHorizontalHeaderLabels({tr("Item"), tr("Property"), tr("Property Type"), tr("Property Value")});
|
2016-05-18 20:54:02 +02:00
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
if (m_view->isAttached()) {
|
|
|
|
|
const auto nodes = selectedNodes();
|
|
|
|
|
for (const ModelNode &modelNode : nodes)
|
2020-10-05 19:26:13 +02:00
|
|
|
addModelNode(modelNode);
|
|
|
|
|
}
|
2016-05-18 20:54:02 +02:00
|
|
|
|
2023-07-04 19:57:59 +02:00
|
|
|
emit currentIndexChanged();
|
2016-05-18 20:54:02 +02:00
|
|
|
endResetModel();
|
2023-07-04 19:57:59 +02:00
|
|
|
m_currentIndex = backIndex;
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
2020-06-02 14:17:33 +02:00
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
// Method creates dynamic BindingProperty with the same name and type as old VariantProperty
|
|
|
|
|
// Value copying is optional
|
2020-06-02 14:17:33 +02:00
|
|
|
BindingProperty DynamicPropertiesModel::replaceVariantWithBinding(const PropertyName &name, bool copyValue)
|
|
|
|
|
{
|
2023-06-07 13:03:11 +02:00
|
|
|
if (selectedNodes().size() == 1) {
|
2022-07-22 16:46:48 +02:00
|
|
|
const ModelNode modelNode = selectedNodes().constFirst();
|
2020-06-02 14:17:33 +02:00
|
|
|
if (modelNode.isValid()) {
|
|
|
|
|
if (modelNode.hasVariantProperty(name)) {
|
|
|
|
|
try {
|
|
|
|
|
VariantProperty vprop = modelNode.variantProperty(name);
|
|
|
|
|
TypeName oldType = vprop.dynamicTypeName();
|
|
|
|
|
QVariant oldValue = vprop.value();
|
|
|
|
|
|
|
|
|
|
modelNode.removeProperty(name);
|
|
|
|
|
|
|
|
|
|
BindingProperty bprop = modelNode.bindingProperty(name);
|
|
|
|
|
if (bprop.isValid()) {
|
|
|
|
|
if (copyValue)
|
|
|
|
|
bprop.setDynamicTypeNameAndExpression(oldType, oldValue.toString());
|
|
|
|
|
return bprop;
|
|
|
|
|
}
|
|
|
|
|
} catch (RewritingException &e) {
|
|
|
|
|
m_exceptionError = e.description();
|
|
|
|
|
QTimer::singleShot(200, this, &DynamicPropertiesModel::handleException);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << "DynamicPropertiesModel::replaceVariantWithBinding: no selected nodes";
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
return {};
|
2020-06-02 14:17:33 +02:00
|
|
|
}
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
// Finds selected property, and changes it to empty value (QVariant())
|
|
|
|
|
// If it's a BindingProperty, then replaces it with empty VariantProperty
|
2020-06-02 14:17:33 +02:00
|
|
|
void DynamicPropertiesModel::resetProperty(const PropertyName &name)
|
|
|
|
|
{
|
2023-06-07 13:03:11 +02:00
|
|
|
if (selectedNodes().size() == 1) {
|
2022-07-22 16:46:48 +02:00
|
|
|
const ModelNode modelNode = selectedNodes().constFirst();
|
2020-06-02 14:17:33 +02:00
|
|
|
if (modelNode.isValid()) {
|
|
|
|
|
if (modelNode.hasProperty(name)) {
|
|
|
|
|
try {
|
|
|
|
|
AbstractProperty abProp = modelNode.property(name);
|
|
|
|
|
|
|
|
|
|
if (abProp.isVariantProperty()) {
|
|
|
|
|
VariantProperty property = abProp.toVariantProperty();
|
2022-07-22 16:46:48 +02:00
|
|
|
QVariant newValue = convertVariantForTypeName({}, property.dynamicTypeName());
|
2020-06-02 14:17:33 +02:00
|
|
|
property.setDynamicTypeNameAndValue(property.dynamicTypeName(),
|
|
|
|
|
newValue);
|
2022-07-22 16:46:48 +02:00
|
|
|
} else if (abProp.isBindingProperty()) {
|
2020-06-02 14:17:33 +02:00
|
|
|
BindingProperty property = abProp.toBindingProperty();
|
|
|
|
|
TypeName oldType = property.dynamicTypeName();
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
// removing old property, to create the new one with the same name
|
2020-06-02 14:17:33 +02:00
|
|
|
modelNode.removeProperty(name);
|
|
|
|
|
|
|
|
|
|
VariantProperty newProperty = modelNode.variantProperty(name);
|
2022-07-22 16:46:48 +02:00
|
|
|
QVariant newValue = convertVariantForTypeName({}, oldType);
|
|
|
|
|
newProperty.setDynamicTypeNameAndValue(oldType, newValue);
|
2020-06-02 14:17:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} catch (RewritingException &e) {
|
|
|
|
|
m_exceptionError = e.description();
|
|
|
|
|
QTimer::singleShot(200, this, &DynamicPropertiesModel::handleException);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-16 16:26:36 +02:00
|
|
|
} else {
|
2020-06-02 14:17:33 +02:00
|
|
|
qWarning() << "DynamicPropertiesModel::resetProperty: no selected nodes";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 16:33:23 +02:00
|
|
|
void DynamicPropertiesModel::dispatchPropertyChanges(const AbstractProperty &abstractProperty)
|
|
|
|
|
{
|
|
|
|
|
if (abstractProperty.parentModelNode().simplifiedTypeName() == "PropertyChanges") {
|
|
|
|
|
QmlPropertyChanges changes(abstractProperty.parentModelNode());
|
|
|
|
|
if (changes.target().isValid()) {
|
|
|
|
|
const ModelNode target = changes.target();
|
|
|
|
|
const PropertyName propertyName = abstractProperty.name();
|
|
|
|
|
const AbstractProperty targetProperty = target.variantProperty(propertyName);
|
|
|
|
|
if (target.hasProperty(propertyName) && targetProperty.isDynamic())
|
|
|
|
|
abstractPropertyChanged(targetProperty);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-18 15:38:15 +02:00
|
|
|
void DynamicPropertiesModel::bindingPropertyChanged(const BindingProperty &bindingProperty)
|
|
|
|
|
{
|
|
|
|
|
if (!bindingProperty.isDynamic())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
m_handleDataChanged = false;
|
|
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
const QList<ModelNode> nodes = selectedNodes();
|
|
|
|
|
if (!nodes.contains(bindingProperty.parentModelNode()))
|
2015-09-18 15:38:15 +02:00
|
|
|
return;
|
2023-03-16 16:26:36 +02:00
|
|
|
|
2015-09-18 15:38:15 +02:00
|
|
|
if (!m_lock) {
|
|
|
|
|
int rowNumber = findRowForBindingProperty(bindingProperty);
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
if (rowNumber == -1)
|
2015-09-18 15:38:15 +02:00
|
|
|
addBindingProperty(bindingProperty);
|
2023-03-16 16:26:36 +02:00
|
|
|
else
|
2015-09-18 15:38:15 +02:00
|
|
|
updateBindingProperty(rowNumber);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_handleDataChanged = true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 16:33:23 +02:00
|
|
|
void DynamicPropertiesModel::abstractPropertyChanged(const AbstractProperty &property)
|
|
|
|
|
{
|
|
|
|
|
if (!property.isDynamic())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
m_handleDataChanged = false;
|
|
|
|
|
|
|
|
|
|
const QList<ModelNode> nodes = selectedNodes();
|
|
|
|
|
if (!nodes.contains(property.parentModelNode()))
|
|
|
|
|
return;
|
2023-03-16 16:26:36 +02:00
|
|
|
|
2022-09-09 16:33:23 +02:00
|
|
|
int rowNumber = findRowForProperty(property);
|
|
|
|
|
if (rowNumber > -1) {
|
|
|
|
|
if (property.isVariantProperty())
|
|
|
|
|
updateVariantProperty(rowNumber);
|
|
|
|
|
else
|
|
|
|
|
updateBindingProperty(rowNumber);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_handleDataChanged = true;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-18 15:38:15 +02:00
|
|
|
void DynamicPropertiesModel::variantPropertyChanged(const VariantProperty &variantProperty)
|
|
|
|
|
{
|
|
|
|
|
if (!variantProperty.isDynamic())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
m_handleDataChanged = false;
|
|
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
const QList<ModelNode> nodes = selectedNodes();
|
|
|
|
|
if (!nodes.contains(variantProperty.parentModelNode()))
|
2015-09-18 15:38:15 +02:00
|
|
|
return;
|
2023-03-16 16:26:36 +02:00
|
|
|
|
2015-09-18 15:38:15 +02:00
|
|
|
if (!m_lock) {
|
|
|
|
|
int rowNumber = findRowForVariantProperty(variantProperty);
|
|
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
if (rowNumber == -1)
|
2015-09-18 15:38:15 +02:00
|
|
|
addVariantProperty(variantProperty);
|
2022-07-22 16:46:48 +02:00
|
|
|
else
|
2015-09-18 15:38:15 +02:00
|
|
|
updateVariantProperty(rowNumber);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_handleDataChanged = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::bindingRemoved(const BindingProperty &bindingProperty)
|
|
|
|
|
{
|
|
|
|
|
m_handleDataChanged = false;
|
|
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
const QList<ModelNode> nodes = selectedNodes();
|
|
|
|
|
if (!nodes.contains(bindingProperty.parentModelNode()))
|
2015-09-18 15:38:15 +02:00
|
|
|
return;
|
2023-03-16 16:26:36 +02:00
|
|
|
|
2015-09-18 15:38:15 +02:00
|
|
|
if (!m_lock) {
|
|
|
|
|
int rowNumber = findRowForBindingProperty(bindingProperty);
|
|
|
|
|
removeRow(rowNumber);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-04 19:57:59 +02:00
|
|
|
emit currentIndexChanged();
|
|
|
|
|
|
2015-09-18 15:38:15 +02:00
|
|
|
m_handleDataChanged = true;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
void DynamicPropertiesModel::variantRemoved(const VariantProperty &variantProperty)
|
|
|
|
|
{
|
|
|
|
|
m_handleDataChanged = false;
|
|
|
|
|
|
|
|
|
|
const QList<ModelNode> nodes = selectedNodes();
|
|
|
|
|
if (!nodes.contains(variantProperty.parentModelNode()))
|
|
|
|
|
return;
|
2023-03-16 16:26:36 +02:00
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
if (!m_lock) {
|
|
|
|
|
int rowNumber = findRowForVariantProperty(variantProperty);
|
|
|
|
|
removeRow(rowNumber);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-04 19:57:59 +02:00
|
|
|
emit currentIndexChanged();
|
|
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
m_handleDataChanged = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::reset()
|
2015-09-18 15:38:15 +02:00
|
|
|
{
|
|
|
|
|
m_handleDataChanged = false;
|
|
|
|
|
resetModel();
|
|
|
|
|
m_handleDataChanged = true;
|
2023-07-04 19:57:59 +02:00
|
|
|
emit currentIndexChanged();
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
void DynamicPropertiesModel::setSelectedNode(const ModelNode &node)
|
2015-09-18 15:38:15 +02:00
|
|
|
{
|
2022-07-22 16:46:48 +02:00
|
|
|
QTC_ASSERT(m_explicitSelection, return);
|
2023-01-26 17:14:10 +01:00
|
|
|
|
|
|
|
|
if (!node.isValid())
|
|
|
|
|
return;
|
2022-07-22 16:46:48 +02:00
|
|
|
|
|
|
|
|
m_selectedNodes.clear();
|
|
|
|
|
m_selectedNodes.append(node);
|
|
|
|
|
reset();
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
2020-06-02 14:17:33 +02:00
|
|
|
AbstractProperty DynamicPropertiesModel::abstractPropertyForRow(int rowNumber) const
|
2015-09-18 15:38:15 +02:00
|
|
|
{
|
2020-06-02 14:17:33 +02:00
|
|
|
const int internalId = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 1).toInt();
|
2022-09-09 16:33:23 +02:00
|
|
|
const QString targetPropertyName = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 2)
|
|
|
|
|
.toString();
|
2020-06-02 14:17:33 +02:00
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
if (!m_view->isAttached())
|
2022-07-11 15:20:39 +02:00
|
|
|
return AbstractProperty();
|
|
|
|
|
|
2022-09-09 16:33:23 +02:00
|
|
|
ModelNode modelNode = m_view->modelNodeForInternalId(internalId);
|
2015-09-18 15:38:15 +02:00
|
|
|
|
2020-06-02 14:17:33 +02:00
|
|
|
if (modelNode.isValid())
|
|
|
|
|
return modelNode.property(targetPropertyName.toUtf8());
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
return {};
|
2020-06-02 14:17:33 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BindingProperty DynamicPropertiesModel::bindingPropertyForRow(int rowNumber) const
|
|
|
|
|
{
|
2015-09-18 15:38:15 +02:00
|
|
|
const int internalId = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 1).toInt();
|
|
|
|
|
const QString targetPropertyName = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 2).toString();
|
|
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
ModelNode modelNode = m_view->modelNodeForInternalId(internalId);
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
if (modelNode.isValid())
|
2016-03-23 12:34:03 +01:00
|
|
|
return modelNode.bindingProperty(targetPropertyName.toUtf8());
|
2015-09-18 15:38:15 +02:00
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
return {};
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VariantProperty DynamicPropertiesModel::variantPropertyForRow(int rowNumber) const
|
|
|
|
|
{
|
|
|
|
|
const int internalId = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 1).toInt();
|
|
|
|
|
const QString targetPropertyName = data(index(rowNumber, TargetModelNodeRow), Qt::UserRole + 2).toString();
|
|
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
ModelNode modelNode = m_view->modelNodeForInternalId(internalId);
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
if (modelNode.isValid())
|
2016-03-23 12:34:03 +01:00
|
|
|
return modelNode.variantProperty(targetPropertyName.toUtf8());
|
2015-09-18 15:38:15 +02:00
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
return {};
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList DynamicPropertiesModel::possibleTargetProperties(const BindingProperty &bindingProperty) const
|
|
|
|
|
{
|
|
|
|
|
const ModelNode modelNode = bindingProperty.parentModelNode();
|
|
|
|
|
|
|
|
|
|
if (!modelNode.isValid()) {
|
|
|
|
|
qWarning() << " BindingModel::possibleTargetPropertiesForRow invalid model node";
|
|
|
|
|
return QStringList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NodeMetaInfo metaInfo = modelNode.metaInfo();
|
|
|
|
|
|
|
|
|
|
if (metaInfo.isValid()) {
|
|
|
|
|
QStringList possibleProperties;
|
2023-03-16 16:26:36 +02:00
|
|
|
const PropertyMetaInfos props = metaInfo.properties();
|
|
|
|
|
for (const auto &property : props) {
|
2022-06-09 17:03:42 +02:00
|
|
|
if (property.isWritable())
|
|
|
|
|
possibleProperties.push_back(QString::fromUtf8(property.name()));
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return possibleProperties;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
return {};
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::addDynamicPropertyForCurrentNode()
|
|
|
|
|
{
|
2020-11-19 18:23:35 +01:00
|
|
|
QmlDesignerPlugin::emitUsageStatistics(Constants::EVENT_PROPERTY_ADDED);
|
|
|
|
|
|
2023-06-07 13:03:11 +02:00
|
|
|
if (selectedNodes().size() == 1) {
|
2022-07-22 16:46:48 +02:00
|
|
|
const ModelNode modelNode = selectedNodes().constFirst();
|
2015-09-18 15:38:15 +02:00
|
|
|
if (modelNode.isValid()) {
|
|
|
|
|
try {
|
2022-09-09 10:14:27 +02:00
|
|
|
modelNode.variantProperty(unusedProperty(modelNode)).setDynamicTypeNameAndValue("string", "This is a string");
|
2015-09-18 15:38:15 +02:00
|
|
|
} catch (RewritingException &e) {
|
|
|
|
|
m_exceptionError = e.description();
|
2017-03-19 00:19:33 +02:00
|
|
|
QTimer::singleShot(200, this, &DynamicPropertiesModel::handleException);
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << " BindingModel::addBindingForCurrentNode not one node selected";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList DynamicPropertiesModel::possibleSourceProperties(const BindingProperty &bindingProperty) const
|
|
|
|
|
{
|
|
|
|
|
const QString expression = bindingProperty.expression();
|
|
|
|
|
const QStringList stringlist = expression.split(QLatin1String("."));
|
|
|
|
|
|
2022-08-23 16:43:44 +02:00
|
|
|
NodeMetaInfo type;
|
2015-09-18 15:38:15 +02:00
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
if (auto metaInfo = bindingProperty.parentModelNode().metaInfo(); metaInfo.isValid())
|
2022-08-23 16:43:44 +02:00
|
|
|
type = metaInfo.property(bindingProperty.name()).propertyType();
|
2023-03-16 16:26:36 +02:00
|
|
|
else
|
2015-09-18 15:38:15 +02:00
|
|
|
qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for target node";
|
|
|
|
|
|
2018-01-13 18:49:39 +01:00
|
|
|
const QString &id = stringlist.constFirst();
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
ModelNode modelNode = getNodeByIdOrParent(id, bindingProperty.parentModelNode());
|
|
|
|
|
|
|
|
|
|
if (!modelNode.isValid()) {
|
|
|
|
|
qWarning() << " BindingModel::possibleSourcePropertiesForRow invalid model node";
|
|
|
|
|
return QStringList();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
NodeMetaInfo metaInfo = modelNode.metaInfo();
|
|
|
|
|
|
|
|
|
|
if (metaInfo.isValid()) {
|
|
|
|
|
QStringList possibleProperties;
|
2023-03-16 16:26:36 +02:00
|
|
|
const PropertyMetaInfos props = metaInfo.properties();
|
|
|
|
|
for (const auto &property : props) {
|
|
|
|
|
if (property.propertyType() == type) // TODO: proper check
|
2022-06-09 17:03:42 +02:00
|
|
|
possibleProperties.push_back(QString::fromUtf8(property.name()));
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
return possibleProperties;
|
|
|
|
|
} else {
|
|
|
|
|
qWarning() << " BindingModel::possibleSourcePropertiesForRow no meta info for source node";
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
return {};
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::deleteDynamicPropertyByRow(int rowNumber)
|
|
|
|
|
{
|
2023-03-16 16:26:36 +02:00
|
|
|
m_view->executeInTransaction(__FUNCTION__, [this, rowNumber]() {
|
|
|
|
|
const AbstractProperty property = abstractPropertyForRow(rowNumber);
|
|
|
|
|
const PropertyName propertyName = property.name();
|
|
|
|
|
BindingProperty bindingProperty = bindingPropertyForRow(rowNumber);
|
|
|
|
|
if (bindingProperty.isValid()) {
|
|
|
|
|
bindingProperty.parentModelNode().removeProperty(bindingProperty.name());
|
|
|
|
|
} else {
|
|
|
|
|
VariantProperty variantProperty = variantPropertyForRow(rowNumber);
|
|
|
|
|
if (variantProperty.isValid())
|
|
|
|
|
variantProperty.parentModelNode().removeProperty(variantProperty.name());
|
|
|
|
|
}
|
2022-09-14 16:18:07 +02:00
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
if (property.isValid()) {
|
|
|
|
|
QmlObjectNode objectNode = QmlObjectNode(property.parentModelNode());
|
|
|
|
|
const auto stateOperations = objectNode.allAffectingStatesOperations();
|
|
|
|
|
for (const QmlModelStateOperation &stateOperation : stateOperations) {
|
|
|
|
|
if (stateOperation.modelNode().hasProperty(propertyName))
|
|
|
|
|
stateOperation.modelNode().removeProperty(propertyName);
|
|
|
|
|
}
|
2022-09-14 16:18:07 +02:00
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
const QList<ModelNode> timelineNodes = objectNode.allTimelines();
|
|
|
|
|
for (auto &timelineNode : timelineNodes) {
|
|
|
|
|
QmlTimeline timeline(timelineNode);
|
|
|
|
|
timeline.removeKeyframesForTargetAndProperty(objectNode.modelNode(),
|
|
|
|
|
propertyName);
|
2022-09-14 16:18:07 +02:00
|
|
|
}
|
2023-03-16 16:26:36 +02:00
|
|
|
}
|
|
|
|
|
});
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
resetModel();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::addProperty(const QVariant &propertyValue,
|
|
|
|
|
const QString &propertyType,
|
|
|
|
|
const AbstractProperty &abstractProperty)
|
|
|
|
|
{
|
|
|
|
|
QList<QStandardItem*> items;
|
|
|
|
|
|
|
|
|
|
QStandardItem *idItem;
|
|
|
|
|
QStandardItem *propertyNameItem;
|
|
|
|
|
QStandardItem *propertyTypeItem;
|
|
|
|
|
QStandardItem *propertyValueItem;
|
|
|
|
|
|
|
|
|
|
idItem = new QStandardItem(idOrTypeNameForNode(abstractProperty.parentModelNode()));
|
|
|
|
|
updateCustomData(idItem, abstractProperty);
|
|
|
|
|
|
2023-02-03 13:29:26 +02:00
|
|
|
const QString propName = QString::fromUtf8(abstractProperty.name());
|
|
|
|
|
propertyNameItem = new QStandardItem(propName);
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
items.append(idItem);
|
|
|
|
|
items.append(propertyNameItem);
|
|
|
|
|
|
|
|
|
|
propertyTypeItem = new QStandardItem(propertyType);
|
|
|
|
|
items.append(propertyTypeItem);
|
|
|
|
|
|
|
|
|
|
propertyValueItem = new QStandardItem();
|
|
|
|
|
propertyValueItem->setData(propertyValue, Qt::DisplayRole);
|
|
|
|
|
items.append(propertyValueItem);
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
for (int i = 0; i < rowCount(); ++i) {
|
2023-02-03 13:29:26 +02:00
|
|
|
if (data(index(i, PropertyNameRow)).toString() > propName) {
|
|
|
|
|
insertRow(i, items);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-18 15:38:15 +02:00
|
|
|
appendRow(items);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::addBindingProperty(const BindingProperty &property)
|
|
|
|
|
{
|
|
|
|
|
QVariant value = property.expression();
|
|
|
|
|
QString type = QString::fromLatin1(property.dynamicTypeName());
|
|
|
|
|
addProperty(value, type, property);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::addVariantProperty(const VariantProperty &property)
|
|
|
|
|
{
|
|
|
|
|
QVariant value = property.value();
|
|
|
|
|
QString type = QString::fromLatin1(property.dynamicTypeName());
|
|
|
|
|
addProperty(value, type, property);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::updateBindingProperty(int rowNumber)
|
|
|
|
|
{
|
|
|
|
|
BindingProperty bindingProperty = bindingPropertyForRow(rowNumber);
|
|
|
|
|
|
|
|
|
|
if (bindingProperty.isValid()) {
|
2023-07-04 19:57:59 +02:00
|
|
|
updateCustomData(rowNumber, bindingProperty);
|
|
|
|
|
|
2016-03-23 12:34:03 +01:00
|
|
|
QString propertyName = QString::fromUtf8(bindingProperty.name());
|
2015-09-18 15:38:15 +02:00
|
|
|
updateDisplayRole(rowNumber, PropertyNameRow, propertyName);
|
|
|
|
|
QString value = bindingProperty.expression();
|
2016-03-23 12:34:03 +01:00
|
|
|
QString type = QString::fromUtf8(bindingProperty.dynamicTypeName());
|
2015-09-18 15:38:15 +02:00
|
|
|
updateDisplayRole(rowNumber, PropertyTypeRow, type);
|
|
|
|
|
updateDisplayRole(rowNumber, PropertyValueRow, value);
|
2022-09-09 16:33:23 +02:00
|
|
|
|
|
|
|
|
const QmlObjectNode objectNode = QmlObjectNode(bindingProperty.parentModelNode());
|
|
|
|
|
if (objectNode.isValid() && !objectNode.view()->currentState().isBaseState())
|
|
|
|
|
value = objectNode.expression(bindingProperty.name());
|
|
|
|
|
|
|
|
|
|
updateDisplayRole(rowNumber, PropertyValueRow, value);
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::updateVariantProperty(int rowNumber)
|
|
|
|
|
{
|
|
|
|
|
VariantProperty variantProperty = variantPropertyForRow(rowNumber);
|
|
|
|
|
|
|
|
|
|
if (variantProperty.isValid()) {
|
2023-07-04 19:57:59 +02:00
|
|
|
updateCustomData(rowNumber, variantProperty);
|
2016-03-23 12:34:03 +01:00
|
|
|
QString propertyName = QString::fromUtf8(variantProperty.name());
|
2015-09-18 15:38:15 +02:00
|
|
|
updateDisplayRole(rowNumber, PropertyNameRow, propertyName);
|
|
|
|
|
QVariant value = variantProperty.value();
|
2016-03-23 12:34:03 +01:00
|
|
|
QString type = QString::fromUtf8(variantProperty.dynamicTypeName());
|
2015-09-18 15:38:15 +02:00
|
|
|
updateDisplayRole(rowNumber, PropertyTypeRow, type);
|
2022-09-09 16:33:23 +02:00
|
|
|
const QmlObjectNode objectNode = QmlObjectNode(variantProperty.parentModelNode());
|
|
|
|
|
if (objectNode.isValid() && !objectNode.view()->currentState().isBaseState())
|
|
|
|
|
value = objectNode.modelValue(variantProperty.name());
|
|
|
|
|
|
2015-09-18 15:38:15 +02:00
|
|
|
updateDisplayRoleFromVariant(rowNumber, PropertyValueRow, value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::addModelNode(const ModelNode &modelNode)
|
|
|
|
|
{
|
2022-09-06 09:57:20 +03:00
|
|
|
if (!modelNode.isValid())
|
|
|
|
|
return;
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
const QList<AbstractProperty> properties = modelNode.properties();
|
|
|
|
|
QList<AbstractProperty> dynamicProperties = Utils::filtered(properties, [](const AbstractProperty &p) {
|
2022-09-14 15:59:39 +02:00
|
|
|
return p.isDynamic();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
Utils::sort(dynamicProperties, [](const AbstractProperty &a, const AbstractProperty &b) {
|
|
|
|
|
return a.name() < b.name();
|
|
|
|
|
});
|
|
|
|
|
|
2022-10-07 14:46:06 +02:00
|
|
|
for (const AbstractProperty &property : std::as_const(dynamicProperties)) {
|
2022-09-14 15:59:39 +02:00
|
|
|
if (property.isBindingProperty())
|
|
|
|
|
addBindingProperty(property.toBindingProperty());
|
|
|
|
|
else if (property.isVariantProperty())
|
|
|
|
|
addVariantProperty(property.toVariantProperty());
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::updateValue(int row)
|
|
|
|
|
{
|
|
|
|
|
BindingProperty bindingProperty = bindingPropertyForRow(row);
|
|
|
|
|
|
|
|
|
|
if (bindingProperty.isBindingProperty()) {
|
|
|
|
|
const QString expression = data(index(row, PropertyValueRow)).toString();
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
RewriterTransaction transaction = m_view->beginRewriterTransaction(__FUNCTION__);
|
2015-09-18 15:38:15 +02:00
|
|
|
try {
|
|
|
|
|
bindingProperty.setDynamicTypeNameAndExpression(bindingProperty.dynamicTypeName(), expression);
|
2023-03-16 16:26:36 +02:00
|
|
|
transaction.commit(); // committing in the try block
|
2015-09-18 15:38:15 +02:00
|
|
|
} catch (Exception &e) {
|
|
|
|
|
m_exceptionError = e.description();
|
2017-03-19 00:19:33 +02:00
|
|
|
QTimer::singleShot(200, this, &DynamicPropertiesModel::handleException);
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VariantProperty variantProperty = variantPropertyForRow(row);
|
|
|
|
|
|
|
|
|
|
if (variantProperty.isVariantProperty()) {
|
|
|
|
|
const QVariant value = data(index(row, PropertyValueRow));
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
RewriterTransaction transaction = m_view->beginRewriterTransaction(__FUNCTION__);
|
2015-09-18 15:38:15 +02:00
|
|
|
try {
|
|
|
|
|
variantProperty.setDynamicTypeNameAndValue(variantProperty.dynamicTypeName(), value);
|
2023-03-16 16:26:36 +02:00
|
|
|
transaction.commit(); // committing in the try block
|
2015-09-18 15:38:15 +02:00
|
|
|
} catch (Exception &e) {
|
|
|
|
|
m_exceptionError = e.description();
|
2017-03-19 00:19:33 +02:00
|
|
|
QTimer::singleShot(200, this, &DynamicPropertiesModel::handleException);
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::updatePropertyName(int rowNumber)
|
|
|
|
|
{
|
2016-03-23 12:34:03 +01:00
|
|
|
const PropertyName newName = data(index(rowNumber, PropertyNameRow)).toString().toUtf8();
|
2023-03-16 16:26:36 +02:00
|
|
|
QTC_ASSERT(!newName.isEmpty(), return);
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
BindingProperty bindingProperty = bindingPropertyForRow(rowNumber);
|
|
|
|
|
|
2019-05-31 16:49:04 +02:00
|
|
|
ModelNode targetNode = bindingProperty.parentModelNode();
|
|
|
|
|
|
2015-09-18 15:38:15 +02:00
|
|
|
if (bindingProperty.isBindingProperty()) {
|
2023-03-16 16:26:36 +02:00
|
|
|
m_view->executeInTransaction(__FUNCTION__, [bindingProperty, newName, &targetNode]() {
|
2019-05-31 16:49:04 +02:00
|
|
|
const QString expression = bindingProperty.expression();
|
|
|
|
|
const PropertyName dynamicPropertyType = bindingProperty.dynamicTypeName();
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
targetNode.bindingProperty(newName).setDynamicTypeNameAndExpression(dynamicPropertyType, expression);
|
|
|
|
|
targetNode.removeProperty(bindingProperty.name());
|
2019-05-31 16:49:04 +02:00
|
|
|
});
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
updateCustomData(rowNumber, targetNode.bindingProperty(newName));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VariantProperty variantProperty = variantPropertyForRow(rowNumber);
|
|
|
|
|
|
|
|
|
|
if (variantProperty.isVariantProperty()) {
|
|
|
|
|
const QVariant value = variantProperty.value();
|
|
|
|
|
const PropertyName dynamicPropertyType = variantProperty.dynamicTypeName();
|
|
|
|
|
ModelNode targetNode = variantProperty.parentModelNode();
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
m_view->executeInTransaction(__FUNCTION__, [=]() {
|
2015-09-18 15:38:15 +02:00
|
|
|
targetNode.variantProperty(newName).setDynamicTypeNameAndValue(dynamicPropertyType, value);
|
|
|
|
|
targetNode.removeProperty(variantProperty.name());
|
2019-05-31 16:49:04 +02:00
|
|
|
});
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
updateCustomData(rowNumber, targetNode.variantProperty(newName));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::updatePropertyType(int rowNumber)
|
|
|
|
|
{
|
|
|
|
|
const TypeName newType = data(index(rowNumber, PropertyTypeRow)).toString().toLatin1();
|
2023-03-16 16:26:36 +02:00
|
|
|
QTC_ASSERT(!newType.isEmpty(), return);
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
BindingProperty bindingProperty = bindingPropertyForRow(rowNumber);
|
|
|
|
|
|
|
|
|
|
if (bindingProperty.isBindingProperty()) {
|
|
|
|
|
const QString expression = bindingProperty.expression();
|
|
|
|
|
const PropertyName propertyName = bindingProperty.name();
|
|
|
|
|
ModelNode targetNode = bindingProperty.parentModelNode();
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
m_view->executeInTransaction(__FUNCTION__, [=]() {
|
2015-09-18 15:38:15 +02:00
|
|
|
targetNode.removeProperty(bindingProperty.name());
|
|
|
|
|
targetNode.bindingProperty(propertyName).setDynamicTypeNameAndExpression(newType, expression);
|
2019-05-31 16:49:04 +02:00
|
|
|
});
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
updateCustomData(rowNumber, targetNode.bindingProperty(propertyName));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VariantProperty variantProperty = variantPropertyForRow(rowNumber);
|
|
|
|
|
|
|
|
|
|
if (variantProperty.isVariantProperty()) {
|
|
|
|
|
const QVariant value = variantProperty.value();
|
|
|
|
|
ModelNode targetNode = variantProperty.parentModelNode();
|
|
|
|
|
const PropertyName propertyName = variantProperty.name();
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
m_view->executeInTransaction(__FUNCTION__, [=]() {
|
2015-09-18 15:38:15 +02:00
|
|
|
targetNode.removeProperty(variantProperty.name());
|
2022-07-22 16:46:48 +02:00
|
|
|
if (!isValueType(newType)) {
|
|
|
|
|
targetNode.bindingProperty(propertyName).setDynamicTypeNameAndExpression(
|
|
|
|
|
newType, convertVariantForTypeName({}, newType).toString());
|
2015-09-18 15:38:15 +02:00
|
|
|
} else {
|
2022-07-22 16:46:48 +02:00
|
|
|
targetNode.variantProperty(propertyName).setDynamicTypeNameAndValue(
|
|
|
|
|
newType, convertVariantForTypeName(value, newType));
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
2019-05-31 16:49:04 +02:00
|
|
|
});
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
updateCustomData(rowNumber, targetNode.variantProperty(propertyName));
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
if (variantProperty.isVariantProperty())
|
2015-09-18 15:38:15 +02:00
|
|
|
updateVariantProperty(rowNumber);
|
2023-03-16 16:26:36 +02:00
|
|
|
else if (bindingProperty.isBindingProperty())
|
2015-09-18 15:38:15 +02:00
|
|
|
updateBindingProperty(rowNumber);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ModelNode DynamicPropertiesModel::getNodeByIdOrParent(const QString &id, const ModelNode &targetNode) const
|
|
|
|
|
{
|
2023-03-16 16:26:36 +02:00
|
|
|
if (id != QLatin1String("parent"))
|
|
|
|
|
return m_view->modelNodeForId(id);
|
2015-09-18 15:38:15 +02:00
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
if (targetNode.hasParentProperty())
|
|
|
|
|
return targetNode.parentProperty().parentModelNode();
|
|
|
|
|
|
|
|
|
|
return {};
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::updateCustomData(QStandardItem *item, const AbstractProperty &property)
|
|
|
|
|
{
|
|
|
|
|
item->setData(property.parentModelNode().internalId(), Qt::UserRole + 1);
|
|
|
|
|
item->setData(property.name(), Qt::UserRole + 2);
|
2023-07-04 19:57:59 +02:00
|
|
|
|
|
|
|
|
item->setData(property.parentModelNode().id(), TargetNameRole);
|
|
|
|
|
item->setData(property.name(), PropertyNameRole);
|
|
|
|
|
item->setData(property.parentModelNode().id(), TargetNameRole);
|
|
|
|
|
item->setData(property.dynamicTypeName(), PropertyTypeRole);
|
|
|
|
|
|
|
|
|
|
if (property.isVariantProperty())
|
|
|
|
|
item->setData(property.toVariantProperty().value(), PropertyValueRole);
|
|
|
|
|
if (property.isBindingProperty())
|
|
|
|
|
item->setData(property.toBindingProperty().expression(), PropertyValueRole);
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::updateCustomData(int row, const AbstractProperty &property)
|
|
|
|
|
{
|
|
|
|
|
QStandardItem* idItem = item(row, 0);
|
|
|
|
|
updateCustomData(idItem, property);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int DynamicPropertiesModel::findRowForBindingProperty(const BindingProperty &bindingProperty) const
|
|
|
|
|
{
|
2023-03-16 16:26:36 +02:00
|
|
|
for (int i = 0; i < rowCount(); ++i) {
|
2015-09-18 15:38:15 +02:00
|
|
|
if (compareBindingProperties(bindingPropertyForRow(i), bindingProperty))
|
|
|
|
|
return i;
|
|
|
|
|
}
|
2023-03-16 16:26:36 +02:00
|
|
|
|
|
|
|
|
return -1; // not found
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int DynamicPropertiesModel::findRowForVariantProperty(const VariantProperty &variantProperty) const
|
|
|
|
|
{
|
2023-03-16 16:26:36 +02:00
|
|
|
for (int i = 0; i < rowCount(); ++i) {
|
2015-09-18 15:38:15 +02:00
|
|
|
if (compareVariantProperties(variantPropertyForRow(i), variantProperty))
|
|
|
|
|
return i;
|
|
|
|
|
}
|
2023-03-16 16:26:36 +02:00
|
|
|
|
|
|
|
|
return -1; // not found
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
2022-09-09 16:33:23 +02:00
|
|
|
int DynamicPropertiesModel::findRowForProperty(const AbstractProperty &abstractProperty) const
|
|
|
|
|
{
|
2023-03-16 16:26:36 +02:00
|
|
|
for (int i = 0; i < rowCount(); ++i) {
|
2022-09-09 16:33:23 +02:00
|
|
|
if ((abstractPropertyForRow(i).name() == abstractProperty.name()))
|
|
|
|
|
return i;
|
|
|
|
|
}
|
2023-03-16 16:26:36 +02:00
|
|
|
|
|
|
|
|
return -1; // not found
|
2022-09-09 16:33:23 +02:00
|
|
|
}
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
bool DynamicPropertiesModel::getExpressionStrings(const BindingProperty &bindingProperty, QString *sourceNode,
|
|
|
|
|
QString *sourceProperty)
|
2015-09-18 15:38:15 +02:00
|
|
|
{
|
2023-03-16 16:26:36 +02:00
|
|
|
// TODO: we assume no expressions yet
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
const QString expression = bindingProperty.expression();
|
|
|
|
|
|
|
|
|
|
if (true) {
|
2023-03-16 16:26:36 +02:00
|
|
|
const QStringList expressionParts = expression.split('.');
|
2015-09-18 15:38:15 +02:00
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
*sourceNode = expressionParts.constFirst();
|
2015-09-18 15:38:15 +02:00
|
|
|
|
|
|
|
|
QString propertyName;
|
|
|
|
|
|
2023-06-07 13:03:11 +02:00
|
|
|
for (int i = 1; i < expressionParts.size(); ++i) {
|
2023-03-16 16:26:36 +02:00
|
|
|
propertyName += expressionParts.at(i);
|
2023-06-07 13:03:11 +02:00
|
|
|
if (i != expressionParts.size() - 1)
|
2015-09-18 15:38:15 +02:00
|
|
|
propertyName += QLatin1String(".");
|
|
|
|
|
}
|
|
|
|
|
*sourceProperty = propertyName;
|
|
|
|
|
}
|
2023-03-16 16:26:36 +02:00
|
|
|
|
2015-09-18 15:38:15 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::updateDisplayRole(int row, int columns, const QString &string)
|
|
|
|
|
{
|
|
|
|
|
QModelIndex modelIndex = index(row, columns);
|
|
|
|
|
if (data(modelIndex).toString() != string)
|
|
|
|
|
setData(modelIndex, string);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::updateDisplayRoleFromVariant(int row, int columns, const QVariant &variant)
|
|
|
|
|
{
|
|
|
|
|
QModelIndex modelIndex = index(row, columns);
|
|
|
|
|
if (data(modelIndex) != variant)
|
|
|
|
|
setData(modelIndex, variant);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::handleDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
|
|
|
|
|
{
|
|
|
|
|
if (!m_handleDataChanged)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (topLeft != bottomRight) {
|
2023-03-16 16:26:36 +02:00
|
|
|
qWarning() << __FUNCTION__ << ": multi edit?";
|
2015-09-18 15:38:15 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_lock = true;
|
|
|
|
|
|
|
|
|
|
int currentColumn = topLeft.column();
|
|
|
|
|
int currentRow = topLeft.row();
|
|
|
|
|
|
|
|
|
|
switch (currentColumn) {
|
|
|
|
|
case TargetModelNodeRow: {
|
2023-03-16 16:26:36 +02:00
|
|
|
// updating user data
|
2015-09-18 15:38:15 +02:00
|
|
|
} break;
|
|
|
|
|
case PropertyNameRow: {
|
|
|
|
|
updatePropertyName(currentRow);
|
|
|
|
|
} break;
|
|
|
|
|
case PropertyTypeRow: {
|
|
|
|
|
updatePropertyType(currentRow);
|
|
|
|
|
} break;
|
|
|
|
|
case PropertyValueRow: {
|
|
|
|
|
updateValue(currentRow);
|
|
|
|
|
} break;
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
default: qWarning() << __FUNCTION__ << " column" << currentColumn;
|
2015-09-18 15:38:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_lock = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModel::handleException()
|
|
|
|
|
{
|
2018-07-24 23:56:45 +02:00
|
|
|
QMessageBox::warning(nullptr, tr("Error"), m_exceptionError);
|
2015-09-18 15:38:15 +02:00
|
|
|
resetModel();
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-22 16:46:48 +02:00
|
|
|
const QList<ModelNode> DynamicPropertiesModel::selectedNodes() const
|
|
|
|
|
{
|
|
|
|
|
// If selected nodes are explicitly set, return those.
|
|
|
|
|
// Otherwise return actual selected nodes of the model.
|
|
|
|
|
if (m_explicitSelection)
|
|
|
|
|
return m_selectedNodes;
|
2023-03-16 16:26:36 +02:00
|
|
|
|
|
|
|
|
return m_view->selectedModelNodes();
|
2022-07-22 16:46:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const ModelNode DynamicPropertiesModel::singleSelectedNode() const
|
|
|
|
|
{
|
|
|
|
|
if (m_explicitSelection)
|
|
|
|
|
return m_selectedNodes.first();
|
|
|
|
|
|
2023-03-16 16:26:36 +02:00
|
|
|
return m_view->singleSelectedModelNode();
|
|
|
|
|
}
|
2015-09-18 15:38:15 +02:00
|
|
|
|
2023-07-04 19:57:59 +02:00
|
|
|
QHash<int, QByteArray> DynamicPropertiesModel::roleNames() const
|
|
|
|
|
{
|
|
|
|
|
static QHash<int, QByteArray> roleNames{{TargetNameRole, "target"},
|
|
|
|
|
{PropertyNameRole, "name"},
|
|
|
|
|
{PropertyTypeRole, "type"},
|
|
|
|
|
{PropertyValueRole, "value"}};
|
|
|
|
|
|
|
|
|
|
return roleNames;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DynamicPropertiesModelBackendDelegate *DynamicPropertiesModel::delegate() const
|
|
|
|
|
{
|
|
|
|
|
return m_delegate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DynamicPropertiesModelBackendDelegate::DynamicPropertiesModelBackendDelegate(
|
|
|
|
|
DynamicPropertiesModel *parent)
|
|
|
|
|
: QObject(parent)
|
|
|
|
|
{
|
|
|
|
|
m_type.setModel({"int", "bool", "var", "real", "string", "url", "color"});
|
|
|
|
|
|
|
|
|
|
connect(&m_type, &StudioQmlComboBoxBackend::activated, this, [this]() { handleTypeChanged(); });
|
|
|
|
|
connect(&m_name, &StudioQmlTextBackend::activated, this, [this]() { handleNameChanged(); });
|
|
|
|
|
connect(&m_value, &StudioQmlTextBackend::activated, this, [this]() { handleValueChanged(); });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int DynamicPropertiesModelBackendDelegate::currentRow() const
|
|
|
|
|
{
|
|
|
|
|
return m_currentRow;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModelBackendDelegate::setCurrentRow(int i)
|
|
|
|
|
{
|
|
|
|
|
if (m_currentRow == i)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
m_currentRow = i;
|
|
|
|
|
|
|
|
|
|
//setup
|
|
|
|
|
|
|
|
|
|
DynamicPropertiesModel *model = qobject_cast<DynamicPropertiesModel *>(parent());
|
|
|
|
|
|
|
|
|
|
QTC_ASSERT(model, return );
|
|
|
|
|
|
|
|
|
|
AbstractProperty property = model->abstractPropertyForRow(i);
|
|
|
|
|
|
|
|
|
|
m_type.setCurrentText(QString::fromUtf8(property.dynamicTypeName()));
|
|
|
|
|
m_name.setText(QString::fromUtf8(property.name()));
|
|
|
|
|
|
|
|
|
|
if (property.isVariantProperty())
|
|
|
|
|
m_value.setText(property.toVariantProperty().value().toString());
|
|
|
|
|
else if (property.isBindingProperty())
|
|
|
|
|
m_value.setText(property.toBindingProperty().expression());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModelBackendDelegate::handleTypeChanged()
|
|
|
|
|
{
|
|
|
|
|
//void DynamicPropertiesModel::updatePropertyType(int rowNumber)
|
|
|
|
|
const TypeName type = m_type.currentText().toUtf8();
|
|
|
|
|
|
|
|
|
|
DynamicPropertiesModel *model = qobject_cast<DynamicPropertiesModel *>(parent());
|
|
|
|
|
|
|
|
|
|
QTC_ASSERT(model, return );
|
|
|
|
|
QTC_ASSERT(model->view(), return );
|
|
|
|
|
|
|
|
|
|
BindingProperty bindingProperty = model->bindingPropertyForRow(currentRow());
|
|
|
|
|
|
|
|
|
|
VariantProperty variantProperty = model->variantPropertyForRow(currentRow());
|
|
|
|
|
|
|
|
|
|
RewriterTransaction transaction = model->view()->beginRewriterTransaction(__FUNCTION__);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if (bindingProperty.isBindingProperty() || type == "var") { //var is always a binding
|
|
|
|
|
const QString expression = bindingProperty.expression();
|
|
|
|
|
variantProperty.parentModelNode().removeProperty(variantProperty.name());
|
|
|
|
|
bindingProperty.setDynamicTypeNameAndExpression(type, expression);
|
|
|
|
|
} else if (variantProperty.isVariantProperty()) {
|
|
|
|
|
variantProperty.parentModelNode().removeProperty(variantProperty.name());
|
|
|
|
|
variantProperty.setDynamicTypeNameAndValue(type, variantValue());
|
|
|
|
|
}
|
|
|
|
|
transaction.commit(); // committing in the try block
|
|
|
|
|
} catch (Exception &e) {
|
|
|
|
|
m_exceptionError = e.description();
|
|
|
|
|
QTimer::singleShot(200, this, &DynamicPropertiesModelBackendDelegate::handleException);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModelBackendDelegate::handleNameChanged()
|
|
|
|
|
{
|
|
|
|
|
//see DynamicPropertiesModel::updatePropertyName
|
|
|
|
|
|
|
|
|
|
const PropertyName newName = m_name.text().toUtf8();
|
|
|
|
|
QTC_ASSERT(!newName.isEmpty(), return );
|
|
|
|
|
|
|
|
|
|
DynamicPropertiesModel *model = qobject_cast<DynamicPropertiesModel *>(parent());
|
|
|
|
|
|
|
|
|
|
QTC_ASSERT(model, return );
|
|
|
|
|
QTC_ASSERT(model->view(), return );
|
|
|
|
|
|
|
|
|
|
BindingProperty bindingProperty = model->bindingPropertyForRow(currentRow());
|
|
|
|
|
|
|
|
|
|
ModelNode targetNode = bindingProperty.parentModelNode();
|
|
|
|
|
|
|
|
|
|
if (bindingProperty.isBindingProperty()) {
|
|
|
|
|
model->view()->executeInTransaction(__FUNCTION__, [bindingProperty, newName, &targetNode]() {
|
|
|
|
|
const QString expression = bindingProperty.expression();
|
|
|
|
|
const PropertyName dynamicPropertyType = bindingProperty.dynamicTypeName();
|
|
|
|
|
|
|
|
|
|
targetNode.bindingProperty(newName).setDynamicTypeNameAndExpression(dynamicPropertyType,
|
|
|
|
|
expression);
|
|
|
|
|
targetNode.removeProperty(bindingProperty.name());
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VariantProperty variantProperty = model->variantPropertyForRow(currentRow());
|
|
|
|
|
|
|
|
|
|
if (variantProperty.isVariantProperty()) {
|
|
|
|
|
const QVariant value = variantProperty.value();
|
|
|
|
|
const PropertyName dynamicPropertyType = variantProperty.dynamicTypeName();
|
|
|
|
|
ModelNode targetNode = variantProperty.parentModelNode();
|
|
|
|
|
|
|
|
|
|
model->view()->executeInTransaction(__FUNCTION__, [=]() {
|
|
|
|
|
targetNode.variantProperty(newName).setDynamicTypeNameAndValue(dynamicPropertyType,
|
|
|
|
|
value);
|
|
|
|
|
targetNode.removeProperty(variantProperty.name());
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AbstractProperty property = targetNode.property(newName);
|
|
|
|
|
|
|
|
|
|
//order might have changed because of name change we have to select the correct row
|
|
|
|
|
int newRow = model->findRowForProperty(property);
|
|
|
|
|
model->setCurrentIndex(newRow);
|
|
|
|
|
setCurrentRow(newRow);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModelBackendDelegate::handleValueChanged()
|
|
|
|
|
{
|
|
|
|
|
//see void DynamicPropertiesModel::updateValue(int row)
|
|
|
|
|
|
|
|
|
|
DynamicPropertiesModel *model = qobject_cast<DynamicPropertiesModel *>(parent());
|
|
|
|
|
|
|
|
|
|
QTC_ASSERT(model, return );
|
|
|
|
|
QTC_ASSERT(model->view(), return );
|
|
|
|
|
|
|
|
|
|
BindingProperty bindingProperty = model->bindingPropertyForRow(currentRow());
|
|
|
|
|
|
|
|
|
|
if (bindingProperty.isBindingProperty()) {
|
|
|
|
|
const QString expression = m_value.text();
|
|
|
|
|
|
|
|
|
|
RewriterTransaction transaction = model->view()->beginRewriterTransaction(__FUNCTION__);
|
|
|
|
|
try {
|
|
|
|
|
bindingProperty.setDynamicTypeNameAndExpression(bindingProperty.dynamicTypeName(),
|
|
|
|
|
expression);
|
|
|
|
|
transaction.commit(); // committing in the try block
|
|
|
|
|
} catch (Exception &e) {
|
|
|
|
|
m_exceptionError = e.description();
|
|
|
|
|
QTimer::singleShot(200, this, &DynamicPropertiesModelBackendDelegate::handleException);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
VariantProperty variantProperty = model->variantPropertyForRow(currentRow());
|
|
|
|
|
|
|
|
|
|
if (variantProperty.isVariantProperty()) {
|
|
|
|
|
RewriterTransaction transaction = model->view()->beginRewriterTransaction(__FUNCTION__);
|
|
|
|
|
try {
|
|
|
|
|
variantProperty.setDynamicTypeNameAndValue(variantProperty.dynamicTypeName(),
|
|
|
|
|
variantValue());
|
|
|
|
|
transaction.commit(); // committing in the try block
|
|
|
|
|
} catch (Exception &e) {
|
|
|
|
|
m_exceptionError = e.description();
|
|
|
|
|
QTimer::singleShot(200, this, &DynamicPropertiesModelBackendDelegate::handleException);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DynamicPropertiesModelBackendDelegate::handleException()
|
|
|
|
|
{
|
|
|
|
|
QMessageBox::warning(nullptr, tr("Error"), m_exceptionError);
|
|
|
|
|
//reset
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant DynamicPropertiesModelBackendDelegate::variantValue() const
|
|
|
|
|
{
|
|
|
|
|
//improve
|
|
|
|
|
const QString type = m_type.currentText();
|
|
|
|
|
if (type == "real" || type == "int")
|
|
|
|
|
return m_value.text().toFloat();
|
|
|
|
|
|
|
|
|
|
if (type == "bool")
|
|
|
|
|
return m_value.text() == "true";
|
|
|
|
|
|
|
|
|
|
return m_value.text();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StudioQmlComboBoxBackend *DynamicPropertiesModelBackendDelegate::type()
|
|
|
|
|
{
|
|
|
|
|
return &m_type;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StudioQmlTextBackend *DynamicPropertiesModelBackendDelegate::name()
|
|
|
|
|
{
|
|
|
|
|
return &m_name;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StudioQmlTextBackend *DynamicPropertiesModelBackendDelegate::value()
|
|
|
|
|
{
|
|
|
|
|
return &m_value;
|
|
|
|
|
}
|
|
|
|
|
|
2015-09-18 15:38:15 +02:00
|
|
|
} // namespace QmlDesigner
|