forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -90,6 +90,7 @@ const char fitSelectionToScreenCommandId[] = "FitSelectionToScreen";
|
|||||||
const char editAnnotationCommandId[] = "EditAnnotation";
|
const char editAnnotationCommandId[] = "EditAnnotation";
|
||||||
|
|
||||||
const char openSignalDialogCommandId[] = "OpenSignalDialog";
|
const char openSignalDialogCommandId[] = "OpenSignalDialog";
|
||||||
|
const char update3DAssetCommandId[] = "Update3DAsset";
|
||||||
|
|
||||||
const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection");
|
const char selectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Selection");
|
||||||
const char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect");
|
const char flowConnectionCategoryDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Connect");
|
||||||
@@ -131,6 +132,7 @@ const char moveToComponentDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextM
|
|||||||
const char editAnnotationDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit Annotation");
|
const char editAnnotationDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Edit Annotation");
|
||||||
|
|
||||||
const char openSignalDialogDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Open Signal Dialog");
|
const char openSignalDialogDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Open Signal Dialog");
|
||||||
|
const char update3DAssetDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Update 3D Asset");
|
||||||
|
|
||||||
const char setIdDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set Id");
|
const char setIdDisplayName[] = QT_TRANSLATE_NOOP("QmlDesignerContextMenu", "Set Id");
|
||||||
|
|
||||||
|
|||||||
@@ -1412,6 +1412,17 @@ void DesignerActionManager::createDefaultDesignerActions()
|
|||||||
66,
|
66,
|
||||||
&openSignalDialog,
|
&openSignalDialog,
|
||||||
&singleSelectionAndHasSlotTrigger));
|
&singleSelectionAndHasSlotTrigger));
|
||||||
|
|
||||||
|
addDesignerAction(new ModelNodeContextMenuAction(
|
||||||
|
update3DAssetCommandId,
|
||||||
|
update3DAssetDisplayName,
|
||||||
|
{},
|
||||||
|
rootCategory,
|
||||||
|
QKeySequence(),
|
||||||
|
priorityGenericToolBar,
|
||||||
|
&updateImported3DAsset,
|
||||||
|
&selectionIsImported3DAsset,
|
||||||
|
&selectionIsImported3DAsset));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DesignerActionManager::createDefaultAddResourceHandler()
|
void DesignerActionManager::createDefaultAddResourceHandler()
|
||||||
|
|||||||
@@ -31,6 +31,7 @@
|
|||||||
#include <bindingproperty.h>
|
#include <bindingproperty.h>
|
||||||
#include <nodeproperty.h>
|
#include <nodeproperty.h>
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
|
#include <qmldesignerconstants.h>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -99,6 +100,21 @@ bool selectionIsComponent(const SelectionContext &selectionState)
|
|||||||
&& selectionState.currentSingleSelectedNode().isComponent();
|
&& selectionState.currentSingleSelectedNode().isComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool selectionIsImported3DAsset(const SelectionContext &selectionState)
|
||||||
|
{
|
||||||
|
ModelNode node = selectionState.currentSingleSelectedNode();
|
||||||
|
if (selectionState.view() && node.isValid() && node.hasMetaInfo()) {
|
||||||
|
QString fileName = node.metaInfo().componentFileName(); // absolute path
|
||||||
|
if (fileName.isEmpty()) {
|
||||||
|
// Node is not a file component, so we have to check if the current doc itself is
|
||||||
|
fileName = node.model()->fileUrl().toLocalFile();
|
||||||
|
}
|
||||||
|
if (fileName.contains(Constants::QUICK_3D_ASSETS_FOLDER))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
} //SelectionStateFunctors
|
} //SelectionStateFunctors
|
||||||
|
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ bool selectionHasSameParent(const SelectionContext &selectionState);
|
|||||||
bool selectionIsComponent(const SelectionContext &selectionState);
|
bool selectionIsComponent(const SelectionContext &selectionState);
|
||||||
bool singleSelectionItemIsAnchored(const SelectionContext &selectionState);
|
bool singleSelectionItemIsAnchored(const SelectionContext &selectionState);
|
||||||
bool singleSelectionItemIsNotAnchored(const SelectionContext &selectionState);
|
bool singleSelectionItemIsNotAnchored(const SelectionContext &selectionState);
|
||||||
|
bool selectionIsImported3DAsset(const SelectionContext &selectionState);
|
||||||
|
|
||||||
} // namespace SelectionStateFunctors
|
} // namespace SelectionStateFunctors
|
||||||
|
|
||||||
|
|||||||
@@ -1581,6 +1581,15 @@ void openSignalDialog(const SelectionContext &selectionContext)
|
|||||||
SignalList::showWidget(selectionContext.currentSingleSelectedNode());
|
SignalList::showWidget(selectionContext.currentSingleSelectedNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateImported3DAsset(const SelectionContext &selectionContext)
|
||||||
|
{
|
||||||
|
if (selectionContext.view()) {
|
||||||
|
selectionContext.view()->emitCustomNotification(
|
||||||
|
"UpdateImported3DAsset", {selectionContext.currentSingleSelectedNode()});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ModelNodeOperations
|
} // namespace ModelNodeOperations
|
||||||
|
|
||||||
} //QmlDesigner
|
} //QmlDesigner
|
||||||
|
|||||||
@@ -89,6 +89,7 @@ void removeGroup(const SelectionContext &selectionContext);
|
|||||||
void editAnnotation(const SelectionContext &selectionContext);
|
void editAnnotation(const SelectionContext &selectionContext);
|
||||||
|
|
||||||
void openSignalDialog(const SelectionContext &selectionContext);
|
void openSignalDialog(const SelectionContext &selectionContext);
|
||||||
|
void updateImported3DAsset(const SelectionContext &selectionContext);
|
||||||
|
|
||||||
// ModelNodePreviewImageOperations
|
// ModelNodePreviewImageOperations
|
||||||
QVariant previewImageDataForGenericNode(const ModelNode &modelNode);
|
QVariant previewImageDataForGenericNode(const ModelNode &modelNode);
|
||||||
|
|||||||
@@ -28,26 +28,33 @@
|
|||||||
#include "qmldesignerplugin.h"
|
#include "qmldesignerplugin.h"
|
||||||
#include "qmldesignerconstants.h"
|
#include "qmldesignerconstants.h"
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
#include "nodemetainfo.h"
|
||||||
|
#include "variantproperty.h"
|
||||||
|
|
||||||
#include "utils/outputformatter.h"
|
#include "utils/outputformatter.h"
|
||||||
#include "theme.h"
|
#include "theme.h"
|
||||||
|
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/session.h>
|
#include <projectexplorer/session.h>
|
||||||
|
#include <coreplugin/icore.h>
|
||||||
|
|
||||||
#include <QtCore/qfileinfo.h>
|
#include <QFileInfo>
|
||||||
#include <QtCore/qdir.h>
|
#include <QDir>
|
||||||
#include <QtCore/qloggingcategory.h>
|
#include <QLoggingCategory>
|
||||||
#include <QtCore/qtimer.h>
|
#include <QTimer>
|
||||||
#include <QtCore/qjsonarray.h>
|
#include <QJsonArray>
|
||||||
#include <QtWidgets/qpushbutton.h>
|
#include <QJsonDocument>
|
||||||
#include <QtWidgets/qgridlayout.h>
|
#include <QJsonParseError>
|
||||||
#include <QtWidgets/qlabel.h>
|
#include <QPushButton>
|
||||||
#include <QtWidgets/qcheckbox.h>
|
#include <QGridLayout>
|
||||||
#include <QtWidgets/qspinbox.h>
|
#include <QLabel>
|
||||||
#include <QtWidgets/qscrollbar.h>
|
#include <QCheckBox>
|
||||||
#include <QtWidgets/qtabbar.h>
|
#include <QSpinBox>
|
||||||
#include <QtWidgets/qscrollarea.h>
|
#include <QScrollBar>
|
||||||
|
#include <QTabBar>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QFileDialog>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -70,14 +77,15 @@ static const int rowHeight = 26;
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &importFiles,
|
ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(
|
||||||
const QString &defaulTargetDirectory,
|
const QStringList &importFiles, const QString &defaulTargetDirectory,
|
||||||
const QVariantMap &supportedExts,
|
const QVariantMap &supportedExts, const QVariantMap &supportedOpts,
|
||||||
const QVariantMap &supportedOpts,
|
const QJsonObject &defaultOpts, const QSet<QString> &preselectedFilesForOverwrite,
|
||||||
QWidget *parent) :
|
QWidget *parent)
|
||||||
QDialog(parent)
|
: QDialog(parent)
|
||||||
, ui(new Ui::ItemLibraryAssetImportDialog)
|
, ui(new Ui::ItemLibraryAssetImportDialog)
|
||||||
, m_importer(this)
|
, m_importer(this)
|
||||||
|
, m_preselectedFilesForOverwrite(preselectedFilesForOverwrite)
|
||||||
{
|
{
|
||||||
setModal(true);
|
setModal(true);
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
@@ -172,6 +180,16 @@ ItemLibraryAssetImportDialog::ItemLibraryAssetImportDialog(const QStringList &im
|
|||||||
while (optIt != supportedOpts.constEnd()) {
|
while (optIt != supportedOpts.constEnd()) {
|
||||||
QJsonObject options = QJsonObject::fromVariantMap(qvariant_cast<QVariantMap>(optIt.value()));
|
QJsonObject options = QJsonObject::fromVariantMap(qvariant_cast<QVariantMap>(optIt.value()));
|
||||||
m_importOptions << options.value("options").toObject();
|
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();
|
groups << options.value("groups").toObject();
|
||||||
const auto &exts = optIt.key().split(':');
|
const auto &exts = optIt.key().split(':');
|
||||||
for (const auto &ext : exts)
|
for (const auto &ext : exts)
|
||||||
@@ -252,6 +270,125 @@ ItemLibraryAssetImportDialog::~ItemLibraryAssetImportDialog()
|
|||||||
delete ui;
|
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,
|
void ItemLibraryAssetImportDialog::createTab(const QString &tabLabel, int optionsIndex,
|
||||||
const QJsonObject &groups)
|
const QJsonObject &groups)
|
||||||
{
|
{
|
||||||
@@ -610,7 +747,8 @@ void ItemLibraryAssetImportDialog::onImport()
|
|||||||
|
|
||||||
if (!m_quick3DFiles.isEmpty()) {
|
if (!m_quick3DFiles.isEmpty()) {
|
||||||
m_importer.importQuick3D(m_quick3DFiles, m_quick3DImportPath,
|
m_importer.importQuick3D(m_quick3DFiles, m_quick3DImportPath,
|
||||||
m_importOptions, m_extToImportOptionsMap);
|
m_importOptions, m_extToImportOptionsMap,
|
||||||
|
m_preselectedFilesForOverwrite);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,9 +25,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "itemlibraryassetimporter.h"
|
#include "itemlibraryassetimporter.h"
|
||||||
|
#include "modelnode.h"
|
||||||
|
|
||||||
#include <QtWidgets/qdialog.h>
|
#include <QDialog>
|
||||||
#include <QtCore/qjsonobject.h>
|
#include <QJsonObject>
|
||||||
|
#include <QSet>
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
class OutputFormatter;
|
class OutputFormatter;
|
||||||
@@ -49,9 +51,15 @@ public:
|
|||||||
const QString &defaulTargetDirectory,
|
const QString &defaulTargetDirectory,
|
||||||
const QVariantMap &supportedExts,
|
const QVariantMap &supportedExts,
|
||||||
const QVariantMap &supportedOpts,
|
const QVariantMap &supportedOpts,
|
||||||
|
const QJsonObject &defaultOpts,
|
||||||
|
const QSet<QString> &preselectedFilesForOverwrite,
|
||||||
QWidget *parent = nullptr);
|
QWidget *parent = nullptr);
|
||||||
~ItemLibraryAssetImportDialog();
|
~ItemLibraryAssetImportDialog();
|
||||||
|
|
||||||
|
static void updateImport(const ModelNode &updateNode,
|
||||||
|
const QVariantMap &supportedExts,
|
||||||
|
const QVariantMap &supportedOpts);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void resizeEvent(QResizeEvent *event) override;
|
void resizeEvent(QResizeEvent *event) override;
|
||||||
|
|
||||||
@@ -82,5 +90,6 @@ private:
|
|||||||
QHash<QString, int> m_extToImportOptionsMap;
|
QHash<QString, int> m_extToImportOptionsMap;
|
||||||
int m_optionsHeight = 0;
|
int m_optionsHeight = 0;
|
||||||
int m_optionsRows = 0;
|
int m_optionsRows = 0;
|
||||||
|
QSet<QString> m_preselectedFilesForOverwrite;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QJsonDocument>
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@@ -64,7 +65,8 @@ ItemLibraryAssetImporter::~ItemLibraryAssetImporter() {
|
|||||||
void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles,
|
void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles,
|
||||||
const QString &importPath,
|
const QString &importPath,
|
||||||
const QVector<QJsonObject> &options,
|
const QVector<QJsonObject> &options,
|
||||||
const QHash<QString, int> &extToImportOptionsMap)
|
const QHash<QString, int> &extToImportOptionsMap,
|
||||||
|
const QSet<QString> &preselectedFilesForOverwrite)
|
||||||
{
|
{
|
||||||
if (m_isImporting)
|
if (m_isImporting)
|
||||||
cancelImport();
|
cancelImport();
|
||||||
@@ -79,7 +81,7 @@ void ItemLibraryAssetImporter::importQuick3D(const QStringList &inputFiles,
|
|||||||
|
|
||||||
m_importPath = importPath;
|
m_importPath = importPath;
|
||||||
|
|
||||||
parseFiles(inputFiles, options, extToImportOptionsMap);
|
parseFiles(inputFiles, options, extToImportOptionsMap, preselectedFilesForOverwrite);
|
||||||
|
|
||||||
if (!isCancelled()) {
|
if (!isCancelled()) {
|
||||||
const auto parseData = m_parseData;
|
const auto parseData = m_parseData;
|
||||||
@@ -203,7 +205,8 @@ void ItemLibraryAssetImporter::reset()
|
|||||||
|
|
||||||
void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths,
|
void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths,
|
||||||
const QVector<QJsonObject> &options,
|
const QVector<QJsonObject> &options,
|
||||||
const QHash<QString, int> &extToImportOptionsMap)
|
const QHash<QString, int> &extToImportOptionsMap,
|
||||||
|
const QSet<QString> &preselectedFilesForOverwrite)
|
||||||
{
|
{
|
||||||
if (isCancelled())
|
if (isCancelled())
|
||||||
return;
|
return;
|
||||||
@@ -219,7 +222,7 @@ void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths,
|
|||||||
int index = extToImportOptionsMap.value(QFileInfo(file).suffix());
|
int index = extToImportOptionsMap.value(QFileInfo(file).suffix());
|
||||||
ParseData pd;
|
ParseData pd;
|
||||||
pd.options = options[index];
|
pd.options = options[index];
|
||||||
if (preParseQuick3DAsset(file, pd)) {
|
if (preParseQuick3DAsset(file, pd, preselectedFilesForOverwrite)) {
|
||||||
pd.importId = ++m_importIdCounter;
|
pd.importId = ++m_importIdCounter;
|
||||||
m_parseData.insert(pd.importId, pd);
|
m_parseData.insert(pd.importId, pd);
|
||||||
}
|
}
|
||||||
@@ -227,7 +230,8 @@ void ItemLibraryAssetImporter::parseFiles(const QStringList &filePaths,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseData &pd)
|
bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseData &pd,
|
||||||
|
const QSet<QString> &preselectedFilesForOverwrite)
|
||||||
{
|
{
|
||||||
pd.targetDir = QDir(m_importPath);
|
pd.targetDir = QDir(m_importPath);
|
||||||
pd.outDir = QDir(m_tempDir->path());
|
pd.outDir = QDir(m_tempDir->path());
|
||||||
@@ -264,7 +268,9 @@ bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseDa
|
|||||||
pd.assetName = assetDirs[0];
|
pd.assetName = assetDirs[0];
|
||||||
pd.targetDirPath = pd.targetDir.filePath(pd.assetName);
|
pd.targetDirPath = pd.targetDir.filePath(pd.assetName);
|
||||||
}
|
}
|
||||||
OverwriteResult result = confirmAssetOverwrite(pd.assetName);
|
OverwriteResult result = preselectedFilesForOverwrite.isEmpty()
|
||||||
|
? confirmAssetOverwrite(pd.assetName)
|
||||||
|
: OverwriteResult::Update;
|
||||||
if (result == OverwriteResult::Skip) {
|
if (result == OverwriteResult::Skip) {
|
||||||
addWarning(tr("Skipped import of existing asset: \"%1\"").arg(pd.assetName));
|
addWarning(tr("Skipped import of existing asset: \"%1\"").arg(pd.assetName));
|
||||||
return false;
|
return false;
|
||||||
@@ -282,8 +288,11 @@ bool ItemLibraryAssetImporter::preParseQuick3DAsset(const QString &file, ParseDa
|
|||||||
alwaysOverwrite.insert(iconIt.fileInfo().absoluteFilePath());
|
alwaysOverwrite.insert(iconIt.fileInfo().absoluteFilePath());
|
||||||
}
|
}
|
||||||
alwaysOverwrite.insert(sourceSceneTargetFilePath(pd));
|
alwaysOverwrite.insert(sourceSceneTargetFilePath(pd));
|
||||||
|
alwaysOverwrite.insert(pd.targetDirPath + '/' + Constants::QUICK_3D_ASSET_IMPORT_DATA_NAME);
|
||||||
|
|
||||||
Internal::AssetImportUpdateDialog dlg {pd.targetDirPath, {}, alwaysOverwrite,
|
Internal::AssetImportUpdateDialog dlg {pd.targetDirPath,
|
||||||
|
preselectedFilesForOverwrite,
|
||||||
|
alwaysOverwrite,
|
||||||
qobject_cast<QWidget *>(parent())};
|
qobject_cast<QWidget *>(parent())};
|
||||||
int exitVal = dlg.exec();
|
int exitVal = dlg.exec();
|
||||||
|
|
||||||
@@ -421,6 +430,18 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(const ParseData &pd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Generate import metadata file
|
||||||
|
const QString sourcePath = pd.sourceInfo.absoluteFilePath();
|
||||||
|
QString importDataFileName = outDir.absoluteFilePath(Constants::QUICK_3D_ASSET_IMPORT_DATA_NAME);
|
||||||
|
QSaveFile importDataFile(importDataFileName);
|
||||||
|
if (importDataFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||||
|
QJsonObject optObj;
|
||||||
|
optObj.insert(Constants::QUICK_3D_ASSET_IMPORT_DATA_OPTIONS_KEY, pd.options);
|
||||||
|
optObj.insert(Constants::QUICK_3D_ASSET_IMPORT_DATA_SOURCE_KEY, sourcePath);
|
||||||
|
importDataFile.write(QJsonDocument{optObj}.toJson());
|
||||||
|
importDataFile.commit();
|
||||||
|
}
|
||||||
|
|
||||||
// Gather all generated files
|
// Gather all generated files
|
||||||
QDirIterator dirIt(outDir.path(), QDir::Files, QDirIterator::Subdirectories);
|
QDirIterator dirIt(outDir.path(), QDir::Files, QDirIterator::Subdirectories);
|
||||||
while (dirIt.hasNext()) {
|
while (dirIt.hasNext()) {
|
||||||
@@ -429,7 +450,7 @@ void ItemLibraryAssetImporter::postParseQuick3DAsset(const ParseData &pd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copy the original asset into a subdirectory
|
// Copy the original asset into a subdirectory
|
||||||
assetFiles.insert(pd.sourceInfo.absoluteFilePath(), sourceSceneTargetFilePath(pd));
|
assetFiles.insert(sourcePath, sourceSceneTargetFilePath(pd));
|
||||||
m_importFiles.insert(assetFiles);
|
m_importFiles.insert(assetFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ public:
|
|||||||
|
|
||||||
void importQuick3D(const QStringList &inputFiles, const QString &importPath,
|
void importQuick3D(const QStringList &inputFiles, const QString &importPath,
|
||||||
const QVector<QJsonObject> &options,
|
const QVector<QJsonObject> &options,
|
||||||
const QHash<QString, int> &extToImportOptionsMap);
|
const QHash<QString, int> &extToImportOptionsMap,
|
||||||
|
const QSet<QString> &preselectedFilesForOverwrite);
|
||||||
|
|
||||||
bool isImporting() const;
|
bool isImporting() const;
|
||||||
void cancelImport();
|
void cancelImport();
|
||||||
@@ -91,8 +92,10 @@ private:
|
|||||||
void notifyFinished();
|
void notifyFinished();
|
||||||
void reset();
|
void reset();
|
||||||
void parseFiles(const QStringList &filePaths, const QVector<QJsonObject> &options,
|
void parseFiles(const QStringList &filePaths, const QVector<QJsonObject> &options,
|
||||||
const QHash<QString, int> &extToImportOptionsMap);
|
const QHash<QString, int> &extToImportOptionsMap,
|
||||||
bool preParseQuick3DAsset(const QString &file, ParseData &pd);
|
const QSet<QString> &preselectedFilesForOverwrite);
|
||||||
|
bool preParseQuick3DAsset(const QString &file, ParseData &pd,
|
||||||
|
const QSet<QString> &preselectedFilesForOverwrite);
|
||||||
void postParseQuick3DAsset(const ParseData &pd);
|
void postParseQuick3DAsset(const ParseData &pd);
|
||||||
void copyImportedFiles();
|
void copyImportedFiles();
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
#include <utils/algorithm.h>
|
#include <utils/algorithm.h>
|
||||||
#include <qmldesignerplugin.h>
|
#include <qmldesignerplugin.h>
|
||||||
#include <qmlitemnode.h>
|
#include <qmlitemnode.h>
|
||||||
|
#include <qmldesignerconstants.h>
|
||||||
|
|
||||||
namespace QmlDesigner {
|
namespace QmlDesigner {
|
||||||
|
|
||||||
@@ -240,7 +241,7 @@ void ItemLibraryView::updateImport3DSupport(const QVariantMap &supportMap)
|
|||||||
auto handle3DModel = [this](const QStringList &fileNames, const QString &defaultDir) -> bool {
|
auto handle3DModel = [this](const QStringList &fileNames, const QString &defaultDir) -> bool {
|
||||||
auto importDlg = new ItemLibraryAssetImportDialog(fileNames, defaultDir,
|
auto importDlg = new ItemLibraryAssetImportDialog(fileNames, defaultDir,
|
||||||
m_importableExtensions3DMap,
|
m_importableExtensions3DMap,
|
||||||
m_importOptions3DMap,
|
m_importOptions3DMap, {}, {},
|
||||||
Core::ICore::mainWindow());
|
Core::ICore::mainWindow());
|
||||||
importDlg->show();
|
importDlg->show();
|
||||||
return true;
|
return true;
|
||||||
@@ -263,4 +264,15 @@ void ItemLibraryView::updateImport3DSupport(const QVariantMap &supportMap)
|
|||||||
m_importOptions3DMap = qvariant_cast<QVariantMap>(supportMap.value("options"));
|
m_importOptions3DMap = qvariant_cast<QVariantMap>(supportMap.value("options"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemLibraryView::customNotification(const AbstractView *view, const QString &identifier,
|
||||||
|
const QList<ModelNode> &nodeList, const QList<QVariant> &data)
|
||||||
|
{
|
||||||
|
if (identifier == "UpdateImported3DAsset" && nodeList.size() > 0) {
|
||||||
|
ItemLibraryAssetImportDialog::updateImport(nodeList[0], m_importableExtensions3DMap,
|
||||||
|
m_importOptions3DMap);
|
||||||
|
} else {
|
||||||
|
AbstractView::customNotification(view, identifier, nodeList, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace QmlDesigner
|
} // namespace QmlDesigner
|
||||||
|
|||||||
@@ -55,6 +55,8 @@ public:
|
|||||||
void usedImportsChanged(const QList<Import> &usedImports) override;
|
void usedImportsChanged(const QList<Import> &usedImports) override;
|
||||||
void documentMessagesChanged(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings) override;
|
void documentMessagesChanged(const QList<DocumentMessage> &errors, const QList<DocumentMessage> &warnings) override;
|
||||||
void updateImport3DSupport(const QVariantMap &supportMap) override;
|
void updateImport3DSupport(const QVariantMap &supportMap) override;
|
||||||
|
void customNotification(const AbstractView *view, const QString &identifier,
|
||||||
|
const QList<ModelNode> &nodeList, const QList<QVariant> &data) override;
|
||||||
|
|
||||||
void setResourcePath(const QString &resourcePath);
|
void setResourcePath(const QString &resourcePath);
|
||||||
|
|
||||||
|
|||||||
@@ -69,6 +69,9 @@ const char QML_DESIGNER_SUBFOLDER[] = "/designer/";
|
|||||||
const char QUICK_3D_ASSETS_FOLDER[] = "/Quick3DAssets";
|
const char QUICK_3D_ASSETS_FOLDER[] = "/Quick3DAssets";
|
||||||
const char QUICK_3D_ASSET_LIBRARY_ICON_SUFFIX[] = "_libicon";
|
const char QUICK_3D_ASSET_LIBRARY_ICON_SUFFIX[] = "_libicon";
|
||||||
const char QUICK_3D_ASSET_ICON_DIR[] = "_icons";
|
const char QUICK_3D_ASSET_ICON_DIR[] = "_icons";
|
||||||
|
const char QUICK_3D_ASSET_IMPORT_DATA_NAME[] = "_importdata.json";
|
||||||
|
const char QUICK_3D_ASSET_IMPORT_DATA_OPTIONS_KEY[] = "import_options";
|
||||||
|
const char QUICK_3D_ASSET_IMPORT_DATA_SOURCE_KEY[] = "source_scene";
|
||||||
const char DEFAULT_ASSET_IMPORT_FOLDER[] = "/asset_imports";
|
const char DEFAULT_ASSET_IMPORT_FOLDER[] = "/asset_imports";
|
||||||
|
|
||||||
// Menus
|
// Menus
|
||||||
|
|||||||
Reference in New Issue
Block a user