summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2018-11-30 15:00:28 +0200
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2018-12-03 08:53:16 +0000
commit821ca83228ff5d5ed2b770e1d122f94a7da7c831 (patch)
tree8a4de7d2b39004fdb73f50f095f6782fe3858070
parent4e40714dee6cf4fee908d8651989a19b010ad5f6 (diff)
Import data inputs when importing a presentation
Data inputs used by imported presentations are copied from source project. Duplicate inputs are ignored. Task-number: QT3DS-2742 Change-Id: Ia0162f3f91c78b35888e235b764985e09160498d Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Janne Kangas <janne.kangas@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
-rw-r--r--src/Authoring/Studio/Application/PresentationFile.cpp24
-rw-r--r--src/Authoring/Studio/Application/PresentationFile.h3
-rw-r--r--src/Authoring/Studio/Application/ProjectFile.cpp83
-rw-r--r--src/Authoring/Studio/Application/ProjectFile.h5
-rw-r--r--src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp46
-rw-r--r--src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.h7
6 files changed, 129 insertions, 39 deletions
diff --git a/src/Authoring/Studio/Application/PresentationFile.cpp b/src/Authoring/Studio/Application/PresentationFile.cpp
index deef4c24..21260213 100644
--- a/src/Authoring/Studio/Application/PresentationFile.cpp
+++ b/src/Authoring/Studio/Application/PresentationFile.cpp
@@ -273,7 +273,8 @@ QString PresentationFile::findProjectFile(const QString &uipPath)
void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo &uipTarget,
QHash<QString, QString> &outPathMap,
QString &outProjPathSrc,
- QHash<QString, QString> &outPresentationNodes)
+ QHash<QString, QString> &outPresentationNodes,
+ QSet<QString> &outDataInputs)
{
QDomDocument domDoc;
if (!StudioUtils::readFileToDomDocument(uipTarget.filePath(), domDoc))
@@ -337,10 +338,29 @@ void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo &
}
}
+ std::function<void(const QDomElement &, bool)> parseDataInput;
+ parseDataInput = [&](const QDomElement &elem, bool parseChildren) {
+ const QString ctrlAtt = elem.attribute(QStringLiteral("controlledproperty"));
+ if (!ctrlAtt.isEmpty()) {
+ const QStringList dataInputs = ctrlAtt.split(QLatin1Char('$'));
+ for (auto &di : dataInputs) {
+ if (!di.isEmpty())
+ outDataInputs.insert(di.left(di.indexOf(QLatin1Char(' '))));
+ }
+ }
+ if (parseChildren) {
+ const QDomNodeList children = elem.childNodes();
+ for (int i = 0; i < children.count(); ++i)
+ parseDataInput(children.at(i).toElement(), true);
+ }
+ };
+
// mesh files for group imports, materials, and effects are found under <Graph>
QDomElement graphElement = domDoc.documentElement().firstChild()
.firstChildElement(QStringLiteral("Graph"));
+ parseDataInput(graphElement, true);
+
QDomNodeList modelElems = graphElement.elementsByTagName(QStringLiteral("Model"));
for (int i = 0; i < modelElems.count(); ++i) {
QDomElement elem = modelElems.at(i).toElement();
@@ -475,6 +495,8 @@ void PresentationFile::getSourcePaths(const QFileInfo &uipSrc, const QFileInfo &
}
}
}
+
+ parseDataInput(elem, false);
}
};
diff --git a/src/Authoring/Studio/Application/PresentationFile.h b/src/Authoring/Studio/Application/PresentationFile.h
index 146149f5..5ff13221 100644
--- a/src/Authoring/Studio/Application/PresentationFile.h
+++ b/src/Authoring/Studio/Application/PresentationFile.h
@@ -44,7 +44,8 @@ class PresentationFile
public:
static void getSourcePaths(const QFileInfo &uipSrc, const QFileInfo &uipTarget,
QHash<QString, QString> &outPathMap, QString &outRootPath,
- QHash<QString, QString> &outPresentationNodes);
+ QHash<QString, QString> &outPresentationNodes,
+ QSet<QString> &outDataInputs);
static void updatePresentationId(const QString &url, const QString &oldId,
const QString &newId);
static void renameMaterial(const QString &uipPath, const QString &oldName,
diff --git a/src/Authoring/Studio/Application/ProjectFile.cpp b/src/Authoring/Studio/Application/ProjectFile.cpp
index 4b433f06..617659e2 100644
--- a/src/Authoring/Studio/Application/ProjectFile.cpp
+++ b/src/Authoring/Studio/Application/ProjectFile.cpp
@@ -41,7 +41,6 @@
#include "StudioUtils.h"
#include "Dispatch.h"
#include <QtCore/qdiriterator.h>
-#include <QtXml/qdom.h>
#include <QtCore/qsavefile.h>
#include <QtCore/qtimer.h>
@@ -464,6 +463,58 @@ QString ProjectFile::createPreview()
return {};
}
+void ProjectFile::parseDataInputElem(const QDomElement &elem,
+ QMap<QString, CDataInputDialogItem *> &dataInputs)
+{
+ if (elem.nodeName() == QLatin1String("dataInput")) {
+ CDataInputDialogItem *item = new CDataInputDialogItem();
+ item->name = elem.attribute(QStringLiteral("name"));
+ QString type = elem.attribute(QStringLiteral("type"));
+ if (type == QLatin1String("Ranged Number")) {
+ item->type = EDataType::DataTypeRangedNumber;
+ item->minValue = elem.attribute(QStringLiteral("min")).toFloat();
+ item->maxValue = elem.attribute(QStringLiteral("max")).toFloat();
+ } else if (type == QLatin1String("String")) {
+ item->type = EDataType::DataTypeString;
+ } else if (type == QLatin1String("Float")) {
+ item->type = EDataType::DataTypeFloat;
+ } else if (type == QLatin1String("Boolean")) {
+ item->type = EDataType::DataTypeBoolean;
+ } else if (type == QLatin1String("Vector3")) {
+ item->type = EDataType::DataTypeVector3;
+ } else if (type == QLatin1String("Vector2")) {
+ item->type = EDataType::DataTypeVector2;
+ } else if (type == QLatin1String("Variant")) {
+ item->type = EDataType::DataTypeVariant;
+ }
+#ifdef DATAINPUT_EVALUATOR_ENABLED
+ else if (type == QLatin1String("Evaluator")) {
+ item->type = EDataType::DataTypeEvaluator;
+ item->valueString = elem.attribute(QStringLiteral("evaluator"));
+ }
+#endif
+ dataInputs.insert(item->name, item);
+ }
+}
+
+void ProjectFile::loadDataInputs(const QString &projFile,
+ QMap<QString, CDataInputDialogItem *> &dataInputs)
+{
+ QFileInfo fi(projFile);
+ if (fi.exists()) {
+ QDomDocument doc;
+ if (!StudioUtils::readFileToDomDocument(projFile, doc))
+ return;
+ QDomElement assetsElem = doc.documentElement().firstChildElement(QStringLiteral("assets"));
+ if (!assetsElem.isNull()) {
+ for (QDomElement p = assetsElem.firstChild().toElement(); !p.isNull();
+ p = p.nextSibling().toElement()) {
+ parseDataInputElem(p, dataInputs);
+ }
+ }
+ }
+}
+
void ProjectFile::loadSubpresentationsAndDatainputs(
QVector<SubPresentationRecord> &subpresentations,
QMap<QString, CDataInputDialogItem *> &datainputs)
@@ -496,34 +547,8 @@ void ProjectFile::loadSubpresentationsAndDatainputs(
argsOrSrc = p.attribute(QStringLiteral("args"));
subpresentations.push_back(
SubPresentationRecord(p.nodeName(), p.attribute("id"), argsOrSrc));
- } else if (p.nodeName() == QLatin1String("dataInput")) {
- CDataInputDialogItem *item = new CDataInputDialogItem();
- item->name = p.attribute(QStringLiteral("name"));
- QString type = p.attribute(QStringLiteral("type"));
- if (type == QLatin1String("Ranged Number")) {
- item->type = EDataType::DataTypeRangedNumber;
- item->minValue = p.attribute(QStringLiteral("min")).toFloat();
- item->maxValue = p.attribute(QStringLiteral("max")).toFloat();
- } else if (type == QLatin1String("String")) {
- item->type = EDataType::DataTypeString;
- } else if (type == QLatin1String("Float")) {
- item->type = EDataType::DataTypeFloat;
- } else if (type == QLatin1String("Boolean")) {
- item->type = EDataType::DataTypeBoolean;
- } else if (type == QLatin1String("Vector3")) {
- item->type = EDataType::DataTypeVector3;
- } else if (type == QLatin1String("Vector2")) {
- item->type = EDataType::DataTypeVector2;
- } else if (type == QLatin1String("Variant")) {
- item->type = EDataType::DataTypeVariant;
- }
-#ifdef DATAINPUT_EVALUATOR_ENABLED
- else if (type == QLatin1String("Evaluator")) {
- item->type = EDataType::DataTypeEvaluator;
- item->valueString = p.attribute(QStringLiteral("evaluator"));
- }
-#endif
- datainputs.insert(item->name, item);
+ } else {
+ parseDataInputElem(p, datainputs);
}
}
}
diff --git a/src/Authoring/Studio/Application/ProjectFile.h b/src/Authoring/Studio/Application/ProjectFile.h
index df9e435a..0ea0244e 100644
--- a/src/Authoring/Studio/Application/ProjectFile.h
+++ b/src/Authoring/Studio/Application/ProjectFile.h
@@ -30,6 +30,7 @@
#define PROJECTFILE_H
#include "Qt3DSFileTools.h"
+#include <QtXml/qdom.h>
namespace Q3DStudio {
class CFilePath;
@@ -48,6 +49,10 @@ public:
void create(const QString &uiaPath);
void ensureProjectFile();
void initProjectFile(const QString &presPath);
+ static void parseDataInputElem(const QDomElement &elem,
+ QMap<QString, CDataInputDialogItem *> &dataInputs);
+ static void loadDataInputs(const QString &projFile,
+ QMap<QString, CDataInputDialogItem *> &dataInputs);
void loadSubpresentationsAndDatainputs(
QVector<SubPresentationRecord> &subpresentations,
QMap<QString, CDataInputDialogItem *> &datainputs);
diff --git a/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp b/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp
index 587cb084..24d24f1b 100644
--- a/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp
+++ b/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp
@@ -317,8 +317,9 @@ void ProjectFileSystemModel::updateProjectReferences()
// asset files
QString dummyStr;
QHash<QString, QString> dummyMap;
+ QSet<QString> dummySet;
PresentationFile::getSourcePaths(fi, fi, importPathMap,
- dummyStr, dummyMap);
+ dummyStr, dummyMap, dummySet);
addReferencesFromImportMap();
} else { // qml-stream
QQmlApplicationEngine qmlEngine;
@@ -670,6 +671,7 @@ void ProjectFileSystemModel::importUrls(const QList<QUrl> &urls, int row, bool a
// List of all files that have been copied by this import. Used to avoid duplicate imports
// due to some of the imported files also being assets used by other imported files.
QStringList importedFiles;
+ QMap<QString, CDataInputDialogItem *> importedDataInputs;
int overrideChoice = QMessageBox::NoButton;
for (const auto &url : urls) {
@@ -686,7 +688,8 @@ void ProjectFileSystemModel::importUrls(const QList<QUrl> &urls, int row, bool a
}
if (sortedDir.exists()) {
- importUrl(sortedDir, url, presentationNodes, importedFiles, overrideChoice);
+ importUrl(sortedDir, url, presentationNodes, importedFiles, importedDataInputs,
+ overrideChoice);
expandPaths << sortedDir.path();
}
}
@@ -694,6 +697,24 @@ void ProjectFileSystemModel::importUrls(const QList<QUrl> &urls, int row, bool a
// Batch update all imported presentation nodes
g_StudioApp.GetCore()->getProjectFile().addPresentationNodes(presentationNodes);
+ // Add new data inputs that are missing from project's data inputs. Duplicates are ignored,
+ // even if they are different type.
+ QMapIterator<QString, CDataInputDialogItem *> diIt(importedDataInputs);
+ bool addedDi = false;
+ while (diIt.hasNext()) {
+ diIt.next();
+ if (!g_StudioApp.m_dataInputDialogItems.contains(diIt.key())) {
+ g_StudioApp.m_dataInputDialogItems.insert(diIt.key(), diIt.value());
+ addedDi = true;
+ } else {
+ delete diIt.value();
+ }
+ }
+ if (addedDi) {
+ g_StudioApp.saveDataInputsToProjectFile();
+ g_StudioApp.checkDeletedDatainputs(); // Updates externalPresBoundTypes
+ }
+
for (const QString &expandPath : qAsConst(expandPaths)) {
int expandRow = rowForPath(expandPath);
if (expandRow >= 0 && !m_items[expandRow].expanded)
@@ -711,11 +732,13 @@ void ProjectFileSystemModel::importUrls(const QList<QUrl> &urls, int row, bool a
* is presentation id.
* @param outImportedFiles List of absolute source paths of the dependent assets that are imported
* in the same import context.
+ * @param outDataInputs Map of data inputs that are in use in this import context.
* @param outOverrideChoice The copy skip/override choice used in this import context.
*/
void ProjectFileSystemModel::importUrl(QDir &targetDir, const QUrl &url,
QHash<QString, QString> &outPresentationNodes,
QStringList &outImportedFiles,
+ QMap<QString, CDataInputDialogItem *> &outDataInputs,
int &outOverrideChoice) const
{
using namespace Q3DStudio;
@@ -801,8 +824,16 @@ void ProjectFileSystemModel::importUrl(QDir &targetDir, const QUrl &url,
= doc->GetCore()->getProjectFile().getRelativeFilePathTo(destPath);
if (!outPresentationNodes.contains(presPath))
outPresentationNodes.insert(presPath, {});
+ QSet<QString> dataInputs;
importPresentationAssets(fileInfo, QFileInfo(destPath), outPresentationNodes,
- outImportedFiles, outOverrideChoice);
+ outImportedFiles, dataInputs, outOverrideChoice);
+ const QString projFile = PresentationFile::findProjectFile(fileInfo.absoluteFilePath());
+ QMap<QString, CDataInputDialogItem *> allDataInputs;
+ ProjectFile::loadDataInputs(projFile, allDataInputs);
+ for (auto &di : dataInputs) {
+ if (allDataInputs.contains(di))
+ outDataInputs.insert(di, allDataInputs[di]);
+ }
} else if (qmlRoot && isQmlStream) { // importing a qml stream
const QString presPath
= doc->GetCore()->getProjectFile().getRelativeFilePathTo(destPath);
@@ -853,17 +884,19 @@ void ProjectFileSystemModel::importUrl(QDir &targetDir, const QUrl &url,
* recursive calls
* @param outImportedFiles list of absolute source paths of the dependent assets that are imported
* in the same import context.
+ * @param outDataInputs set of data input identifiers that are in use by this presentation and its
+ * subpresentations.
* @param outOverrideChoice The copy skip/override choice used in this import context.
*/
void ProjectFileSystemModel::importPresentationAssets(
const QFileInfo &uipSrc, const QFileInfo &uipTarget,
QHash<QString, QString> &outPresentationNodes, QStringList &outImportedFiles,
- int &outOverrideChoice) const
+ QSet<QString> &outDataInputs, int &outOverrideChoice) const
{
QHash<QString, QString> importPathMap;
QString projPathSrc; // project absolute path for the source uip
PresentationFile::getSourcePaths(uipSrc, uipTarget, importPathMap, projPathSrc,
- outPresentationNodes);
+ outPresentationNodes, outDataInputs);
const QDir projDir(g_StudioApp.GetCore()->getProjectFile().getProjectPath());
const QDir uipSrcDir = uipSrc.dir();
const QDir uipTargetDir = uipTarget.dir();
@@ -883,7 +916,8 @@ void ProjectFileSystemModel::importPresentationAssets(
if (path.endsWith(QLatin1String(".uip"))) {
// recursively load any uip asset's assets
importPresentationAssets(QFileInfo(srcAssetPath), QFileInfo(targetAssetPath),
- outPresentationNodes, outImportedFiles, outOverrideChoice);
+ outPresentationNodes, outImportedFiles, outDataInputs,
+ outOverrideChoice);
// update the path in outPresentationNodes to be correctly relative in target project
const QString subId = outPresentationNodes.take(path);
diff --git a/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.h b/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.h
index 9ff909f3..f8786345 100644
--- a/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.h
+++ b/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.h
@@ -42,6 +42,7 @@
#include <QtQml/qqmlapplicationengine.h>
QT_FORWARD_DECLARE_CLASS(QFileSystemModel)
+class CDataInputDialogItem;
class ProjectFileSystemModel : public QAbstractListModel
{
@@ -105,10 +106,12 @@ private:
bool hasVisibleChildren(const QModelIndex &modelIndex) const;
void importUrl(QDir &targetDir, const QUrl &url,
QHash<QString, QString> &outPresentationNodes,
- QStringList &outImportedFiles, int &outOverrideChoice) const;
+ QStringList &outImportedFiles,
+ QMap<QString, CDataInputDialogItem *> &outDataInputs,
+ int &outOverrideChoice) const;
void importPresentationAssets(const QFileInfo &uipSrc, const QFileInfo &uipTarget,
QHash<QString, QString> &outPresentationNodes,
- QStringList &outImportedFiles,
+ QStringList &outImportedFiles, QSet<QString> &outDataInputs,
int &outOverrideChoice) const;
void modelRowsInserted(const QModelIndex &parent, int start, int end);