diff options
author | Vikas Pachdha <vikas.pachdha@qt.io> | 2021-01-26 15:59:17 +0100 |
---|---|---|
committer | Vikas Pachdha <vikas.pachdha@qt.io> | 2021-02-01 10:41:22 +0000 |
commit | d3b5e373b8850262e06096642271d3373dc78be0 (patch) | |
tree | 15344b64d619fde76fcf5f4c573b6e75baaf039a | |
parent | 368864a0af3052adf1f63e40d830a69b5d999eae (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>
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; } |