aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAli Kianian <ali.kianian@qt.io>2024-02-12 12:26:17 +0200
committerAli Kianian <ali.kianian@qt.io>2024-02-12 12:37:14 +0000
commit1f9e41ac9ab56a5c5abb5d0c241b4131f11d570a (patch)
treea9fe805ba1f60ad8944a0dec17ef76c8e30c38fd
parentdccd828f1fd47afcece1166e9532e73354e09f4c (diff)
QmlDesigner: Keep the order of columns for imported jsons
Fixes: QDS-11670 Change-Id: Ia068bbb864065b648cffcab2c3477d3cec7f25f8 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Qt CI Patch Build Bot <ci_patchbuild_bot@qt.io>
-rw-r--r--src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp75
-rw-r--r--src/plugins/qmldesigner/components/collectioneditor/collectiondetails.h7
-rw-r--r--src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp4
3 files changed, 77 insertions, 9 deletions
diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp
index 4acd2f601a..e8e8e18dc0 100644
--- a/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp
+++ b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.cpp
@@ -6,6 +6,9 @@
#include "collectioneditorutils.h"
#include <utils/span.h>
+#include <qmljs/parser/qmljsast_p.h>
+#include <qmljs/parser/qmljsastvisitor_p.h>
+#include <qmljs/qmljsdocument.h>
#include <qqml.h>
#include <QJsonArray>
@@ -261,6 +264,47 @@ inline static bool isEmptyJsonValue(const QJsonValue &value)
return value.isNull() || value.isUndefined() || (value.isString() && value.toString().isEmpty());
}
+class PropertyOrderFinder : public QmlJS::AST::Visitor
+{
+public:
+ static QStringList parse(const QString &jsonContent)
+ {
+ PropertyOrderFinder finder;
+ QmlJS::Document::MutablePtr jsonDoc = QmlJS::Document::create(Utils::FilePath::fromString(
+ "<expression>"),
+ QmlJS::Dialect::Json);
+
+ jsonDoc->setSource(jsonContent);
+ jsonDoc->parseJavaScript();
+
+ if (!jsonDoc->isParsedCorrectly())
+ return {};
+
+ jsonDoc->ast()->accept(&finder);
+ return finder.m_orderedList;
+ }
+
+protected:
+ bool visit(QmlJS::AST::PatternProperty *patternProperty) override
+ {
+ const QString propertyName = patternProperty->name->asString();
+ if (!m_propertySet.contains(propertyName)) {
+ m_propertySet.insert(propertyName);
+ m_orderedList.append(propertyName);
+ }
+ return true;
+ }
+
+ void throwRecursionDepthError() override
+ {
+ qWarning() << Q_FUNC_INFO << __LINE__ << "Recursion depth error";
+ };
+
+private:
+ QSet<QString> m_propertySet;
+ QStringList m_orderedList;
+};
+
QString CollectionParseError::errorString() const
{
switch (errorNo) {
@@ -690,7 +734,7 @@ CollectionDetails CollectionDetails::fromImportedCsv(const QByteArray &document)
return fromImportedJson(importedArray);
}
-CollectionDetails CollectionDetails::fromImportedJson(const QJsonDocument &document)
+CollectionDetails CollectionDetails::fromImportedJson(const QByteArray &json, QJsonParseError *error)
{
QJsonArray importedCollection;
auto refineJsonArray = [](const QJsonArray &array) -> QJsonArray {
@@ -710,6 +754,14 @@ CollectionDetails CollectionDetails::fromImportedJson(const QJsonDocument &docum
return resultArray;
};
+ QJsonParseError parseError;
+ QJsonDocument document = QJsonDocument::fromJson(json, &parseError);
+ if (error)
+ *error = parseError;
+
+ if (parseError.error != QJsonParseError::NoError)
+ return CollectionDetails{};
+
if (document.isArray()) {
importedCollection = refineJsonArray(document.array());
} else if (document.isObject()) {
@@ -738,7 +790,7 @@ CollectionDetails CollectionDetails::fromImportedJson(const QJsonDocument &docum
}
}
- return fromImportedJson(importedCollection);
+ return fromImportedJson(importedCollection, PropertyOrderFinder::parse(QLatin1String(json)));
}
CollectionDetails CollectionDetails::fromLocalJson(const QJsonDocument &document,
@@ -803,9 +855,24 @@ void CollectionDetails::insertRecords(const QJsonArray &record, int idx, int cou
d->dataRecords.insert(idx, count, localRecord);
}
-CollectionDetails CollectionDetails::fromImportedJson(const QJsonArray &importedArray)
+CollectionDetails CollectionDetails::fromImportedJson(const QJsonArray &importedArray,
+ const QStringList &propertyPriority)
{
- const QList<CollectionProperty> columnData = getColumnsFromImportedJsonArray(importedArray);
+ QList<CollectionProperty> columnData = getColumnsFromImportedJsonArray(importedArray);
+ if (!propertyPriority.isEmpty()) {
+ QMap<QString, int> priorityMap;
+ for (const QString &propertyName : propertyPriority) {
+ if (!priorityMap.contains(propertyName))
+ priorityMap.insert(propertyName, priorityMap.size());
+ }
+ const int lowestPriority = priorityMap.size();
+
+ Utils::sort(columnData, [&](const CollectionProperty &a, const CollectionProperty &b) {
+ return priorityMap.value(a.name, lowestPriority)
+ < priorityMap.value(b.name, lowestPriority);
+ });
+ }
+
QList<QJsonArray> localJsonArray;
for (const QJsonValue &importedRowValue : importedArray) {
QJsonObject importedRowObject = importedRowValue.toObject();
diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.h b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.h
index 2ccc69e447..95528413f6 100644
--- a/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.h
+++ b/src/plugins/qmldesigner/components/collectioneditor/collectiondetails.h
@@ -9,6 +9,7 @@
QT_BEGIN_NAMESPACE
class QJsonObject;
+struct QJsonParseError;
class QVariant;
QT_END_NAMESPACE
@@ -125,7 +126,8 @@ public:
static void registerDeclarativeType();
static CollectionDetails fromImportedCsv(const QByteArray &document);
- static CollectionDetails fromImportedJson(const QJsonDocument &document);
+ static CollectionDetails fromImportedJson(const QByteArray &json,
+ QJsonParseError *error = nullptr);
static CollectionDetails fromLocalJson(const QJsonDocument &document,
const QString &collectionName,
CollectionParseError *error = nullptr);
@@ -136,7 +138,8 @@ private:
void markChanged();
void insertRecords(const QJsonArray &record, int idx = -1, int count = 1);
- static CollectionDetails fromImportedJson(const QJsonArray &importedArray);
+ static CollectionDetails fromImportedJson(const QJsonArray &importedArray,
+ const QStringList &propertyPriority = {});
static CollectionDetails fromLocalCollection(const QJsonObject &localCollection,
CollectionParseError *error = nullptr);
diff --git a/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp b/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp
index efffa2c2e9..24fb745ab7 100644
--- a/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp
+++ b/src/plugins/qmldesigner/components/collectioneditor/collectionwidget.cpp
@@ -306,13 +306,11 @@ bool CollectionWidget::importFile(const QString &collectionName, const QUrl &url
return false;
QJsonParseError parseError;
- QJsonDocument document = QJsonDocument::fromJson(fileContent, &parseError);
+ loadedCollection = CollectionDetails::fromImportedJson(fileContent, &parseError);
if (parseError.error != QJsonParseError::NoError) {
warn(tr("Json file Import error"),
tr("Cannot parse json content\n%1").arg(parseError.errorString()));
}
-
- loadedCollection = CollectionDetails::fromImportedJson(document);
} else if (fileInfo.suffix() == "csv") {
if (!loadUrlContent())
return false;