QmlDesigner: Use Int and Real types instead of Number in Model Editor

* If a column has both integer and real numbers, it will be considered
as a real type.
* The edit delegate for integer has no decimals, and it's limited to
integer range.
* Data types are ordered for the column editor dialog

Task-number: QDS-11675
Change-Id: I43364e8dddd3fc9c336723f4db337088ffdd97ed
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
This commit is contained in:
Ali Kianian
2024-01-24 12:09:41 +02:00
parent 6c026c703f
commit 58dd1405fe
5 changed files with 105 additions and 27 deletions

View File

@@ -74,16 +74,16 @@ Item {
}
Component {
id: numberEditor
id: realEditor
EditorPopup {
editor: numberField
editor: realField
StudioControls.RealSpinBox {
id: numberField
id: realField
property alias editValue: numberField.realValue
property alias editValue: realField.realValue
actionIndicator.visible: false
realFrom: -9e9
@@ -95,6 +95,27 @@ Item {
}
}
Component {
id: integerEditor
EditorPopup {
editor: integerField
StudioControls.SpinBox {
id: integerField
property alias editValue: integerField.value
actionIndicatorVisible: false
spinBoxIndicatorVisible: true
from: -2147483647
to: 2147483647
decimals: 0
}
}
}
Component {
id: boolEditor
@@ -150,7 +171,8 @@ Item {
name: "default"
when: columnType !== CollectionDetails.DataType.Boolean
&& columnType !== CollectionDetails.DataType.Color
&& columnType !== CollectionDetails.DataType.Number
&& columnType !== CollectionDetails.DataType.Integer
&& columnType !== CollectionDetails.DataType.Real
PropertyChanges {
target: editorLoader
@@ -158,12 +180,21 @@ Item {
}
},
State {
name: "number"
when: columnType === CollectionDetails.DataType.Number
name: "integer"
when: columnType === CollectionDetails.DataType.Integer
PropertyChanges {
target: editorLoader
sourceComponent: numberEditor
sourceComponent: integerEditor
}
},
State {
name: "real"
when: columnType === CollectionDetails.DataType.Real
PropertyChanges {
target: editorLoader
sourceComponent: realEditor
}
},
State {

View File

@@ -126,8 +126,11 @@ static CollectionProperty::DataType collectionDataTypeFromJsonValue(const QJsonV
return DataType::Unknown;
case JsonType::Bool:
return DataType::Boolean;
case JsonType::Double:
return DataType::Number;
case JsonType::Double: {
if (qFuzzyIsNull(std::remainder(value.toDouble(), 1)))
return DataType::Integer;
return DataType::Real;
}
case JsonType::String: {
const QString stringValue = value.toString();
if (isValidColorName(stringValue))
@@ -152,7 +155,9 @@ static QVariant valueToVariant(const QJsonValue &value, CollectionDetails::DataT
switch (type) {
case DataType::String:
return variantValue.toString();
case DataType::Number:
case DataType::Integer:
return variantValue.toInt();
case DataType::Real:
return variantValue.toDouble();
case DataType::Boolean:
return variantValue.toBool();
@@ -180,8 +185,8 @@ static QJsonValue variantToJsonValue(
if (type == CollectionDetails::DataType::Unknown) {
static const QHash<VariantType, DataType> typeMap = {{VariantType::Bool, DataType::Boolean},
{VariantType::Double, DataType::Number},
{VariantType::Int, DataType::Number},
{VariantType::Double, DataType::Real},
{VariantType::Int, DataType::Integer},
{VariantType::String, DataType::String},
{VariantType::Color, DataType::Color},
{VariantType::Url, DataType::Url}};
@@ -191,8 +196,10 @@ static QJsonValue variantToJsonValue(
switch (type) {
case DataType::Boolean:
return variant.toBool();
case DataType::Number:
case DataType::Real:
return variant.toDouble();
case DataType::Integer:
return variant.toInt();
case DataType::Image: {
const QUrl url(variant.toUrl());
if (url.isValid())
@@ -489,13 +496,19 @@ DataTypeWarning::Warning CollectionDetails::cellWarningCheck(int row, int column
const QString &propertyName = d->properties.at(column).name;
const QJsonObject &element = d->elements.at(row);
if (typeAt(column) == DataType::Unknown || element.isEmpty()
const DataType columnType = typeAt(column);
const DataType cellType = typeAt(row, column);
if (columnType == DataType::Unknown || element.isEmpty()
|| data(row, column) == QVariant::fromValue(nullptr)) {
return DataTypeWarning::Warning::None;
}
if (element.contains(propertyName) && typeAt(column) != typeAt(row, column))
if (element.contains(propertyName)) {
if (columnType == DataType::Real && cellType == DataType::Integer)
return DataTypeWarning::Warning::None;
else if (columnType != cellType)
return DataTypeWarning::Warning::CellDataTypeMismatch;
}
return DataTypeWarning::Warning::None;
}
@@ -577,16 +590,23 @@ void CollectionDetails::resetPropertyType(const QString &propertyName)
void CollectionDetails::resetPropertyType(CollectionProperty &property)
{
const QString &propertyName = property.name;
DataType type = DataType::Unknown;
DataType columnType = DataType::Unknown;
for (const QJsonObject &element : std::as_const(d->elements)) {
if (element.contains(propertyName)) {
type = collectionDataTypeFromJsonValue(element.value(propertyName));
if (type != DataType::Unknown)
const DataType cellType = collectionDataTypeFromJsonValue(element.value(propertyName));
if (cellType != DataType::Unknown) {
if (columnType == DataType::Integer && cellType != DataType::Real)
continue;
columnType = cellType;
if (columnType == DataType::Integer)
continue;
break;
}
}
property.type = type;
}
property.type = columnType;
}
void CollectionDetails::resetPropertyTypes()

View File

@@ -60,7 +60,7 @@ class CollectionDetails
Q_GADGET
public:
enum class DataType { Unknown, String, Url, Number, Boolean, Image, Color };
enum class DataType { Unknown, String, Url, Integer, Real, Boolean, Image, Color };
Q_ENUM(DataType)
explicit CollectionDetails();

View File

@@ -66,7 +66,7 @@ public:
static QStringList typesStringList()
{
static const QStringList typesList = typeToStringHash().values();
static const QStringList typesList = orderedTypeNames();
return typesList;
}
@@ -79,7 +79,8 @@ private:
{DataType::Unknown, "Unknown"},
{DataType::String, "String"},
{DataType::Url, "Url"},
{DataType::Number, "Number"},
{DataType::Real, "Real"},
{DataType::Integer, "Integer"},
{DataType::Boolean, "Boolean"},
{DataType::Image, "Image"},
{DataType::Color, "Color"},
@@ -95,6 +96,29 @@ private:
return stringTypeHash;
}
static QStringList orderedTypeNames()
{
const QList<DataType> orderedtypes{
DataType::String,
DataType::Integer,
DataType::Real,
DataType::Image,
DataType::Color,
DataType::Url,
DataType::Boolean,
DataType::Unknown,
};
QStringList orderedNames;
QHash<DataType, QString> typeStringHash = typeToStringHash();
for (const DataType &type : orderedtypes)
orderedNames.append(typeStringHash.take(type));
Q_ASSERT(typeStringHash.isEmpty());
return orderedNames;
}
};
} // namespace

View File

@@ -26,7 +26,7 @@
namespace {
using CollectionDataVariant = std::variant<QString, bool, double, QUrl, QColor>;
using CollectionDataVariant = std::variant<QString, bool, double, int, QUrl, QColor>;
inline bool operator<(const QColor &a, const QColor &b)
{
@@ -40,12 +40,15 @@ inline CollectionDataVariant valueToVariant(const QVariant &value,
switch (type) {
case DataType::String:
return value.toString();
case DataType::Number:
case DataType::Real:
return value.toDouble();
case DataType::Integer:
return value.toInt();
case DataType::Boolean:
return value.toBool();
case DataType::Color:
return value.value<QColor>();
case DataType::Image:
case DataType::Url:
return value.value<QUrl>();
default: