Akonadi

collectionmaintenancepage.cpp
1/*
2 SPDX-FileCopyrightText: 2009-2024 Laurent Montel <montel@kde.org>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5*/
6
7#include "collectionmaintenancepage.h"
8#include "agentmanager.h"
9#include "akonadiwidgets_debug.h"
10#include "cachepolicy.h"
11#include "core/collectionstatistics.h"
12#include "indexpolicyattribute.h"
13#include "monitor.h"
14#include "servermanager.h"
15#include "ui_collectionmaintenancepage.h"
16
17#include <QDBusInterface>
18#include <QDBusPendingCallWatcher>
19#include <QDBusPendingReply>
20
21#include <KFormat>
22
23#include <KLocalizedString>
24#include <QCheckBox>
25#include <QPushButton>
26
27using namespace Akonadi;
28
29class Akonadi::CollectionMaintenancePagePrivate
30{
31public:
32 CollectionMaintenancePagePrivate()
33 {
34 }
35
36 void slotReindexCollection()
37 {
38 if (currentCollection.isValid()) {
39 // Don't allow to reindex twice.
40 ui.reindexButton->setEnabled(false);
41
42 const auto service = ServerManager::agentServiceName(ServerManager::Agent, QStringLiteral("akonadi_indexing_agent"));
43 QDBusInterface indexingAgentIface(service, QStringLiteral("/"), QStringLiteral("org.freedesktop.Akonadi.Indexer"));
44 if (indexingAgentIface.isValid()) {
45 indexingAgentIface.call(QStringLiteral("reindexCollection"), static_cast<qlonglong>(currentCollection.id()));
46 ui.indexedCountLbl->setText(i18n("Remember that indexing can take some minutes."));
47 } else {
48 qCWarning(AKONADIWIDGETS_LOG) << "indexer interface not valid";
49 }
50 }
51 }
52
53 void updateLabel(qint64 nbMail, qint64 nbUnreadMail, qint64 size)
54 {
55 ui.itemsCountLbl->setText(QString::number(qMax(0LL, nbMail)));
56 ui.unreadItemsCountLbl->setText(QString::number(qMax(0LL, nbUnreadMail)));
57 KFormat format;
58 ui.folderSizeLbl->setText(format.formatByteSize(qMax(0LL, size)));
59 }
60
61 Akonadi::Collection currentCollection;
62 Akonadi::Monitor *monitor = nullptr;
63
64 Ui::CollectionMaintenancePage ui;
65};
66
67CollectionMaintenancePage::CollectionMaintenancePage(QWidget *parent)
69 , d(new CollectionMaintenancePagePrivate)
70{
71 setObjectName(QLatin1StringView("Akonadi::CollectionMaintenancePage"));
72 setPageTitle(i18n("Maintenance"));
73}
74
75CollectionMaintenancePage::~CollectionMaintenancePage() = default;
76
77void CollectionMaintenancePage::init(const Collection &col)
78{
79 d->ui.setupUi(this);
80
81 d->currentCollection = col;
82 d->monitor = new Monitor(this);
83 d->monitor->setObjectName(QLatin1StringView("CollectionMaintenancePageMonitor"));
84 d->monitor->setCollectionMonitored(col, true);
85 d->monitor->fetchCollectionStatistics(true);
86 connect(d->monitor, &Monitor::collectionStatisticsChanged, this, [this](Collection::Id /*unused*/, const CollectionStatistics &stats) {
87 d->updateLabel(stats.count(), stats.unreadCount(), stats.size());
88 });
89
90 if (!col.isVirtual()) {
91 const AgentInstance instance = Akonadi::AgentManager::self()->instance(col.resource());
92 d->ui.folderTypeLbl->setText(instance.type().name());
93 } else {
94 d->ui.folderTypeLbl->hide();
95 d->ui.verticalLayout->labelForField(d->ui.folderTypeLbl)->hide();
96 }
97
98 connect(d->ui.reindexButton, &QPushButton::clicked, this, [this]() {
99 d->slotReindexCollection();
100 });
101
102 // Check if the resource caches full payloads or at least has local storage
103 // (so that the indexer can retrieve the payloads on demand)
104 const auto resource = Akonadi::AgentManager::self()->instance(col.resource()).type();
105 if (!col.cachePolicy().localParts().contains(QLatin1StringView("RFC822"))
106 && resource.customProperties().value(QStringLiteral("HasLocalStorage"), QString()) != QLatin1StringView("true")) {
107 d->ui.indexingLabel->hide();
108 d->ui.enableIndexingChkBox->hide();
109 d->ui.indexedCountLbl->hide();
110 d->ui.reindexButton->hide();
111 }
112}
113
114void CollectionMaintenancePage::load(const Collection &col)
115{
116 init(col);
117 if (col.isValid()) {
118 d->updateLabel(col.statistics().count(), col.statistics().unreadCount(), col.statistics().size());
119 const auto attr = col.attribute<Akonadi::IndexPolicyAttribute>();
120 const bool indexingWasEnabled(!attr || attr->indexingEnabled());
121 d->ui.enableIndexingChkBox->setChecked(indexingWasEnabled);
122 if (indexingWasEnabled) {
123 const auto service = ServerManager::agentServiceName(ServerManager::Agent, QStringLiteral("akonadi_indexing_agent"));
124 QDBusInterface indexingAgentIface(service, QStringLiteral("/"), QStringLiteral("org.freedesktop.Akonadi.Indexer"));
125 if (indexingAgentIface.isValid()) {
126 auto reply = indexingAgentIface.asyncCall(QStringLiteral("indexedItems"), static_cast<qint64>(col.id()));
127 auto w = new QDBusPendingCallWatcher(reply, this);
129 QDBusPendingReply<qint64> reply = *w;
130 if (reply.isError()) {
131 d->ui.indexedCountLbl->setText(i18n("Error while retrieving indexed items count"));
132 qCWarning(AKONADIWIDGETS_LOG) << "Failed to retrieve indexed items count:" << reply.error().message();
133 } else {
134 d->ui.indexedCountLbl->setText(i18np("Indexed %1 item in this folder", "Indexed %1 items in this folder", reply.argumentAt<0>()));
135 }
136 w->deleteLater();
137 });
138 d->ui.indexedCountLbl->setText(i18n("Calculating indexed items..."));
139 } else {
140 qCDebug(AKONADIWIDGETS_LOG) << "Failed to obtain Indexer interface";
141 d->ui.indexedCountLbl->hide();
142 }
143 } else {
144 d->ui.indexedCountLbl->hide();
145 }
146 }
147}
148
149void CollectionMaintenancePage::save(Collection &collection)
150{
151 if (!collection.hasAttribute<Akonadi::IndexPolicyAttribute>() && d->ui.enableIndexingChkBox->isChecked()) {
152 return;
153 }
154
156 attr->setIndexingEnabled(d->ui.enableIndexingChkBox->isChecked());
157}
158
159#include "moc_collectionmaintenancepage.cpp"
Represents one agent instance and takes care of communication with it.
AgentType type() const
Returns the agent type of this instance.
static AgentManager * self()
Returns the global instance of the agent manager.
AgentInstance instance(const QString &identifier) const
Returns the agent instance with the given identifier or an invalid agent instance if the identifier d...
QStringList localParts() const
Returns the parts to permanently cache locally.
A single page in a collection properties dialog.
Provides statistics information of a Collection.
qint64 unreadCount() const
Returns the number of unread items in this collection or -1 if this information is not available.
qint64 count() const
Returns the number of items in this collection or -1 if this information is not available.
qint64 size() const
Returns the total size of the items in this collection or -1 if this information is not available.
Represents a collection of PIM items.
Definition collection.h:62
qint64 Id
Describes the unique id type.
Definition collection.h:79
CollectionStatistics statistics() const
Returns the collection statistics of the collection.
bool hasAttribute(const QByteArray &name) const
Returns true if the collection has an attribute of the given type name, false otherwise.
CachePolicy cachePolicy() const
Returns the cache policy of the collection.
@ AddIfMissing
Creates the attribute if it is missing.
Definition collection.h:281
Attribute * attribute(const QByteArray &name)
Returns the attribute of the given type name if available, 0 otherwise.
An attribute to specify how a collection should be indexed for searching.
void setIndexingEnabled(bool enable)
Sets whether this collection should be indexed at all.
Monitors an item or collection for changes.
Definition monitor.h:71
void collectionStatisticsChanged(Akonadi::Collection::Id id, const Akonadi::CollectionStatistics &statistics)
This signal is emitted if the statistics information of a monitored collection has changed.
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...
QString formatByteSize(double size, int precision=1, KFormat::BinaryUnitDialect dialect=KFormat::DefaultBinaryDialect, KFormat::BinarySizeUnits units=KFormat::DefaultBinaryUnits) const
QString i18np(const char *singular, const char *plural, const TYPE &arg...)
QString i18n(const char *text, const TYPE &arg...)
Helper integration between Akonadi and Qt.
void clicked(bool checked)
QString message() const const
void finished(QDBusPendingCallWatcher *self)
QVariant argumentAt(int index) const const
QDBusError error() const const
bool isError() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
QString number(double n, char format, int precision)
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:01:42 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.