diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp index 54c6b01709c..80e223d2ec9 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -52,13 +53,6 @@ public: bool isValidRowId(int row) const { return row > -1 && row < dataRecords.size(); } }; -inline static bool isValidColorName(const QString &colorName) -{ - static const QRegularExpression colorRegex{ - "(?^(?:#(?:(?:[0-9a-fA-F]{2}){3,4}|(?:[0-9a-fA-F]){3,4}))$)"}; - return colorRegex.match(colorName).hasMatch(); -} - /** * @brief getCustomUrl * MimeType = @@ -73,10 +67,10 @@ inline static bool isValidColorName(const QString &colorName) * will be stored in this parameter, otherwise it will be empty. * @return true if the result is either url or image */ -inline static bool getCustomUrl(const QString &value, - CollectionDetails::DataType &dataType, - QUrl *urlResult = nullptr, - QString *subType = nullptr) +static bool getCustomUrl(const QString &value, + CollectionDetails::DataType &dataType, + QUrl *urlResult = nullptr, + QString *subType = nullptr) { static const QRegularExpression urlRegex{ "^(?" @@ -120,6 +114,60 @@ inline static bool getCustomUrl(const QString &value, return false; } +/** + * @brief dataTypeFromString + * @param value The string value to be evaluated + * @return Unknown if the string is empty, But returns Bool, Color, Integer, + * Real, Url, Image if these types are detected within the non-empty string, + * Otherwise it returns String. + * If the value is integer, but it's out of the int range, it will be + * considered as a Real. + */ +static CollectionDetails::DataType dataTypeFromString(const QString &value) +{ + using DataType = CollectionDetails::DataType; + static const QRegularExpression validator{ + "(?^(?:true|false)$)|" + "(?^(?:#(?:(?:[0-9a-fA-F]{2}){3,4}|(?:[0-9a-fA-F]){3,4}))$)|" + "(?^\\d+$)|" + "(?^(?:-?(?:0|[1-9]\\d*)?(?:\\.\\d*)?(?<=\\d|\\.)" + "(?:e-?(?:0|[1-9]\\d*))?|0x[0-9a-f]+)$)"}; + static const int boolIndex = validator.namedCaptureGroups().indexOf("boolean"); + static const int colorIndex = validator.namedCaptureGroups().indexOf("color"); + static const int integerIndex = validator.namedCaptureGroups().indexOf("integer"); + static const int realIndex = validator.namedCaptureGroups().indexOf("real"); + + [[maybe_unused]] static const bool allIndexesFound = + [](const std::initializer_list &captureIndexes) { + QTC_ASSERT(Utils::allOf(captureIndexes, [](int val) { return val > -1; }), return false); + return true; + }({boolIndex, colorIndex, integerIndex, realIndex}); + + if (value.isEmpty()) + return DataType::Unknown; + + const QString trimmedValue = value.trimmed(); + QRegularExpressionMatch match = validator.match(trimmedValue); + + if (match.hasCaptured(boolIndex)) + return DataType::Boolean; + if (match.hasCaptured(colorIndex)) + return DataType::Color; + if (match.hasCaptured(integerIndex)) { + bool isInt = false; + trimmedValue.toInt(&isInt); + return isInt ? DataType::Integer : DataType::Real; + } + if (match.hasCaptured(realIndex)) + return DataType::Real; + + DataType urlType; + if (getCustomUrl(value, urlType)) + return urlType; + + return DataType::String; +} + static CollectionProperty::DataType dataTypeFromJsonValue(const QJsonValue &value) { using DataType = CollectionDetails::DataType; @@ -136,21 +184,8 @@ static CollectionProperty::DataType dataTypeFromJsonValue(const QJsonValue &valu return DataType::Integer; return DataType::Real; } - case JsonType::String: { - const QString stringValue = value.toString(); - - if (stringValue.isEmpty()) - return DataType::Unknown; - - if (isValidColorName(stringValue)) - return DataType::Color; - - DataType urlType; - if (getCustomUrl(stringValue, urlType)) - return urlType; - - return DataType::String; - } break; + case JsonType::String: + return dataTypeFromString(value.toString()); default: return DataType::Unknown; } diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp index 326afb203ae..b26b1a845e9 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp +++ b/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.cpp @@ -584,33 +584,6 @@ void CollectionDetailsModel::ensureSingleCell() updateEmpty(); } -QVariant CollectionDetailsModel::variantFromString(const QString &value) -{ - constexpr QStringView typesPattern{u"(?^(?:true|false)$)|" - u"(?^(?:-?(?:0|[1-9]\\d*)?(?:\\.\\d*)?(?<=\\d|\\.)" - u"(?:e-?(?:0|[1-9]\\d*))?|0x[0-9a-f]+)$)|" - u"(?^(?:#(?:(?:[0-9a-fA-F]{2}){3,4}|" - u"(?:[0-9a-fA-F]){3,4}))$)|" - u"(?[A-Za-z][A-Za-z0-9_ -]*)"}; - static QRegularExpression validator(typesPattern.toString()); - const QString trimmedValue = value.trimmed(); - QRegularExpressionMatch match = validator.match(trimmedValue); - QVariant variantValue = value; - - if (value.isEmpty()) - return QVariant(); - if (!match.captured(u"boolean").isEmpty()) - return variantValue.toBool(); - if (!match.captured(u"number").isEmpty()) - return variantValue.toDouble(); - if (!match.captured(u"color").isEmpty()) - return variantValue.value(); - if (!match.captured(u"string").isEmpty()) - return variantValue.toString(); - - return QVariant::fromValue(value); -} - QJsonDocument CollectionDetailsModel::readJsonFile(const QUrl &url) { using Utils::FilePath; diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.h b/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.h index 0ad6e86f10c..24a040cce6c 100644 --- a/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.h +++ b/src/plugins/qmldesigner/components/collectioneditor/collectiondetailsmodel.h @@ -88,7 +88,6 @@ private: void setCollectionName(const QString &newCollectionName); void loadJsonCollection(const QString &filePath, const QString &collection); void ensureSingleCell(); - QVariant variantFromString(const QString &value); QJsonDocument readJsonFile(const QUrl &url); QHash m_openedCollections;