summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2018-11-15 16:29:44 +0200
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2018-11-16 12:44:31 +0000
commit4d0b587d99f1755023b4f66071b09138b65a1d17 (patch)
treef338cac83296a5325e1069aafd8c657585604d02
parentfdb943ad0a699bfaaadbfc27f1442307747fd020 (diff)
Fix importing .materialdef files
The paths were changed to always be relative to project file in materialdef files. The default texture paths of materials and effects are converted to presentation relative when an instance is made out of them to keep paths consistent in presentations. Importing materialdef file now imports all referenced assets, including default assets of the shader. In-use highlighting in project panel got fixed alongside import fixes as they use same mechanism to determine referred assets. Task-number: QT3DS-2656 Task-number: QT3DS-2657 Change-Id: I473e77ab5d76328c642dc16fc3a3b4016bf85313 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io>
-rw-r--r--src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp187
-rw-r--r--src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp2
-rw-r--r--src/Authoring/Client/Code/Core/Doc/IDocumentEditor.h2
-rw-r--r--src/Authoring/Client/Code/Core/Doc/IDocumentReader.h1
-rw-r--r--src/Authoring/Studio/Application/PresentationFile.cpp2
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp12
-rw-r--r--src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp2
-rw-r--r--src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp128
-rw-r--r--src/Authoring/Studio/Workspace/Dialogs.cpp12
-rw-r--r--src/Authoring/Studio/Workspace/Dialogs.h1
10 files changed, 229 insertions, 120 deletions
diff --git a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp
index c4d49ade..c4f06075 100644
--- a/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp
+++ b/src/Authoring/Client/Code/Core/Doc/DocumentEditor.cpp
@@ -806,6 +806,8 @@ public:
@param inFile The file to parse. Can be absolute or relative to current directory.
@param projectPath The absolute path of the project root the inFile belongs to, if any.
Can be left empty for files that are not in any project.
+ @param recurseSourceMaterial If true, parsing .materialdef files will recursively also
+ parse the shader .material file.
@param outPathMap A map to return the parsed assets.
The key is the destination path parsed from the file. It is assumed to be
relative to the project root rather than the asset file itself.
@@ -817,11 +819,13 @@ public:
*/
void ParseSourcePathsOutOfEffectFile(const QString &inFile,
const QString &projectPath,
+ bool recurseSourceMaterial,
QHash<QString, QString> &outPathMap,
QSet<QString> &outPropertySet) override
{
- QFileInfo fi(inFile);
QDomDocument domDocMat;
+ QDir projDir(projectPath);
+ QDir fileDir(QFileInfo(inFile).dir());
if (StudioUtils::readFileToDomDocument(inFile, domDocMat)) {
QVector<QDomNodeList> nodeLists;
QVector<bool> isMatDefs;
@@ -841,32 +845,38 @@ public:
isMatDefs.append(true);
}
- QString type, path, name;
for (int j = 0; j < nodeLists.count(); ++j) {
for (int i = 0, c = nodeLists[j].count(); i < c; ++i) {
- auto elem = nodeLists[j].at(i).toElement();
+ auto elem = nodeLists[j].at(i).toElement();
+ QString path;
if (isMatDefs[j]) {
- type = elem.attribute(QStringLiteral("name"));
- path = elem.text();
- name = QLatin1String("sourcepath");
- } else {
- type = elem.attribute(QStringLiteral("type"));
+ if (elem.attribute(QStringLiteral("name")) == QLatin1String("sourcepath")
+ || elem.attribute(QStringLiteral("type")) == QLatin1String("Texture")) {
+ path = elem.text();
+ }
+ } else if (elem.attribute(QStringLiteral("type")) == QLatin1String("Texture")) {
path = elem.attribute(QStringLiteral("default"));
- name = QLatin1String("Texture");
}
- if (type == name) {
+ if (!path.isEmpty()) {
if (!isMatDefs[j])
outPropertySet.insert(elem.attribute(QStringLiteral("name")));
if (!path.isEmpty() && !outPathMap.contains(path)) {
- QString absAssetPath = fi.absolutePath() + QStringLiteral("/") + path;
- if (QFile::exists(absAssetPath)) {
- outPathMap.insert(path, absAssetPath);
- } else if (!projectPath.isEmpty()) {
- absAssetPath = projectPath + QStringLiteral("/") + path;
- if (QFile::exists(absAssetPath))
- outPathMap.insert(path, absAssetPath);
+ 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);
}
}
}
@@ -913,6 +923,9 @@ public:
qt3ds::foundation::CFileSeekableIOStream theStream(inAbsoluteFilePath,
qt3ds::foundation::FileReadFlags());
if (theStream.IsOpen()) {
+ const QDir docDir(m_Doc.GetDocumentDirectory().toQString());
+ const QDir projDir = g_StudioApp.GetCore()->getProjectFile().getProjectPath();
+
std::shared_ptr<IDOMFactory> theFactory =
IDOMFactory::CreateDOMFactory(m_DataCore.GetStringTablePtr());
SImportXmlErrorHandler theImportHandler(m_Doc.GetImportFailedHandler(),
@@ -926,22 +939,28 @@ public:
*theElem, m_DataCore.GetStringTablePtr(), theFactory);
const QString sourcePath = QStringLiteral("sourcepath");
+ QStringList convertPaths;
for (bool success = theReader->MoveToFirstChild("Property"); success;
success = theReader->MoveToNextSibling("Property")) {
const char8_t *name = "";
const char8_t *value = "";
+ const char8_t *type = "";
theReader->Att("name", name);
+ theReader->Att("type", type);
theReader->Value(value);
- outValues[name] = value;
+ const QString nameStr = QString::fromUtf8(name);
+ const QString valueStr = QString::fromUtf8(value);
+ if (!valueStr.isEmpty() && (QString::fromUtf8(type) == QLatin1String("Texture")
+ || nameStr == sourcePath)) {
+ convertPaths.append(nameStr);
+ }
+ outValues[nameStr] = valueStr;
}
- if (outValues.contains(sourcePath) && !outValues[sourcePath].isEmpty()) {
+ for (const auto &prop : qAsConst(convertPaths)) {
// Change paths to be relative to the presentation
- QFileInfo sourcePathFileInfo(m_Doc.GetCore()->getProjectFile()
- .getProjectPath() + QLatin1Char('/')
- + outValues[sourcePath]);
- outValues[sourcePath] = QDir(m_Doc.GetDocumentDirectory().toQString())
- .relativeFilePath(sourcePathFileInfo.absoluteFilePath());
+ const QString origPath = outValues[prop];
+ outValues[prop] = docDir.relativeFilePath(projDir.absoluteFilePath(origPath));
}
if (AreEqual(theReader->GetElementName(), L"Property"))
@@ -962,12 +981,9 @@ public:
}
if (texValues.contains(sourcePath) && !texValues[sourcePath].isEmpty()) {
- // Change paths to be relative to the presentation
- QFileInfo sourcePathFileInfo(m_Doc.GetCore()->getProjectFile()
- .getProjectPath() + QLatin1Char('/')
- + texValues[sourcePath]);
- texValues[sourcePath] = QDir(m_Doc.GetDocumentDirectory().toQString())
- .relativeFilePath(sourcePathFileInfo.absoluteFilePath());
+ // Change path to be relative to the presentation
+ texValues[sourcePath] = docDir.relativeFilePath(
+ projDir.absoluteFilePath(texValues[sourcePath]));
}
outTextureValues[texName] = texValues;
@@ -2028,26 +2044,22 @@ public:
return "";
}
- void writeProperty(QFile &file, const QString &name, const QString &value, int indent = 1)
+ void writeProperty(QFile &file, const QString &name, const QString &value,
+ int indent = 1, bool isTexture = false)
{
for (int i = 0; i < indent; ++i)
file.write("\t");
file.write("<Property name=\"");
file.write(name.toUtf8().constData());
+ if (isTexture)
+ file.write("\" type=\"Texture");
file.write("\">");
- QString finalValue = value;
- if (name == QLatin1String("sourcepath") && !value.isEmpty()) {
- // Save paths relative to the project, not the presentation
- QFileInfo sourcePathFileInfo(m_Doc.GetDocumentDirectory().toQString()
- + QLatin1Char('/') + finalValue);
- finalValue = QDir(m_Doc.GetCore()->getProjectFile().getProjectPath())
- .relativeFilePath(sourcePathFileInfo.absoluteFilePath());
- }
- file.write(finalValue.toUtf8().constData());
+ file.write(value.toUtf8().constData());
file.write("</Property>\n");
}
- void writeProperty(QFile &file, const QString &name, const SValue &value, int indent = 1)
+ void writeProperty(QFile &file, const QString &name, const SValue &value, int indent = 1,
+ bool isTexture = false)
{
MemoryBuffer<RawAllocator> tempBuffer;
WCharTWriter writer(tempBuffer);
@@ -2056,7 +2068,8 @@ public:
if (tempBuffer.size()) {
writeProperty(file, name,
- QString::fromWCharArray((const wchar_t *)tempBuffer.begin()), indent);
+ QString::fromWCharArray((const wchar_t *)tempBuffer.begin()),
+ indent, isTexture);
}
}
@@ -2099,6 +2112,13 @@ public:
file.write("<MaterialData version=\"1.0\">\n");
QMap<QString, Qt3DSDMInstanceHandle> textureHandles;
qt3dsdm::TPropertyHandleList propList;
+
+ const QDir docDir(m_Doc.GetDocumentDirectory().toQString());
+ const QDir projDir = g_StudioApp.GetCore()->getProjectFile().getProjectPath();
+ auto sourcePathProp = m_Bridge.GetSourcePathProperty();
+ // Importing interprets "./" prefix to mean project dir relative
+ const QString projPrefix = QStringLiteral("./");
+
m_PropertySystem.GetAggregateInstanceProperties(instance, propList);
for (auto &prop : propList) {
const auto name = QString::fromWCharArray(m_PropertySystem.GetName(prop).wide_str());
@@ -2113,24 +2133,47 @@ public:
if (!value.empty()) {
bool valid = true;
- QString path;
+ bool isTexture = false;
+ bool isPath = true;
+ QString strValue;
if (value.getType() == DataModelDataType::Long4) {
SLong4 guid = get<qt3dsdm::SLong4>(value);
if (guid.Valid()) {
auto ref = m_Bridge.GetInstanceByGUID(guid);
textureHandles[name] = ref;
- path = m_Bridge.GetSourcePath(ref).toQString();
- if (path.isEmpty())
- path = m_Bridge.getSubpresentation(ref).toQString();
+ strValue = m_Bridge.GetSourcePath(ref).toQString();
+ if (strValue.isEmpty()) {
+ strValue = m_Bridge.getSubpresentation(ref).toQString();
+ isPath = false;
+ }
} else {
valid = false;
}
+ } else {
+ qt3dsdm::AdditionalMetaDataType::Value additionalMetaDataType
+ = m_PropertySystem.GetAdditionalMetaDataType(instance, prop);
+ if (additionalMetaDataType == AdditionalMetaDataType::Texture) {
+ isTexture = true;
+ TDataStrPtr strPtr = get<TDataStrPtr>(value);
+ strValue = QString::fromWCharArray(strPtr->GetData());
+ } else if (sourcePathProp == prop) {
+ TDataStrPtr strPtr = get<TDataStrPtr>(value);
+ strValue = QString::fromWCharArray(strPtr->GetData());
+ }
}
- if (path.isEmpty() && valid)
+ if (strValue.isEmpty() && valid) {
writeProperty(file, name, value);
- else
- writeProperty(file, name, path);
+ } else if (!strValue.isEmpty()) {
+ // Save paths relative to the project instead of the presentation.
+ // This makes it possible to use same material from multiple presentations
+ // that are not all in the same folder.
+ if (isPath) {
+ strValue = projPrefix
+ + projDir.relativeFilePath(docDir.absoluteFilePath(strValue));
+ }
+ writeProperty(file, name, strValue, 1, isTexture);
+ }
}
}
@@ -2157,8 +2200,17 @@ public:
continue;
m_PropertySystem.GetInstancePropertyValue(handle, prop, value);
- if (!value.empty())
- writeProperty(file, name, value, 2);
+ if (!value.empty()) {
+ if (sourcePathProp == prop) {
+ TDataStrPtr strPtr = get<TDataStrPtr>(value);
+ QString strValue = QString::fromWCharArray(strPtr->GetData());
+ strValue = projPrefix
+ + projDir.relativeFilePath(docDir.absoluteFilePath(strValue));
+ writeProperty(file, name, strValue, 2);
+ } else {
+ writeProperty(file, name, value, 2);
+ }
+ }
}
file.write("\t</TextureData>\n");
}
@@ -4428,6 +4480,7 @@ public:
theRelativePath.GetFileStem().c_str(),
theWarnings,
*theStream);
+ IDocumentEditor::fixDefaultTexturePaths(theParentInstance);
DisplayLoadWarnings(shaderFile, theWarnings, QString());
} else {
if (theHandler)
@@ -5323,6 +5376,7 @@ public:
theInstances[0].second,
TCharStr(theNameStr),
theWarnings, *theStream);
+ IDocumentEditor::fixDefaultTexturePaths(theInstances[0].second);
}
for (size_t i = 0; i < theInstances.size(); ++i) {
@@ -5409,6 +5463,37 @@ IDocumentEditor::GetAlwaysUnlinkedProperties(qt3dsdm::SComposerObjectDefinitions
return theProperties;
}
+// Fixes the default texture paths loaded from material and effect to be presentation relative
+void IDocumentEditor::fixDefaultTexturePaths(Qt3DSDMInstanceHandle instance)
+{
+ const auto core = g_StudioApp.GetCore();
+ const QDir docDir(core->GetDoc()->GetDocumentDirectory().toQString());
+ const QDir projDir = core->getProjectFile().getProjectPath();
+ const auto propertySystem = core->GetDoc()->GetStudioSystem()->GetPropertySystem();
+ qt3dsdm::TPropertyHandleList propList;
+ SValue value;
+
+ propertySystem->GetAggregateInstanceProperties(instance, propList);
+ for (auto &prop : propList) {
+ qt3dsdm::AdditionalMetaDataType::Value additionalMetaDataType
+ = propertySystem->GetAdditionalMetaDataType(instance, prop);
+ if (additionalMetaDataType == AdditionalMetaDataType::Texture) {
+ propertySystem->GetInstancePropertyValue(instance, prop, value);
+ TDataStrPtr strPtr = get<TDataStrPtr>(value);
+ const QString strValue = QString::fromWCharArray(strPtr->GetData());
+ const QString docRelative = docDir.relativeFilePath(strValue);
+ const QString projRelative = projDir.relativeFilePath(strValue);
+ if (!QFileInfo(docRelative).exists() && !QFileInfo(projRelative).exists()) {
+ // Convert path to presentation relative
+ const QVariant newVarValue = QVariant::fromValue(
+ docDir.relativeFilePath(projDir.absoluteFilePath(strValue)));
+ const SValue newValue = newVarValue;
+ propertySystem->SetInstancePropertyValue(instance, prop, newValue);
+ }
+ }
+ }
+}
+
void IDocumentEditor::UnlinkAlwaysUnlinkedProperties(Qt3DSDMInstanceHandle inInstance,
SComposerObjectDefinitions &inDefs,
ISlideSystem &inSlideSystem)
diff --git a/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp b/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp
index dbdf8e76..5dbbd953 100644
--- a/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp
+++ b/src/Authoring/Client/Code/Core/Doc/IComposerSerializer.cpp
@@ -2509,6 +2509,7 @@ struct SComposerSerializerImpl : public IComposerSerializer
theFullPath.GetFileStem().c_str(),
warnings,
*theStream);
+ IDocumentEditor::fixDefaultTexturePaths(theMaster);
}
} else {
QT3DS_ASSERT(false);
@@ -2541,6 +2542,7 @@ struct SComposerSerializerImpl : public IComposerSerializer
theFullPath.GetFileStem().c_str(),
warnings,
*theStream);
+ IDocumentEditor::fixDefaultTexturePaths(theMaster);
}
} else {
QT3DS_ASSERT(false);
diff --git a/src/Authoring/Client/Code/Core/Doc/IDocumentEditor.h b/src/Authoring/Client/Code/Core/Doc/IDocumentEditor.h
index 7dad0327..111161d4 100644
--- a/src/Authoring/Client/Code/Core/Doc/IDocumentEditor.h
+++ b/src/Authoring/Client/Code/Core/Doc/IDocumentEditor.h
@@ -143,6 +143,8 @@ public:
static Qt3DSDMPropertyHandle *
GetAlwaysUnlinkedProperties(qt3dsdm::SComposerObjectDefinitions &inDefs);
+ static void fixDefaultTexturePaths(qt3dsdm::Qt3DSDMInstanceHandle instance);
+
// Create a new instance in the scene under this slide and such
// Target id must be an id of an invalid instance so that we can potentially change an object
// type while still maintaining references to that logical object.
diff --git a/src/Authoring/Client/Code/Core/Doc/IDocumentReader.h b/src/Authoring/Client/Code/Core/Doc/IDocumentReader.h
index 6cf4505f..d0f563aa 100644
--- a/src/Authoring/Client/Code/Core/Doc/IDocumentReader.h
+++ b/src/Authoring/Client/Code/Core/Doc/IDocumentReader.h
@@ -229,6 +229,7 @@ public:
virtual void ParseSourcePathsOutOfEffectFile(const QString &inFile,
const QString &projectPath,
+ bool recurseSourceMaterial,
QHash<QString, QString> &outPathMap,
QSet<QString> &outPropertyMap) = 0;
diff --git a/src/Authoring/Studio/Application/PresentationFile.cpp b/src/Authoring/Studio/Application/PresentationFile.cpp
index 30794471..0ffe5c5f 100644
--- a/src/Authoring/Studio/Application/PresentationFile.cpp
+++ b/src/Authoring/Studio/Application/PresentationFile.cpp
@@ -185,7 +185,7 @@ void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo &
g_StudioApp.GetCore()->GetDoc()->GetDocumentReader()
.ParseSourcePathsOutOfEffectFile(
uipSrc.path() + QStringLiteral("/") + sourcepath,
- outProjPathSrc, outPathMap, propertySet);
+ outProjPathSrc, true, outPathMap, propertySet);
matEffPropertyMap.insert(QStringLiteral("#") + p.attribute(QStringLiteral("id")),
propertySet);
}
diff --git a/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp b/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp
index 2e670794..d2d27e74 100644
--- a/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp
+++ b/src/Authoring/Studio/Palettes/Inspector/InspectorControlModel.cpp
@@ -1723,18 +1723,6 @@ void InspectorControlModel::setPropertyValue(long instance, int handle, const QV
const QVector3D theFloat3 = qt3dsdm::get<QVector3D>(v);
if (theFloat3.x() == 0.0f || theFloat3.y() == 0.0f || theFloat3.z() == 0.0f )
v = oldValue;
- } else if ((theType == EStudioObjectType::OBJTYPE_CUSTOMMATERIAL
- || theType == EStudioObjectType::OBJTYPE_EFFECT) &&
- studio->GetPropertySystem()->GetDataType(handle)
- == qt3dsdm::DataModelDataType::String
- && additionalType == qt3dsdm::AdditionalMetaDataType::Texture) {
- // force . at the beginning of the url
- QString x = value.toString();
- QUrl url(x);
- if (url.isRelative() && !x.startsWith("./")) {
- QString s = QString("./%1").arg(url.path());
- v = QVariant::fromValue(s);
- }
}
// some properties may initialize OpenGL resources (e.g. loading meshes will
diff --git a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp
index 06d3d1e7..456a21b0 100644
--- a/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp
+++ b/src/Authoring/Studio/Palettes/Inspector/InspectorControlView.cpp
@@ -407,7 +407,7 @@ void InspectorControlView::setPropertyValueFromFilename(long instance, int handl
if (m_inspectorControlModel) {
QString value;
if (name != ChooserModelBase::noneString()) {
- // Relativize the path to the project
+ // Relativize the path to the presentation
const auto doc = g_StudioApp.GetCore()->GetDoc();
const QDir documentDir(doc->GetDocumentDirectory().toQString());
QString relativeName = documentDir.relativeFilePath(name);
diff --git a/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp b/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp
index a64810a6..23b7e09e 100644
--- a/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp
+++ b/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp
@@ -195,11 +195,6 @@ void ProjectFileSystemModel::updateReferences()
auto addReferencesPresentation = [this, doc, &projectPath](const Q3DStudio::CString &str) {
addPathsToReferences(m_references, projectPath, doc->GetResolvedPathToDoc(str).toQString());
};
- auto addReferencesProject = [this, doc, &projectPath](const Q3DStudio::CString &str) {
- addPathsToReferences(
- m_references, projectPath,
- doc->GetCore()->getProjectFile().getAbsoluteFilePathTo(str.toQString()));
- };
auto addReferencesRenderable = [this, &projectPath, &projectPathSlash, &subpresentationRecord]
(const QString &id) {
for (SubPresentationRecord r : qAsConst(subpresentationRecord)) {
@@ -210,7 +205,6 @@ void ProjectFileSystemModel::updateReferences()
std::for_each(sourcePathList.begin(), sourcePathList.end(), addReferencesPresentation);
std::for_each(fontFileList.begin(), fontFileList.end(), addReferencesPresentation);
- std::for_each(effectTextureList.begin(), effectTextureList.end(), addReferencesProject);
std::for_each(effectTextureList.begin(), effectTextureList.end(), addReferencesPresentation);
std::for_each(renderableList.begin(), renderableList.end(), addReferencesRenderable);
@@ -288,56 +282,77 @@ void ProjectFileSystemModel::updateProjectReferences()
updateIt.next();
m_presentationReferences.remove(updateIt.key());
if (updateIt.value()) {
- // Presentation file added/modified, check that it is one of the subpresentations,
- // or we don't care about it
- const QString relPath = g_StudioApp.GetCore()->getProjectFile()
- .getRelativeFilePathTo(updateIt.key());
- for (int i = 0, count = g_StudioApp.m_subpresentations.size(); i < count; ++i) {
- SubPresentationRecord &rec = g_StudioApp.m_subpresentations[i];
- if (rec.m_argsOrSrc == relPath) {
- QFileInfo fi(updateIt.key());
- QSet<QString> newReferences;
- if (rec.m_type == QLatin1String("presentation")) {
- // Since this is not actual import, source and target uip is the same,
- // and we are only interested in the absolute paths of the "imported"
- // asset files
- QHash<QString, QString> importPathMap;
- QHash<QString, QString> dummyMap;
- QString dummyStr;
-
- PresentationFile::getSourcePaths(fi, fi, importPathMap, dummyStr, dummyMap);
-
- QHashIterator<QString, QString> pathIter(importPathMap);
- while (pathIter.hasNext()) {
- pathIter.next();
- const QString path = pathIter.key();
- QString targetAssetPath;
- if (path.startsWith(QLatin1String("./"))) // path from project root
- targetAssetPath = projectDir.absoluteFilePath(path);
- else // relative path
- targetAssetPath = fi.dir().absoluteFilePath(path);
- newReferences.insert(QDir::cleanPath(targetAssetPath));
- }
- } else { // qml-stream
- QQmlApplicationEngine qmlEngine;
- bool isQmlStream = false;
- QObject *qmlRoot = getQmlStreamRootNode(qmlEngine, updateIt.key(),
- isQmlStream);
- if (qmlRoot && isQmlStream) {
- QSet<QString> assetPaths;
- getQmlAssets(qmlRoot, assetPaths);
- QDir qmlDir = fi.dir();
- for (auto &assetSrc : qAsConst(assetPaths)) {
- QString targetAssetPath;
- targetAssetPath = qmlDir.absoluteFilePath(assetSrc);
- newReferences.insert(QDir::cleanPath(targetAssetPath));
+ QFileInfo fi(updateIt.key());
+ QDir fileDir = fi.dir();
+ const QString suffix = fi.suffix();
+ QHash<QString, QString> importPathMap;
+ QSet<QString> newReferences;
+
+ const auto addReferencesFromImportMap = [&]() {
+ QHashIterator<QString, QString> pathIter(importPathMap);
+ while (pathIter.hasNext()) {
+ pathIter.next();
+ const QString path = pathIter.key();
+ QString targetAssetPath;
+ if (path.startsWith(QLatin1String("./"))) // path from project root
+ targetAssetPath = projectDir.absoluteFilePath(path);
+ else // relative path
+ targetAssetPath = fileDir.absoluteFilePath(path);
+ newReferences.insert(QDir::cleanPath(targetAssetPath));
+ }
+ };
+
+ if (CDialogs::presentationExtensions().contains(suffix)
+ || CDialogs::qmlStreamExtensions().contains(suffix)) {
+ // Presentation file added/modified, check that it is one of the subpresentations,
+ // or we don't care about it
+ const QString relPath = g_StudioApp.GetCore()->getProjectFile()
+ .getRelativeFilePathTo(updateIt.key());
+ for (int i = 0, count = g_StudioApp.m_subpresentations.size(); i < count; ++i) {
+ SubPresentationRecord &rec = g_StudioApp.m_subpresentations[i];
+ if (rec.m_argsOrSrc == relPath) {
+ if (rec.m_type == QLatin1String("presentation")) {
+ // Since this is not actual import, source and target uip is the same,
+ // and we are only interested in the absolute paths of the "imported"
+ // asset files
+ QString dummyStr;
+ QHash<QString, QString> dummyMap;
+ PresentationFile::getSourcePaths(fi, fi, importPathMap,
+ dummyStr, dummyMap);
+ addReferencesFromImportMap();
+ } else { // qml-stream
+ QQmlApplicationEngine qmlEngine;
+ bool isQmlStream = false;
+ QObject *qmlRoot = getQmlStreamRootNode(qmlEngine, updateIt.key(),
+ isQmlStream);
+ if (qmlRoot && isQmlStream) {
+ QSet<QString> assetPaths;
+ getQmlAssets(qmlRoot, assetPaths);
+ QDir qmlDir = fi.dir();
+ for (auto &assetSrc : qAsConst(assetPaths)) {
+ QString targetAssetPath;
+ targetAssetPath = qmlDir.absoluteFilePath(assetSrc);
+ newReferences.insert(QDir::cleanPath(targetAssetPath));
+ }
}
}
+ break;
}
- m_presentationReferences.insert(updateIt.key(), newReferences);
- break;
}
+ } else if (CDialogs::materialExtensions().contains(suffix)
+ || CDialogs::effectExtensions().contains(suffix)) {
+ // Use dummy set, as we are only interested in values set in material files
+ QSet<QString> dummySet;
+ g_StudioApp.GetCore()->GetDoc()->GetDocumentReader()
+ .ParseSourcePathsOutOfEffectFile(
+ updateIt.key(),
+ g_StudioApp.GetCore()->getProjectFile().getProjectPath(),
+ false, // No need to recurse src mats; those get handled individually
+ importPathMap, dummySet);
+ addReferencesFromImportMap();
}
+ if (!newReferences.isEmpty())
+ m_presentationReferences.insert(updateIt.key(), newReferences);
}
}
@@ -795,8 +810,8 @@ void ProjectFileSystemModel::importUrl(QDir &targetDir, const QUrl &url,
// values of texture properties
QSet<QString> dummyPropertySet;
g_StudioApp.GetCore()->GetDoc()->GetDocumentReader()
- .ParseSourcePathsOutOfEffectFile(absSrcPath, projectPath, effectFileSourcePaths,
- dummyPropertySet);
+ .ParseSourcePathsOutOfEffectFile(absSrcPath, projectPath, true,
+ effectFileSourcePaths, dummyPropertySet);
QHashIterator<QString, QString> pathIter(effectFileSourcePaths);
while (pathIter.hasNext()) {
@@ -1212,8 +1227,11 @@ void ProjectFileSystemModel::onFilesChanged(
for (size_t idx = 0, end = inFileModificationList.size(); idx < end; ++idx) {
const Q3DStudio::SFileModificationRecord &record(inFileModificationList[idx]);
if (record.m_File.isFile()) {
- const bool isQml = record.m_File.suffix() == QLatin1String("qml");
- if (isQml || record.m_File.suffix() == QLatin1String("uip")) {
+ const QString suffix = record.m_File.suffix();
+ const bool isQml = CDialogs::qmlStreamExtensions().contains(suffix);
+ if (isQml || CDialogs::presentationExtensions().contains(suffix)
+ || CDialogs::materialExtensions().contains(suffix)
+ || CDialogs::effectExtensions().contains(suffix)) {
const QString filePath = record.m_File.absoluteFilePath();
if (record.m_ModificationType == Q3DStudio::FileModificationType::Created
|| record.m_ModificationType == Q3DStudio::FileModificationType::Modified) {
diff --git a/src/Authoring/Studio/Workspace/Dialogs.cpp b/src/Authoring/Studio/Workspace/Dialogs.cpp
index f6520904..87ba3b70 100644
--- a/src/Authoring/Studio/Workspace/Dialogs.cpp
+++ b/src/Authoring/Studio/Workspace/Dialogs.cpp
@@ -1514,6 +1514,18 @@ QStringList CDialogs::presentationExtensions()
return exts;
}
+QStringList CDialogs::qmlStreamExtensions()
+{
+ static QStringList exts;
+ if (exts.isEmpty()) {
+ for (const char *ext : qmlStreamExts) {
+ if (ext)
+ exts << QString::fromLatin1(ext);
+ }
+ }
+ return exts;
+}
+
QColor CDialogs::displayColorDialog(const QColor &color) const
{
QColorDialog theColorDlg;
diff --git a/src/Authoring/Studio/Workspace/Dialogs.h b/src/Authoring/Studio/Workspace/Dialogs.h
index 987ccc95..7a2a3a9a 100644
--- a/src/Authoring/Studio/Workspace/Dialogs.h
+++ b/src/Authoring/Studio/Workspace/Dialogs.h
@@ -85,6 +85,7 @@ public:
static QStringList modelExtensions();
static QStringList behaviorExtensions();
static QStringList presentationExtensions();
+ static QStringList qmlStreamExtensions();
// This is not an appropriate place for these, but better
// in an inappropriate place than duplicated