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
parent 6418033cc8
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 <QFileInfo>
#include <QIcon>
#include <QMimeData>
#include <QPointer>
#include <QScopeGuard>
#include <QUrl>
#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<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()
{
Q_ASSERT(m_contentHandler && m_contentHandler->hasMetadata());

View file

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

View file

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