Akonadi

collectionmaintenancepage.cpp
1 /*
2  Copyright (C) 2009-2020 Laurent Montel <[email protected]>
3 
4  This program is free software; you can redistribute it and/or
5  modify it under the terms of the GNU General Public
6  License as published by the Free Software Foundation; either
7  version 2 of the License, or (at your option) any later version.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; see the file COPYING. If not, write to
16  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  Boston, MA 02110-1301, USA.
18 */
19 
20 #include "collectionmaintenancepage.h"
21 #include "ui_collectionmaintenancepage.h"
22 #include "core/collectionstatistics.h"
23 #include "monitor.h"
24 #include "agentmanager.h"
25 #include "akonadiwidgets_debug.h"
26 #include "indexpolicyattribute.h"
27 #include "cachepolicy.h"
28 #include "servermanager.h"
29 
30 #include <QDBusInterface>
31 #include <QDBusPendingReply>
32 #include <QDBusPendingCallWatcher>
33 
34 #include <QPushButton>
35 #include <KLocalizedString>
36 #include <QCheckBox>
37 #include <KFormat>
38 
39 using namespace Akonadi;
40 
41 class CollectionMaintenancePage::Private
42 {
43 public:
44  Private()
45  {}
46 
47  void slotReindexCollection()
48  {
49  if (currentCollection.isValid()) {
50  //Don't allow to reindex twice.
51  ui.reindexButton->setEnabled(false);
52 
53  const auto service = ServerManager::agentServiceName(ServerManager::Agent, QStringLiteral("akonadi_indexing_agent"));
54  QDBusInterface indexingAgentIface(service,
55  QStringLiteral("/"),
56  QStringLiteral("org.freedesktop.Akonadi.Indexer"));
57  if (indexingAgentIface.isValid()) {
58  indexingAgentIface.call(QStringLiteral("reindexCollection"), static_cast<qlonglong>(currentCollection.id()));
59  ui.indexedCountLbl->setText(i18n("Remember that indexing can take some minutes."));
60  } else {
61  qCWarning(AKONADIWIDGETS_LOG) << "indexer interface not valid";
62  }
63  }
64  }
65 
66  void updateLabel(qint64 nbMail, qint64 nbUnreadMail, qint64 size)
67  {
68  ui.itemsCountLbl->setText(QString::number(qMax(0LL, nbMail)));
69  ui.unreadItemsCountLbl->setText(QString::number(qMax(0LL, nbUnreadMail)));
70  ui.folderSizeLbl->setText(KFormat().formatByteSize(qMax(0LL, size)));
71  }
72 
73  Akonadi::Collection currentCollection;
74  Akonadi::Monitor *monitor = nullptr;
75 
76  Ui::CollectionMaintenancePage ui;
77 };
78 
79 CollectionMaintenancePage::CollectionMaintenancePage(QWidget *parent)
80  : CollectionPropertiesPage(parent)
81  , d(new Private)
82 {
83  setObjectName(QStringLiteral("Akonadi::CollectionMaintenancePage"));
84  setPageTitle(i18n("Maintenance"));
85 }
86 
87 CollectionMaintenancePage::~CollectionMaintenancePage()
88 {
89  delete d;
90 }
91 
92 void CollectionMaintenancePage::init(const Collection &col)
93 {
94  d->ui.setupUi(this);
95 
96  d->currentCollection = col;
97  d->monitor = new Monitor(this);
98  d->monitor->setObjectName(QStringLiteral("CollectionMaintenancePageMonitor"));
99  d->monitor->setCollectionMonitored(col, true);
100  d->monitor->fetchCollectionStatistics(true);
101  connect(d->monitor, &Monitor::collectionStatisticsChanged,
102  this, [this](Collection::Id, const CollectionStatistics &stats) {
103  d->updateLabel(stats.count(), stats.unreadCount(), stats.size());
104  });
105 
106 
107  if (!col.isVirtual()) {
108  const AgentInstance instance = Akonadi::AgentManager::self()->instance(col.resource());
109  d->ui.folderTypeLbl->setText(instance.type().name());
110  } else {
111  d->ui.folderTypeLbl->hide();
112  d->ui.filesLayout->labelForField(d->ui.folderTypeLbl)->hide();
113  }
114 
115  connect(d->ui.reindexButton, &QPushButton::clicked,
116  this, [this]() { d->slotReindexCollection(); });
117 
118  // Check if the resource caches full payloads or at least has local storage
119  // (so that the indexer can retrieve the payloads on demand)
120  const auto resource = Akonadi::AgentManager::self()->instance(col.resource()).type();
121  if (!col.cachePolicy().localParts().contains(QLatin1String("RFC822"))
122  && resource.customProperties().value(QStringLiteral("HasLocalStorage"), QString()) != QLatin1String("true")) {
123  d->ui.indexingGroup->hide();
124  }
125 }
126 
127 void CollectionMaintenancePage::load(const Collection &col)
128 {
129  init(col);
130  if (col.isValid()) {
131  d->updateLabel(col.statistics().count(), col.statistics().unreadCount(), col.statistics().size());
133  const bool indexingWasEnabled(!attr || attr->indexingEnabled());
134  d->ui.enableIndexingChkBox->setChecked(indexingWasEnabled);
135  if (indexingWasEnabled) {
136  const auto service = ServerManager::agentServiceName(ServerManager::Agent, QStringLiteral("akonadi_indexing_agent"));
137  QDBusInterface indexingAgentIface(service,
138  QStringLiteral("/"),
139  QStringLiteral("org.freedesktop.Akonadi.Indexer"));
140  if (indexingAgentIface.isValid()) {
141  auto reply = indexingAgentIface.asyncCall(QStringLiteral("indexedItems"), (qlonglong) col.id());
142  auto w = new QDBusPendingCallWatcher(reply, this);
144  this, [this](QDBusPendingCallWatcher *w) {
145  QDBusPendingReply<qlonglong> reply = *w;
146  if (reply.isError()) {
147  d->ui.indexedCountLbl->setText(i18n("Error while retrieving indexed items count"));
148  qCWarning(AKONADIWIDGETS_LOG) << "Failed to retrieve indexed items count:" << reply.error().message();
149  } else {
150  d->ui.indexedCountLbl->setText(i18np("Indexed %1 item in this folder",
151  "Indexed %1 items in this folder",
152  reply.argumentAt<0>()));
153  }
154  w->deleteLater();
155  });
156  d->ui.indexedCountLbl->setText(i18n("Calculating indexed items..."));
157  } else {
158  qCDebug(AKONADIWIDGETS_LOG) << "Failed to obtain Indexer interface";
159  d->ui.indexedCountLbl->hide();
160  }
161  } else {
162  d->ui.indexedCountLbl->hide();
163  }
164  }
165 }
166 
167 void CollectionMaintenancePage::save(Collection &collection)
168 {
169  if (!collection.hasAttribute<Akonadi::IndexPolicyAttribute>() && d->ui.enableIndexingChkBox->isChecked()) {
170  return;
171  }
172 
174  attr->setIndexingEnabled(d->ui.enableIndexingChkBox->isChecked());
175 }
qint64 count() const
Returns the number of items in this collection or -1 if this information is not available.
bool isValid() const
Returns whether the collection is valid.
Definition: collection.cpp:137
Provides statistics information of a Collection.
Represents a collection of PIM items.
Definition: collection.h:76
qint64 Id
Describes the unique id type.
Definition: collection.h:82
AgentType type() const
Returns the agent type of this instance.
void finished(QDBusPendingCallWatcher *self)
QString name() const
Returns the i18n&#39;ed name of the agent type.
bool contains(const QString &str, Qt::CaseSensitivity cs) const const
QString message() const const
A single page in a collection properties dialog.
Creates the attribute if it is missing.
Definition: collection.h:283
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
An attribute to specify how a collection should be indexed for searching.
QString number(int n, int base)
AgentInstance instance(const QString &identifier) const
Returns the agent instance with the given identifier or an invalid agent instance if the identifier d...
void clicked(bool checked)
void deleteLater()
QDBusError error() const const
static QString agentServiceName(ServiceAgentType agentType, const QString &identifier)
Returns the namespaced D-Bus service name for an agent of type agentType with agent identifier identi...
Attribute * attribute(const QByteArray &name)
Returns the attribute of the given type name if available, 0 otherwise.
Definition: collection.cpp:192
QCA_EXPORT void init()
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
void collectionStatisticsChanged(Akonadi::Collection::Id id, const Akonadi::CollectionStatistics &statistics)
This signal is emitted if the statistics information of a monitored collection has changed...
Monitors an item or collection for changes.
Definition: monitor.h:84
QString i18n(const char *text, const TYPE &arg...)
QByteArray type() const override
Returns the type of the attribute.
Id id() const
Returns the unique identifier of the collection.
Definition: collection.cpp:112
QVariant argumentAt(int index) const const
Helper integration between Akonadi and Qt.
void setIndexingEnabled(bool enable)
Sets whether this collection should be indexed at all.
qint64 unreadCount() const
Returns the number of unread items in this collection or -1 if this information is not available...
static AgentManager * self()
Returns the global instance of the agent manager.
CachePolicy cachePolicy() const
Returns the cache policy of the collection.
Definition: collection.cpp:353
QStringList localParts() const
Returns the parts to permanently cache locally.
Definition: cachepolicy.cpp:95
A representation of an agent instance.
bool indexingEnabled() const
Returns whether this collection is supposed to be indexed at all.
QString resource() const
Returns the identifier of the resource owning the collection.
Definition: collection.cpp:318
CollectionStatistics statistics() const
Returns the collection statistics of the collection.
Definition: collection.cpp:343
bool isVirtual() const
Returns whether the collection is virtual, for example a search collection.
Definition: collection.cpp:364
bool isError() const const
qint64 size() const
Returns the total size of the items in this collection or -1 if this information is not available...
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.