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 #pragma once
9 
10 #include "mailcommon/mailinterfaces.h"
11 #include "mailcommon_export.h"
12 
13 #include <Akonadi/Collection>
14 #include <Akonadi/KMime/SpecialMailCollections>
15 #include <KSharedConfig>
16 
17 #include <QObject>
18 namespace PimCommon
19 {
20 class ImapResourceCapabilitiesManager;
21 }
22 namespace MailCommon
23 {
24 /**
25  * Deals with common mail application related operations. The required interfaces
26  * MUST be registered before using it!
27  * Be careful when using in multi-threaded applications, as Kernel is a QObject
28  * singleton, created in the main thread, thus event handling for Kernel::self()
29  * will happen in the main thread.
30  */
31 
32 class MAILCOMMON_EXPORT Kernel : public QObject
33 {
34     Q_OBJECT
35 public:
36     ~Kernel() override;
37 
38     static Kernel *self();
39 
40     /**
41      * Registers the interface dealing with main mail functionality. This function
42      * MUST be called with a valid interface pointer, before any Kernel::self()
43      * method is used. The pointer ownership will not be transferred to Kernel.
44      */
45     void registerKernelIf(IKernel *kernelIf);
46 
47     bool kernelIsRegistered() const;
48 
49     IKernel *kernelIf() const;
50 
51     /**
52      * Registers the interface dealing with mail settings. This function
53      * MUST be called with a valid interface pointer, before any Kernel::self()
54      * method is used. The pointer ownership will not be transferred to Kernel.
55      */
56     void registerSettingsIf(ISettings *settingsIf);
57 
58     ISettings *settingsIf() const;
59 
60     /**
61      * Registers the interface dealing with mail settings. This function
62      * MUST be called with a valid interface pointer, before any Kernel::self()
63      * method is used. The pointer ownership will not be transferred to Kernel.
64      */
65     void registerFilterIf(IFilter *filterIf);
66 
67     IFilter *filterIf() const;
68 
69     /**
70      * Returns the collection associated with the given @p id, or an invalid
71      * collection if not found. The EntityTreeModel of the kernel is searched for
72      * the collection. Since the ETM is loaded async, this method will not find
73      * the collection right after startup, when the ETM is not yet fully loaded.
74      */
75     Akonadi::Collection collectionFromId(Akonadi::Collection::Id id) const;
76 
77     Akonadi::Collection inboxCollectionFolder();
78     Akonadi::Collection outboxCollectionFolder();
79     Akonadi::Collection sentCollectionFolder();
80     Akonadi::Collection trashCollectionFolder();
81     Akonadi::Collection draftsCollectionFolder();
82     Akonadi::Collection templatesCollectionFolder();
83 
84     bool isSystemFolderCollection(const Akonadi::Collection &col);
85 
86     /**
87      * Returns true if this folder is the inbox on the local disk
88      */
89     bool isMainFolderCollection(const Akonadi::Collection &col);
90 
91     /**
92      * Returns true if the folder is either the outbox or one of the drafts-folders.
93      */
94     bool folderIsDraftOrOutbox(const Akonadi::Collection &collection);
95 
96     bool folderIsDrafts(const Akonadi::Collection &);
97 
98     bool folderIsTemplates(const Akonadi::Collection &collection);
99 
100     /**
101      * Returns true if the folder is a trash folder.
102      *
103      * When calling this too early (before the SpecialMailCollectionsDiscoveryJob from initFolders finishes),
104      * it will say false erroneously. However you can connect to SpecialMailCollections::collectionsChanged
105      * to react on dynamic changes and call this again.
106      */
107     bool folderIsTrash(const Akonadi::Collection &collection);
108 
109     /**
110      * Returns the trash folder for the resource which @p col belongs to.
111      *
112      * When calling this too early (before the SpecialMailCollectionsDiscoveryJob from initFolders finishes),
113      * it will return an invalid collection erroneously. However you can connect to SpecialMailCollections::collectionsChanged
114      * to react on dynamic changes and call this again.
115      */
116     Akonadi::Collection trashCollectionFromResource(const Akonadi::Collection &col);
117 
118     /**
119      * Returns true if the folder is one of the sent-mail folders.
120      */
121     bool folderIsSentMailFolder(const Akonadi::Collection &);
122 
123     static bool folderIsInbox(const Akonadi::Collection &);
124 
125     void initFolders();
126 
127     void emergencyExit(const QString &reason);
128 
129     PimCommon::ImapResourceCapabilitiesManager *imapResourceManager() const;
130 
131     static QMap<QString, Akonadi::Collection::Id> pop3ResourceTargetCollection();
132 
133 private:
134     void findCreateDefaultCollection(Akonadi::SpecialMailCollections::Type);
135 
136 private Q_SLOTS:
137     void createDefaultCollectionDone(KJob *job);
138     void slotDefaultCollectionsChanged();
139 
140 Q_SIGNALS:
141     void requestConfigSync();
142     void requestSystemTrayUpdate();
143 
144 private:
145     Kernel(QObject *parent = nullptr);
146     friend class KernelPrivate;
147 
148     IKernel *mKernelIf;
149     IFilter *mFilterIf;
150     ISettings *mSettingsIf;
151     PimCommon::ImapResourceCapabilitiesManager *mImapResourceManager;
152 };
153 }
154 
155 #define KernelIf MailCommon::Kernel::self()->kernelIf()
156 #define FilterIf MailCommon::Kernel::self()->filterIf()
157 #define SettingsIf MailCommon::Kernel::self()->settingsIf()
158 #define CommonKernel MailCommon::Kernel::self()
159 
160