aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
diff options
context:
space:
mode:
authorMiikka Heikkinen <miikka.heikkinen@qt.io>2021-02-23 13:02:31 +0200
committerMiikka Heikkinen <miikka.heikkinen@qt.io>2021-02-25 09:39:13 +0000
commit69087a2c4bba58e473c79b4d90c41c6af3c68f43 (patch)
tree24747437d7f21a5f63c4c2c34ecc144df50ed8cf /src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
parentf51387fb8eac774c08597bd200d704802f578104 (diff)
QmlDesigner: Update selected imported node
Add context menu item for updating selected 3D node. If selected node is a component created by import, that import is updated. Otherwise if the open document itself is an imported component, update that import. In the latter case, preselect the source file relevant for the selected node. Fixes: QDS-3738 Change-Id: Id678288893f1700648d084ba92df40844d2af0b5 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
Diffstat (limited to 'src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp')
-rw-r--r--src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp180
1 files changed, 159 insertions, 21 deletions
diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
index 0b0c7fef10..1192fb0fef 100644
--- a/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
+++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp
@@ -28,26 +28,33 @@
#include "qmldesignerplugin.h"
#include "qmldesignerconstants.h"
#include "model.h"
+#include "nodemetainfo.h"
+#include "variantproperty.h"
#include "utils/outputformatter.h"
#include "theme.h"
#include <projectexplorer/project.h>
#include <projectexplorer/session.h>
-
-#include <QtCore/qfileinfo.h>
-#include <QtCore/qdir.h>
-#include <QtCore/qloggingcategory.h>
-#include <QtCore/qtimer.h>
-#include <QtCore/qjsonarray.h>
-#include <QtWidgets/qpushbutton.h>
-#include <QtWidgets/qgridlayout.h>
-#include <QtWidgets/qlabel.h>
-#include <QtWidgets/qcheckbox.h>
-#include <QtWidgets/qspinbox.h>
-#include <QtWidgets/qscrollbar.h>
-#include <QtWidgets/qtabbar.h>
-#include <QtWidgets/qscrollarea.h>
+#include <coreplugin/icore.h>
+
+#include <QFileInfo>
+#include <QDir>
+#include <QLoggingCategory>
+#include <QTimer>
+#include <QJsonArray>
+#include <QJsonDocument>
+#include <QJsonParseError>
+#include <QPushButton>
+#include <QGridLayout>
+#include <QLabel>
+#include <QCheckBox>
+#include <QSpinBox>
+#include <QScrollBar>
+#include <QTabBar>
+#include <QScrollArea>
+#include <QMessageBox>
+#include <QFileDialog>
namespace QmlDesigner {
@@ -70,14 +77,15 @@ static const int rowHeight = 26;
}
-ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &importFiles,
- const QString &defaulTargetDirectory,
- const QVariantMap &supportedExts,
- const QVariantMap &supportedOpts,
- QWidget *parent) :
- QDialog(parent)
+ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(
+ const QStringList &importFiles, const QString &defaulTargetDirectory,
+ const QVariantMap &supportedExts, const QVariantMap &supportedOpts,
+ const QJsonObject &defaultOpts, const QSet<QString> &preselectedFilesForOverwrite,
+ QWidget *parent)
+ : QDialog(parent)
, ui(new Ui::ItemLibraryAssetImportDialog)
, m_importer(this)
+ , m_preselectedFilesForOverwrite(preselectedFilesForOverwrite)
{
setModal(true);
ui->setupUi(this);
@@ -172,6 +180,16 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
while (optIt != supportedOpts.constEnd()) {
QJsonObject options = QJsonObject::fromVariantMap(qvariant_cast<QVariantMap>(optIt.value()));
m_importOptions << options.value("options").toObject();
+ auto it = defaultOpts.constBegin();
+ while (it != defaultOpts.constEnd()) {
+ if (m_importOptions.last().contains(it.key())) {
+ QJsonObject optObj = m_importOptions.last()[it.key()].toObject();
+ QJsonValue value(it.value()["value"]);
+ optObj.insert("value", value);
+ m_importOptions.last().insert(it.key(), optObj);
+ }
+ ++it;
+ }
groups << options.value("groups").toObject();
const auto &exts = optIt.key().split(':');
for (const auto &ext : exts)
@@ -252,6 +270,125 @@ ItemLibraryAssetImportDialog::~ItemLibraryAssetImportDialog()
delete ui;
}
+void ItemLibraryAssetImportDialog::updateImport(const ModelNode &updateNode,
+ const QVariantMap &supportedExts,
+ const QVariantMap &supportedOpts)
+{
+ QString errorMsg;
+ const ModelNode &node = updateNode;
+ if (node.isValid() && node.hasMetaInfo()) {
+ QString compFileName = node.metaInfo().componentFileName(); // absolute path
+ bool preselectNodeSource = false;
+ if (compFileName.isEmpty()) {
+ // Node is not a file component, so we have to check if the current doc itself is
+ compFileName = node.model()->fileUrl().toLocalFile();
+ preselectNodeSource = true;
+ }
+ QFileInfo compFileInfo{compFileName};
+
+ // Find to top asset folder
+ const QString assetFolder = QLatin1String(Constants::QUICK_3D_ASSETS_FOLDER).mid(1);
+ const QStringList parts = compFileName.split('/');
+ int i = parts.size() - 1;
+ int previousSize = 0;
+ for (; i >= 0; --i) {
+ if (parts[i] == assetFolder)
+ break;
+ previousSize = parts[i].size();
+ }
+ if (i >= 0) {
+ const QString assetPath = compFileName.left(compFileName.lastIndexOf(assetFolder)
+ + assetFolder.size() + previousSize + 1);
+ const QDir assetDir(assetPath);
+
+ // Find import options and the original source scene
+ const QString jsonFileName = assetDir.absoluteFilePath(
+ Constants::QUICK_3D_ASSET_IMPORT_DATA_NAME);
+ QFile jsonFile{jsonFileName};
+ if (jsonFile.open(QIODevice::ReadOnly)) {
+ QJsonParseError jsonError;
+ const QByteArray fileData = jsonFile.readAll();
+ auto jsonDocument = QJsonDocument::fromJson(fileData, &jsonError);
+ jsonFile.close();
+ if (jsonError.error == QJsonParseError::NoError) {
+ QJsonObject jsonObj = jsonDocument.object();
+ const QJsonObject options = jsonObj.value(
+ Constants::QUICK_3D_ASSET_IMPORT_DATA_OPTIONS_KEY).toObject();
+ QString sourcePath = jsonObj.value(
+ Constants::QUICK_3D_ASSET_IMPORT_DATA_SOURCE_KEY).toString();
+ if (options.isEmpty() || sourcePath.isEmpty()) {
+ errorMsg = QCoreApplication::translate(
+ "ModelNodeOperations",
+ "Asset import data file '%1' is invalid.").arg(jsonFileName);
+ } else {
+ QFileInfo sourceInfo{sourcePath};
+ if (!sourceInfo.exists()) {
+ // Unable to find original scene source, launch file dialog to locate it
+ QString initialPath;
+ ProjectExplorer::Project *currentProject
+ = ProjectExplorer::SessionManager::projectForFile(
+ Utils::FilePath::fromString(compFileName));
+ if (currentProject)
+ initialPath = currentProject->projectDirectory().toString();
+ else
+ initialPath = compFileInfo.absolutePath();
+ QStringList selectedFiles = QFileDialog::getOpenFileNames(
+ Core::ICore::dialogParent(),
+ tr("Locate 3D Asset '%1'").arg(sourceInfo.fileName()),
+ initialPath, sourceInfo.fileName());
+ if (!selectedFiles.isEmpty()
+ && QFileInfo{selectedFiles[0]}.fileName() == sourceInfo.fileName()) {
+ sourcePath = selectedFiles[0];
+ sourceInfo.setFile(sourcePath);
+ }
+ }
+ if (sourceInfo.exists()) {
+ // In case of a selected node inside an imported component, preselect
+ // any file pointed to by a "source" property of the node.
+ QSet<QString> preselectedFiles;
+ if (preselectNodeSource && updateNode.hasProperty("source")) {
+ QString source = updateNode.variantProperty("source").value().toString();
+ if (QFileInfo{source}.isRelative())
+ source = QDir{compFileInfo.absolutePath()}.absoluteFilePath(source);
+ preselectedFiles.insert(source);
+ }
+ auto importDlg = new ItemLibraryAssetImportDialog(
+ {sourceInfo.absoluteFilePath()},
+ node.model()->fileUrl().toLocalFile(),
+ supportedExts, supportedOpts, options,
+ preselectedFiles, Core::ICore::mainWindow());
+ importDlg->show();
+
+ } else {
+ errorMsg = QCoreApplication::translate(
+ "ModelNodeOperations", "Unable to locate source scene '%1'.")
+ .arg(sourceInfo.fileName());
+ }
+ }
+ } else {
+ errorMsg = jsonError.errorString();
+ }
+ } else {
+ errorMsg = QCoreApplication::translate("ModelNodeOperations",
+ "Opening asset import data file '%1' failed.")
+ .arg(jsonFileName);
+ }
+ } else {
+ errorMsg = QCoreApplication::translate("ModelNodeOperations",
+ "Unable to resolve asset import path.");
+ }
+ }
+
+ if (!errorMsg.isEmpty()) {
+ QMessageBox::warning(
+ qobject_cast<QWidget *>(Core::ICore::dialogParent()),
+ QCoreApplication::translate("ModelNodeOperations", "Import Update Failed"),
+ QCoreApplication::translate("ModelNodeOperations",
+ "Failed to update import.\nError:\n%1").arg(errorMsg),
+ QMessageBox::Close);
+ }
+}
+
void ItemLibraryAssetImportDialog::createTab(const QString &tabLabel, int optionsIndex,
const QJsonObject &groups)
{
@@ -610,7 +747,8 @@ void ItemLibraryAssetImportDialog::onImport()
if (!m_quick3DFiles.isEmpty()) {
m_importer.importQuick3D(m_quick3DFiles, m_quick3DImportPath,
- m_importOptions, m_extToImportOptionsMap);
+ m_importOptions, m_extToImportOptionsMap,
+ m_preselectedFilesForOverwrite);
}
}