From c4eeb4a14a19cfcdf54aac9eb07f02080666aef1 Mon Sep 17 00:00:00 2001 From: Chocobo1 Date: Sat, 12 Oct 2024 14:49:17 +0800 Subject: [PATCH] Add drag support to torrent content widget Now qbt supports dragging items from torrent content widget to another app. Closes #5860. PR #21569. --- src/gui/torrentcontentmodel.cpp | 45 +++++++++++++++++++++++++++++++- src/gui/torrentcontentmodel.h | 3 +++ src/gui/torrentcontentwidget.cpp | 2 ++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/gui/torrentcontentmodel.cpp b/src/gui/torrentcontentmodel.cpp index c911bfa9f..474fbd573 100644 --- a/src/gui/torrentcontentmodel.cpp +++ b/src/gui/torrentcontentmodel.cpp @@ -34,8 +34,10 @@ #include #include #include +#include #include #include +#include #if defined(Q_OS_MACOS) #define QBT_PIXMAP_CACHE_FOR_FILE_ICONS @@ -434,7 +436,7 @@ Qt::ItemFlags TorrentContentModel::flags(const QModelIndex &index) const if (!index.isValid()) return Qt::NoItemFlags; - Qt::ItemFlags flags {Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable}; + Qt::ItemFlags flags {Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable}; if (itemType(index) == TorrentContentModelItem::FolderType) flags |= Qt::ItemIsAutoTristate; if (index.column() == TorrentContentModelItem::COL_PRIO) @@ -515,6 +517,47 @@ int TorrentContentModel::rowCount(const QModelIndex &parent) const return parentItem ? parentItem->childCount() : 0; } +QMimeData *TorrentContentModel::mimeData(const QModelIndexList &indexes) const +{ + if (indexes.isEmpty()) + return nullptr; + + const Path storagePath = contentHandler()->actualStorageLocation(); + + QList paths; + paths.reserve(indexes.size()); + + for (const QModelIndex &index : indexes) + { + if (!index.isValid()) + continue; + if (index.column() != TorrentContentModelItem::COL_NAME) + continue; + + if (itemType(index) == TorrentContentModelItem::FileType) + { + const int idx = getFileIndex(index); + const Path fullPath = storagePath / contentHandler()->actualFilePath(idx); + paths.append(QUrl::fromLocalFile(fullPath.data())); + } + else // folder type + { + const Path fullPath = storagePath / getItemPath(index); + paths.append(QUrl::fromLocalFile(fullPath.data())); + } + } + + auto *mimeData = new QMimeData; // lifetime will be handled by Qt + mimeData->setUrls(paths); + + return mimeData; +} + +QStringList TorrentContentModel::mimeTypes() const +{ + return {u"text/uri-list"_s}; +} + void TorrentContentModel::populate() { Q_ASSERT(m_contentHandler && m_contentHandler->hasMetadata()); diff --git a/src/gui/torrentcontentmodel.h b/src/gui/torrentcontentmodel.h index cffb02081..b1b331052 100644 --- a/src/gui/torrentcontentmodel.h +++ b/src/gui/torrentcontentmodel.h @@ -37,6 +37,7 @@ #include "torrentcontentmodelitem.h" class QFileIconProvider; +class QMimeData; class QModelIndex; class QVariant; @@ -86,6 +87,8 @@ signals: private: using ColumnInterval = IndexInterval; + QMimeData *mimeData(const QModelIndexList &indexes) const override; + QStringList mimeTypes() const override; void populate(); void updateFilesProgress(); void updateFilesPriorities(); diff --git a/src/gui/torrentcontentwidget.cpp b/src/gui/torrentcontentwidget.cpp index ebafe0dfa..472537bf2 100644 --- a/src/gui/torrentcontentwidget.cpp +++ b/src/gui/torrentcontentwidget.cpp @@ -71,6 +71,8 @@ namespace TorrentContentWidget::TorrentContentWidget(QWidget *parent) : QTreeView(parent) { + setDragEnabled(true); + setDragDropMode(QAbstractItemView::DragOnly); setExpandsOnDoubleClick(false); setSortingEnabled(true); setUniformRowHeights(true);