diff options
author | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2021-02-23 13:02:31 +0200 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2021-02-25 09:39:13 +0000 |
commit | 69087a2c4bba58e473c79b4d90c41c6af3c68f43 (patch) | |
tree | 24747437d7f21a5f63c4c2c34ecc144df50ed8cf /src/plugins/qmldesigner/components/itemlibrary/itemlibraryassetimportdialog.cpp | |
parent | f51387fb8eac774c08597bd200d704802f578104 (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.cpp | 180 |
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); } } |