From 6e0aa9874659f209622d0aa7eb42e3ec19de2007 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 28 Dec 2020 16:43:02 +0200 Subject: [PATCH] QmlDesigner: Allow importing assets by dragging from file explorer Supported assets can now be imported by dragging files from external file explorer to Assets tab in item library. Fixes: QDS-3447 Change-Id: Id7c5a808c99e0e6b021414d4ca0541620e8d9f47 Reviewed-by: Mahmoud Badri Reviewed-by: Thomas Hartmann --- .../itemlibrary/customfilesystemmodel.cpp | 16 ++++ .../itemlibrary/customfilesystemmodel.h | 2 + .../itemlibrary/itemlibrarywidget.cpp | 79 ++++++++++++++----- .../itemlibrary/itemlibrarywidget.h | 4 +- 4 files changed, 79 insertions(+), 22 deletions(-) diff --git a/src/plugins/qmldesigner/components/itemlibrary/customfilesystemmodel.cpp b/src/plugins/qmldesigner/components/itemlibrary/customfilesystemmodel.cpp index dcf9acada99..b16902ecd4e 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/customfilesystemmodel.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/customfilesystemmodel.cpp @@ -329,6 +329,22 @@ QPair CustomFileSystemModel::resourceTypeAndData(const QMod return {}; } +const QSet &CustomFileSystemModel::supportedSuffixes() const +{ + static QSet allSuffixes; + if (allSuffixes.isEmpty()) { + auto insertSuffixes = [](const QStringList &suffixes) { + for (const auto &suffix : suffixes) + allSuffixes.insert(suffix); + }; + insertSuffixes(supportedImageSuffixes()); + insertSuffixes(supportedShaderSuffixes()); + insertSuffixes(supportedFontSuffixes()); + insertSuffixes(supportedAudioSuffixes()); + } + return allSuffixes; +} + void CustomFileSystemModel::appendIfNotFiltered(const QString &file) { if (filterMetaIcons(file)) diff --git a/src/plugins/qmldesigner/components/itemlibrary/customfilesystemmodel.h b/src/plugins/qmldesigner/components/itemlibrary/customfilesystemmodel.h index ce552ccc231..8825304be1c 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/customfilesystemmodel.h +++ b/src/plugins/qmldesigner/components/itemlibrary/customfilesystemmodel.h @@ -28,6 +28,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE class QFileIconProvider; @@ -62,6 +63,7 @@ public: void setSearchFilter(const QString &nameFilterList); QPair resourceTypeAndData(const QModelIndex &index) const; + const QSet &supportedSuffixes() const; private: QModelIndex updatePath(const QString &newPath); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp index 4ee8346ed11..a0e2214c730 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.cpp @@ -201,7 +201,9 @@ ItemLibraryWidget::ItemLibraryWidget(ImageCache &imageCache) button->setToolTip(tr("Add new assets to project.")); button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); flowLayout->addWidget(button); - connect(button, &QToolButton::clicked, this, &ItemLibraryWidget::addResources); + connect(button, &QToolButton::clicked, [this]() { + addResources({}); + }); #ifdef IMPORT_QUICK3D_ASSETS DesignerActionManager *actionManager = @@ -246,6 +248,26 @@ ItemLibraryWidget::ItemLibraryWidget(ImageCache &imageCache) } #endif + const auto dropSupport = new Utils::DropSupport( + m_resourcesView.data(), [this](QDropEvent *event, Utils::DropSupport *) { + // Accept supported file types + if (event->type() == QDropEvent::DragEnter && !Utils::DropSupport::isFileDrop(event)) + return false; // do not accept drops without files + bool accept = false; + const QSet &suffixes = m_resourcesFileSystemModel->supportedSuffixes(); + const QList urls = event->mimeData()->urls(); + for (const QUrl &url : urls) { + QFileInfo fi(url.toLocalFile()); + if (suffixes.contains(fi.suffix())) { + accept = true; + break; + } + } + return accept; + }); + connect(dropSupport, &Utils::DropSupport::filesDropped, + this, &ItemLibraryWidget::importDroppedFiles); + // init the first load of the QML UI elements reloadQmlSource(); } @@ -511,7 +533,7 @@ void ItemLibraryWidget::addPossibleImport(const QString &name) QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager(); } -void ItemLibraryWidget::addResources() +void ItemLibraryWidget::addResources(const QStringList &files) { auto document = QmlDesignerPlugin::instance()->currentDesignDocument(); @@ -540,28 +562,31 @@ void ItemLibraryWidget::addResources() return priorities.value(first) < priorities.value(second); }); - QStringList filters; + QStringList fileNames = files; + if (fileNames.isEmpty()) { + QStringList filters; - for (const QString &key : sortedKeys) { - QString str = key + " ("; - str.append(map.values(key).join(" ")); - str.append(")"); - filters.append(str); + for (const QString &key : sortedKeys) { + QString str = key + " ("; + str.append(map.values(key).join(" ")); + str.append(")"); + filters.append(str); + } + + filters.prepend(tr("All Files (%1)").arg(map.values().join(" "))); + + static QString lastDir; + const QString currentDir = lastDir.isEmpty() ? document->fileName().parentDir().toString() : lastDir; + + fileNames = QFileDialog::getOpenFileNames(Core::ICore::dialogParent(), + tr("Add Assets"), + currentDir, + filters.join(";;")); + + if (!fileNames.isEmpty()) + lastDir = QFileInfo(fileNames.first()).absolutePath(); } - filters.prepend(tr("All Files (%1)").arg(map.values().join(" "))); - - static QString lastDir; - const QString currentDir = lastDir.isEmpty() ? document->fileName().parentDir().toString() : lastDir; - - const auto fileNames = QFileDialog::getOpenFileNames(Core::ICore::dialogParent(), - tr("Add Assets"), - currentDir, - filters.join(";;")); - - if (!fileNames.isEmpty()) - lastDir = QFileInfo(fileNames.first()).absolutePath(); - QMultiMap partitionedFileNames; for (const QString &fileName : fileNames) { @@ -582,4 +607,16 @@ void ItemLibraryWidget::addResources() } } } + +void ItemLibraryWidget::importDroppedFiles(const QList &files) +{ + QStringList fileNames; + for (const auto &file : files) { + QFileInfo fi(file.filePath); + if (m_resourcesFileSystemModel->supportedSuffixes().contains(fi.suffix())) + fileNames.append(fi.absoluteFilePath()); + } + if (!fileNames.isEmpty()) + addResources(fileNames); +} } // namespace QmlDesigner diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h index bfe9106a23b..b08ccec88d9 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrarywidget.h @@ -29,6 +29,7 @@ #include "itemlibraryresourceview.h" #include +#include #include #include @@ -104,7 +105,8 @@ private: void removeImport(const QString &name); void addImport(const QString &name, const QString &version); void addPossibleImport(const QString &name); - void addResources(); + void addResources(const QStringList &files); + void importDroppedFiles(const QList &files); QTimer m_compressionTimer; QSize m_itemIconSize;