From baf9d210725cdf7fc638ad8072d93b2a61ae8b97 Mon Sep 17 00:00:00 2001 From: sledgehammer999 Date: Sat, 13 Sep 2014 16:02:32 +0300 Subject: [PATCH] Show stalled downloads that are uploading under the 'Active' filter. Closes #1654." --- src/src.pro | 8 ++- src/statussortfilterproxymodel.cpp | 90 ++++++++++++++++++++++++++++++ src/statussortfilterproxymodel.h | 52 +++++++++++++++++ src/torrentfilterenum.h | 37 ++++++++++++ src/transferlistfilterswidget.h | 13 +++-- src/transferlistwidget.cpp | 29 +--------- src/transferlistwidget.h | 5 +- 7 files changed, 196 insertions(+), 38 deletions(-) create mode 100644 src/statussortfilterproxymodel.cpp create mode 100644 src/statussortfilterproxymodel.h create mode 100644 src/torrentfilterenum.h diff --git a/src/src.pro b/src/src.pro index 91d47bf82..58f7f2c5b 100644 --- a/src/src.pro +++ b/src/src.pro @@ -111,7 +111,6 @@ HEADERS += misc.h \ smtp.h \ dnsupdater.h - SOURCES += main.cpp \ downloadthread.cpp \ scannedfoldersmodel.cpp \ @@ -153,7 +152,9 @@ nox { addnewtorrentdialog.h \ autoexpandabledialog.h \ statsdialog.h \ - messageboxraised.h + messageboxraised.h \ + statussortfilterproxymodel.h \ + torrentfilterenum.h SOURCES += mainwindow.cpp \ ico.cpp \ @@ -173,7 +174,8 @@ nox { addnewtorrentdialog.cpp \ autoexpandabledialog.cpp \ statsdialog.cpp \ - messageboxraised.cpp + messageboxraised.cpp \ + statussortfilterproxymodel.cpp win32 { HEADERS += programupdater.h diff --git a/src/statussortfilterproxymodel.cpp b/src/statussortfilterproxymodel.cpp new file mode 100644 index 000000000..5eb4d8ec7 --- /dev/null +++ b/src/statussortfilterproxymodel.cpp @@ -0,0 +1,90 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2014 sledgehammer999 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : hammered999@gmail.com + */ + +#include "statussortfilterproxymodel.h" +#include "torrentmodel.h" + +StatusSortFilterProxyModel::StatusSortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent), filter0(TorrentFilter::ALL) +{ +} + +void StatusSortFilterProxyModel::setFilterStatus(const TorrentFilter::TorrentFilter &filter) { + if (filter != filter0) { + filter0 = filter; + invalidateFilter(); + } +} + +TorrentFilter::TorrentFilter StatusSortFilterProxyModel::getFilterStatus() const { + return filter0; +} + +bool StatusSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { + if (filter0 == TorrentFilter::ALL) + return true; + QAbstractItemModel *model = sourceModel(); + if (!model) return false; + QModelIndex index = model->index(sourceRow, TorrentModelItem::TR_STATUS, sourceParent); + TorrentModelItem::State state = (TorrentModelItem::State)index.data().toInt(); + + switch (filter0) { + case TorrentFilter::DOWNLOADING: + return (state == TorrentModelItem::STATE_DOWNLOADING || state == TorrentModelItem::STATE_STALLED_DL + || state == TorrentModelItem::STATE_PAUSED_DL || state == TorrentModelItem::STATE_CHECKING_DL + || state == TorrentModelItem::STATE_QUEUED_DL || state == TorrentModelItem::STATE_DOWNLOADING_META); + + case TorrentFilter::COMPLETED: + return (state == TorrentModelItem::STATE_SEEDING || state == TorrentModelItem::STATE_STALLED_UP + || state == TorrentModelItem::STATE_PAUSED_UP || state == TorrentModelItem::STATE_CHECKING_UP + || state == TorrentModelItem::STATE_QUEUED_UP); + + case TorrentFilter::PAUSED: + return (state == TorrentModelItem::STATE_PAUSED_UP || state == TorrentModelItem::STATE_PAUSED_DL); + + case TorrentFilter::ACTIVE: + if (state == TorrentModelItem::STATE_STALLED_DL) { + const qulonglong up_speed = model->index(sourceRow, TorrentModelItem::TR_UPSPEED, sourceParent).data().toULongLong(); + return (up_speed > 0); + } + + return (state == TorrentModelItem::STATE_DOWNLOADING || state == TorrentModelItem::STATE_SEEDING); + + case TorrentFilter::INACTIVE: + if (state == TorrentModelItem::STATE_STALLED_DL) { + const qulonglong up_speed = model->index(sourceRow, TorrentModelItem::TR_UPSPEED, sourceParent).data().toULongLong(); + return !(up_speed > 0); + } + + return (state != TorrentModelItem::STATE_DOWNLOADING && state != TorrentModelItem::STATE_SEEDING); + + default: + return false; + } +} diff --git a/src/statussortfilterproxymodel.h b/src/statussortfilterproxymodel.h new file mode 100644 index 000000000..b5a5b1cec --- /dev/null +++ b/src/statussortfilterproxymodel.h @@ -0,0 +1,52 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2014 sledgehammer999 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : hammered999@gmail.com + */ + +#ifndef STATUSSORTFILTERPROXYMODEL_H +#define STATUSSORTFILTERPROXYMODEL_H + +#include +#include "torrentfilterenum.h" + +class StatusSortFilterProxyModel : public QSortFilterProxyModel { + Q_OBJECT + +public: + StatusSortFilterProxyModel(QObject *parent = 0); + void setFilterStatus(const TorrentFilter::TorrentFilter &filter); + TorrentFilter::TorrentFilter getFilterStatus() const; + +protected: + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; + +private: + TorrentFilter::TorrentFilter filter0; +}; + +#endif // STATUSSORTFILTERPROXYMODEL_H diff --git a/src/torrentfilterenum.h b/src/torrentfilterenum.h new file mode 100644 index 000000000..67e59b7e0 --- /dev/null +++ b/src/torrentfilterenum.h @@ -0,0 +1,37 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2014 sledgehammer999 + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. You must obey the GNU General Public + * License in all respects for all of the code used other than "OpenSSL". If you + * modify file(s), you may extend this exception to your version of the file(s), + * but you are not obligated to do so. If you do not wish to do so, delete this + * exception statement from your version. + * + * Contact : hammered999@gmail.com + */ + +#ifndef TORRENTFILTERENUM_H +#define TORRENTFILTERENUM_H + +namespace TorrentFilter { +enum TorrentFilter {ALL, DOWNLOADING, COMPLETED, PAUSED, ACTIVE, INACTIVE}; +} +#endif // TORRENTFILTERENUM_H diff --git a/src/transferlistfilterswidget.h b/src/transferlistfilterswidget.h index 9dfb925a0..0a03854b6 100644 --- a/src/transferlistfilterswidget.h +++ b/src/transferlistfilterswidget.h @@ -50,6 +50,7 @@ #include "iconprovider.h" #include "fs_utils.h" #include "autoexpandabledialog.h" +#include "torrentfilterenum.h" class LabelFiltersList: public QListWidget { Q_OBJECT @@ -301,12 +302,12 @@ public: protected slots: void updateTorrentNumbers() { const TorrentStatusReport report = transferList->getSourceModel()->getTorrentStatusReport(); - statusFilters->item(FILTER_ALL)->setData(Qt::DisplayRole, QVariant(tr("All")+" ("+QString::number(report.nb_active+report.nb_inactive)+")")); - statusFilters->item(FILTER_DOWNLOADING)->setData(Qt::DisplayRole, QVariant(tr("Downloading")+" ("+QString::number(report.nb_downloading)+")")); - statusFilters->item(FILTER_COMPLETED)->setData(Qt::DisplayRole, QVariant(tr("Completed")+" ("+QString::number(report.nb_seeding)+")")); - statusFilters->item(FILTER_PAUSED)->setData(Qt::DisplayRole, QVariant(tr("Paused")+" ("+QString::number(report.nb_paused)+")")); - statusFilters->item(FILTER_ACTIVE)->setData(Qt::DisplayRole, QVariant(tr("Active")+" ("+QString::number(report.nb_active)+")")); - statusFilters->item(FILTER_INACTIVE)->setData(Qt::DisplayRole, QVariant(tr("Inactive")+" ("+QString::number(report.nb_inactive)+")")); + statusFilters->item(TorrentFilter::ALL)->setData(Qt::DisplayRole, QVariant(tr("All")+" ("+QString::number(report.nb_active+report.nb_inactive)+")")); + statusFilters->item(TorrentFilter::DOWNLOADING)->setData(Qt::DisplayRole, QVariant(tr("Downloading")+" ("+QString::number(report.nb_downloading)+")")); + statusFilters->item(TorrentFilter::COMPLETED)->setData(Qt::DisplayRole, QVariant(tr("Completed")+" ("+QString::number(report.nb_seeding)+")")); + statusFilters->item(TorrentFilter::PAUSED)->setData(Qt::DisplayRole, QVariant(tr("Paused")+" ("+QString::number(report.nb_paused)+")")); + statusFilters->item(TorrentFilter::ACTIVE)->setData(Qt::DisplayRole, QVariant(tr("Active")+" ("+QString::number(report.nb_active)+")")); + statusFilters->item(TorrentFilter::INACTIVE)->setData(Qt::DisplayRole, QVariant(tr("Inactive")+" ("+QString::number(report.nb_inactive)+")")); } void torrentDropped(int row) { diff --git a/src/transferlistwidget.cpp b/src/transferlistwidget.cpp index fbe9a912d..40295b428 100644 --- a/src/transferlistwidget.cpp +++ b/src/transferlistwidget.cpp @@ -60,6 +60,7 @@ #include "iconprovider.h" #include "fs_utils.h" #include "autoexpandabledialog.h" +#include "statussortfilterproxymodel.h" using namespace libtorrent; @@ -84,11 +85,9 @@ TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *main_window, labelFilterModel->setFilterKeyColumn(TorrentModelItem::TR_LABEL); labelFilterModel->setFilterRole(Qt::DisplayRole); - statusFilterModel = new QSortFilterProxyModel(); + statusFilterModel = new StatusSortFilterProxyModel(); statusFilterModel->setDynamicSortFilter(true); statusFilterModel->setSourceModel(labelFilterModel); - statusFilterModel->setFilterKeyColumn(TorrentModelItem::TR_STATUS); - statusFilterModel->setFilterRole(Qt::DisplayRole); nameFilterModel = new TransferListSortModel(); nameFilterModel->setDynamicSortFilter(true); @@ -912,29 +911,7 @@ void TransferListWidget::applyNameFilter(const QString& name) { } void TransferListWidget::applyStatusFilter(int f) { - switch(f) { - case FILTER_DOWNLOADING: - statusFilterModel->setFilterRegExp(QRegExp(QString::number(TorrentModelItem::STATE_DOWNLOADING)+"|"+QString::number(TorrentModelItem::STATE_STALLED_DL)+"|"+ - QString::number(TorrentModelItem::STATE_PAUSED_DL)+"|"+QString::number(TorrentModelItem::STATE_CHECKING_DL)+"|"+ - QString::number(TorrentModelItem::STATE_QUEUED_DL)+"|"+QString::number(TorrentModelItem::STATE_DOWNLOADING_META), Qt::CaseSensitive)); - break; - case FILTER_COMPLETED: - statusFilterModel->setFilterRegExp(QRegExp(QString::number(TorrentModelItem::STATE_SEEDING)+"|"+QString::number(TorrentModelItem::STATE_STALLED_UP)+"|"+ - QString::number(TorrentModelItem::STATE_PAUSED_UP)+"|"+QString::number(TorrentModelItem::STATE_CHECKING_UP)+"|"+ - QString::number(TorrentModelItem::STATE_QUEUED_UP), Qt::CaseSensitive)); - break; - case FILTER_ACTIVE: - statusFilterModel->setFilterRegExp(QRegExp(QString::number(TorrentModelItem::STATE_DOWNLOADING)+"|"+QString::number(TorrentModelItem::STATE_SEEDING), Qt::CaseSensitive)); - break; - case FILTER_INACTIVE: - statusFilterModel->setFilterRegExp(QRegExp("[^"+QString::number(TorrentModelItem::STATE_DOWNLOADING)+QString::number(TorrentModelItem::STATE_SEEDING)+"]", Qt::CaseSensitive)); - break; - case FILTER_PAUSED: - statusFilterModel->setFilterRegExp(QRegExp(QString::number(TorrentModelItem::STATE_PAUSED_UP)+"|"+QString::number(TorrentModelItem::STATE_PAUSED_DL))); - break; - default: - statusFilterModel->setFilterRegExp(QRegExp()); - } + statusFilterModel->setFilterStatus((TorrentFilter::TorrentFilter)f); // Select first item if nothing is selected if (selectionModel()->selectedRows(0).empty() && nameFilterModel->rowCount() > 0) { qDebug("Nothing is selected, selecting first row: %s", qPrintable(nameFilterModel->index(0, TorrentModelItem::TR_NAME).data().toString())); diff --git a/src/transferlistwidget.h b/src/transferlistwidget.h index 73b1b8882..d4190cdbd 100644 --- a/src/transferlistwidget.h +++ b/src/transferlistwidget.h @@ -41,14 +41,13 @@ class QBtSession; class TransferListDelegate; class MainWindow; class TorrentModel; +class StatusSortFilterProxyModel; QT_BEGIN_NAMESPACE class QSortFilterProxyModel; class QStandardItemModel; QT_END_NAMESPACE -enum TorrentFilter {FILTER_ALL, FILTER_DOWNLOADING, FILTER_COMPLETED, FILTER_PAUSED, FILTER_ACTIVE, FILTER_INACTIVE}; - class TransferListWidget: public QTreeView { Q_OBJECT @@ -115,7 +114,7 @@ private: TransferListDelegate *listDelegate; TorrentModel *listModel; TransferListSortModel *nameFilterModel; - QSortFilterProxyModel *statusFilterModel; + StatusSortFilterProxyModel *statusFilterModel; QSortFilterProxyModel *labelFilterModel; QBtSession* BTSession; MainWindow *main_window;