Browse Source

Improve behavior of deleting torrents in transfer list

Avoids accessing invalid pointers.
Closes #12584.
adaptive-webui-19844
Chocobo1 5 years ago
parent
commit
7ce83599b4
No known key found for this signature in database
GPG Key ID: 210D9C873253A68C
  1. 40
      src/gui/transferlistwidget.cpp
  2. 1
      src/gui/transferlistwidget.h

40
src/gui/transferlistwidget.cpp

@ -501,6 +501,17 @@ QVector<BitTorrent::TorrentHandle *> TransferListWidget::getSelectedTorrents() c
return torrents; return torrents;
} }
QVector<BitTorrent::TorrentHandle *> TransferListWidget::getVisibleTorrents() const
{
const int visibleTorrentsCount = m_sortFilterModel->rowCount();
QVector<BitTorrent::TorrentHandle *> torrents;
torrents.reserve(visibleTorrentsCount);
for (int i = 0; i < visibleTorrentsCount; ++i)
torrents << m_listModel->torrentHandle(mapToSource(m_sortFilterModel->index(i, 0)));
return torrents;
}
void TransferListWidget::setSelectedTorrentsLocation() void TransferListWidget::setSelectedTorrentsLocation()
{ {
const QVector<BitTorrent::TorrentHandle *> torrents = getSelectedTorrents(); const QVector<BitTorrent::TorrentHandle *> torrents = getSelectedTorrents();
@ -547,11 +558,8 @@ void TransferListWidget::forceStartSelectedTorrents()
void TransferListWidget::startVisibleTorrents() void TransferListWidget::startVisibleTorrents()
{ {
for (int i = 0; i < m_sortFilterModel->rowCount(); ++i) { for (BitTorrent::TorrentHandle *const torrent : asConst(getVisibleTorrents()))
BitTorrent::TorrentHandle *const torrent = m_listModel->torrentHandle(mapToSource(m_sortFilterModel->index(i, 0)));
if (torrent)
torrent->resume(); torrent->resume();
}
} }
void TransferListWidget::pauseSelectedTorrents() void TransferListWidget::pauseSelectedTorrents()
@ -562,11 +570,8 @@ void TransferListWidget::pauseSelectedTorrents()
void TransferListWidget::pauseVisibleTorrents() void TransferListWidget::pauseVisibleTorrents()
{ {
for (int i = 0; i < m_sortFilterModel->rowCount(); ++i) { for (BitTorrent::TorrentHandle *const torrent : asConst(getVisibleTorrents()))
BitTorrent::TorrentHandle *const torrent = m_listModel->torrentHandle(mapToSource(m_sortFilterModel->index(i, 0)));
if (torrent)
torrent->pause(); torrent->pause();
}
} }
void TransferListWidget::softDeleteSelectedTorrents() void TransferListWidget::softDeleteSelectedTorrents()
@ -589,9 +594,11 @@ void TransferListWidget::deleteSelectedTorrents(const bool deleteLocalFiles)
if (Preferences::instance()->confirmTorrentDeletion()) { if (Preferences::instance()->confirmTorrentDeletion()) {
auto *dialog = new DeletionConfirmationDialog(this, torrents.size(), torrents[0]->name(), deleteLocalFiles); auto *dialog = new DeletionConfirmationDialog(this, torrents.size(), torrents[0]->name(), deleteLocalFiles);
dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setAttribute(Qt::WA_DeleteOnClose);
connect(dialog, &DeletionConfirmationDialog::accepted, this, [dialog, torrents]() connect(dialog, &DeletionConfirmationDialog::accepted, this, [this, dialog]()
{ {
removeTorrents(torrents, dialog->isDeleteFileSelected()); // Some torrents might be removed when waiting for user input, so refetch the torrent list
// NOTE: this will only work when dialog is modal
removeTorrents(getSelectedTorrents(), dialog->isDeleteFileSelected());
}); });
dialog->open(); dialog->open();
} }
@ -602,18 +609,17 @@ void TransferListWidget::deleteSelectedTorrents(const bool deleteLocalFiles)
void TransferListWidget::deleteVisibleTorrents() void TransferListWidget::deleteVisibleTorrents()
{ {
if (m_sortFilterModel->rowCount() <= 0) return; const QVector<BitTorrent::TorrentHandle *> torrents = getVisibleTorrents();
if (torrents.empty()) return;
QVector<BitTorrent::TorrentHandle *> torrents;
for (int i = 0; i < m_sortFilterModel->rowCount(); ++i)
torrents << m_listModel->torrentHandle(mapToSource(m_sortFilterModel->index(i, 0)));
if (Preferences::instance()->confirmTorrentDeletion()) { if (Preferences::instance()->confirmTorrentDeletion()) {
auto *dialog = new DeletionConfirmationDialog(this, torrents.size(), torrents[0]->name(), false); auto *dialog = new DeletionConfirmationDialog(this, torrents.size(), torrents[0]->name(), false);
dialog->setAttribute(Qt::WA_DeleteOnClose); dialog->setAttribute(Qt::WA_DeleteOnClose);
connect(dialog, &DeletionConfirmationDialog::accepted, this, [dialog, torrents]() connect(dialog, &DeletionConfirmationDialog::accepted, this, [this, dialog]()
{ {
removeTorrents(torrents, dialog->isDeleteFileSelected()); // Some torrents might be removed when waiting for user input, so refetch the torrent list
// NOTE: this will only work when dialog is modal
removeTorrents(getVisibleTorrents(), dialog->isDeleteFileSelected());
}); });
dialog->open(); dialog->open();
} }

1
src/gui/transferlistwidget.h

@ -141,6 +141,7 @@ private:
void confirmRemoveAllTagsForSelection(); void confirmRemoveAllTagsForSelection();
QStringList askTagsForSelection(const QString &dialogTitle); QStringList askTagsForSelection(const QString &dialogTitle);
void applyToSelectedTorrents(const std::function<void (BitTorrent::TorrentHandle *const)> &fn); void applyToSelectedTorrents(const std::function<void (BitTorrent::TorrentHandle *const)> &fn);
QVector<BitTorrent::TorrentHandle *> getVisibleTorrents() const;
// supposed to be used with qss only // supposed to be used with qss only
QColor unknownStateForeground() const; QColor unknownStateForeground() const;

Loading…
Cancel
Save