Akonadi

entitymimetypefiltermodel.cpp
1 /*
2  SPDX-FileCopyrightText: 2007 Bruno Virlet <[email protected]>
3  SPDX-FileCopyrightText: 2009 Stephen Kelly <[email protected]>
4 
5  SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7 
8 #include "entitymimetypefiltermodel.h"
9 #include "akonadicore_debug.h"
10 #include "entitytreemodel.h"
11 #include "mimetypechecker.h"
12 
13 #include <QString>
14 #include <QStringList>
15 
16 using namespace Akonadi;
17 
18 namespace Akonadi
19 {
23 class EntityMimeTypeFilterModelPrivate
24 {
25 public:
26  explicit EntityMimeTypeFilterModelPrivate(EntityMimeTypeFilterModel *parent)
27  : q_ptr(parent)
28  , m_headerGroup(EntityTreeModel::EntityTreeHeaders)
29  {
30  }
31 
32  Q_DECLARE_PUBLIC(EntityMimeTypeFilterModel)
34 
35  QStringList includedMimeTypes;
36  QStringList excludedMimeTypes;
37 
38  QPersistentModelIndex m_rootIndex;
39 
40  EntityTreeModel::HeaderGroup m_headerGroup;
41 };
42 
43 } // namespace Akonadi
44 
46  : QSortFilterProxyModel(parent)
47  , d_ptr(new EntityMimeTypeFilterModelPrivate(this))
48 {
49 }
50 
52 {
53  delete d_ptr;
54 }
55 
57 {
59  d->includedMimeTypes << typeList;
60  invalidateFilter();
61 }
62 
64 {
66  d->excludedMimeTypes << typeList;
67  invalidateFilter();
68 }
69 
71 {
73  d->includedMimeTypes << type;
74  invalidateFilter();
75 }
76 
78 {
80  d->excludedMimeTypes << type;
81  invalidateFilter();
82 }
83 
84 bool EntityMimeTypeFilterModel::filterAcceptsColumn(int sourceColumn, const QModelIndex &sourceParent) const
85 {
86  if (sourceColumn >= columnCount(mapFromSource(sourceParent))) {
87  return false;
88  }
89  return QSortFilterProxyModel::filterAcceptsColumn(sourceColumn, sourceParent);
90 }
91 
92 bool EntityMimeTypeFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
93 {
94  Q_D(const EntityMimeTypeFilterModel);
95  const QModelIndex idx = sourceModel()->index(sourceRow, 0, sourceParent);
96 
97  const QString rowMimetype = idx.data(EntityTreeModel::MimeTypeRole).toString();
98 
99  if (d->excludedMimeTypes.contains(rowMimetype)) {
100  return false;
101  }
102 
103  if (d->includedMimeTypes.isEmpty() || d->includedMimeTypes.contains(rowMimetype)) {
104  const Akonadi::Item item = idx.data(EntityTreeModel::ItemRole).value<Akonadi::Item>();
105 
106  if (item.isValid() && !item.hasPayload()) {
107  qCDebug(AKONADICORE_LOG) << "Item " << item.id() << " doesn't have payload";
108  return false;
109  }
110 
111  return true;
112  }
113 
114  return false;
115 }
116 
118 {
119  Q_D(const EntityMimeTypeFilterModel);
120  return d->includedMimeTypes;
121 }
122 
124 {
125  Q_D(const EntityMimeTypeFilterModel);
126  return d->excludedMimeTypes;
127 }
128 
130 {
132  d->includedMimeTypes.clear();
133  d->excludedMimeTypes.clear();
134  invalidateFilter();
135 }
136 
138 {
140  d->m_headerGroup = headerGroup;
141 }
142 
143 QVariant EntityMimeTypeFilterModel::headerData(int section, Qt::Orientation orientation, int role) const
144 {
145  if (!sourceModel()) {
146  return QVariant();
147  }
148 
149  Q_D(const EntityMimeTypeFilterModel);
150  role += (EntityTreeModel::TerminalUserRole * d->m_headerGroup);
151  return sourceModel()->headerData(section, orientation, role);
152 }
153 
154 QModelIndexList EntityMimeTypeFilterModel::match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const
155 {
156  if (!sourceModel()) {
157  return QModelIndexList();
158  }
159 
160  if (role < Qt::UserRole) {
161  return QSortFilterProxyModel::match(start, role, value, hits, flags);
162  }
163 
164  QModelIndexList list;
165  QModelIndex proxyIndex;
166  const auto matches = sourceModel()->match(mapToSource(start), role, value, hits, flags);
167  for (const auto &idx: matches) {
168  proxyIndex = mapFromSource(idx);
169  if (proxyIndex.isValid()) {
170  list.push_back(proxyIndex);
171  }
172  }
173 
174  return list;
175 }
176 
177 int EntityMimeTypeFilterModel::columnCount(const QModelIndex &parent) const
178 {
179  Q_D(const EntityMimeTypeFilterModel);
180 
181  if (!sourceModel()) {
182  return 0;
183  }
184 
185  const QVariant value = sourceModel()->data(mapToSource(parent), EntityTreeModel::ColumnCountRole + (EntityTreeModel::TerminalUserRole * d->m_headerGroup));
186  if (!value.isValid()) {
187  return 0;
188  }
189 
190  return value.toInt();
191 }
192 
193 bool EntityMimeTypeFilterModel::hasChildren(const QModelIndex &parent) const
194 {
195  if (!sourceModel()) {
196  return false;
197  }
198 
199  // QSortFilterProxyModel implementation is buggy in that it emits rowsAboutToBeInserted etc
200  // only after the source model has emitted rowsInserted, instead of emitting it when the
201  // source model emits rowsAboutToBeInserted. That means that the source and the proxy are out
202  // of sync around the time of insertions, so we can't use the optimization below.
203  return rowCount(parent) > 0;
204 #if 0
205 
206  if (!parent.isValid()) {
207  return sourceModel()->hasChildren(parent);
208  }
209 
210  Q_D(const EntityMimeTypeFilterModel);
211  if (EntityTreeModel::ItemListHeaders == d->m_headerGroup) {
212  return false;
213  }
214 
215  if (EntityTreeModel::CollectionTreeHeaders == d->m_headerGroup) {
216  QModelIndex childIndex = parent.child(0, 0);
217  while (childIndex.isValid()) {
219  if (col.isValid()) {
220  return true;
221  }
222  childIndex = childIndex.sibling(childIndex.row() + 1, childIndex.column());
223  }
224  }
225  return false;
226 #endif
227 }
228 
229 bool EntityMimeTypeFilterModel::canFetchMore(const QModelIndex &parent) const
230 {
231  Q_D(const EntityMimeTypeFilterModel);
232  if (EntityTreeModel::CollectionTreeHeaders == d->m_headerGroup) {
233  return false;
234  }
236 }
void addMimeTypeExclusionFilter(const QString &mimeType)
Add mime type to be excluded by the filter.
~EntityMimeTypeFilterModel() override
Destroys the entity mime type filter model.
bool isValid() const
Returns whether the collection is valid.
Definition: collection.cpp:124
typedef MatchFlags
Last role for user extensions. Don&#39;t use a role beyond this or headerData will break.
virtual bool filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const const
void addMimeTypeInclusionFilters(const QStringList &mimeTypes)
Add mime types to be shown by the filter.
Represents a collection of PIM items.
Definition: collection.h:63
virtual QModelIndexList match(const QModelIndex &start, int role, const QVariant &value, int hits, Qt::MatchFlags flags) const const override
QStringList mimeTypeInclusionFilters() const
Returns the list of mime type inclusion filters.
T value() const const
A proxy model that filters entities by mime type.
Header information for a collection-only tree.
HeaderGroup
Describes what header information the model shall return.
bool isValid() const const
int toInt(bool *ok) const const
void addMimeTypeExclusionFilters(const QStringList &mimeTypes)
Add mimetypes to filter out.
UserRole
int row() const const
QStringList mimeTypeExclusionFilters() const
Returns the list of mime type exclusion filters.
Header information for a list of items.
void setHeaderGroup(EntityTreeModel::HeaderGroup headerGroup)
Sets the header set of the filter model.
QVariant data(int role) const const
The mimetype of the entity.
QModelIndex sibling(int row, int column) const const
Helper integration between Akonadi and Qt.
A model for collections and items together.
void clearFilters()
Clear all mime type filters.
int column() const const
bool isValid() const const
Orientation
QModelIndex child(int row, int column) const const
QString toString() const const
virtual bool canFetchMore(const QModelIndex &parent) const const override
void addMimeTypeInclusionFilter(const QString &mimeType)
Add mime type to be shown by the filter.
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Sun Jul 12 2020 23:16:56 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.