From f235c0ae6ca3bca45ad3e28e37e5ae178ae09c11 Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Sun, 9 Nov 2014 02:49:21 +0300 Subject: [PATCH] Merge label filter into TransferListSortModel This also fixes a bug that when label filter contains special symbols from regex, the label filter may match torrents with multiple different labels. --- src/transferlistsortmodel.cpp | 28 ++++++++++++++++++++++++++++ src/transferlistsortmodel.h | 6 ++++++ src/transferlistwidget.cpp | 24 ++++++++---------------- src/transferlistwidget.h | 1 - 4 files changed, 42 insertions(+), 17 deletions(-) diff --git a/src/transferlistsortmodel.cpp b/src/transferlistsortmodel.cpp index d74b3c818..56e5cf79c 100644 --- a/src/transferlistsortmodel.cpp +++ b/src/transferlistsortmodel.cpp @@ -45,6 +45,22 @@ void TransferListSortModel::setStatusFilter(const TorrentFilter::TorrentFilter & } } +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(); @@ -180,6 +196,7 @@ bool TransferListSortModel::lessThan(const QModelIndex &left, const QModelIndex bool TransferListSortModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { return matchStatusFilter(sourceRow, sourceParent) + && matchLabelFilter(sourceRow, sourceParent) && QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent); } @@ -225,3 +242,14 @@ bool TransferListSortModel::matchStatusFilter(int sourceRow, const QModelIndex & 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 a0e261efb..e8d35d6f9 100644 --- a/src/transferlistsortmodel.h +++ b/src/transferlistsortmodel.h @@ -41,15 +41,21 @@ public: TransferListSortModel(QObject *parent = 0); void setStatusFilter(const TorrentFilter::TorrentFilter &filter); + void setLabelFilter(QString const& label); + void disableLabelFilter(); private: bool lessThan(const QModelIndex &left, const QModelIndex &right) const; bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; bool matchStatusFilter(int sourceRow, const QModelIndex &sourceParent) const; + bool matchLabelFilter(int sourceRow, const QModelIndex &sourceParent) const; private: TorrentFilter::TorrentFilter filter0; + + bool labelFilterEnabled; + QString labelFilter; }; #endif // TRANSFERLISTSORTMODEL_H diff --git a/src/transferlistwidget.cpp b/src/transferlistwidget.cpp index abd0bea0c..269da5670 100644 --- a/src/transferlistwidget.cpp +++ b/src/transferlistwidget.cpp @@ -81,16 +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); - nameFilterModel = new TransferListSortModel(); nameFilterModel->setDynamicSortFilter(true); - nameFilterModel->setSourceModel(labelFilterModel); + nameFilterModel->setSourceModel(listModel); nameFilterModel->setFilterKeyColumn(TorrentModelItem::TR_NAME); nameFilterModel->setFilterRole(Qt::DisplayRole); nameFilterModel->setSortCaseSensitivity(Qt::CaseInsensitive); @@ -165,7 +158,6 @@ TransferListWidget::~TransferListWidget() { // Save settings saveSettings(); // Clean up - delete labelFilterModel; delete nameFilterModel; delete listModel; delete listDelegate; @@ -198,14 +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(nameFilterModel->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(labelFilterModel->mapFromSource(index)); + Q_ASSERT(index.model() == nameFilterModel); + return nameFilterModel->mapFromSource(index); } void TransferListWidget::torrentDoubleClicked(const QModelIndex& index) { @@ -895,15 +887,15 @@ void TransferListWidget::currentChanged(const QModelIndex& current, const QModel void TransferListWidget::applyLabelFilter(QString label) { if (label == "all") { - labelFilterModel->setFilterRegExp(QRegExp()); + nameFilterModel->disableLabelFilter(); return; } if (label == "none") { - labelFilterModel->setFilterRegExp(QRegExp("^$")); + nameFilterModel->setLabelFilter(QString()); 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) { diff --git a/src/transferlistwidget.h b/src/transferlistwidget.h index 8ddc27900..b593e4f31 100644 --- a/src/transferlistwidget.h +++ b/src/transferlistwidget.h @@ -113,7 +113,6 @@ private: TransferListDelegate *listDelegate; TorrentModel *listModel; TransferListSortModel *nameFilterModel; - QSortFilterProxyModel *labelFilterModel; QBtSession* BTSession; MainWindow *main_window; QShortcut *editHotkey;