summaryrefslogtreecommitdiffstats
path: root/src/Authoring/Studio/Palettes
diff options
context:
space:
mode:
authorMahmoud Badri <mahmoud.badri@qt.io>2018-08-15 14:18:54 +0300
committerTomi Korpipää <tomi.korpipaa@qt.io>2018-08-17 03:39:04 +0000
commitbe23d3d7e307bc91de323bab9d6489c9291a7f71 (patch)
treed51902906d33450f811003b3a550b2b515488ac7 /src/Authoring/Studio/Palettes
parent9080e19cabeae385fd5b9a762d19a8c5a7a7aa74 (diff)
Import Qml streams
Allow importing visual Qml files (Qml streams) to the Studio. visual Qmls are detected and put in the 'qml streams' folder. the qml file is parsed recursively and any node with a valid 'source' attribute is imported as well. Imported Qmls are added to the project file for use as a sub-presentation. Task-number: QT3DS-2061 Change-Id: Ic0ac0178adb4bac06972a9e553c1dc0bb6c5286d Reviewed-by: Miikka Heikkinen <miikka.heikkinen@qt.io> Reviewed-by: Janne Kangas <janne.kangas@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
Diffstat (limited to 'src/Authoring/Studio/Palettes')
-rw-r--r--src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp82
-rw-r--r--src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.h4
-rw-r--r--src/Authoring/Studio/Palettes/Project/ProjectView.cpp2
-rw-r--r--src/Authoring/Studio/Palettes/Project/ProjectView.h2
4 files changed, 85 insertions, 5 deletions
diff --git a/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp b/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp
index b0ab81f2..39587036 100644
--- a/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp
+++ b/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.cpp
@@ -44,6 +44,7 @@
#include "Qt3DSMessageBox.h"
#include "IDocumentEditor.h"
#include "IDragable.h"
+#include <QtQml/qqmlapplicationengine.h>
ProjectFileSystemModel::ProjectFileSystemModel(QObject *parent) : QAbstractListModel(parent)
, m_model(new QFileSystemModel(this))
@@ -128,7 +129,7 @@ bool ProjectFileSystemModel::isRefreshable(int row) const
const QString path = filePath(row);
// Import needs to be refreshable even if it is not referenced, as user may drag just individual
// meshes into the scene, and not the whole import.
- return path.endsWith(QStringLiteral(".import"));
+ return path.endsWith(QLatin1String(".import"));
}
void ProjectFileSystemModel::updateReferences(bool emitDataChanged)
@@ -220,6 +221,8 @@ Q3DStudio::DocumentEditorFileType::Enum ProjectFileSystemModel::assetTypeForRow(
return Q3DStudio::DocumentEditorFileType::Behavior;
else if (path == QLatin1String("presentations"))
return Q3DStudio::DocumentEditorFileType::Presentation;
+ else if (path == QLatin1String("qml streams"))
+ return Q3DStudio::DocumentEditorFileType::QmlStream;
return Q3DStudio::DocumentEditorFileType::Unknown;
}
@@ -362,6 +365,7 @@ void ProjectFileSystemModel::importUrls(const QList<QUrl> &urls, int row, bool a
const TreeItem &item = m_items.at(row);
QString targetPath = item.index.data(QFileSystemModel::FilePathRole).toString();
+
QFileInfo fi(targetPath);
if (!fi.isDir())
targetPath = fi.absolutePath();
@@ -383,8 +387,8 @@ void ProjectFileSystemModel::importUrls(const QList<QUrl> &urls, int row, bool a
}
if (sortedDir.exists()) {
- expandPaths << sortedPath;
- importUrl(sortedPath, url);
+ importUrl(sortedDir, url);
+ expandPaths << sortedDir.path();
}
}
@@ -395,7 +399,7 @@ void ProjectFileSystemModel::importUrls(const QList<QUrl> &urls, int row, bool a
}
}
-void ProjectFileSystemModel::importUrl(const QDir &targetDir, const QUrl &url) const
+void ProjectFileSystemModel::importUrl(QDir &targetDir, const QUrl &url)
{
using namespace Q3DStudio;
using namespace qt3dsimp;
@@ -444,6 +448,25 @@ void ProjectFileSystemModel::importUrl(const QDir &targetDir, const QUrl &url) c
translator.m_TranslationLog, forceError);
#endif
} else {
+ QQmlApplicationEngine qmlEngine;
+ QObject *qmlRoot = nullptr;
+ if (extension == QLatin1String("qml")) {
+ qmlEngine.load(sourceFile);
+ const char *rootClassName = qmlEngine.rootObjects().at(0)
+ ->metaObject()->superClass()->className();
+
+ // the assumption here is that any qml that is not a behavior is a qml stream
+ if (strcmp(rootClassName, "Q3DStudio::Q3DSQmlBehavior") != 0) { // not a behavior
+ qmlRoot = qmlEngine.rootObjects().at(0);
+
+ // put the qml in the correct folder
+ if (targetDir.path().endsWith(QLatin1String("/scripts"))) {
+ const QString path(QStringLiteral("../qml streams"));
+ targetDir.mkpath(path); // create the folder if doesn't exist (i.e. old project)
+ targetDir.cd(path);
+ }
+ }
+ }
// Copy the file to target directory
// FindAndCopyDestFile will make sure the file name is unique and make sure it is
// not read only.
@@ -455,6 +478,10 @@ void ProjectFileSystemModel::importUrl(const QDir &targetDir, const QUrl &url) c
// add presentation node to the project file
g_StudioApp.GetCore()->getProjectFile().addPresentationNode(destPath);
importPresentationAssets(fileInfo, QFileInfo(destPath));
+ } else if (qmlRoot) { // importing a qml stream
+ g_StudioApp.GetCore()->getProjectFile().addPresentationNode(destPath);
+ m_importQmlOverrideChoice = QMessageBox::NoButton;
+ importQmlAssets(qmlRoot, fileInfo.dir(), targetDir);
}
// For effect and custom material files, automatically copy related resources
@@ -543,6 +570,52 @@ void ProjectFileSystemModel::importPresentationAssets(const QFileInfo &uipSrc,
}
}
+void ProjectFileSystemModel::importQmlAssets(const QObject *qmlNode, const QDir &srcDir,
+ const QDir &targetDir)
+{
+ QString assetSrc = qmlNode->property("source").toString(); // absolute file path
+
+ if (!assetSrc.isEmpty()) {
+ // remove file:///
+ if (assetSrc.startsWith(QLatin1String("file:///")))
+ assetSrc = assetSrc.mid(8);
+ else if (assetSrc.startsWith(QLatin1String("file://")))
+ assetSrc = assetSrc.mid(7);
+
+ if (srcDir.exists(assetSrc)) { // there is an asset to import
+ QString assetTarget = targetDir.absoluteFilePath(srcDir.relativeFilePath(assetSrc));
+
+ QFileInfo fi(assetTarget);
+ if (!fi.dir().exists())
+ fi.dir().mkpath(".");
+
+ if (fi.exists()) { // imported asset exists, show override / skip box
+ if (m_importQmlOverrideChoice == QMessageBox::YesToAll) {
+ QFile::remove(assetTarget);
+ } else if (m_importQmlOverrideChoice == QMessageBox::NoToAll) {
+ // QFile::copy() does not override files
+ } else {
+ // get path relative to project root (for neat displaying)
+ QString pathFromRoot = QDir(g_StudioApp.GetCore()->getProjectFile()
+ .getProjectPath()).relativeFilePath(assetTarget);
+
+ m_importQmlOverrideChoice = g_StudioApp.GetDialogs()
+ ->displayOverrideAssetBox(pathFromRoot);
+ if (m_importQmlOverrideChoice & (QMessageBox::Yes | QMessageBox::YesToAll))
+ QFile::remove(assetTarget);
+ }
+ }
+
+ QFile::copy(assetSrc, assetTarget);
+ }
+ }
+
+ // recursively load child nodes
+ const QObjectList qmlNodeChildren = qmlNode->children();
+ for (int i = 0; i < qmlNodeChildren.count(); ++i)
+ importQmlAssets(qmlNodeChildren.at(i), srcDir, targetDir);
+}
+
int ProjectFileSystemModel::rowForPath(const QString &path) const
{
for (int i = m_items.size() - 1; i >= 0 ; --i) {
@@ -782,6 +855,7 @@ void ProjectFileSystemModel::updateDefaultDirMap()
m_defaultDirToAbsPathMap.insert(QStringLiteral("models"), QString());
m_defaultDirToAbsPathMap.insert(QStringLiteral("scripts"), QString());
m_defaultDirToAbsPathMap.insert(QStringLiteral("presentations"), QString());
+ m_defaultDirToAbsPathMap.insert(QStringLiteral("qml streams"), QString());
}
const QString rootPath = m_items[0].index.data(QFileSystemModel::FilePathRole).toString();
diff --git a/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.h b/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.h
index 60bc1f40..75f9e985 100644
--- a/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.h
+++ b/src/Authoring/Studio/Palettes/Project/ProjectFileSystemModel.h
@@ -88,7 +88,7 @@ private:
EStudioObjectType getIconType(const QString &path) const;
bool isVisible(const QModelIndex& modelIndex) const;
bool hasVisibleChildren(const QModelIndex &modelIndex) const;
- void importUrl(const QDir &targetDir, const QUrl &url) const;
+ void importUrl(QDir &targetDir, const QUrl &url);
void importPresentationAssets(const QFileInfo &uipSrc, const QFileInfo &uipTarget,
const int overrideChoice = QMessageBox::NoButton) const;
@@ -96,6 +96,7 @@ private:
void modelRowsRemoved(const QModelIndex &parent, int start, int end);
void modelRowsMoved(const QModelIndex &parent, int start, int end);
void modelLayoutChanged();
+ void importQmlAssets(const QObject *qmlNode, const QDir &srcDir, const QDir &targetDir);
void updateDefaultDirMap();
@@ -112,6 +113,7 @@ private:
QList<TreeItem> m_items;
QStringList m_references;
QHash<QString, QString> m_defaultDirToAbsPathMap;
+ int m_importQmlOverrideChoice = QMessageBox::NoButton;
};
#endif // TREEVIEWADAPTOR_H
diff --git a/src/Authoring/Studio/Palettes/Project/ProjectView.cpp b/src/Authoring/Studio/Palettes/Project/ProjectView.cpp
index 670aab30..f97c7c1a 100644
--- a/src/Authoring/Studio/Palettes/Project/ProjectView.cpp
+++ b/src/Authoring/Studio/Palettes/Project/ProjectView.cpp
@@ -65,6 +65,7 @@ ProjectView::ProjectView(const QSize &preferredSize, QWidget *parent) : QQuickWi
m_defaultMaterialDir = theApplicationPath + QStringLiteral("/Content/Material Library");
m_defaultModelDir = theApplicationPath + QStringLiteral("/Content/Models Library");
m_defaultPresentationDir = theApplicationPath + QStringLiteral("/Content/Presentations");
+ m_defaultQmlStreamDir = theApplicationPath + QStringLiteral("/Content/Qml Streams");
m_BehaviorDir = m_defaultBehaviorDir;
m_EffectDir = m_defaultEffectDir;
@@ -73,6 +74,7 @@ ProjectView::ProjectView(const QSize &preferredSize, QWidget *parent) : QQuickWi
m_MaterialDir = m_defaultMaterialDir;
m_ModelDir = m_defaultModelDir;
m_presentationDir = m_defaultPresentationDir;
+ m_qmlStreamDir = m_defaultQmlStreamDir;
m_assetImportDir = theApplicationPath + QStringLiteral("/Content");
diff --git a/src/Authoring/Studio/Palettes/Project/ProjectView.h b/src/Authoring/Studio/Palettes/Project/ProjectView.h
index 3c24c57f..eedd562e 100644
--- a/src/Authoring/Studio/Palettes/Project/ProjectView.h
+++ b/src/Authoring/Studio/Palettes/Project/ProjectView.h
@@ -112,6 +112,7 @@ private:
QString m_defaultMaterialDir;
QString m_defaultModelDir;
QString m_defaultPresentationDir;
+ QString m_defaultQmlStreamDir;
QString m_BehaviorDir;
QString m_EffectDir;
QString m_FontDir;
@@ -119,6 +120,7 @@ private:
QString m_MaterialDir;
QString m_ModelDir;
QString m_presentationDir;
+ QString m_qmlStreamDir;
QString m_assetImportDir;
QSize m_preferredSize;
};