mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-11-28 13:28:50 +03:00
Merge pull request #11085 from Chocobo1/model
Better on-demand reloading of torrent data
This commit is contained in:
commit
62a3938480
10 changed files with 95 additions and 73 deletions
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,12 +271,14 @@ 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;
|
|
||||||
endInsertRows();
|
beginInsertRows({}, row, row);
|
||||||
}
|
m_torrentList << torrent;
|
||||||
|
m_torrentMap[torrent] = row;
|
||||||
|
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
|
||||||
|
|
|
@ -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…
Reference in a new issue