Akonadi

subscriptionmodel.cpp
1 /*
2  Copyright (c) 2007 Volker Krause <[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 "subscriptionmodel_p.h"
21 #include "collectionutils.h"
22 #include "specialcollectionattribute.h"
23 #include "entityhiddenattribute.h"
24 #include "entitytreemodel.h"
25 
26 #include "akonadicore_debug.h"
27 #include <qnamespace.h>
28 #include <shared/akranges.h>
29 
30 #include <QFont>
31 #include <QSortFilterProxyModel>
32 
33 using namespace Akonadi;
34 using namespace AkRanges;
35 
36 namespace
37 {
38 
39 class FilterProxyModel : public QSortFilterProxyModel
40 {
41  Q_OBJECT
42 
43 public:
44  FilterProxyModel()
46  {
47  setDynamicSortFilter(true);
48  }
49 
50  void setShowHidden(bool showHidden)
51  {
52  if (mShowHidden != showHidden) {
53  mShowHidden = showHidden;
54  invalidateFilter();
55  }
56  }
57 
58  bool showHidden() const
59  {
60  return mShowHidden;
61  }
62 
63 protected:
64  bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override
65  {
66  const auto source_index = sourceModel()->index(source_row, 0, source_parent);
67  const auto col = source_index.data(EntityTreeModel::CollectionRole).value<Collection>();
68  if (mShowHidden) {
69  return true;
70  }
71 
72  return !col.hasAttribute<EntityHiddenAttribute>();
73  }
74 
75 private:
76  bool mShowHidden = false;
77 };
78 
79 }
80 
84 class SubscriptionModel::Private
85 {
86 public:
87  Private(Monitor *monitor)
88  : etm(monitor)
89  {
90  etm.setShowSystemEntities(true); // show hidden collections
91  etm.setItemPopulationStrategy(EntityTreeModel::NoItemPopulation);
92  etm.setCollectionFetchStrategy(EntityTreeModel::FetchCollectionsRecursive);
93 
94  proxy.setSourceModel(&etm);
95  }
96 
97  Collection::List changedSubscriptions(bool subscribed)
98  {
99  return Views::range(subscriptions.constKeyValueBegin(), subscriptions.constKeyValueEnd())
100  | Views::filter([subscribed](const auto &val) { return val.second == subscribed; })
101  | Views::transform([](const auto &val) { return Collection{val.first}; })
102  | Actions::toQVector;
103  }
104 
105  bool isSubscribable(const Collection &col)
106  {
107  if (CollectionUtils::isStructural(col) || col.isVirtual() || CollectionUtils::isUnifiedMailbox(col)) {
108  return false;
109  }
111  return false;
112  }
113  if (col.contentMimeTypes().isEmpty()) {
114  return false;
115  }
116  return true;
117  }
118 
119 public:
120  EntityTreeModel etm;
121  FilterProxyModel proxy;
122  QHash<Collection::Id, bool> subscriptions;
123 };
124 
125 SubscriptionModel::SubscriptionModel(Monitor *monitor, QObject *parent) :
126  QIdentityProxyModel(parent),
127  d(new Private(monitor))
128 {
130 
131  connect(&d->etm, &EntityTreeModel::collectionTreeFetched, this, &SubscriptionModel::modelLoaded);
132 }
133 
134 SubscriptionModel::~SubscriptionModel() = default;
135 
136 void SubscriptionModel::setSourceModel(QAbstractItemModel *)
137 {
138  // no-op
139 }
140 
141 QVariant SubscriptionModel::data(const QModelIndex &index, int role) const
142 {
143  switch (role) {
144  case Qt::CheckStateRole: {
145  const auto col = index.data(EntityTreeModel::CollectionRole).value<Collection>();
146  if (!d->isSubscribable(col)) {
147  return QVariant();
148  }
149  // Check if we have "override" for the subscription state stored
150  const auto it = d->subscriptions.constFind(col.id());
151  if (it != d->subscriptions.cend()) {
152  return (*it) ? Qt::Checked : Qt::Unchecked;
153  } else {
154  // Fallback to the current state of the collection
155  return col.enabled() ? Qt::Checked : Qt::Unchecked;
156  }
157  }
158  case SubscriptionChangedRole: {
159  const auto col = index.data(EntityTreeModel::CollectionIdRole).toLongLong();
160  return d->subscriptions.contains(col);
161  }
162  case Qt::FontRole: {
163  const auto col = index.data(EntityTreeModel::CollectionIdRole).toLongLong();
164  QFont font = QIdentityProxyModel::data(index, role).value<QFont>();
165  font.setBold(d->subscriptions.contains(col));
166  return font;
167  }
168  }
169 
170  return QIdentityProxyModel::data(index, role);
171 }
172 
173 Qt::ItemFlags SubscriptionModel::flags(const QModelIndex &index) const
174 {
176  const auto col = index.data(EntityTreeModel::CollectionRole).value<Collection>();
177  if (d->isSubscribable(col)) {
178  return flags | Qt::ItemIsUserCheckable;
179  }
180  return flags;
181 }
182 
183 bool SubscriptionModel::setData(const QModelIndex &index, const QVariant &value, int role)
184 {
185  if (role == Qt::CheckStateRole) {
186  const auto col = index.data(EntityTreeModel::CollectionRole).value<Collection>();
187  if (!d->isSubscribable(col)) {
188  return true; //No change
189  }
190  if (col.enabled() == (value == Qt::Checked)) { // No change compared to the underlying model
191  d->subscriptions.remove(col.id());
192  } else {
193  d->subscriptions[col.id()] = (value == Qt::Checked);
194  }
195  Q_EMIT dataChanged(index, index);
196  return true;
197  }
198  return QIdentityProxyModel::setData(index, value, role);
199 }
200 
201 Akonadi::Collection::List SubscriptionModel::subscribed() const
202 {
203  return d->changedSubscriptions(true);
204 }
205 
206 Akonadi::Collection::List SubscriptionModel::unsubscribed() const
207 {
208  return d->changedSubscriptions(false);
209 }
210 
211 void SubscriptionModel::setShowHiddenCollections(bool showHidden)
212 {
213  d->proxy.setShowHidden(showHidden);
214 }
215 
216 bool SubscriptionModel::showHiddenCollections() const
217 {
218  return d->proxy.showHidden();
219 }
220 
221 #include "subscriptionmodel.moc"
222 
qlonglong toLongLong(bool *ok) const const
virtual void setSourceModel(QAbstractItemModel *newSourceModel) override
Represents a collection of PIM items.
Definition: collection.h:76
Do not include items in the model.
Fetches collections in the root collection recursively. This is the default.
An Attribute that stores the special collection type of a collection.
T value() const const
void collectionTreeFetched(const Akonadi::Collection::List &collections)
Signal emitted when the collection tree has been fetched for the first time.
void setBold(bool enable)
bool isEmpty() const const
virtual QVariant data(const QModelIndex &proxyIndex, int role) const const override
const QFont & font() const const
bool hasAttribute(const QByteArray &name) const
Returns true if the collection has an attribute of the given type name, false otherwise.
Definition: collection.cpp:177
Monitors an item or collection for changes.
Definition: monitor.h:84
Id id() const
Returns the unique identifier of the collection.
Definition: collection.cpp:112
QVariant data(int role) const const
An Attribute that marks that an entity should be hidden in the UI.
Helper integration between Akonadi and Qt.
A model for collections and items together.
virtual Qt::ItemFlags flags(const QModelIndex &index) const const override
QStringList contentMimeTypes() const
Returns a list of possible content mimetypes, e.g.
Definition: collection.cpp:256
bool enabled() const
Returns the collection&#39;s enabled state.
Definition: collection.cpp:380
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Q_EMITQ_EMIT
virtual bool setData(const QModelIndex &index, const QVariant &value, int role) override
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:56 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.