qBittorrent
torrentcontentfiltermodel.cpp
Go to the documentation of this file.
1 /*
2  * Bittorrent Client using Qt and libtorrent.
3  * Copyright (C) 2006-2012 Christophe Dumez <chris@qbittorrent.org>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * In addition, as a special exception, the copyright holders give permission to
20  * link this program with the OpenSSL project's "OpenSSL" library (or with
21  * modified versions of it that use the same license as the "OpenSSL" library),
22  * and distribute the linked executables. You must obey the GNU General Public
23  * License in all respects for all of the code used other than "OpenSSL". If you
24  * modify file(s), you may extend this exception to your version of the file(s),
25  * but you are not obligated to do so. If you do not wish to do so, delete this
26  * exception statement from your version.
27  */
28 
30 
31 #include "torrentcontentmodel.h"
32 
34  : QSortFilterProxyModel(parent)
35  , m_model(new TorrentContentModel(this))
36 {
38  setSourceModel(m_model);
39  // Filter settings
40  setFilterKeyColumn(TorrentContentModelItem::COL_NAME);
42  setDynamicSortFilter(true);
43  setSortCaseSensitivity(Qt::CaseInsensitive);
45 }
46 
48 {
49  return m_model;
50 }
51 
53 {
54  return m_model->itemType(mapToSource(index));
55 }
56 
57 int TorrentContentFilterModel::getFileIndex(const QModelIndex &index) const
58 {
59  return m_model->getFileIndex(mapToSource(index));
60 }
61 
62 QModelIndex TorrentContentFilterModel::parent(const QModelIndex &child) const
63 {
64  if (!child.isValid()) return {};
65 
66  QModelIndex sourceParent = m_model->parent(mapToSource(child));
67  if (!sourceParent.isValid()) return {};
68 
69  return mapFromSource(sourceParent);
70 }
71 
72 bool TorrentContentFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
73 {
74  if (m_model->itemType(m_model->index(sourceRow, 0, sourceParent)) == TorrentContentModelItem::FolderType)
75  {
76  // accept folders if they have at least one filtered item
77  return hasFiltered(m_model->index(sourceRow, 0, sourceParent));
78  }
79 
80  return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
81 }
82 
83 bool TorrentContentFilterModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
84 {
85  switch (sortColumn())
86  {
88  {
89  const TorrentContentModelItem::ItemType leftType = m_model->itemType(m_model->index(left.row(), 0, left.parent()));
90  const TorrentContentModelItem::ItemType rightType = m_model->itemType(m_model->index(right.row(), 0, right.parent()));
91 
92  if (leftType == rightType)
93  {
94  const QString strL = left.data().toString();
95  const QString strR = right.data().toString();
96  return m_naturalLessThan(strL, strR);
97  }
98  if ((leftType == TorrentContentModelItem::FolderType) && (sortOrder() == Qt::AscendingOrder))
99  {
100  return true;
101  }
102 
103  return false;
104  }
105  default:
106  return QSortFilterProxyModel::lessThan(left, right);
107  };
108 }
109 
111 {
112  for (int i = 0; i < rowCount(); ++i)
113  setData(index(i, 0), Qt::Checked, Qt::CheckStateRole);
114 
115  emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
116 }
117 
119 {
120  for (int i = 0; i < rowCount(); ++i)
121  setData(index(i, 0), Qt::Unchecked, Qt::CheckStateRole);
122 
123  emit dataChanged(index(0, 0), index((rowCount() - 1), (columnCount() - 1)));
124 }
125 
126 bool TorrentContentFilterModel::hasFiltered(const QModelIndex &folder) const
127 {
128  // this should be called only with folders
129  // check if the folder name itself matches the filter string
130  QString name = folder.data().toString();
131  if (name.contains(filterRegularExpression()))
132  return true;
133  for (int child = 0; child < m_model->rowCount(folder); ++child)
134  {
135  QModelIndex childIndex = m_model->index(child, 0, folder);
136  if (m_model->hasChildren(childIndex))
137  {
138  if (hasFiltered(childIndex))
139  return true;
140  continue;
141  }
142  name = childIndex.data().toString();
143  if (name.contains(filterRegularExpression()))
144  return true;
145  }
146 
147  return false;
148 }
TorrentContentFilterModel(QObject *parent=nullptr)
TorrentContentModelItem::ItemType itemType(const QModelIndex &index) const
TorrentContentModel * model() const
Utils::Compare::NaturalLessThan< Qt::CaseInsensitive > m_naturalLessThan
int getFileIndex(const QModelIndex &index) const
bool hasFiltered(const QModelIndex &folder) const
QModelIndex parent(const QModelIndex &child) const override
bool lessThan(const QModelIndex &left, const QModelIndex &right) const override
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override
TorrentContentModelItem::ItemType itemType(const QModelIndex &index) const
QModelIndex index(int row, int column, const QModelIndex &parent={}) const override
int getFileIndex(const QModelIndex &index)
QModelIndex parent(const QModelIndex &index) const override
int rowCount(const QModelIndex &parent={}) const override