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 <mahmoud.badri@qt.io>
Reviewed-by: Thomas Hartmann <thomas.hartmann@qt.io>
This commit is contained in:
Miikka Heikkinen
2020-12-28 16:43:02 +02:00
parent d7890aa473
commit 6e0aa98746
4 changed files with 79 additions and 22 deletions

View File

@@ -329,6 +329,22 @@ QPair<QString, QByteArray> CustomFileSystemModel::resourceTypeAndData(const QMod
return {};
}
const QSet<QString> &CustomFileSystemModel::supportedSuffixes() const
{
static QSet<QString> 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))

View File

@@ -28,6 +28,7 @@
#include <QAbstractTableModel>
#include <QDir>
#include <QPair>
#include <QSet>
QT_BEGIN_NAMESPACE
class QFileIconProvider;
@@ -62,6 +63,7 @@ public:
void setSearchFilter(const QString &nameFilterList);
QPair<QString, QByteArray> resourceTypeAndData(const QModelIndex &index) const;
const QSet<QString> &supportedSuffixes() const;
private:
QModelIndex updatePath(const QString &newPath);

View File

@@ -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<QString> &suffixes = m_resourcesFileSystemModel->supportedSuffixes();
const QList<QUrl> 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<QString, QString> partitionedFileNames;
for (const QString &fileName : fileNames) {
@@ -582,4 +607,16 @@ void ItemLibraryWidget::addResources()
}
}
}
void ItemLibraryWidget::importDroppedFiles(const QList<Utils::DropSupport::FileSpec> &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

View File

@@ -29,6 +29,7 @@
#include "itemlibraryresourceview.h"
#include <utils/fancylineedit.h>
#include <utils/dropsupport.h>
#include <QFrame>
#include <QToolButton>
@@ -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<Utils::DropSupport::FileSpec> &files);
QTimer m_compressionTimer;
QSize m_itemIconSize;