Mailcommon

mailkernel.cpp
1/*
2 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
3 SPDX-FileCopyrightText: 2010 Andras Mantia <andras@kdab.com>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6*/
7
8#include "mailkernel.h"
9#include "mailcommon_debug.h"
10#include "util/mailutil.h"
11#include <PimCommon/PimUtil>
12#include <PimCommonAkonadi/ImapResourceCapabilitiesManager>
13
14#include "util/resourcereadconfigfile.h"
15#include <Akonadi/AgentInstance>
16#include <Akonadi/AgentManager>
17#include <Akonadi/EntityMimeTypeFilterModel>
18#include <Akonadi/SpecialMailCollectionsDiscoveryJob>
19#include <Akonadi/SpecialMailCollectionsRequestJob>
20#include <QApplication>
21
22#include <KIdentityManagementCore/Identity>
23#include <KIdentityManagementCore/IdentityManager>
24
25#include <KLocalizedString>
26#include <KMessageBox>
27
28namespace MailCommon
29{
30class KernelPrivate
31{
32public:
33 KernelPrivate()
34 : kernel(new Kernel)
35 {
36 }
37
38 ~KernelPrivate()
39 {
40 qCDebug(MAILCOMMON_LOG);
41 delete kernel;
42 }
43
44 Kernel *const kernel;
45};
46
47Q_GLOBAL_STATIC(KernelPrivate, sInstance)
48
49Kernel::Kernel(QObject *parent)
50 : QObject(parent)
51{
52 mKernelIf = nullptr;
53 mSettingsIf = nullptr;
54 mFilterIf = nullptr;
55 mImapResourceManager = new PimCommon::ImapResourceCapabilitiesManager(this);
56}
57
58Kernel::~Kernel()
59{
60 qCDebug(MAILCOMMON_LOG);
61}
62
63Kernel *Kernel::self()
64{
65 return sInstance->kernel; // will create it
66}
67
68void Kernel::registerKernelIf(IKernel *kernelIf)
69{
70 mKernelIf = kernelIf;
71}
72
73bool Kernel::kernelIsRegistered() const
74{
75 return mKernelIf != nullptr;
76}
77
78IKernel *Kernel::kernelIf() const
79{
80 Q_ASSERT(mKernelIf);
81 return mKernelIf;
82}
83
84void Kernel::registerSettingsIf(ISettings *settingsIf)
85{
86 mSettingsIf = settingsIf;
87}
88
89ISettings *Kernel::settingsIf() const
90{
91 Q_ASSERT(mSettingsIf);
92 return mSettingsIf;
93}
94
95void Kernel::registerFilterIf(IFilter *filterIf)
96{
97 mFilterIf = filterIf;
98}
99
100IFilter *Kernel::filterIf() const
101{
102 Q_ASSERT(mFilterIf);
103 return mFilterIf;
104}
105
106PimCommon::ImapResourceCapabilitiesManager *Kernel::imapResourceManager() const
107{
108 return mImapResourceManager;
109}
110
111Akonadi::Collection Kernel::collectionFromId(Akonadi::Collection::Id id) const
112{
113 return Akonadi::EntityTreeModel::updatedCollection(kernelIf()->collectionModel(), id);
114}
115
116Akonadi::Collection Kernel::trashCollectionFolder()
117{
119}
120
121Akonadi::Collection Kernel::inboxCollectionFolder()
122{
124}
125
126Akonadi::Collection Kernel::outboxCollectionFolder()
127{
129}
130
131Akonadi::Collection Kernel::sentCollectionFolder()
132{
134}
135
136Akonadi::Collection Kernel::draftsCollectionFolder()
137{
139}
140
141Akonadi::Collection Kernel::templatesCollectionFolder()
142{
144}
145
146bool Kernel::isSystemFolderCollection(const Akonadi::Collection &col)
147{
148 return col == inboxCollectionFolder() || col == outboxCollectionFolder() || col == sentCollectionFolder() || col == trashCollectionFolder()
149 || col == draftsCollectionFolder() || col == templatesCollectionFolder();
150}
151
152bool Kernel::isMainFolderCollection(const Akonadi::Collection &col)
153{
154 return col == inboxCollectionFolder();
155}
156
157//-----------------------------------------------------------------------------
158void Kernel::initFolders()
159{
160 qCDebug(MAILCOMMON_LOG) << "Initialized and looking for specialcollection folders.";
161 findCreateDefaultCollection(Akonadi::SpecialMailCollections::Inbox);
162 findCreateDefaultCollection(Akonadi::SpecialMailCollections::Outbox);
163 findCreateDefaultCollection(Akonadi::SpecialMailCollections::SentMail);
164 findCreateDefaultCollection(Akonadi::SpecialMailCollections::Drafts);
165 findCreateDefaultCollection(Akonadi::SpecialMailCollections::Trash);
166 findCreateDefaultCollection(Akonadi::SpecialMailCollections::Templates);
167
168 auto job = new Akonadi::SpecialMailCollectionsDiscoveryJob(this);
169 job->start();
170 // we don't connect to the job directly: it will register stuff into SpecialMailCollections, which will Q_EMIT signals.
171}
172
173void Kernel::findCreateDefaultCollection(Akonadi::SpecialMailCollections::Type type)
174{
175 if (Akonadi::SpecialMailCollections::self()->hasDefaultCollection(type)) {
177
178 if (!(col.rights() & Akonadi::Collection::AllRights)) {
179 emergencyExit(i18n("You do not have read/write permission to your inbox folder."));
180 }
181 } else {
183
184 connect(job, &Akonadi::SpecialMailCollectionsRequestJob::result, this, &Kernel::createDefaultCollectionDone);
185
186 job->requestDefaultCollection(type);
187 }
188}
189
190void Kernel::createDefaultCollectionDone(KJob *job)
191{
192 if (job->error()) {
193 emergencyExit(job->errorText());
194 return;
195 }
196
197 auto requestJob = qobject_cast<Akonadi::SpecialMailCollectionsRequestJob *>(job);
198
199 const Akonadi::Collection col = requestJob->collection();
200 if (!(col.rights() & Akonadi::Collection::AllRights)) {
201 emergencyExit(i18n("You do not have read/write permission to your inbox folder."));
202 }
209
212 this,
213 &Kernel::slotDefaultCollectionsChanged,
215}
216
217void Kernel::slotDefaultCollectionsChanged()
218{
221 this,
222 &Kernel::slotDefaultCollectionsChanged);
223 initFolders();
224}
225
226void Kernel::emergencyExit(const QString &reason)
227{
228 QString mesg;
229 if (reason.isEmpty()) {
230 mesg = i18n("The Email program encountered a fatal error and will terminate now");
231 } else {
232 mesg = i18n(
233 "The Email program encountered a fatal error and will terminate now.\n"
234 "The error was:\n%1",
235 reason);
236 }
237
238 qCWarning(MAILCOMMON_LOG) << mesg;
239
240 // Show error box for the first error that caused emergencyExit.
241 static bool s_showingErrorBox = false;
242 if (!s_showingErrorBox) {
243 s_showingErrorBox = true;
244 if (qApp) { // see bug 313104
245 KMessageBox::error(nullptr, mesg);
246 }
247 ::exit(1);
248 }
249}
250
251bool Kernel::folderIsDraftOrOutbox(const Akonadi::Collection &col)
252{
254 return true;
255 }
256
257 return folderIsDrafts(col);
258}
259
260bool Kernel::folderIsDrafts(const Akonadi::Collection &col)
261{
263 return true;
264 }
265
266 const QString idString = QString::number(col.id());
267 if (idString.isEmpty()) {
268 return false;
269 }
270
271 // search the identities if the folder matches the drafts-folder
272 const KIdentityManagementCore::IdentityManager *im = KernelIf->identityManager();
273 KIdentityManagementCore::IdentityManager::ConstIterator end(im->end());
274 for (KIdentityManagementCore::IdentityManager::ConstIterator it = im->begin(); it != end; ++it) {
275 if ((*it).drafts() == idString) {
276 return true;
277 }
278 }
279 return false;
280}
281
282bool Kernel::folderIsTemplates(const Akonadi::Collection &col)
283{
285 return true;
286 }
287 const QString idString = QString::number(col.id());
288 if (idString.isEmpty()) {
289 return false;
290 }
291
292 // search the identities if the folder matches the templates-folder
293 const KIdentityManagementCore::IdentityManager *im = KernelIf->identityManager();
294 KIdentityManagementCore::IdentityManager::ConstIterator end(im->end());
295 for (KIdentityManagementCore::IdentityManager::ConstIterator it = im->begin(); it != end; ++it) {
296 if ((*it).templates() == idString) {
297 return true;
298 }
299 }
300 return false;
301}
302
303Akonadi::Collection Kernel::trashCollectionFromResource(const Akonadi::Collection &col)
304{
305 Akonadi::Collection trashCol;
306 if (col.isValid()) {
309 }
310 return trashCol;
311}
312
313bool Kernel::folderIsTrash(const Akonadi::Collection &col)
314{
316 return true;
317 }
318
319 const Akonadi::AgentInstance::List lst = MailCommon::Util::agentInstances();
320 for (const Akonadi::AgentInstance &agent : lst) {
322 if (col == trash) {
323 return true;
324 }
325 }
326 return false;
327}
328
329bool Kernel::folderIsSentMailFolder(const Akonadi::Collection &col)
330{
332 return true;
333 }
334 const QString idString = QString::number(col.id());
335 if (idString.isEmpty()) {
336 return false;
337 }
338
339 // search the identities if the folder matches the sent-folder
340 const KIdentityManagementCore::IdentityManager *im = KernelIf->identityManager();
341 KIdentityManagementCore::IdentityManager::ConstIterator end(im->end());
342 for (KIdentityManagementCore::IdentityManager::ConstIterator it = im->begin(); it != end; ++it) {
343 if ((*it).fcc() == idString) {
344 return true;
345 }
346 }
347 return false;
348}
349
350bool Kernel::folderIsInbox(const Akonadi::Collection &collection)
351{
352 const QString collectionRemoteIdLower = collection.remoteId().toLower();
353 if (collectionRemoteIdLower == QLatin1StringView("inbox") || collectionRemoteIdLower == QLatin1StringView("/inbox")
354 || collectionRemoteIdLower == QLatin1StringView(".inbox") || collectionRemoteIdLower == QLatin1StringView("|inbox")) {
355 return true;
356 }
357 // Fix order. Remoteid is not "inbox" when translated
358 if (Akonadi::SpecialMailCollections::self()->specialCollectionType(collection) == Akonadi::SpecialMailCollections::Inbox) {
359 return true;
360 }
361
362 // MBOX is one folder only, treat as inbox
363 if (collection.resource().contains(MBOX_RESOURCE_IDENTIFIER)) {
364 return true;
365 }
366 return false;
367}
368
369QMap<QString, Akonadi::Collection::Id> Kernel::pop3ResourceTargetCollection()
370{
371 QMap<QString, Akonadi::Collection::Id> mapIdentifierCollectionId;
372 const Akonadi::AgentInstance::List lst = MailCommon::Util::agentInstances();
373 for (const Akonadi::AgentInstance &type : lst) {
374 if (type.status() == Akonadi::AgentInstance::Broken) {
375 continue;
376 }
377 const QString typeIdentifier = type.identifier();
378 if (typeIdentifier.contains(POP3_RESOURCE_IDENTIFIER)) {
379 MailCommon::ResourceReadConfigFile resourceFile(typeIdentifier);
380 const KConfigGroup grp = resourceFile.group(QStringLiteral("General"));
381 if (grp.isValid()) {
382 const Akonadi::Collection::Id targetCollection = grp.readEntry(QStringLiteral("targetCollection"), -1);
383 mapIdentifierCollectionId.insert(typeIdentifier, targetCollection);
384 }
385 }
386 }
387 return mapIdentifierCollectionId;
388}
389
390#if MAILCOMMON_HAVE_ACTIVITY_SUPPORT
391PimCommonActivities::ActivitiesBaseManager *Kernel::activitiesBaseManager() const
392{
393 return mActivitiesBaseManager;
394}
395
396void Kernel::registerActivitiesBaseManager(PimCommonActivities::ActivitiesBaseManager *manager)
397{
398 mActivitiesBaseManager = manager;
399}
400#endif
401}
402
403#include "moc_mailkernel.cpp"
static AgentManager * self()
AgentInstance instance(const QString &identifier) const
QString resource() const
bool isValid() const
Rights rights() const
QString remoteId() const
static Collection updatedCollection(const QAbstractItemModel *model, qint64 collectionId)
static SpecialMailCollections * self()
Akonadi::Collection collection(Type type, const AgentInstance &instance) const
Akonadi::Collection defaultCollection(Type type) const
KConfigGroup group(const QString &group)
bool isValid() const
QString readEntry(const char *key, const char *aDefault=nullptr) const
int error() const
void result(KJob *job)
QString errorText() const
Filter related interface.
Generic interface for mail kernels.
Interface to access some settings.
QString i18n(const char *text, const TYPE &arg...)
Type type(const QSqlDatabase &db)
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
const QList< QKeySequence > & end()
The filter dialog.
iterator insert(const Key &key, const T &value)
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
bool isEmpty() const const
QString number(double n, char format, int precision)
QString toLower() const const
UniqueConnection
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Dec 6 2024 12:02:04 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.