From a3074871d0dd8159f95ef91bb4a536dc07a943ad Mon Sep 17 00:00:00 2001 From: Vikas Pachdha Date: Wed, 25 Mar 2020 23:33:59 +0100 Subject: [PATCH 1/1] Chain deep overrides Change-Id: I9f6fe04e9749dcadc643a9549f1c342e2a5d9432 --- .../assetexporterplugin.cpp | 5 +- .../assetimporterconstants.h | 1 + .../assetimporterplugin/core/component.cpp | 52 +++++++++++++----- .../assetimporterplugin/core/component.h | 3 +- .../core/importcontext.cpp | 53 +++++++++++++++---- .../assetimporterplugin/core/importcontext.h | 7 ++- .../assetimporterplugin/core/importmerger.cpp | 17 +++--- .../genericparser/genericmetadataparser.cpp | 4 +- 8 files changed, 104 insertions(+), 38 deletions(-) diff --git a/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.cpp b/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.cpp index deeea24a..6f707d29 100644 --- a/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.cpp +++ b/plugins/qmldesigner/assetexporterplugin/assetexporterplugin.cpp @@ -60,7 +60,9 @@ AssetExporterPlugin::AssetExporterPlugin() return; #endif -#ifdef ENABLE_ASSET_EXPORT +#ifndef ENABLE_ASSET_EXPORT + return; +#endif // Add parsers templates for factory instantiation. ModelExporter::addNodeParser(); @@ -72,7 +74,6 @@ AssetExporterPlugin::AssetExporterPlugin() this, &AssetExporterPlugin::updateActions); updateActions(); -#endif } QString AssetExporterPlugin::pluginName() const diff --git a/plugins/qmldesigner/assetimporterplugin/assetimporterconstants.h b/plugins/qmldesigner/assetimporterplugin/assetimporterconstants.h index aea8b583..f0efc6ff 100644 --- a/plugins/qmldesigner/assetimporterplugin/assetimporterconstants.h +++ b/plugins/qmldesigner/assetimporterplugin/assetimporterconstants.h @@ -42,6 +42,7 @@ const int RefNodePriority = 300; const int PsdTextNodePriority = TextNodePriority + 1; const int PsdAssetNodePriority = AssetNodePriority + 1; + //*************************************************************************** // Metadata tags //*************************************************************************** diff --git a/plugins/qmldesigner/assetimporterplugin/core/component.cpp b/plugins/qmldesigner/assetimporterplugin/core/component.cpp index d9c9ba63..36d39aae 100644 --- a/plugins/qmldesigner/assetimporterplugin/core/component.cpp +++ b/plugins/qmldesigner/assetimporterplugin/core/component.cpp @@ -44,6 +44,7 @@ #include #include +#include #include namespace { @@ -76,6 +77,23 @@ static QString toAliasName(const QString &nodeId, const QString &property) { name += capitalize(fragment); return name; } + +static QmlDesigner::ModelNode findNodeId(const QmlDesigner::ModelNode &parentNode, + const QString &childUuid) +{ + QQueue nodes; + nodes.enqueue(parentNode); + while (!nodes.isEmpty()) { + const QmlDesigner::ModelNode currentNode = nodes.dequeue(); + for (const QmlDesigner::ModelNode &childNode : currentNode.directSubModelNodes()) { + const QString uuid = childNode.auxiliaryData(QmlDesigner::Constants::UuidAuxTag).toString(); + if (childUuid == uuid) + return childNode; + nodes.enqueue(childNode); + } + } + return {}; +} } // namepace namespace QmlDesigner { @@ -219,15 +237,6 @@ void Component::addLazyTypeProperty(const QString &typeUuid, const ModelNode &no m_lazyProperties[node].insert(Internal::LazyProperty(propertyName, placeholderValue, typeUuid)); } -void Component::updateTypeNameCache(const QString &uuid) -{ - if (uuid.isEmpty()) { - qCDebug(componentLog()) << "Can not update component type cache. Empty UUID."; - return; - } - m_importContext.cacheComponentType(uuid, capitalize(rootNode().id()), m_contextId); -} - bool Component::write() const { RewriterView *view = rewriterView(); @@ -306,9 +315,28 @@ bool Component::write() const // Assign alias overrides. forEachOverride([&addLazyImports, this](const ModelNode &node, const QJsonObject &data) { const QString propertyName = data.value("name").toString().trimmed(); - const QByteArray resolvedAlias =m_importContext.resolvedAlias( - data.value("targetId").toString().trimmed(), - propertyName); + + const QString nodeUuid = node.auxiliaryData(Constants::UuidAuxTag).toString(); + const Component* nodeComponent = m_importContext.findComponent(node.type()); + QStringList parts = data.value("targetId").toString().trimmed().split("/"); + const QString targetUuid = parts.takeLast(); + QByteArray resolvedAlias = m_importContext.resolvedAlias(targetUuid, propertyName); + if (!parts.isEmpty()) { + if (!nodeComponent) { + ImportNotification::addError(tr("Alias override failure. " + "Can not resolve QML component for %1.") + .arg(node.id())); + return; + } + while (!parts.isEmpty()) { + // find item chain + ModelNode chainNode = findNodeId(nodeComponent->rootNode(), parts.takeLast()); + if (!chainNode.isValid()) + break; + resolvedAlias.prepend(chainNode.id().toLatin1() + "."); + } + } + if (resolvedAlias.isEmpty()) { ImportNotification::addError(tr("Can not resolve alias property name. Item %1:%2") .arg(node.id(), propertyName)); diff --git a/plugins/qmldesigner/assetimporterplugin/core/component.h b/plugins/qmldesigner/assetimporterplugin/core/component.h index 4185218c..16497523 100644 --- a/plugins/qmldesigner/assetimporterplugin/core/component.h +++ b/plugins/qmldesigner/assetimporterplugin/core/component.h @@ -93,7 +93,6 @@ public: void addLazyInitializedType(const QString &typeUuid, const ModelNode &node); void addLazyTypeProperty(const QString &typeUuid, const ModelNode &node, const QString &propertyName, const QString& placeholderValue); - void updateTypeNameCache(const QString &uuid); bool write() const; void findIdConflicts() const; @@ -118,4 +117,4 @@ private: }; } // QmlDesigner -using ComponentList = std::vector>; +//using ComponentList = std::vector>; diff --git a/plugins/qmldesigner/assetimporterplugin/core/importcontext.cpp b/plugins/qmldesigner/assetimporterplugin/core/importcontext.cpp index 9b1b769f..fcd09c7c 100644 --- a/plugins/qmldesigner/assetimporterplugin/core/importcontext.cpp +++ b/plugins/qmldesigner/assetimporterplugin/core/importcontext.cpp @@ -61,6 +61,16 @@ QString addAssetNameSuffix(const QString &assetName, const QString &suffix) } return QString("%1%2%3.%4").arg(base, suffix, scale, info.completeSuffix()); } + +static QString capitalize(const QString &str) +{ + if (str.isEmpty()) + return QString(); + QString tmp = str; + tmp[0] = str[0].toUpper(); + return tmp; +} + } namespace QmlDesigner { @@ -242,6 +252,25 @@ void ImportContext::merge(AbstractView *view, const ulong contextId, const QStri } } +const Component *ImportContext::findComponent(const QString &uuid) const +{ + auto itr = m_components.find(uuid); + if (itr != m_components.end()) + return itr->second.get(); + return nullptr; +} + +const Component *ImportContext::findComponent(const QByteArray &type) const +{ + // Find conflicts before writing components. + for (auto itr = m_components.cbegin(); itr != m_components.end(); ++itr) { + ComponentTypeInfo info = qmlTypeFromUuid(itr->first); + if ( info.type().toLatin1() == type) + return itr->second.get(); + } + return nullptr; +} + bool ImportContext::contextIdIsValid(ulong contextId) const { return contextId < m_contextInfoList.size(); @@ -296,15 +325,22 @@ const AssetPaths &ImportContext::assetPaths(ulong contextId) const return m_contextInfoList.at(contextId)->m_assetPaths; } -void ImportContext::addComponent(std::unique_ptr component) +void ImportContext::addComponent(const QString &uuid, std::unique_ptr component) { - m_components.push_back(std::move(component)); + if (uuid.isEmpty()) { + ImportNotification::addError(tr("Error creating QML component %1. Invalid UUID.") + .arg(component->rootNode().id())); + return; + } + cacheComponentType(uuid, capitalize(component->rootNode().id()), component->contextId()); + m_components.insert({uuid, std::move(component)}); + //m_components[uuid] = ; } bool ImportContext::writeComponents(std::function progress) const { bool success = true; - if (m_components.size() < 1) { + if (m_components.empty()) { ImportNotification::addWarning(tr("No components to write.")); return true; } @@ -312,18 +348,18 @@ bool ImportContext::writeComponents(std::function progress) const double done = 0.0; // Find conflicts before writing components. - for (auto &component: m_components) { + for (auto itr = m_components.cbegin(); itr != m_components.end(); ++itr) { if (m_assetImporter->isCancelled()) return false; - component->findIdConflicts(); + itr->second->findIdConflicts(); progress(done+=share); } // Write Components. - for (auto &component: m_components) { + for (auto itr = m_components.cbegin(); itr != m_components.end(); ++itr) { if (m_assetImporter->isCancelled()) return false; - success &= component->write(); + success &= itr->second->write(); progress(done+=share); } progress(1.0); @@ -351,8 +387,7 @@ void ImportContext::addResolvedAliasName(const QString &uuid, m_reslovedAliases[uuid + name] = aliasName; } -QByteArray ImportContext::resolvedAlias(const QString &uuid, - const QString &name) const +QByteArray ImportContext::resolvedAlias(const QString &uuid, const QString &name) const { return m_reslovedAliases.value(uuid + name).toLatin1(); } diff --git a/plugins/qmldesigner/assetimporterplugin/core/importcontext.h b/plugins/qmldesigner/assetimporterplugin/core/importcontext.h index 2ef0bb9e..ddf51a26 100644 --- a/plugins/qmldesigner/assetimporterplugin/core/importcontext.h +++ b/plugins/qmldesigner/assetimporterplugin/core/importcontext.h @@ -31,6 +31,7 @@ #include #include #include +#include #include @@ -91,7 +92,7 @@ public: QString addAssetPath(ulong contextId, const QFileInfo &path, const QString &targetAssetName); const AssetPaths &assetPaths(ulong contextId) const; - void addComponent(std::unique_ptr component); + void addComponent(const QString &uuid, std::unique_ptr component); bool writeComponents(std::function progress) const; void cacheComponentType(const QString &uuid, const QString &qmlType, ulong contextId); ComponentTypeInfo qmlTypeFromUuid(const QString &uuid) const; @@ -101,6 +102,8 @@ public: QByteArray resolvedAlias(const QString &uuid, const QString &name) const; void merge(AbstractView *view, const ulong contextId, const QString &fileName) const; + const Component *findComponent(const QString& uuid) const; + const Component *findComponent(const QByteArray& type) const; private: bool contextIdIsValid(ulong contextId) const; @@ -112,7 +115,7 @@ private: QStringList m_metadataFiles; QHash m_componentTypeCache; QHash m_reslovedAliases; - ComponentList m_components; + std::unordered_map> m_components; vector> m_contextInfoList; }; } diff --git a/plugins/qmldesigner/assetimporterplugin/core/importmerger.cpp b/plugins/qmldesigner/assetimporterplugin/core/importmerger.cpp index e8f8d931..9059f3a2 100644 --- a/plugins/qmldesigner/assetimporterplugin/core/importmerger.cpp +++ b/plugins/qmldesigner/assetimporterplugin/core/importmerger.cpp @@ -25,6 +25,7 @@ #include "importmerger.h" #include "importnotification.h" +#include "assetimporterconstants.h" #include #include @@ -39,7 +40,6 @@ #include namespace QmlDesigner { -static const char *uuidAuxTag = "UUID"; static Q_LOGGING_CATEGORY(rewriterBenchmark, "qtc.assetimporter.merge", QtWarningMsg) ImportMerger::ImportMerger(AbstractView *oldModel, AbstractView *newModel) @@ -48,8 +48,8 @@ ImportMerger::ImportMerger(AbstractView *oldModel, AbstractView *newModel) { for (ModelNode &node : m_newModel->allModelNodes()) { - if (node.hasAuxiliaryData(uuidAuxTag)) - m_nodesHash[node.auxiliaryData(uuidAuxTag).toString()] = node; + if (node.hasAuxiliaryData(Constants::UuidAuxTag)) + m_nodesHash[node.auxiliaryData(Constants::UuidAuxTag).toString()] = node; } } @@ -58,8 +58,9 @@ void ImportMerger::merge() for (ModelNode &node : m_oldModel->allModelNodes()) { if (nodeIsInBothModels(node)) { - mergeExistingNode(m_nodesHash[node.auxiliaryData(uuidAuxTag).toString()], node); - } else if (node.hasAuxiliaryData(uuidAuxTag)) { + mergeExistingNode(m_nodesHash[node.auxiliaryData(Constants::UuidAuxTag).toString()], + node); + } else if (node.hasAuxiliaryData(Constants::UuidAuxTag)) { if (nodeIsInBothModels(node, true)) { addWarning(tr("Merging by id: %1").arg(node.id())); auto newNode = m_newModel->modelNodeForId(node.id()); @@ -107,7 +108,7 @@ void ImportMerger::syncBindingProperties(ModelNode &outputNode, const ModelNode ModelNode ImportMerger::lookUpByUuidOrFallbackToId(const ModelNode &node) { - const QString uuid = node.auxiliaryData(uuidAuxTag).toString(); + const QString uuid = node.auxiliaryData(Constants::UuidAuxTag).toString(); auto modelNode = m_nodesHash[uuid]; @@ -192,10 +193,10 @@ void ImportMerger::mergeNewNode(const ModelNode &node) bool ImportMerger::nodeIsInBothModels(const ModelNode &node, bool useHeuristic) { - if (!node.hasAuxiliaryData(uuidAuxTag)) + if (!node.hasAuxiliaryData(Constants::UuidAuxTag)) return false; - QString uuid = node.auxiliaryData(uuidAuxTag).toString(); + QString uuid = node.auxiliaryData(Constants::UuidAuxTag).toString(); if (!uuid.isEmpty() && m_nodesHash[uuid].isValid()) return true; diff --git a/plugins/qmldesigner/assetimporterplugin/genericparser/genericmetadataparser.cpp b/plugins/qmldesigner/assetimporterplugin/genericparser/genericmetadataparser.cpp index 45b77474..c781c830 100644 --- a/plugins/qmldesigner/assetimporterplugin/genericparser/genericmetadataparser.cpp +++ b/plugins/qmldesigner/assetimporterplugin/genericparser/genericmetadataparser.cpp @@ -191,9 +191,7 @@ ModelNode GenericMetadataParser::parseComponent(const QJsonObject &object, ulong addError(e.description()); } - // Cache the Component Type. - component->updateTypeNameCache(reader->uuid()); - importContext().addComponent(std::move(component)); + importContext().addComponent(reader->uuid(), std::move(component)); return componentNode; } else { addError(tr("Error parsing component.")); -- 2.20.1