forked from qt-creator/qt-creator
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:
@@ -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 {
|
||||
|
@@ -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))
|
||||
return DataTypeWarning::Warning::CellDataTypeMismatch;
|
||||
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()
|
||||
|
@@ -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();
|
||||
|
@@ -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
|
||||
|
@@ -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:
|
||||
|
Reference in New Issue
Block a user