Browse Source

Merge pull request #11085 from Chocobo1/model

Better on-demand reloading of torrent data
adaptive-webui-19844
Mike Tzou 5 years ago committed by GitHub
parent
commit
62a3938480
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/app/application.cpp
  2. 6
      src/base/bittorrent/session.cpp
  3. 2
      src/base/bittorrent/session.h
  4. 4
      src/gui/search/pluginselectdialog.cpp
  5. 12
      src/gui/search/searchwidget.cpp
  6. 4
      src/gui/torrentcontentfiltermodel.cpp
  7. 12
      src/gui/torrentcontentmodel.cpp
  8. 48
      src/gui/transferlistfilterswidget.cpp
  9. 65
      src/gui/transferlistmodel.cpp
  10. 9
      src/gui/transferlistmodel.h

2
src/app/application.cpp

@ -203,7 +203,7 @@ void Application::setFileLoggerEnabled(const bool value)
QString Application::fileLoggerPath() const QString Application::fileLoggerPath() const
{ {
return settings()->loadValue(KEY_FILELOGGER_PATH, return settings()->loadValue(KEY_FILELOGGER_PATH,
QVariant(specialFolderLocation(SpecialFolder::Data) + LOG_FOLDER)).toString(); {specialFolderLocation(SpecialFolder::Data) + LOG_FOLDER}).toString();
} }
void Application::setFileLoggerPath(const QString &path) void Application::setFileLoggerPath(const QString &path)

6
src/base/bittorrent/session.cpp

@ -4354,6 +4354,9 @@ void Session::handleSessionStatsAlert(const lt::session_stats_alert *p)
void Session::handleStateUpdateAlert(const lt::state_update_alert *p) void Session::handleStateUpdateAlert(const lt::state_update_alert *p)
{ {
QVector<BitTorrent::TorrentHandle *> updatedTorrents;
updatedTorrents.reserve(p->status.size());
for (const lt::torrent_status &status : p->status) { for (const lt::torrent_status &status : p->status) {
TorrentHandle *const torrent = m_torrents.value(status.info_hash); TorrentHandle *const torrent = m_torrents.value(status.info_hash);
@ -4361,6 +4364,7 @@ void Session::handleStateUpdateAlert(const lt::state_update_alert *p)
continue; continue;
torrent->handleStateUpdate(status); torrent->handleStateUpdate(status);
updatedTorrents.push_back(torrent);
} }
m_torrentStatusReport = TorrentStatusReport(); m_torrentStatusReport = TorrentStatusReport();
@ -4383,7 +4387,7 @@ void Session::handleStateUpdateAlert(const lt::state_update_alert *p)
++m_torrentStatusReport.nbErrored; ++m_torrentStatusReport.nbErrored;
} }
emit torrentsUpdated(); emit torrentsUpdated(updatedTorrents);
} }
namespace namespace

2
src/base/bittorrent/session.h

@ -450,7 +450,7 @@ namespace BitTorrent
signals: signals:
void statsUpdated(); void statsUpdated();
void torrentsUpdated(); void torrentsUpdated(const QVector<BitTorrent::TorrentHandle *> &torrents);
void addTorrentFailed(const QString &error); void addTorrentFailed(const QString &error);
void torrentAdded(BitTorrent::TorrentHandle *const torrent); void torrentAdded(BitTorrent::TorrentHandle *const torrent);
void torrentNew(BitTorrent::TorrentHandle *const torrent); void torrentNew(BitTorrent::TorrentHandle *const torrent);

4
src/gui/search/pluginselectdialog.cpp

@ -234,7 +234,7 @@ void PluginSelectDialog::setRowColor(const int row, const QString &color)
{ {
QTreeWidgetItem *item = m_ui->pluginsTree->topLevelItem(row); QTreeWidgetItem *item = m_ui->pluginsTree->topLevelItem(row);
for (int i = 0; i < m_ui->pluginsTree->columnCount(); ++i) { for (int i = 0; i < m_ui->pluginsTree->columnCount(); ++i) {
item->setData(i, Qt::ForegroundRole, QVariant(QColor(color))); item->setData(i, Qt::ForegroundRole, QColor(color));
} }
} }
@ -289,7 +289,7 @@ void PluginSelectDialog::addNewPlugin(const QString &pluginName)
// Handle icon // Handle icon
if (QFile::exists(plugin->iconPath)) { if (QFile::exists(plugin->iconPath)) {
// Good, we already have the icon // Good, we already have the icon
item->setData(PLUGIN_NAME, Qt::DecorationRole, QVariant(QIcon(plugin->iconPath))); item->setData(PLUGIN_NAME, Qt::DecorationRole, QIcon(plugin->iconPath));
} }
else { else {
// Icon is missing, we must download it // Icon is missing, we must download it

12
src/gui/search/searchwidget.cpp

@ -144,7 +144,7 @@ SearchWidget::SearchWidget(MainWindow *mainWindow)
void SearchWidget::fillCatCombobox() void SearchWidget::fillCatCombobox()
{ {
m_ui->comboCategory->clear(); m_ui->comboCategory->clear();
m_ui->comboCategory->addItem(SearchPluginManager::categoryFullName("all"), QVariant("all")); m_ui->comboCategory->addItem(SearchPluginManager::categoryFullName("all"), "all");
using QStrPair = QPair<QString, QString>; using QStrPair = QPair<QString, QString>;
QVector<QStrPair> tmpList; QVector<QStrPair> tmpList;
@ -154,7 +154,7 @@ void SearchWidget::fillCatCombobox()
for (const QStrPair &p : asConst(tmpList)) { for (const QStrPair &p : asConst(tmpList)) {
qDebug("Supported category: %s", qUtf8Printable(p.second)); qDebug("Supported category: %s", qUtf8Printable(p.second));
m_ui->comboCategory->addItem(p.first, QVariant(p.second)); m_ui->comboCategory->addItem(p.first, p.second);
} }
if (m_ui->comboCategory->count() > 1) if (m_ui->comboCategory->count() > 1)
@ -164,9 +164,9 @@ void SearchWidget::fillCatCombobox()
void SearchWidget::fillPluginComboBox() void SearchWidget::fillPluginComboBox()
{ {
m_ui->selectPlugin->clear(); m_ui->selectPlugin->clear();
m_ui->selectPlugin->addItem(tr("Only enabled"), QVariant("enabled")); m_ui->selectPlugin->addItem(tr("Only enabled"), "enabled");
m_ui->selectPlugin->addItem(tr("All plugins"), QVariant("all")); m_ui->selectPlugin->addItem(tr("All plugins"), "all");
m_ui->selectPlugin->addItem(tr("Select..."), QVariant("multi")); m_ui->selectPlugin->addItem(tr("Select..."), "multi");
using QStrPair = QPair<QString, QString>; using QStrPair = QPair<QString, QString>;
QVector<QStrPair> tmpList; QVector<QStrPair> tmpList;
@ -175,7 +175,7 @@ void SearchWidget::fillPluginComboBox()
std::sort(tmpList.begin(), tmpList.end(), [](const QStrPair &l, const QStrPair &r) { return (l.first < r.first); } ); std::sort(tmpList.begin(), tmpList.end(), [](const QStrPair &l, const QStrPair &r) { return (l.first < r.first); } );
for (const QStrPair &p : asConst(tmpList)) for (const QStrPair &p : asConst(tmpList))
m_ui->selectPlugin->addItem(p.first, QVariant(p.second)); m_ui->selectPlugin->addItem(p.first, p.second);
if (m_ui->selectPlugin->count() > 3) if (m_ui->selectPlugin->count() > 3)
m_ui->selectPlugin->insertSeparator(3); m_ui->selectPlugin->insertSeparator(3);

4
src/gui/torrentcontentfiltermodel.cpp

@ -107,7 +107,7 @@ void TorrentContentFilterModel::selectAll()
for (int i = 0; i < rowCount(); ++i) for (int i = 0; i < rowCount(); ++i)
setData(index(i, 0), Qt::Checked, Qt::CheckStateRole); setData(index(i, 0), Qt::Checked, Qt::CheckStateRole);
emit dataChanged(index(0,0), index(rowCount(), columnCount())); emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
} }
void TorrentContentFilterModel::selectNone() void TorrentContentFilterModel::selectNone()
@ -115,7 +115,7 @@ void TorrentContentFilterModel::selectNone()
for (int i = 0; i < rowCount(); ++i) for (int i = 0; i < rowCount(); ++i)
setData(index(i, 0), Qt::Unchecked, Qt::CheckStateRole); setData(index(i, 0), Qt::Unchecked, Qt::CheckStateRole);
emit dataChanged(index(0,0), index(rowCount(), columnCount())); emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
} }
bool TorrentContentFilterModel::hasFiltered(const QModelIndex &folder) const bool TorrentContentFilterModel::hasFiltered(const QModelIndex &folder) const

12
src/gui/torrentcontentmodel.cpp

@ -228,7 +228,7 @@ void TorrentContentModel::updateFilesProgress(const QVector<qreal> &fp)
// Update folders progress in the tree // Update folders progress in the tree
m_rootItem->recalculateProgress(); m_rootItem->recalculateProgress();
m_rootItem->recalculateAvailability(); m_rootItem->recalculateAvailability();
emit dataChanged(index(0, 0), index(rowCount(), columnCount())); emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
} }
void TorrentContentModel::updateFilesPriorities(const QVector<BitTorrent::DownloadPriority> &fprio) void TorrentContentModel::updateFilesPriorities(const QVector<BitTorrent::DownloadPriority> &fprio)
@ -241,7 +241,7 @@ void TorrentContentModel::updateFilesPriorities(const QVector<BitTorrent::Downlo
emit layoutAboutToBeChanged(); emit layoutAboutToBeChanged();
for (int i = 0; i < fprio.size(); ++i) for (int i = 0; i < fprio.size(); ++i)
m_filesIndex[i]->setPriority(static_cast<BitTorrent::DownloadPriority>(fprio[i])); m_filesIndex[i]->setPriority(static_cast<BitTorrent::DownloadPriority>(fprio[i]));
emit dataChanged(index(0, 0), index(rowCount(), columnCount())); emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
} }
void TorrentContentModel::updateFilesAvailability(const QVector<qreal> &fa) void TorrentContentModel::updateFilesAvailability(const QVector<qreal> &fa)
@ -255,7 +255,7 @@ void TorrentContentModel::updateFilesAvailability(const QVector<qreal> &fa)
m_filesIndex[i]->setAvailability(fa[i]); m_filesIndex[i]->setAvailability(fa[i]);
// Update folders progress in the tree // Update folders progress in the tree
m_rootItem->recalculateProgress(); m_rootItem->recalculateProgress();
emit dataChanged(index(0, 0), index(rowCount(), columnCount())); emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
} }
QVector<BitTorrent::DownloadPriority> TorrentContentModel::getFilePriorities() const QVector<BitTorrent::DownloadPriority> TorrentContentModel::getFilePriorities() const
@ -302,7 +302,7 @@ bool TorrentContentModel::setData(const QModelIndex &index, const QVariant &valu
// Update folders progress in the tree // Update folders progress in the tree
m_rootItem->recalculateProgress(); m_rootItem->recalculateProgress();
m_rootItem->recalculateAvailability(); m_rootItem->recalculateAvailability();
emit dataChanged(this->index(0, 0), this->index(rowCount() - 1, columnCount() - 1)); emit dataChanged(this->index(0, 0), this->index((rowCount() - 1), (columnCount() - 1)));
emit filteredFilesChanged(); emit filteredFilesChanged();
} }
return true; return true;
@ -502,12 +502,12 @@ void TorrentContentModel::selectAll()
if (child->priority() == BitTorrent::DownloadPriority::Ignored) if (child->priority() == BitTorrent::DownloadPriority::Ignored)
child->setPriority(BitTorrent::DownloadPriority::Normal); child->setPriority(BitTorrent::DownloadPriority::Normal);
} }
emit dataChanged(index(0, 0), index(rowCount(), columnCount())); emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
} }
void TorrentContentModel::selectNone() void TorrentContentModel::selectNone()
{ {
for (int i = 0; i < m_rootItem->childCount(); ++i) for (int i = 0; i < m_rootItem->childCount(); ++i)
m_rootItem->child(i)->setPriority(BitTorrent::DownloadPriority::Ignored); m_rootItem->child(i)->setPriority(BitTorrent::DownloadPriority::Ignored);
emit dataChanged(index(0, 0), index(rowCount(), columnCount())); emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
} }

48
src/gui/transferlistfilterswidget.cpp

@ -151,31 +151,31 @@ StatusFilterWidget::StatusFilterWidget(QWidget *parent, TransferListWidget *tran
// Add status filters // Add status filters
auto *all = new QListWidgetItem(this); auto *all = new QListWidgetItem(this);
all->setData(Qt::DisplayRole, QVariant(tr("All (0)", "this is for the status filter"))); all->setData(Qt::DisplayRole, tr("All (0)", "this is for the status filter"));
all->setData(Qt::DecorationRole, QIcon(":/icons/skin/filterall.svg")); all->setData(Qt::DecorationRole, QIcon(":/icons/skin/filterall.svg"));
auto *downloading = new QListWidgetItem(this); auto *downloading = new QListWidgetItem(this);
downloading->setData(Qt::DisplayRole, QVariant(tr("Downloading (0)"))); downloading->setData(Qt::DisplayRole, tr("Downloading (0)"));
downloading->setData(Qt::DecorationRole, QIcon(":/icons/skin/downloading.svg")); downloading->setData(Qt::DecorationRole, QIcon(":/icons/skin/downloading.svg"));
auto *seeding = new QListWidgetItem(this); auto *seeding = new QListWidgetItem(this);
seeding->setData(Qt::DisplayRole, QVariant(tr("Seeding (0)"))); seeding->setData(Qt::DisplayRole, tr("Seeding (0)"));
seeding->setData(Qt::DecorationRole, QIcon(":/icons/skin/uploading.svg")); seeding->setData(Qt::DecorationRole, QIcon(":/icons/skin/uploading.svg"));
auto *completed = new QListWidgetItem(this); auto *completed = new QListWidgetItem(this);
completed->setData(Qt::DisplayRole, QVariant(tr("Completed (0)"))); completed->setData(Qt::DisplayRole, tr("Completed (0)"));
completed->setData(Qt::DecorationRole, QIcon(":/icons/skin/completed.svg")); completed->setData(Qt::DecorationRole, QIcon(":/icons/skin/completed.svg"));
auto *resumed = new QListWidgetItem(this); auto *resumed = new QListWidgetItem(this);
resumed->setData(Qt::DisplayRole, QVariant(tr("Resumed (0)"))); resumed->setData(Qt::DisplayRole, tr("Resumed (0)"));
resumed->setData(Qt::DecorationRole, QIcon(":/icons/skin/resumed.svg")); resumed->setData(Qt::DecorationRole, QIcon(":/icons/skin/resumed.svg"));
auto *paused = new QListWidgetItem(this); auto *paused = new QListWidgetItem(this);
paused->setData(Qt::DisplayRole, QVariant(tr("Paused (0)"))); paused->setData(Qt::DisplayRole, tr("Paused (0)"));
paused->setData(Qt::DecorationRole, QIcon(":/icons/skin/paused.svg")); paused->setData(Qt::DecorationRole, QIcon(":/icons/skin/paused.svg"));
auto *active = new QListWidgetItem(this); auto *active = new QListWidgetItem(this);
active->setData(Qt::DisplayRole, QVariant(tr("Active (0)"))); active->setData(Qt::DisplayRole, tr("Active (0)"));
active->setData(Qt::DecorationRole, QIcon(":/icons/skin/filteractive.svg")); active->setData(Qt::DecorationRole, QIcon(":/icons/skin/filteractive.svg"));
auto *inactive = new QListWidgetItem(this); auto *inactive = new QListWidgetItem(this);
inactive->setData(Qt::DisplayRole, QVariant(tr("Inactive (0)"))); inactive->setData(Qt::DisplayRole, tr("Inactive (0)"));
inactive->setData(Qt::DecorationRole, QIcon(":/icons/skin/filterinactive.svg")); inactive->setData(Qt::DecorationRole, QIcon(":/icons/skin/filterinactive.svg"));
auto *errored = new QListWidgetItem(this); auto *errored = new QListWidgetItem(this);
errored->setData(Qt::DisplayRole, QVariant(tr("Errored (0)"))); errored->setData(Qt::DisplayRole, tr("Errored (0)"));
errored->setData(Qt::DecorationRole, QIcon(":/icons/skin/error.svg")); errored->setData(Qt::DecorationRole, QIcon(":/icons/skin/error.svg"));
const Preferences *const pref = Preferences::instance(); const Preferences *const pref = Preferences::instance();
@ -190,17 +190,17 @@ StatusFilterWidget::~StatusFilterWidget()
void StatusFilterWidget::updateTorrentNumbers() void StatusFilterWidget::updateTorrentNumbers()
{ {
auto report = BitTorrent::Session::instance()->torrentStatusReport(); const BitTorrent::TorrentStatusReport report = BitTorrent::Session::instance()->torrentStatusReport();
item(TorrentFilter::All)->setData(Qt::DisplayRole, QVariant(tr("All (%1)").arg(report.nbActive + report.nbInactive))); item(TorrentFilter::All)->setData(Qt::DisplayRole, tr("All (%1)").arg(report.nbActive + report.nbInactive));
item(TorrentFilter::Downloading)->setData(Qt::DisplayRole, QVariant(tr("Downloading (%1)").arg(report.nbDownloading))); item(TorrentFilter::Downloading)->setData(Qt::DisplayRole, tr("Downloading (%1)").arg(report.nbDownloading));
item(TorrentFilter::Seeding)->setData(Qt::DisplayRole, QVariant(tr("Seeding (%1)").arg(report.nbSeeding))); item(TorrentFilter::Seeding)->setData(Qt::DisplayRole, tr("Seeding (%1)").arg(report.nbSeeding));
item(TorrentFilter::Completed)->setData(Qt::DisplayRole, QVariant(tr("Completed (%1)").arg(report.nbCompleted))); item(TorrentFilter::Completed)->setData(Qt::DisplayRole, tr("Completed (%1)").arg(report.nbCompleted));
item(TorrentFilter::Paused)->setData(Qt::DisplayRole, QVariant(tr("Paused (%1)").arg(report.nbPaused))); item(TorrentFilter::Paused)->setData(Qt::DisplayRole, tr("Paused (%1)").arg(report.nbPaused));
item(TorrentFilter::Resumed)->setData(Qt::DisplayRole, QVariant(tr("Resumed (%1)").arg(report.nbResumed))); item(TorrentFilter::Resumed)->setData(Qt::DisplayRole, tr("Resumed (%1)").arg(report.nbResumed));
item(TorrentFilter::Active)->setData(Qt::DisplayRole, QVariant(tr("Active (%1)").arg(report.nbActive))); item(TorrentFilter::Active)->setData(Qt::DisplayRole, tr("Active (%1)").arg(report.nbActive));
item(TorrentFilter::Inactive)->setData(Qt::DisplayRole, QVariant(tr("Inactive (%1)").arg(report.nbInactive))); item(TorrentFilter::Inactive)->setData(Qt::DisplayRole, tr("Inactive (%1)").arg(report.nbInactive));
item(TorrentFilter::Errored)->setData(Qt::DisplayRole, QVariant(tr("Errored (%1)").arg(report.nbErrored))); item(TorrentFilter::Errored)->setData(Qt::DisplayRole, tr("Errored (%1)").arg(report.nbErrored));
} }
void StatusFilterWidget::showMenu(const QPoint &) {} void StatusFilterWidget::showMenu(const QPoint &) {}
@ -220,16 +220,16 @@ TrackerFiltersList::TrackerFiltersList(QWidget *parent, TransferListWidget *tran
, m_downloadTrackerFavicon(downloadFavicon) , m_downloadTrackerFavicon(downloadFavicon)
{ {
auto *allTrackers = new QListWidgetItem(this); auto *allTrackers = new QListWidgetItem(this);
allTrackers->setData(Qt::DisplayRole, QVariant(tr("All (0)", "this is for the tracker filter"))); allTrackers->setData(Qt::DisplayRole, tr("All (0)", "this is for the tracker filter"));
allTrackers->setData(Qt::DecorationRole, UIThemeManager::instance()->getIcon("network-server")); allTrackers->setData(Qt::DecorationRole, UIThemeManager::instance()->getIcon("network-server"));
auto *noTracker = new QListWidgetItem(this); auto *noTracker = new QListWidgetItem(this);
noTracker->setData(Qt::DisplayRole, QVariant(tr("Trackerless (0)"))); noTracker->setData(Qt::DisplayRole, tr("Trackerless (0)"));
noTracker->setData(Qt::DecorationRole, UIThemeManager::instance()->getIcon("network-server")); noTracker->setData(Qt::DecorationRole, UIThemeManager::instance()->getIcon("network-server"));
auto *errorTracker = new QListWidgetItem(this); auto *errorTracker = new QListWidgetItem(this);
errorTracker->setData(Qt::DisplayRole, QVariant(tr("Error (0)"))); errorTracker->setData(Qt::DisplayRole, tr("Error (0)"));
errorTracker->setData(Qt::DecorationRole, style()->standardIcon(QStyle::SP_MessageBoxCritical)); errorTracker->setData(Qt::DecorationRole, style()->standardIcon(QStyle::SP_MessageBoxCritical));
auto *warningTracker = new QListWidgetItem(this); auto *warningTracker = new QListWidgetItem(this);
warningTracker->setData(Qt::DisplayRole, QVariant(tr("Warning (0)"))); warningTracker->setData(Qt::DisplayRole, tr("Warning (0)"));
warningTracker->setData(Qt::DecorationRole, style()->standardIcon(QStyle::SP_MessageBoxWarning)); warningTracker->setData(Qt::DecorationRole, style()->standardIcon(QStyle::SP_MessageBoxWarning));
m_trackers.insert("", QStringList()); m_trackers.insert("", QStringList());
@ -460,7 +460,7 @@ void TrackerFiltersList::handleFavicoDownloadFinished(const Net::DownloadResult
Utils::Fs::forceRemove(result.filePath); Utils::Fs::forceRemove(result.filePath);
} }
else { else {
trackerItem->setData(Qt::DecorationRole, QVariant(QIcon(result.filePath))); trackerItem->setData(Qt::DecorationRole, QIcon(result.filePath));
m_iconPaths.append(result.filePath); m_iconPaths.append(result.filePath);
} }
} }

65
src/gui/transferlistmodel.cpp

@ -77,15 +77,13 @@ TransferListModel::TransferListModel(QObject *parent)
connect(Session::instance(), &Session::torrentFinishedChecking, this, &TransferListModel::handleTorrentStatusUpdated); connect(Session::instance(), &Session::torrentFinishedChecking, this, &TransferListModel::handleTorrentStatusUpdated);
} }
int TransferListModel::rowCount(const QModelIndex &index) const int TransferListModel::rowCount(const QModelIndex &) const
{ {
Q_UNUSED(index); return m_torrentList.size();
return m_torrents.size();
} }
int TransferListModel::columnCount(const QModelIndex &parent) const int TransferListModel::columnCount(const QModelIndex &) const
{ {
Q_UNUSED(parent);
return NB_COLUMNS; return NB_COLUMNS;
} }
@ -164,7 +162,7 @@ QVariant TransferListModel::data(const QModelIndex &index, const int role) const
{ {
if (!index.isValid()) return {}; if (!index.isValid()) return {};
const BitTorrent::TorrentHandle *torrent = m_torrents.value(index.row()); const BitTorrent::TorrentHandle *torrent = m_torrentList.value(index.row());
if (!torrent) return {}; if (!torrent) return {};
if ((role == Qt::DecorationRole) && (index.column() == TR_NAME)) if ((role == Qt::DecorationRole) && (index.column() == TR_NAME))
@ -251,11 +249,9 @@ QVariant TransferListModel::data(const QModelIndex &index, const int role) const
bool TransferListModel::setData(const QModelIndex &index, const QVariant &value, int role) bool TransferListModel::setData(const QModelIndex &index, const QVariant &value, int role)
{ {
qDebug() << Q_FUNC_INFO << value;
if (!index.isValid() || (role != Qt::DisplayRole)) return false; if (!index.isValid() || (role != Qt::DisplayRole)) return false;
qDebug("Index is valid and role is DisplayRole"); BitTorrent::TorrentHandle *const torrent = m_torrentList.value(index.row());
BitTorrent::TorrentHandle *const torrent = m_torrents.value(index.row());
if (!torrent) return false; if (!torrent) return false;
// Category and Name columns can be edited // Category and Name columns can be edited
@ -275,13 +271,15 @@ bool TransferListModel::setData(const QModelIndex &index, const QVariant &value,
void TransferListModel::addTorrent(BitTorrent::TorrentHandle *const torrent) void TransferListModel::addTorrent(BitTorrent::TorrentHandle *const torrent)
{ {
if (!m_torrents.contains(torrent)) { Q_ASSERT(!m_torrentMap.contains(torrent));
const int row = m_torrents.size();
beginInsertRows(QModelIndex(), row, row); const int row = m_torrentList.size();
m_torrents << torrent;
beginInsertRows({}, row, row);
m_torrentList << torrent;
m_torrentMap[torrent] = row;
endInsertRows(); endInsertRows();
} }
}
Qt::ItemFlags TransferListModel::flags(const QModelIndex &index) const Qt::ItemFlags TransferListModel::flags(const QModelIndex &index) const
{ {
@ -295,29 +293,48 @@ BitTorrent::TorrentHandle *TransferListModel::torrentHandle(const QModelIndex &i
{ {
if (!index.isValid()) return nullptr; if (!index.isValid()) return nullptr;
return m_torrents.value(index.row()); return m_torrentList.value(index.row());
} }
void TransferListModel::handleTorrentAboutToBeRemoved(BitTorrent::TorrentHandle *const torrent) void TransferListModel::handleTorrentAboutToBeRemoved(BitTorrent::TorrentHandle *const torrent)
{ {
const int row = m_torrents.indexOf(torrent); const int row = m_torrentMap.value(torrent, -1);
if (row >= 0) { Q_ASSERT(row >= 0);
beginRemoveRows(QModelIndex(), row, row);
m_torrents.removeAt(row); beginRemoveRows({}, row, row);
endRemoveRows(); m_torrentList.removeAt(row);
m_torrentMap.remove(torrent);
for (int &value : m_torrentMap) {
if (value > row)
--value;
} }
endRemoveRows();
} }
void TransferListModel::handleTorrentStatusUpdated(BitTorrent::TorrentHandle *const torrent) void TransferListModel::handleTorrentStatusUpdated(BitTorrent::TorrentHandle *const torrent)
{ {
const int row = m_torrents.indexOf(torrent); const int row = m_torrentMap.value(torrent, -1);
if (row >= 0) Q_ASSERT(row >= 0);
emit dataChanged(index(row, 0), index(row, columnCount() - 1)); emit dataChanged(index(row, 0), index(row, columnCount() - 1));
} }
void TransferListModel::handleTorrentsUpdated() void TransferListModel::handleTorrentsUpdated(const QVector<BitTorrent::TorrentHandle *> &torrents)
{ {
emit dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1)); const int columns = (columnCount() - 1);
if (torrents.size() <= (m_torrentList.size() * 0.5)) {
for (BitTorrent::TorrentHandle *const torrent : torrents) {
const int row = m_torrentMap.value(torrent, -1);
Q_ASSERT(row >= 0);
emit dataChanged(index(row, 0), index(row, columns));
}
}
else {
// save the overhead when more than half of the torrent list needs update
emit dataChanged(index(0, 0), index((rowCount() - 1), columns));
}
} }
// Static functions // Static functions

9
src/gui/transferlistmodel.h

@ -84,8 +84,8 @@ public:
explicit TransferListModel(QObject *parent = nullptr); explicit TransferListModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &index = {}) const override; int rowCount(const QModelIndex &parent = {}) const override;
int columnCount(const QModelIndex &parent=QModelIndex()) const override; int columnCount(const QModelIndex &parent = {}) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
bool setData(const QModelIndex &index, const QVariant &value, int role) override; bool setData(const QModelIndex &index, const QVariant &value, int role) override;
QVariant headerData(int section, Qt::Orientation orientation, int role) const override; QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
@ -97,10 +97,11 @@ private slots:
void addTorrent(BitTorrent::TorrentHandle *const torrent); void addTorrent(BitTorrent::TorrentHandle *const torrent);
void handleTorrentAboutToBeRemoved(BitTorrent::TorrentHandle *const torrent); void handleTorrentAboutToBeRemoved(BitTorrent::TorrentHandle *const torrent);
void handleTorrentStatusUpdated(BitTorrent::TorrentHandle *const torrent); void handleTorrentStatusUpdated(BitTorrent::TorrentHandle *const torrent);
void handleTorrentsUpdated(); void handleTorrentsUpdated(const QVector<BitTorrent::TorrentHandle *> &torrents);
private: private:
QList<BitTorrent::TorrentHandle *> m_torrents; QList<BitTorrent::TorrentHandle *> m_torrentList; // maps row number to torrent handle
QHash<BitTorrent::TorrentHandle *, int> m_torrentMap; // maps torrent handle to row number
}; };
#endif // TRANSFERLISTMODEL_H #endif // TRANSFERLISTMODEL_H

Loading…
Cancel
Save