Add drag support to torrent content widget

Now qbt supports dragging items from torrent content widget to another app.

Closes #5860.
PR #21569.
This commit is contained in:
Chocobo1 2024-10-12 14:49:17 +08:00 committed by GitHub
commit c4eeb4a14a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 49 additions and 1 deletions

View file

@ -34,8 +34,10 @@
#include <QFileIconProvider> #include <QFileIconProvider>
#include <QFileInfo> #include <QFileInfo>
#include <QIcon> #include <QIcon>
#include <QMimeData>
#include <QPointer> #include <QPointer>
#include <QScopeGuard> #include <QScopeGuard>
#include <QUrl>
#if defined(Q_OS_MACOS) #if defined(Q_OS_MACOS)
#define QBT_PIXMAP_CACHE_FOR_FILE_ICONS #define QBT_PIXMAP_CACHE_FOR_FILE_ICONS
@ -434,7 +436,7 @@ Qt::ItemFlags TorrentContentModel::flags(const QModelIndex &index) const
if (!index.isValid()) if (!index.isValid())
return Qt::NoItemFlags; 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) if (itemType(index) == TorrentContentModelItem::FolderType)
flags |= Qt::ItemIsAutoTristate; flags |= Qt::ItemIsAutoTristate;
if (index.column() == TorrentContentModelItem::COL_PRIO) if (index.column() == TorrentContentModelItem::COL_PRIO)
@ -515,6 +517,47 @@ int TorrentContentModel::rowCount(const QModelIndex &parent) const
return parentItem ? parentItem->childCount() : 0; return parentItem ? parentItem->childCount() : 0;
} }
QMimeData *TorrentContentModel::mimeData(const QModelIndexList &indexes) const
{
if (indexes.isEmpty())
return nullptr;
const Path storagePath = contentHandler()->actualStorageLocation();
QList<QUrl> 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() void TorrentContentModel::populate()
{ {
Q_ASSERT(m_contentHandler && m_contentHandler->hasMetadata()); Q_ASSERT(m_contentHandler && m_contentHandler->hasMetadata());

View file

@ -37,6 +37,7 @@
#include "torrentcontentmodelitem.h" #include "torrentcontentmodelitem.h"
class QFileIconProvider; class QFileIconProvider;
class QMimeData;
class QModelIndex; class QModelIndex;
class QVariant; class QVariant;
@ -86,6 +87,8 @@ signals:
private: private:
using ColumnInterval = IndexInterval<int>; using ColumnInterval = IndexInterval<int>;
QMimeData *mimeData(const QModelIndexList &indexes) const override;
QStringList mimeTypes() const override;
void populate(); void populate();
void updateFilesProgress(); void updateFilesProgress();
void updateFilesPriorities(); void updateFilesPriorities();

View file

@ -71,6 +71,8 @@ namespace
TorrentContentWidget::TorrentContentWidget(QWidget *parent) TorrentContentWidget::TorrentContentWidget(QWidget *parent)
: QTreeView(parent) : QTreeView(parent)
{ {
setDragEnabled(true);
setDragDropMode(QAbstractItemView::DragOnly);
setExpandsOnDoubleClick(false); setExpandsOnDoubleClick(false);
setSortingEnabled(true); setSortingEnabled(true);
setUniformRowHeights(true); setUniformRowHeights(true);