forked from qt-creator/qt-creator
QmlDesigner: Detect literal types from string values in ModelEditor
Fixes: QDS-12213 Change-Id: I58d56c42b94be99309a344e084c68703b0b25b82 Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io> Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
#include <QRegularExpression>
|
||||||
#include <QTextStream>
|
#include <QTextStream>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
@@ -52,13 +53,6 @@ public:
|
|||||||
bool isValidRowId(int row) const { return row > -1 && row < dataRecords.size(); }
|
bool isValidRowId(int row) const { return row > -1 && row < dataRecords.size(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
inline static bool isValidColorName(const QString &colorName)
|
|
||||||
{
|
|
||||||
static const QRegularExpression colorRegex{
|
|
||||||
"(?<color>^(?:#(?:(?:[0-9a-fA-F]{2}){3,4}|(?:[0-9a-fA-F]){3,4}))$)"};
|
|
||||||
return colorRegex.match(colorName).hasMatch();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief getCustomUrl
|
* @brief getCustomUrl
|
||||||
* MimeType = <MainType/SubType>
|
* MimeType = <MainType/SubType>
|
||||||
@@ -73,7 +67,7 @@ inline static bool isValidColorName(const QString &colorName)
|
|||||||
* will be stored in this parameter, otherwise it will be empty.
|
* will be stored in this parameter, otherwise it will be empty.
|
||||||
* @return true if the result is either url or image
|
* @return true if the result is either url or image
|
||||||
*/
|
*/
|
||||||
inline static bool getCustomUrl(const QString &value,
|
static bool getCustomUrl(const QString &value,
|
||||||
CollectionDetails::DataType &dataType,
|
CollectionDetails::DataType &dataType,
|
||||||
QUrl *urlResult = nullptr,
|
QUrl *urlResult = nullptr,
|
||||||
QString *subType = nullptr)
|
QString *subType = nullptr)
|
||||||
@@ -120,6 +114,60 @@ inline static bool getCustomUrl(const QString &value,
|
|||||||
return false;
|
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{
|
||||||
|
"(?<boolean>^(?:true|false)$)|"
|
||||||
|
"(?<color>^(?:#(?:(?:[0-9a-fA-F]{2}){3,4}|(?:[0-9a-fA-F]){3,4}))$)|"
|
||||||
|
"(?<integer>^\\d+$)|"
|
||||||
|
"(?<real>^(?:-?(?: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<int> &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)
|
static CollectionProperty::DataType dataTypeFromJsonValue(const QJsonValue &value)
|
||||||
{
|
{
|
||||||
using DataType = CollectionDetails::DataType;
|
using DataType = CollectionDetails::DataType;
|
||||||
@@ -136,21 +184,8 @@ static CollectionProperty::DataType dataTypeFromJsonValue(const QJsonValue &valu
|
|||||||
return DataType::Integer;
|
return DataType::Integer;
|
||||||
return DataType::Real;
|
return DataType::Real;
|
||||||
}
|
}
|
||||||
case JsonType::String: {
|
case JsonType::String:
|
||||||
const QString stringValue = value.toString();
|
return dataTypeFromString(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;
|
|
||||||
default:
|
default:
|
||||||
return DataType::Unknown;
|
return DataType::Unknown;
|
||||||
}
|
}
|
||||||
|
@@ -584,33 +584,6 @@ void CollectionDetailsModel::ensureSingleCell()
|
|||||||
updateEmpty();
|
updateEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant CollectionDetailsModel::variantFromString(const QString &value)
|
|
||||||
{
|
|
||||||
constexpr QStringView typesPattern{u"(?<boolean>^(?:true|false)$)|"
|
|
||||||
u"(?<number>^(?:-?(?:0|[1-9]\\d*)?(?:\\.\\d*)?(?<=\\d|\\.)"
|
|
||||||
u"(?:e-?(?:0|[1-9]\\d*))?|0x[0-9a-f]+)$)|"
|
|
||||||
u"(?<color>^(?:#(?:(?:[0-9a-fA-F]{2}){3,4}|"
|
|
||||||
u"(?:[0-9a-fA-F]){3,4}))$)|"
|
|
||||||
u"(?<string>[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<QColor>();
|
|
||||||
if (!match.captured(u"string").isEmpty())
|
|
||||||
return variantValue.toString();
|
|
||||||
|
|
||||||
return QVariant::fromValue(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonDocument CollectionDetailsModel::readJsonFile(const QUrl &url)
|
QJsonDocument CollectionDetailsModel::readJsonFile(const QUrl &url)
|
||||||
{
|
{
|
||||||
using Utils::FilePath;
|
using Utils::FilePath;
|
||||||
|
@@ -88,7 +88,6 @@ private:
|
|||||||
void setCollectionName(const QString &newCollectionName);
|
void setCollectionName(const QString &newCollectionName);
|
||||||
void loadJsonCollection(const QString &filePath, const QString &collection);
|
void loadJsonCollection(const QString &filePath, const QString &collection);
|
||||||
void ensureSingleCell();
|
void ensureSingleCell();
|
||||||
QVariant variantFromString(const QString &value);
|
|
||||||
QJsonDocument readJsonFile(const QUrl &url);
|
QJsonDocument readJsonFile(const QUrl &url);
|
||||||
|
|
||||||
QHash<CollectionReference, CollectionDetails> m_openedCollections;
|
QHash<CollectionReference, CollectionDetails> m_openedCollections;
|
||||||
|
Reference in New Issue
Block a user