diff options
author | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2018-11-27 12:22:24 +0200 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2018-11-29 08:50:49 +0000 |
commit | 660eb01c5b91df7fca6cc00fb25b20710cbaded4 (patch) | |
tree | 5287051005f97a728f388ea119b31a46f28b5b03 | |
parent | 59553021acfe3df91a42e2ba06baf4f06777b3b0 (diff) |
Fix referenced assets importing when importing a presentation
Fixes following issues when importing presentations:
- Importing presentations with different relative path to project file
caused some assets to be imported into wrong folders
- Importing custom materials didn't import texture assets that didn't
have a default asset set in .material file
Task-number: QT3DS-2599
Change-Id: I38e2afa1fbf793f9808a0056529336f26e6cad7e
Reviewed-by: Jere Tuliniemi <jere.tuliniemi@qt.io>
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
4 files changed, 68 insertions, 57 deletions
diff --git a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp index cb6c0145..eab8b2eb 100644 --- a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp +++ b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp @@ -856,28 +856,25 @@ public: } } else if (elem.attribute(QStringLiteral("type")) == QLatin1String("Texture")) { path = elem.attribute(QStringLiteral("default")); + outPropertySet.insert(elem.attribute(QStringLiteral("name"))); } - if (!path.isEmpty()) { - if (!isMatDefs[j]) - outPropertySet.insert(elem.attribute(QStringLiteral("name"))); - if (!path.isEmpty() && !outPathMap.contains(path)) { - QString absAssetPath; - if (projectPath.isEmpty()) { - // Importing from library, assume relative path to file itself - absAssetPath = QDir::cleanPath(fileDir.absoluteFilePath(path)); - } else { - // When importing from project, all paths are relative to project - absAssetPath = QDir::cleanPath(projDir.absoluteFilePath(path)); - } - if (recurseSourceMaterial - && absAssetPath.endsWith(QLatin1String(".material")) - && !outPathMap.contains(path)) { - ParseSourcePathsOutOfEffectFile(absAssetPath, projectPath, - false, outPathMap, outPropertySet); - } - outPathMap.insert(path, absAssetPath); + if (!path.isEmpty() && !outPathMap.contains(path)) { + QString absAssetPath; + if (projectPath.isEmpty()) { + // Importing from library, assume relative path to file itself + absAssetPath = QDir::cleanPath(fileDir.absoluteFilePath(path)); + } else { + // When importing from project, all paths are relative to project + absAssetPath = QDir::cleanPath(projDir.absoluteFilePath(path)); + } + if (recurseSourceMaterial + && absAssetPath.endsWith(QLatin1String(".material")) + && !outPathMap.contains(path)) { + ParseSourcePathsOutOfEffectFile(absAssetPath, projectPath, + false, outPathMap, outPropertySet); } + outPathMap.insert(path, absAssetPath); } } } diff --git a/src/Authoring/Studio/Application/PresentationFile.cpp b/src/Authoring/Studio/Application/PresentationFile.cpp index 52229205..7e8e4ef2 100644 --- a/src/Authoring/Studio/Application/PresentationFile.cpp +++ b/src/Authoring/Studio/Application/PresentationFile.cpp @@ -261,7 +261,8 @@ QString PresentationFile::findProjectFile(const QString &uipPath) return {}; } -// get all available child assets source paths (materials, images, effects, etc) +// Get all available child assets source paths (materials, images, effects, etc). +// The source paths returned are relative to the presentation file being parsed. // static void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo &uipTarget, QHash<QString, QString> &outPathMap, @@ -278,7 +279,18 @@ void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo & outProjPathSrc = QFileInfo(uiaPath).path(); QString uipPathRelative = QFileInfo(uiaPath).dir().relativeFilePath(uipSrc.filePath()); ProjectFile::getPresentations(uiaPath, subpresentations, uipPathRelative); + } else { + outProjPathSrc = uipSrc.path(); } + QDir srcProjDir(outProjPathSrc); + QDir srcUipDir(uipSrc.path()); + + const auto convertPath = [&](const QString &path, bool forceProj = false) -> QString { + if (forceProj || path.startsWith(QLatin1String("./"))) + return srcUipDir.relativeFilePath(srcProjDir.absoluteFilePath(path)); + else + return path; // Assuming path is already presentation relative + }; // Map to cache effect and material properties during the presentation file parsing, // as we don't yet know which ones are actually assets. @@ -291,7 +303,7 @@ void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo & .firstChildElement(QStringLiteral("Classes")); for (QDomElement p = classesElem.firstChild().toElement(); !p.isNull(); p = p.nextSibling().toElement()) { - const QString sourcepath = p.attribute(QStringLiteral("sourcepath")); + const QString sourcepath = convertPath(p.attribute(QStringLiteral("sourcepath"))); if (!sourcepath.isEmpty() && !outPathMap.contains(sourcepath)) { outPathMap.insert(sourcepath, {}); @@ -302,10 +314,17 @@ void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo & if (CDialogs::IsMaterialFileExtension(ext.data()) || CDialogs::IsEffectFileExtension(ext.data())) { QSet<QString> propertySet; + QHash<QString, QString> matEffPathMap; g_StudioApp.GetCore()->GetDoc()->GetDocumentReader() .ParseSourcePathsOutOfEffectFile( uipSrc.path() + QStringLiteral("/") + sourcepath, - outProjPathSrc, true, outPathMap, propertySet); + outProjPathSrc, true, matEffPathMap, propertySet); + // ParseSourcePathsOutOfEffectFile returns paths relative to project + QHashIterator<QString, QString> pathIter(matEffPathMap); + while (pathIter.hasNext()) { + pathIter.next(); + outPathMap.insert(convertPath(pathIter.key(), true), pathIter.value()); + } matEffPropertyMap.insert(QStringLiteral("#") + p.attribute(QStringLiteral("id")), propertySet); } @@ -319,7 +338,7 @@ void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo & QDomNodeList modelElems = graphElement.elementsByTagName(QStringLiteral("Model")); for (int i = 0; i < modelElems.count(); ++i) { QDomElement elem = modelElems.at(i).toElement(); - const QString sourcePath = elem.attribute(QStringLiteral("sourcepath")); + const QString sourcePath = convertPath(elem.attribute(QStringLiteral("sourcepath"))); if (!sourcePath.isEmpty()) { QFileInfo fi(sourcePath); QByteArray ext = fi.suffix().toLatin1(); @@ -354,7 +373,7 @@ void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo & for (int i = 0; i < addElems.count(); ++i) { QDomElement elem = addElems.at(i).toElement(); - const QString sourcePath = elem.attribute(QStringLiteral("sourcepath")); + const QString sourcePath = convertPath(elem.attribute(QStringLiteral("sourcepath"))); if (!sourcePath.isEmpty()) { QFileInfo fi(sourcePath); QByteArray ext = fi.suffix().toLatin1(); @@ -373,17 +392,10 @@ void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo & return spr.m_id == sourcePath; }); if (sp != subpresentations.end()) { // has a subpresentation - QString spPath = sp->m_argsOrSrc; - // set as root path (if it is not root nor relative) to make sure importing - // works correctly - if (!spPath.startsWith(QLatin1String("../")) - && !spPath.startsWith(QLatin1String("./"))) { - spPath.prepend(QLatin1String("./")); - } - + QString spPath = convertPath(sp->m_argsOrSrc, true); if (!outPathMap.contains(spPath)) { outPathMap.insert(spPath, {}); - outPresentationNodes.insert(sp->m_argsOrSrc, sp->m_id); + outPresentationNodes.insert(spPath, sp->m_id); } } } @@ -397,17 +409,10 @@ void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo & return spr.m_id == subpresentation; }); if (sp != subpresentations.end()) { // has a subpresentation - QString spPath = sp->m_argsOrSrc; - // set as root path (if it is not root nor relative) to make sure importing works - // correctly. - if (!spPath.startsWith(QLatin1String("../")) - && !spPath.startsWith(QLatin1String("./"))) { - spPath.prepend(QLatin1String("./")); - } - + QString spPath = convertPath(sp->m_argsOrSrc, true); if (!outPathMap.contains(spPath)) { outPathMap.insert(spPath, {}); - outPresentationNodes.insert(sp->m_argsOrSrc, sp->m_id); + outPresentationNodes.insert(spPath, sp->m_id); } } } @@ -453,12 +458,16 @@ void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo & QString texturePath = elem.attribute(prop); if (!texturePath.isEmpty()) { // Typically these paths have ./ prepended even though they are relative to uip - // Remove it as ./ at start interpreted as relative to project file + // Remove it as ./ at start is interpreted as relative to project file if (texturePath.startsWith(QLatin1String("./"))) texturePath = texturePath.mid(2); - QFileInfo absTexPath(uipSrc.path() + QLatin1Char('/') + texturePath); - if (absTexPath.exists() && !outPathMap.contains(texturePath)) - outPathMap.insert(texturePath, absTexPath.absoluteFilePath()); + if (!texturePath.isEmpty()) { + QFileInfo absTexPath(uipSrc.path() + QLatin1Char('/') + texturePath); + if (!outPathMap.contains(texturePath) && absTexPath.exists() + && absTexPath.isFile()) { + outPathMap.insert(texturePath, absTexPath.absoluteFilePath()); + } + } } } } diff --git a/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp b/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp index efc4201b..587cb084 100644 --- a/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp +++ b/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp @@ -864,6 +864,9 @@ void ProjectFileSystemModel::importPresentationAssets( QString projPathSrc; // project absolute path for the source uip PresentationFile::getSourcePaths(uipSrc, uipTarget, importPathMap, projPathSrc, outPresentationNodes); + const QDir projDir(g_StudioApp.GetCore()->getProjectFile().getProjectPath()); + const QDir uipSrcDir = uipSrc.dir(); + const QDir uipTargetDir = uipTarget.dir(); QHashIterator<QString, QString> pathIter(importPathMap); while (pathIter.hasNext()) { @@ -871,16 +874,9 @@ void ProjectFileSystemModel::importPresentationAssets( QString srcAssetPath = pathIter.value(); const QString path = pathIter.key(); QString targetAssetPath; - if (path.startsWith(QLatin1String("./"))) { // path from project root - if (srcAssetPath.isEmpty()) - srcAssetPath = QDir(projPathSrc).absoluteFilePath(path); - targetAssetPath = QDir(g_StudioApp.GetCore()->getProjectFile().getProjectPath()) - .absoluteFilePath(path); - } else { // relative path - if (srcAssetPath.isEmpty()) - srcAssetPath = uipSrc.dir().absoluteFilePath(path); - targetAssetPath = uipTarget.dir().absoluteFilePath(path); - } + if (srcAssetPath.isEmpty()) + srcAssetPath = uipSrcDir.absoluteFilePath(path); + targetAssetPath = uipTargetDir.absoluteFilePath(path); overridableCopyFile(srcAssetPath, targetAssetPath, outImportedFiles, outOverrideChoice); @@ -888,6 +884,11 @@ void ProjectFileSystemModel::importPresentationAssets( // recursively load any uip asset's assets importPresentationAssets(QFileInfo(srcAssetPath), QFileInfo(targetAssetPath), outPresentationNodes, outImportedFiles, outOverrideChoice); + + // update the path in outPresentationNodes to be correctly relative in target project + const QString subId = outPresentationNodes.take(path); + if (!subId.isEmpty()) + outPresentationNodes.insert(projDir.relativeFilePath(targetAssetPath), subId); } else if (path.endsWith(QLatin1String(".qml"))) { // recursively load any qml stream assets QQmlApplicationEngine qmlEngine; @@ -897,6 +898,10 @@ void ProjectFileSystemModel::importPresentationAssets( importQmlAssets(qmlRoot, QFileInfo(srcAssetPath).dir(), QFileInfo(targetAssetPath).dir(), outImportedFiles, outOverrideChoice); + // update path in outPresentationNodes to be correctly relative in target project + const QString subId = outPresentationNodes.take(path); + if (!subId.isEmpty()) + outPresentationNodes.insert(projDir.relativeFilePath(targetAssetPath), subId); } } } diff --git a/src/Authoring/Studio/Utils/StudioUtils.cpp b/src/Authoring/Studio/Utils/StudioUtils.cpp index 7553d0b2..e309491f 100644 --- a/src/Authoring/Studio/Utils/StudioUtils.cpp +++ b/src/Authoring/Studio/Utils/StudioUtils.cpp @@ -79,7 +79,7 @@ bool StudioUtils::readFileToDomDocument(const QString &filePath, QDomDocument &d { QFile file(filePath); if (!file.open(QFile::Text | QIODevice::ReadOnly)) { - qWarning() << __FUNCTION__ << file.errorString(); + qWarning() << __FUNCTION__ << file.errorString() << "'" << filePath << "'"; return false; } |