aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVikas Pachdha <vikas.pachdha@qt.io>2021-01-26 15:59:17 +0100
committerVikas Pachdha <vikas.pachdha@qt.io>2021-02-01 10:41:22 +0000
commitd3b5e373b8850262e06096642271d3373dc78be0 (patch)
tree15344b64d619fde76fcf5f4c573b6e75baaf039a
parent368864a0af3052adf1f63e40d830a69b5d999eae (diff)
AssetExport: Add typeId and typeName to component instances
typdId is required to identify the instance's component while generating PSDs Task-number: QDS-2811 Change-Id: I61e0fe977e252c9c2aaeacd425b057c92a7c5b49 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
-rw-r--r--src/plugins/qmldesigner/assetexporterplugin/assetexporter.cpp94
-rw-r--r--src/plugins/qmldesigner/assetexporterplugin/assetexporter.h6
-rw-r--r--src/plugins/qmldesigner/assetexporterplugin/assetexportpluginconstants.h3
-rw-r--r--src/plugins/qmldesigner/assetexporterplugin/componentexporter.cpp6
-rw-r--r--src/plugins/qmldesigner/assetexporterplugin/parsers/modelitemnodeparser.cpp6
5 files changed, 107 insertions, 8 deletions
diff --git a/src/plugins/qmldesigner/assetexporterplugin/assetexporter.cpp b/src/plugins/qmldesigner/assetexporterplugin/assetexporter.cpp
index 74498f185b..03f1e71f1d 100644
--- a/src/plugins/qmldesigner/assetexporterplugin/assetexporter.cpp
+++ b/src/plugins/qmldesigner/assetexporterplugin/assetexporter.cpp
@@ -28,6 +28,7 @@
#include "exportnotification.h"
#include "designdocument.h"
+#include "nodemetainfo.h"
#include "qmldesignerplugin.h"
#include "rewriterview.h"
#include "qmlitemnode.h"
@@ -43,6 +44,7 @@
#include <QJsonArray>
#include <QJsonDocument>
#include <QLoggingCategory>
+#include <QPlainTextEdit>
#include <QWaitCondition>
#include <random>
@@ -130,13 +132,27 @@ void AssetExporter::exportQml(const Utils::FilePaths &qmlFiles, const Utils::Fil
m_exportFiles = qmlFiles;
m_totalFileCount = m_exportFiles.count();
m_components.clear();
+ m_componentUuidCache.clear();
m_exportPath = exportPath;
m_currentState.change(ParsingState::Parsing);
- triggerLoadNextFile();
if (exportAssets)
m_assetDumper = make_unique<AssetDumper>();
else
m_assetDumper.reset();
+
+ QTimer::singleShot(0, this, &AssetExporter::beginExport);
+}
+
+void AssetExporter::beginExport()
+{
+ for (const Utils::FilePath &p : m_exportFiles) {
+ if (m_cancelled)
+ break;
+ preprocessQmlFile(p);
+ }
+
+ if (!m_cancelled)
+ triggerLoadNextFile();
}
void AssetExporter::cancel()
@@ -253,6 +269,68 @@ Utils::FilePath AssetExporter::componentExportDir(const Component *component) co
return m_exportPath.pathAppended(component->name());
}
+void AssetExporter::preprocessQmlFile(const Utils::FilePath &path)
+{
+ // Load the QML file and assign UUIDs to items having none.
+ // Meanwhile cache the Component UUIDs as well
+ std::unique_ptr<Model> model(Model::create("Item", 2, 7));
+ Utils::FileReader reader;
+ if (!reader.fetch(path.toString())) {
+ ExportNotification::addError(tr("Cannot preprocess file: %1. Error %2")
+ .arg(path.toString()).arg(reader.errorString()));
+ return;
+ }
+
+ QPlainTextEdit textEdit;
+ textEdit.setPlainText(QString::fromUtf8(reader.data()));
+ NotIndentingTextEditModifier *modifier = new NotIndentingTextEditModifier(&textEdit);
+ modifier->setParent(model.get());
+ RewriterView *rewriterView = new RewriterView(QmlDesigner::RewriterView::Validate, model.get());
+ rewriterView->setCheckSemanticErrors(false);
+ rewriterView->setTextModifier(modifier);
+ model->attachView(rewriterView);
+ rewriterView->restoreAuxiliaryData();
+ ModelNode rootNode = rewriterView->rootModelNode();
+ if (!rootNode.isValid()) {
+ ExportNotification::addError(tr("Cannot preprocess file: %1").arg(path.toString()));
+ return;
+ }
+
+ if (assignUuids(rootNode)) {
+ // Some UUIDs were assigned. Rewrite the file.
+ rewriterView->writeAuxiliaryData();
+ const QByteArray data = textEdit.toPlainText().toUtf8();
+ Utils::FileSaver saver(path.toString(), QIODevice::Text);
+ saver.write(data);
+ if (!saver.finalize()) {
+ ExportNotification::addError(tr("Cannot update %1.\n%2")
+ .arg(path.toString()).arg(saver.errorString()));
+ return;
+ }
+ }
+
+ // Cache component UUID
+ const QString uuid = rootNode.auxiliaryData(Constants::UuidAuxTag).toString();
+ m_componentUuidCache[path.toString()] = uuid;
+}
+
+bool AssetExporter::assignUuids(const ModelNode &root)
+{
+ // Assign an UUID to the node without one.
+ // Return true if an assignment takes place.
+ bool changed = false;
+ for (const ModelNode &node : root.allSubModelNodesAndThisNode()) {
+ const QString uuid = node.auxiliaryData(Constants::UuidAuxTag).toString();
+ if (uuid.isEmpty()) {
+ // Assign an unique identifier to the node.
+ QByteArray uuid = generateUuid(node);
+ node.setAuxiliaryData(Constants::UuidAuxTag, QString::fromLatin1(uuid));
+ changed = true;
+ }
+ }
+ return changed;
+}
+
QByteArray AssetExporter::generateUuid(const ModelNode &node)
{
QByteArray uuid;
@@ -263,6 +341,20 @@ QByteArray AssetExporter::generateUuid(const ModelNode &node)
return uuid;
}
+QString AssetExporter::componentUuid(const ModelNode &instance) const
+{
+ // Returns the UUID of the component's root node
+ // Empty string is returned if the node is not an instance of a component within
+ // the project.
+ NodeMetaInfo metaInfo = instance.metaInfo();
+ if (!metaInfo.isValid())
+ return {};
+ const QString path = metaInfo.componentFileName();
+ if (m_componentUuidCache.contains(path))
+ return m_componentUuidCache[path];
+ return {};
+}
+
void AssetExporter::triggerLoadNextFile()
{
QTimer::singleShot(0, this, &AssetExporter::loadNextFile);
diff --git a/src/plugins/qmldesigner/assetexporterplugin/assetexporter.h b/src/plugins/qmldesigner/assetexporterplugin/assetexporter.h
index 55b1432d22..adfc71a115 100644
--- a/src/plugins/qmldesigner/assetexporterplugin/assetexporter.h
+++ b/src/plugins/qmldesigner/assetexporterplugin/assetexporter.h
@@ -76,6 +76,7 @@ public:
const QString &suffix = {}) const;
void exportAsset(const QPixmap &asset, const Utils::FilePath &path);
QByteArray generateUuid(const ModelNode &node);
+ QString componentUuid(const ModelNode &instance) const;
signals:
void stateChanged(ParsingState);
@@ -93,6 +94,10 @@ private:
void onQmlFileLoaded();
Utils::FilePath componentExportDir(const Component *component) const;
+ void beginExport();
+ void preprocessQmlFile(const Utils::FilePath &path);
+ bool assignUuids(const ModelNode &root);
+
private:
mutable class State {
public:
@@ -109,6 +114,7 @@ private:
Utils::FilePath m_exportPath;
bool m_perComponentExport = false;
std::vector<std::unique_ptr<Component>> m_components;
+ QHash<QString, QString> m_componentUuidCache;
QSet<QByteArray> m_usedHashes;
QHash<QString, QPixmap> m_assets;
std::unique_ptr<AssetDumper> m_assetDumper;
diff --git a/src/plugins/qmldesigner/assetexporterplugin/assetexportpluginconstants.h b/src/plugins/qmldesigner/assetexporterplugin/assetexportpluginconstants.h
index 36033a5ea2..07b2fa1833 100644
--- a/src/plugins/qmldesigner/assetexporterplugin/assetexportpluginconstants.h
+++ b/src/plugins/qmldesigner/assetexporterplugin/assetexportpluginconstants.h
@@ -67,7 +67,8 @@ const char ReferenceAssetTag[] = "referenceAsset";
const char AssetPathTag[] = "assetPath";
const char AssetBoundsTag[] = "assetBounds";
const char OpacityTag[] = "opacity";
-const char TypeNameTag[] = "qmlType";
+const char TypeNameTag[] = "typeName";
+const char TypeIdTag[] = "typeId";
const char TextDetailsTag[] = "textDetails";
const char FontFamilyTag[] = "fontFamily";
diff --git a/src/plugins/qmldesigner/assetexporterplugin/componentexporter.cpp b/src/plugins/qmldesigner/assetexporterplugin/componentexporter.cpp
index d3e2edfc82..13dfb3a5aa 100644
--- a/src/plugins/qmldesigner/assetexporterplugin/componentexporter.cpp
+++ b/src/plugins/qmldesigner/assetexporterplugin/componentexporter.cpp
@@ -130,12 +130,6 @@ QJsonObject Component::nodeToJson(const ModelNode &node)
std::unique_ptr<ModelNodeParser> parser(createNodeParser(node));
if (parser) {
- if (parser->uuid().isEmpty()) {
- // Assign an unique identifier to the node.
- QByteArray uuid = m_exporter.generateUuid(node);
- node.setAuxiliaryData(Constants::UuidAuxTag, QString::fromLatin1(uuid));
- node.model()->rewriterView()->writeAuxiliaryData();
- }
jsonObject = parser->json(*this);
} else {
ExportNotification::addError(tr("Error exporting node %1. Cannot parse type %2.")
diff --git a/src/plugins/qmldesigner/assetexporterplugin/parsers/modelitemnodeparser.cpp b/src/plugins/qmldesigner/assetexporterplugin/parsers/modelitemnodeparser.cpp
index 43963aa8b2..56ccd890f2 100644
--- a/src/plugins/qmldesigner/assetexporterplugin/parsers/modelitemnodeparser.cpp
+++ b/src/plugins/qmldesigner/assetexporterplugin/parsers/modelitemnodeparser.cpp
@@ -25,6 +25,8 @@
#include "modelitemnodeparser.h"
#include "assetexportpluginconstants.h"
+#include "assetexporter.h"
+#include "componentexporter.h"
#include "qmlitemnode.h"
@@ -83,6 +85,10 @@ QJsonObject QmlDesigner::ItemNodeParser::json(QmlDesigner::Component &component)
metadata.insert(ExportTypeTag, ExportTypeChild);
metadata.insert(TypeNameTag, QString::fromLatin1(m_node.type()));
+ QString typeId = component.exporter().componentUuid(m_node);
+ if (!typeId.isEmpty())
+ metadata.insert(TypeIdTag, typeId);
+
jsonObject.insert(MetadataTag, metadata);
return jsonObject;
}