Akonadi

collectionfilterproxymodel.cpp
1 /*
2  Copyright (c) 2007 Bruno Virlet <[email protected]>
3 
4  This library is free software; you can redistribute it and/or modify it
5  under the terms of the GNU Library General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or (at your
7  option) any later version.
8 
9  This library is distributed in the hope that it will be useful, but WITHOUT
10  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12  License for more details.
13 
14  You should have received a copy of the GNU Library General Public License
15  along with this library; see the file COPYING.LIB. If not, write to the
16  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  02110-1301, USA.
18 */
19 
20 #include "collectionfilterproxymodel.h"
21 #include "akonadicore_debug.h"
22 #include "entitytreemodel.h"
23 #include "mimetypechecker.h"
24 
25 #include <QString>
26 #include <QStringList>
27 
28 using namespace Akonadi;
29 
33 class Q_DECL_HIDDEN CollectionFilterProxyModel::Private
34 {
35 public:
36  Private(CollectionFilterProxyModel *parent)
37  : mParent(parent)
38  {
39  mimeChecker.addWantedMimeType(QStringLiteral("text/uri-list"));
40  }
41 
42  bool collectionAccepted(const QModelIndex &index, bool checkResourceVisibility = true);
43 
44  QVector< QModelIndex > acceptedResources;
45  CollectionFilterProxyModel *mParent = nullptr;
46  MimeTypeChecker mimeChecker;
47  bool mExcludeVirtualCollections = false;
48 };
49 
50 bool CollectionFilterProxyModel::Private::collectionAccepted(const QModelIndex &index, bool checkResourceVisibility)
51 {
52  // Retrieve supported mimetypes
53  const Collection collection = mParent->sourceModel()->data(index, EntityTreeModel::CollectionRole).value<Collection>();
54 
55  if (!collection.isValid()) {
56  return false;
57  }
58 
59  if (collection.isVirtual() && mExcludeVirtualCollections) {
60  return false;
61  }
62 
63  // If this collection directly contains one valid mimetype, it is accepted
64  if (mimeChecker.isWantedCollection(collection)) {
65  // The folder will be accepted, but we need to make sure the resource is visible too.
66  if (checkResourceVisibility) {
67 
68  // find the resource
69  QModelIndex resource = index;
70  while (resource.parent().isValid()) {
71  resource = resource.parent();
72  }
73 
74  // See if that resource is visible, if not, invalidate the filter.
75  if (resource != index && !acceptedResources.contains(resource)) {
76  qCDebug(AKONADICORE_LOG) << "We got a new collection:" << mParent->sourceModel()->data(index).toString()
77  << "but the resource is not visible:" << mParent->sourceModel()->data(resource).toString();
78  acceptedResources.clear();
79  // defer reset, the model might still be supplying new items at this point which crashs
80  mParent->invalidateFilter();
81  return true;
82  }
83  }
84 
85  // Keep track of all the resources that are visible.
86  if (!index.parent().isValid()) {
87  acceptedResources.append(index);
88  }
89 
90  return true;
91  }
92 
93  // If this collection has a child which contains valid mimetypes, it is accepted
94  QModelIndex childIndex = mParent->sourceModel()->index(0, 0, index);
95  while (childIndex.isValid()) {
96  if (collectionAccepted(childIndex, false /* don't check visibility of the parent, as we are checking the child now */)) {
97 
98  // Keep track of all the resources that are visible.
99  if (!index.parent().isValid()) {
100  acceptedResources.append(index);
101  }
102 
103  return true;
104  }
105  childIndex = childIndex.sibling(childIndex.row() + 1, 0);
106  }
107 
108  // Or else, no reason to keep this collection.
109  return false;
110 }
111 
113  : QSortFilterProxyModel(parent)
114  , d(new Private(this))
115 {
116 }
117 
119 {
120  delete d;
121 }
122 
124 {
125  const QStringList mimeTypes = d->mimeChecker.wantedMimeTypes() + typeList;
126  d->mimeChecker.setWantedMimeTypes(mimeTypes);
128 }
129 
131 {
132  d->mimeChecker.addWantedMimeType(type);
134 }
135 
136 bool CollectionFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
137 {
138  return d->collectionAccepted(sourceModel()->index(sourceRow, 0, sourceParent));
139 }
140 
142 {
143  return d->mimeChecker.wantedMimeTypes();
144 }
145 
147 {
148  d->mimeChecker = MimeTypeChecker();
150 }
151 
153 {
154  if (exclude != d->mExcludeVirtualCollections) {
155  d->mExcludeVirtualCollections = exclude;
157  }
158 }
159 
160 bool CollectionFilterProxyModel::excludeVirtualCollections() const
161 {
162  return d->mExcludeVirtualCollections;
163 }
164 
165 Qt::ItemFlags CollectionFilterProxyModel::flags(const QModelIndex &index) const
166 {
167  if (!index.isValid()) {
168  // Don't crash
169  return Qt::NoItemFlags;
170  }
171 
173 
174  // If this collection directly contains one valid mimetype, it is accepted
175  if (d->mimeChecker.isWantedCollection(collection)) {
176  return QSortFilterProxyModel::flags(index);
177  } else {
178  return QSortFilterProxyModel::flags(index) & ~(Qt::ItemIsSelectable);
179  }
180 }
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
bool isValid() const
Returns whether the collection is valid.
Definition: collection.cpp:137
virtual Qt::ItemFlags flags(const QModelIndex &index) const const override
A proxy model that filters collections by mime type.
Represents a collection of PIM items.
Definition: collection.h:76
T value() const const
~CollectionFilterProxyModel() override
Destroys the collection proxy filter model.
Helper for checking MIME types of Collections and Items.
void addMimeTypeFilters(const QStringList &mimeTypes)
Adds a list of mime types to be shown by the filter.
bool isValid() const const
QStringList mimeTypeFilters() const
Returns the list of mime type filters.
int row() const const
virtual QVariant data(const QModelIndex &index, int role) const const =0
QModelIndex parent() const const
CollectionFilterProxyModel(QObject *parent=nullptr)
Creates a new collection proxy filter model.
virtual QStringList mimeTypes() const const override
void setExcludeVirtualCollections(bool exclude)
Sets whether we want virtual collections to be filtered or not.
QAbstractItemModel * sourceModel() const const
virtual QModelIndex mapToSource(const QModelIndex &proxyIndex) const const override
void addMimeTypeFilter(const QString &mimeType)
Adds a mime type to be shown by the filter.
QVariant data(int role) const const
QModelIndex sibling(int row, int column) const const
Helper integration between Akonadi and Qt.
void clearFilters()
Clears all mime type filters.
QChar * data()
QString toString() const const
bool isVirtual() const
Returns whether the collection is virtual, for example a search collection.
Definition: collection.cpp:364
typedef ItemFlags
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Fri Jun 5 2020 23:08:54 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.