diff --git a/src/qtlibtorrent/torrentmodel.cpp b/src/qtlibtorrent/torrentmodel.cpp index eb819ee03..9234a1138 100644 --- a/src/qtlibtorrent/torrentmodel.cpp +++ b/src/qtlibtorrent/torrentmodel.cpp @@ -508,7 +508,6 @@ void TorrentModel::setRefreshInterval(int refreshInterval) void TorrentModel::forceModelRefresh() { - emit dataChanged(index(0, 0), index(rowCount()-1, columnCount()-1)); QBtSession::instance()->postTorrentUpdate(); } @@ -591,9 +590,13 @@ void TorrentModel::stateUpdated(const std::vector &s libtorrent::torrent_status const& status = *i; const int row = torrentRow(misc::toQString(status.info_hash)); - if (row >= 0) + if (row >= 0) { m_torrents[row]->refreshStatus(status); + notifyTorrentChanged(row); + } } + + emit modelRefreshed(); } bool TorrentModel::inhibitSystem() diff --git a/src/qtlibtorrent/torrentmodel.h b/src/qtlibtorrent/torrentmodel.h index e62fce743..8bebce656 100644 --- a/src/qtlibtorrent/torrentmodel.h +++ b/src/qtlibtorrent/torrentmodel.h @@ -57,7 +57,7 @@ public: inline int columnCount() const { return NB_COLUMNS; } QVariant data(int column, int role = Qt::DisplayRole) const; bool setData(int column, const QVariant &value, int role = Qt::DisplayRole); - inline QString hash() const { return m_hash; } + inline QString const& hash() const { return m_hash; } State state() const; signals: @@ -101,6 +101,7 @@ signals: void torrentAdded(TorrentModelItem *torrentItem); void torrentAboutToBeRemoved(TorrentModelItem *torrentItem); void torrentChangedLabel(TorrentModelItem *torrentItem, QString previous, QString current); + void modelRefreshed(); private slots: void addTorrent(const QTorrentHandle& h); diff --git a/src/src.pro b/src/src.pro index b00956a2e..34eb13e7b 100644 --- a/src/src.pro +++ b/src/src.pro @@ -154,12 +154,12 @@ nox { autoexpandabledialog.h \ statsdialog.h \ messageboxraised.h \ - statussortfilterproxymodel.h \ torrentfilterenum.h SOURCES += mainwindow.cpp \ ico.cpp \ transferlistwidget.cpp \ + transferlistsortmodel.cpp \ transferlistdelegate.cpp \ transferlistfilterswidget.cpp \ torrentcontentmodel.cpp \ @@ -178,7 +178,6 @@ nox { autoexpandabledialog.cpp \ statsdialog.cpp \ messageboxraised.cpp \ - statussortfilterproxymodel.cpp \ statusbar.cpp \ trackerlogin.cpp diff --git a/src/statussortfilterproxymodel.cpp b/src/statussortfilterproxymodel.cpp deleted file mode 100644 index 5eb4d8ec7..000000000 --- a/src/statussortfilterproxymodel.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * 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 deleted file mode 100644 index b5a5b1cec..000000000 --- a/src/statussortfilterproxymodel.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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/transferlistfilterswidget.cpp b/src/transferlistfilterswidget.cpp index 21618c429..f52f13d5a 100644 --- a/src/transferlistfilterswidget.cpp +++ b/src/transferlistfilterswidget.cpp @@ -203,7 +203,7 @@ TransferListFiltersWidget::TransferListFiltersWidget(QWidget *parent, TransferLi // SIGNAL/SLOT connect(statusFilters, SIGNAL(currentRowChanged(int)), transferList, SLOT(applyStatusFilter(int))); - connect(transferList->getSourceModel(), SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(updateTorrentNumbers())); + connect(transferList->getSourceModel(), SIGNAL(modelRefreshed()), SLOT(updateTorrentNumbers())); connect(transferList->getSourceModel(), SIGNAL(torrentAdded(TorrentModelItem*)), SLOT(handleNewTorrent(TorrentModelItem*))); connect(labelFilters, SIGNAL(currentRowChanged(int)), this, SLOT(applyLabelFilter(int))); connect(labelFilters, SIGNAL(torrentDropped(int)), this, SLOT(torrentDropped(int))); @@ -359,10 +359,10 @@ void TransferListFiltersWidget::removeSelectedLabel() { void TransferListFiltersWidget::applyLabelFilter(int row) { switch(row) { case 0: - transferList->applyLabelFilter("all"); + transferList->applyLabelFilterAll(); break; case 1: - transferList->applyLabelFilter("none"); + transferList->applyLabelFilter(QString()); break; default: transferList->applyLabelFilter(labelFilters->labelFromRow(row)); diff --git a/src/transferlistsortmodel.cpp b/src/transferlistsortmodel.cpp new file mode 100644 index 000000000..56e5cf79c --- /dev/null +++ b/src/transferlistsortmodel.cpp @@ -0,0 +1,255 @@ +/* + * Bittorrent Client using Qt4 and libtorrent. + * Copyright (C) 2013 Nick Tiskov + * + * 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 : daymansmail@gmail.com + */ + +#include "transferlistsortmodel.h" + +#include "torrentmodel.h" +#include "misc.h" + +TransferListSortModel::TransferListSortModel(QObject *parent) + : QSortFilterProxyModel(parent) + , filter0(TorrentFilter::ALL) +{} + +void TransferListSortModel::setStatusFilter(const TorrentFilter::TorrentFilter &filter) { + if (filter != filter0) { + filter0 = filter; + invalidateFilter(); + } +} + +void TransferListSortModel::setLabelFilter(QString const& label) { + if (!labelFilterEnabled || labelFilter != label) { + labelFilterEnabled = true; + labelFilter = label; + invalidateFilter(); + } +} + +void TransferListSortModel::disableLabelFilter() { + if (labelFilterEnabled) { + labelFilterEnabled = false; + labelFilter = QString(); + invalidateFilter(); + } +} + +bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { + const int column = sortColumn(); + + if (column == TorrentModelItem::TR_NAME) { + QVariant vL = left.data(); + QVariant vR = right.data(); + if (!(vL.isValid() && vR.isValid())) + return QSortFilterProxyModel::lessThan(left, right); + Q_ASSERT(vL.isValid()); + Q_ASSERT(vR.isValid()); + + bool res = false; + if (misc::naturalSort(vL.toString(), vR.toString(), res)) + return res; + + return QSortFilterProxyModel::lessThan(left, right); + } + else if (column == TorrentModelItem::TR_ADD_DATE || column == TorrentModelItem::TR_SEED_DATE || column == TorrentModelItem::TR_SEEN_COMPLETE_DATE) { + QDateTime vL = left.data().toDateTime(); + QDateTime vR = right.data().toDateTime(); + + //not valid dates should be sorted at the bottom. + if (!vL.isValid()) return false; + if (!vR.isValid()) return true; + + return vL < vR; + } + else if (column == TorrentModelItem::TR_PRIORITY) { + const int vL = left.data().toInt(); + const int vR = right.data().toInt(); + + // Seeding torrents should be sorted by their completed date instead. + if (vL == -1 && vR == -1) { + QAbstractItemModel *model = sourceModel(); + const QDateTime dateL = model->data(model->index(left.row(), TorrentModelItem::TR_SEED_DATE)).toDateTime(); + const QDateTime dateR = model->data(model->index(right.row(), TorrentModelItem::TR_SEED_DATE)).toDateTime(); + + //not valid dates should be sorted at the bottom. + if (!dateL.isValid()) return false; + if (!dateR.isValid()) return true; + + return dateL < dateR; + } + + // Seeding torrents should be at the bottom + if (vL == -1) return false; + if (vR == -1) return true; + return vL < vR; + } + else if (column == TorrentModelItem::TR_PEERS || column == TorrentModelItem::TR_SEEDS) { + int left_active = left.data().toInt(); + int left_total = left.data(Qt::UserRole).toInt(); + int right_active = right.data().toInt(); + int right_total = right.data(Qt::UserRole).toInt(); + + // Active peers/seeds take precedence over total peers/seeds. + if (left_active == right_active) + return (left_total < right_total); + else return (left_active < right_active); + } + else if (column == TorrentModelItem::TR_ETA) { + const QAbstractItemModel *model = sourceModel(); + const int prioL = model->data(model->index(left.row(), TorrentModelItem::TR_PRIORITY)).toInt(); + const int prioR = model->data(model->index(right.row(), TorrentModelItem::TR_PRIORITY)).toInt(); + const qlonglong etaL = left.data().toLongLong(); + const qlonglong etaR = right.data().toLongLong(); + const bool ascend = (sortOrder() == Qt::AscendingOrder); + const bool invalidL = (etaL < 0 || etaL >= MAX_ETA); + const bool invalidR = (etaR < 0 || etaR >= MAX_ETA); + const bool seedingL = (prioL < 0); + const bool seedingR = (prioR < 0); + bool activeL; + bool activeR; + + switch (model->data(model->index(left.row(), TorrentModelItem::TR_STATUS)).toInt()) { + case TorrentModelItem::STATE_DOWNLOADING: + case TorrentModelItem::STATE_DOWNLOADING_META: + case TorrentModelItem::STATE_STALLED_DL: + case TorrentModelItem::STATE_SEEDING: + case TorrentModelItem::STATE_STALLED_UP: + activeL = true; + break; + default: + activeL = false; + } + + switch (model->data(model->index(right.row(), TorrentModelItem::TR_STATUS)).toInt()) { + case TorrentModelItem::STATE_DOWNLOADING: + case TorrentModelItem::STATE_DOWNLOADING_META: + case TorrentModelItem::STATE_STALLED_DL: + case TorrentModelItem::STATE_SEEDING: + case TorrentModelItem::STATE_STALLED_UP: + activeR = true; + break; + default: + activeR = false; + } + + // Sorting rules prioritized. + // 1. Active torrents at the top + // 2. Seeding torrents at the bottom + // 3. Torrents with invalid ETAs at the bottom + + if (activeL != activeR) return activeL; + if (seedingL != seedingR) { + if (seedingL) return !ascend; + else return ascend; + } + + if (invalidL && invalidR) { + + if (seedingL) { //Both seeding + QDateTime dateL = model->data(model->index(left.row(), TorrentModelItem::TR_SEED_DATE)).toDateTime(); + QDateTime dateR = model->data(model->index(right.row(), TorrentModelItem::TR_SEED_DATE)).toDateTime(); + + //not valid dates should be sorted at the bottom. + if (!dateL.isValid()) return false; + if (!dateR.isValid()) return true; + + return dateL < dateR; + } + else + return prioL < prioR; + } + else if ((invalidL == false) && (invalidR == false)) + return QSortFilterProxyModel::lessThan(left, right); + else + return !invalidL; + } + + return QSortFilterProxyModel::lessThan(left, right); +} + +bool TransferListSortModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { + return matchStatusFilter(sourceRow, sourceParent) + && matchLabelFilter(sourceRow, sourceParent) + && QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); +} + +bool TransferListSortModel::matchStatusFilter(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; + } +} + +bool TransferListSortModel::matchLabelFilter(int sourceRow, const QModelIndex &sourceParent) const { + if (!labelFilterEnabled) + return true; + + QAbstractItemModel *model = sourceModel(); + if (!model) + return false; + + return model->index(sourceRow, TorrentModelItem::TR_LABEL, sourceParent).data().toString() == labelFilter; +} diff --git a/src/transferlistsortmodel.h b/src/transferlistsortmodel.h index 7414172c4..e8d35d6f9 100644 --- a/src/transferlistsortmodel.h +++ b/src/transferlistsortmodel.h @@ -32,148 +32,30 @@ #define TRANSFERLISTSORTMODEL_H #include -#include "torrentmodel.h" -#include "misc.h" +#include "torrentfilterenum.h" class TransferListSortModel : public QSortFilterProxyModel { Q_OBJECT public: - TransferListSortModel(QObject *parent = 0) : QSortFilterProxyModel(parent) {} + TransferListSortModel(QObject *parent = 0); -protected: - virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const { - const int column = sortColumn(); + void setStatusFilter(const TorrentFilter::TorrentFilter &filter); + void setLabelFilter(QString const& label); + void disableLabelFilter(); - if (column == TorrentModelItem::TR_NAME) { - QVariant vL = left.data(); - QVariant vR = right.data(); - if (!(vL.isValid() && vR.isValid())) - return QSortFilterProxyModel::lessThan(left, right); - Q_ASSERT(vL.isValid()); - Q_ASSERT(vR.isValid()); +private: + bool lessThan(const QModelIndex &left, const QModelIndex &right) const; + bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; - bool res = false; - if (misc::naturalSort(vL.toString(), vR.toString(), res)) - return res; + bool matchStatusFilter(int sourceRow, const QModelIndex &sourceParent) const; + bool matchLabelFilter(int sourceRow, const QModelIndex &sourceParent) const; - return QSortFilterProxyModel::lessThan(left, right); - } - else if (column == TorrentModelItem::TR_ADD_DATE || column == TorrentModelItem::TR_SEED_DATE || column == TorrentModelItem::TR_SEEN_COMPLETE_DATE) { - QDateTime vL = left.data().toDateTime(); - QDateTime vR = right.data().toDateTime(); +private: + TorrentFilter::TorrentFilter filter0; - //not valid dates should be sorted at the bottom. - if (!vL.isValid()) return false; - if (!vR.isValid()) return true; - - return vL < vR; - } - else if (column == TorrentModelItem::TR_PRIORITY) { - const int vL = left.data().toInt(); - const int vR = right.data().toInt(); - - // Seeding torrents should be sorted by their completed date instead. - if (vL == -1 && vR == -1) { - QAbstractItemModel *model = sourceModel(); - const QDateTime dateL = model->data(model->index(left.row(), TorrentModelItem::TR_SEED_DATE)).toDateTime(); - const QDateTime dateR = model->data(model->index(right.row(), TorrentModelItem::TR_SEED_DATE)).toDateTime(); - - //not valid dates should be sorted at the bottom. - if (!dateL.isValid()) return false; - if (!dateR.isValid()) return true; - - return dateL < dateR; - } - - // Seeding torrents should be at the bottom - if (vL == -1) return false; - if (vR == -1) return true; - return vL < vR; - } - else if (column == TorrentModelItem::TR_PEERS || column == TorrentModelItem::TR_SEEDS) { - int left_active = left.data().toInt(); - int left_total = left.data(Qt::UserRole).toInt(); - int right_active = right.data().toInt(); - int right_total = right.data(Qt::UserRole).toInt(); - - // Active peers/seeds take precedence over total peers/seeds. - if (left_active == right_active) - return (left_total < right_total); - else return (left_active < right_active); - } - else if (column == TorrentModelItem::TR_ETA) { - const QAbstractItemModel *model = sourceModel(); - const int prioL = model->data(model->index(left.row(), TorrentModelItem::TR_PRIORITY)).toInt(); - const int prioR = model->data(model->index(right.row(), TorrentModelItem::TR_PRIORITY)).toInt(); - const qlonglong etaL = left.data().toLongLong(); - const qlonglong etaR = right.data().toLongLong(); - const bool ascend = (sortOrder() == Qt::AscendingOrder); - const bool invalidL = (etaL < 0 || etaL >= MAX_ETA); - const bool invalidR = (etaR < 0 || etaR >= MAX_ETA); - const bool seedingL = (prioL < 0); - const bool seedingR = (prioR < 0); - bool activeL; - bool activeR; - - switch (model->data(model->index(left.row(), TorrentModelItem::TR_STATUS)).toInt()) { - case TorrentModelItem::STATE_DOWNLOADING: - case TorrentModelItem::STATE_DOWNLOADING_META: - case TorrentModelItem::STATE_STALLED_DL: - case TorrentModelItem::STATE_SEEDING: - case TorrentModelItem::STATE_STALLED_UP: - activeL = true; - break; - default: - activeL = false; - } - - switch (model->data(model->index(right.row(), TorrentModelItem::TR_STATUS)).toInt()) { - case TorrentModelItem::STATE_DOWNLOADING: - case TorrentModelItem::STATE_DOWNLOADING_META: - case TorrentModelItem::STATE_STALLED_DL: - case TorrentModelItem::STATE_SEEDING: - case TorrentModelItem::STATE_STALLED_UP: - activeR = true; - break; - default: - activeR = false; - } - - // Sorting rules prioritized. - // 1. Active torrents at the top - // 2. Seeding torrents at the bottom - // 3. Torrents with invalid ETAs at the bottom - - if (activeL != activeR) return activeL; - if (seedingL != seedingR) { - if (seedingL) return !ascend; - else return ascend; - } - - if (invalidL && invalidR) { - - if (seedingL) { //Both seeding - QDateTime dateL = model->data(model->index(left.row(), TorrentModelItem::TR_SEED_DATE)).toDateTime(); - QDateTime dateR = model->data(model->index(right.row(), TorrentModelItem::TR_SEED_DATE)).toDateTime(); - - //not valid dates should be sorted at the bottom. - if (!dateL.isValid()) return false; - if (!dateR.isValid()) return true; - - return dateL < dateR; - } - else - return prioL < prioR; - } - else if ((invalidL == false) && (invalidR == false)) - return QSortFilterProxyModel::lessThan(left, right); - else - return !invalidL; - } - - return QSortFilterProxyModel::lessThan(left, right); - } + bool labelFilterEnabled; + QString labelFilter; }; #endif // TRANSFERLISTSORTMODEL_H diff --git a/src/transferlistwidget.cpp b/src/transferlistwidget.cpp index f8e435a09..00a99ac61 100644 --- a/src/transferlistwidget.cpp +++ b/src/transferlistwidget.cpp @@ -63,7 +63,6 @@ #include "iconprovider.h" #include "fs_utils.h" #include "autoexpandabledialog.h" -#include "statussortfilterproxymodel.h" #include "transferlistsortmodel.h" using namespace libtorrent; @@ -82,20 +81,9 @@ TransferListWidget::TransferListWidget(QWidget *parent, MainWindow *main_window, // Create transfer list model listModel = new TorrentModel(this); - // Set Sort/Filter proxy - labelFilterModel = new QSortFilterProxyModel(); - labelFilterModel->setDynamicSortFilter(true); - labelFilterModel->setSourceModel(listModel); - labelFilterModel->setFilterKeyColumn(TorrentModelItem::TR_LABEL); - labelFilterModel->setFilterRole(Qt::DisplayRole); - - statusFilterModel = new StatusSortFilterProxyModel(); - statusFilterModel->setDynamicSortFilter(true); - statusFilterModel->setSourceModel(labelFilterModel); - nameFilterModel = new TransferListSortModel(); nameFilterModel->setDynamicSortFilter(true); - nameFilterModel->setSourceModel(statusFilterModel); + nameFilterModel->setSourceModel(listModel); nameFilterModel->setFilterKeyColumn(TorrentModelItem::TR_NAME); nameFilterModel->setFilterRole(Qt::DisplayRole); nameFilterModel->setSortCaseSensitivity(Qt::CaseInsensitive); @@ -170,8 +158,6 @@ TransferListWidget::~TransferListWidget() { // Save settings saveSettings(); // Clean up - delete labelFilterModel; - delete statusFilterModel; delete nameFilterModel; delete listModel; delete listDelegate; @@ -204,16 +190,14 @@ inline QString TransferListWidget::getHashFromRow(int row) const { inline QModelIndex TransferListWidget::mapToSource(const QModelIndex &index) const { Q_ASSERT(index.isValid()); if (index.model() == nameFilterModel) - return labelFilterModel->mapToSource(statusFilterModel->mapToSource(nameFilterModel->mapToSource(index))); - if (index.model() == statusFilterModel) - return labelFilterModel->mapToSource(statusFilterModel->mapToSource(index)); - return labelFilterModel->mapToSource(index); + return nameFilterModel->mapToSource(index); + return index; } inline QModelIndex TransferListWidget::mapFromSource(const QModelIndex &index) const { Q_ASSERT(index.isValid()); - Q_ASSERT(index.model() == labelFilterModel); - return nameFilterModel->mapFromSource(statusFilterModel->mapFromSource(labelFilterModel->mapFromSource(index))); + Q_ASSERT(index.model() == nameFilterModel); + return nameFilterModel->mapFromSource(index); } void TransferListWidget::torrentDoubleClicked(const QModelIndex& index) { @@ -901,17 +885,13 @@ void TransferListWidget::currentChanged(const QModelIndex& current, const QModel emit currentTorrentChanged(h); } +void TransferListWidget::applyLabelFilterAll() { + nameFilterModel->disableLabelFilter(); +} + void TransferListWidget::applyLabelFilter(QString label) { - if (label == "all") { - labelFilterModel->setFilterRegExp(QRegExp()); - return; - } - if (label == "none") { - labelFilterModel->setFilterRegExp(QRegExp("^$")); - return; - } qDebug("Applying Label filter: %s", qPrintable(label)); - labelFilterModel->setFilterRegExp(QRegExp("^" + QRegExp::escape(label) + "$", Qt::CaseSensitive)); + nameFilterModel->setLabelFilter(label); } void TransferListWidget::applyNameFilter(const QString& name) { @@ -919,7 +899,7 @@ void TransferListWidget::applyNameFilter(const QString& name) { } void TransferListWidget::applyStatusFilter(int f) { - statusFilterModel->setFilterStatus((TorrentFilter::TorrentFilter)f); + nameFilterModel->setStatusFilter((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 a07e6123a..47f1773e0 100644 --- a/src/transferlistwidget.h +++ b/src/transferlistwidget.h @@ -40,7 +40,6 @@ class MainWindow; class TransferListDelegate; class TransferListSortModel; class TorrentModel; -class StatusSortFilterProxyModel; QT_BEGIN_NAMESPACE class QShortcut; @@ -81,6 +80,7 @@ public slots: void displayDLHoSMenu(const QPoint&); void applyNameFilter(const QString& name); void applyStatusFilter(int f); + void applyLabelFilterAll(); void applyLabelFilter(QString label); void previewFile(QString filePath); void removeLabelFromRows(QString label); @@ -114,8 +114,6 @@ private: TransferListDelegate *listDelegate; TorrentModel *listModel; TransferListSortModel *nameFilterModel; - StatusSortFilterProxyModel *statusFilterModel; - QSortFilterProxyModel *labelFilterModel; QBtSession* BTSession; MainWindow *main_window; QShortcut *editHotkey;