Mailcommon

mailkernel.cpp
1 /*
2  SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
3  SPDX-FileCopyrightText: 2010 Andras Mantia <[email protected]>
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 <Akonadi/AgentInstance>
15 #include <Akonadi/AgentManager>
16 #include <Akonadi/EntityMimeTypeFilterModel>
17 #include <Akonadi/SpecialMailCollectionsDiscoveryJob>
18 #include <Akonadi/SpecialMailCollectionsRequestJob>
19 #include <QApplication>
20 #include <util/resourcereadconfigfile.h>
21 
22 #include <KIdentityManagement/Identity>
23 #include <KIdentityManagement/IdentityManager>
24 
25 #include <KLocalizedString>
26 #include <KMessageBox>
27 
28 namespace MailCommon
29 {
30 class KernelPrivate
31 {
32 public:
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 
47 Q_GLOBAL_STATIC(KernelPrivate, sInstance)
48 
49 Kernel::Kernel(QObject *parent)
50  : QObject(parent)
51 {
52  mKernelIf = nullptr;
53  mSettingsIf = nullptr;
54  mFilterIf = nullptr;
55  mImapResourceManager = new PimCommon::ImapResourceCapabilitiesManager(this);
56 }
57 
58 Kernel::~Kernel()
59 {
60  qCDebug(MAILCOMMON_LOG);
61 }
62 
63 Kernel *Kernel::self()
64 {
65  return sInstance->kernel; // will create it
66 }
67 
69 {
70  mKernelIf = kernelIf;
71 }
72 
73 bool Kernel::kernelIsRegistered() const
74 {
75  return mKernelIf != nullptr;
76 }
77 
78 IKernel *Kernel::kernelIf() const
79 {
80  Q_ASSERT(mKernelIf);
81  return mKernelIf;
82 }
83 
85 {
86  mSettingsIf = settingsIf;
87 }
88 
89 ISettings *Kernel::settingsIf() const
90 {
91  Q_ASSERT(mSettingsIf);
92  return mSettingsIf;
93 }
94 
96 {
97  mFilterIf = filterIf;
98 }
99 
100 IFilter *Kernel::filterIf() const
101 {
102  Q_ASSERT(mFilterIf);
103  return mFilterIf;
104 }
105 
106 PimCommon::ImapResourceCapabilitiesManager *Kernel::imapResourceManager() const
107 {
108  return mImapResourceManager;
109 }
110 
112 {
113  return Akonadi::EntityTreeModel::updatedCollection(kernelIf()->collectionModel(), id);
114 }
115 
116 Akonadi::Collection Kernel::trashCollectionFolder()
117 {
119 }
120 
121 Akonadi::Collection Kernel::inboxCollectionFolder()
122 {
124 }
125 
126 Akonadi::Collection Kernel::outboxCollectionFolder()
127 {
129 }
130 
131 Akonadi::Collection Kernel::sentCollectionFolder()
132 {
134 }
135 
136 Akonadi::Collection Kernel::draftsCollectionFolder()
137 {
139 }
140 
141 Akonadi::Collection Kernel::templatesCollectionFolder()
142 {
144 }
145 
146 bool Kernel::isSystemFolderCollection(const Akonadi::Collection &col)
147 {
148  return col == inboxCollectionFolder() || col == outboxCollectionFolder() || col == sentCollectionFolder() || col == trashCollectionFolder()
149  || col == draftsCollectionFolder() || col == templatesCollectionFolder();
150 }
151 
153 {
154  return col == inboxCollectionFolder();
155 }
156 
157 //-----------------------------------------------------------------------------
158 void 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 
173 void 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 {
182  auto *job = new Akonadi::SpecialMailCollectionsRequestJob(this);
183 
184  connect(job, &Akonadi::SpecialMailCollectionsRequestJob::result, this, &Kernel::createDefaultCollectionDone);
185 
186  job->requestDefaultCollection(type);
187  }
188 }
189 
190 void 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 
217 void Kernel::slotDefaultCollectionsChanged()
218 {
221  this,
222  &Kernel::slotDefaultCollectionsChanged);
223  initFolders();
224 }
225 
226 void 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 
252 {
254  return true;
255  }
256 
257  return folderIsDrafts(col);
258 }
259 
260 bool 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 KIdentityManagement::IdentityManager *im = KernelIf->identityManager();
273  KIdentityManagement::IdentityManager::ConstIterator end(im->end());
274  for (KIdentityManagement::IdentityManager::ConstIterator it = im->begin(); it != end; ++it) {
275  if ((*it).drafts() == idString) {
276  return true;
277  }
278  }
279  return false;
280 }
281 
282 bool 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 KIdentityManagement::IdentityManager *im = KernelIf->identityManager();
294  KIdentityManagement::IdentityManager::ConstIterator end(im->end());
295  for (KIdentityManagement::IdentityManager::ConstIterator it = im->begin(); it != end; ++it) {
296  if ((*it).templates() == idString) {
297  return true;
298  }
299  }
300  return false;
301 }
302 
304 {
305  Akonadi::Collection trashCol;
306  if (col.isValid()) {
309  }
310  return trashCol;
311 }
312 
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 
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 KIdentityManagement::IdentityManager *im = KernelIf->identityManager();
341  KIdentityManagement::IdentityManager::ConstIterator end(im->end());
342  for (KIdentityManagement::IdentityManager::ConstIterator it = im->begin(); it != end; ++it) {
343  if ((*it).fcc() == idString) {
344  return true;
345  }
346  }
347  return false;
348 }
349 
350 bool Kernel::folderIsInbox(const Akonadi::Collection &collection)
351 {
352  const QString collectionRemoteIdLower = collection.remoteId().toLower();
353  if (collectionRemoteIdLower == QLatin1String("inbox") || collectionRemoteIdLower == QLatin1String("/inbox")
354  || collectionRemoteIdLower == QLatin1String(".inbox") || collectionRemoteIdLower == QLatin1String("|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 
369 QMap<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 }
static Collection updatedCollection(const QAbstractItemModel *model, qint64 collectionId)
QString readEntry(const char *key, const char *aDefault=nullptr) const
Akonadi::Collection collectionFromId(Akonadi::Collection::Id id) const
Returns the collection associated with the given id, or an invalid collection if not found.
Definition: mailkernel.cpp:111
Akonadi::Collection defaultCollection(Type type) const
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QString number(int n, int base)
void result(KJob *job)
Type type(const QSqlDatabase &db)
Akonadi::Collection trashCollectionFromResource(const Akonadi::Collection &col)
Returns the trash folder for the resource which col belongs to.
Definition: mailkernel.cpp:303
void registerFilterIf(IFilter *filterIf)
Registers the interface dealing with mail settings.
Definition: mailkernel.cpp:95
bool isValid() const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void registerKernelIf(IKernel *kernelIf)
Registers the interface dealing with main mail functionality.
Definition: mailkernel.cpp:68
Q_GLOBAL_STATIC(Internal::StaticControl, s_instance) class ControlPrivate
AgentInstance instance(const QString &identifier) const
QMap::iterator insert(const Key &key, const T &value)
bool folderIsDraftOrOutbox(const Akonadi::Collection &collection)
Returns true if the folder is either the outbox or one of the drafts-folders.
Definition: mailkernel.cpp:251
Interface to access some settings.
QString i18n(const char *text, const TYPE &arg...)
bool folderIsSentMailFolder(const Akonadi::Collection &)
Returns true if the folder is one of the sent-mail folders.
Definition: mailkernel.cpp:329
bool isMainFolderCollection(const Akonadi::Collection &col)
Returns true if this folder is the inbox on the local disk.
Definition: mailkernel.cpp:152
bool isEmpty() const const
QString errorText() const
KConfigGroup group(const char *group)
UniqueConnection
Rights rights() const
void registerSettingsIf(ISettings *settingsIf)
Registers the interface dealing with mail settings.
Definition: mailkernel.cpp:84
void error(QWidget *parent, const QString &text, const QString &title, const KGuiItem &buttonOk, Options options=Notify)
QString remoteId() const
Akonadi::Collection collection(Type type, const AgentInstance &instance) const
QString toLower() const const
Filter related interface.
Generic interface for mail kernels.
QString resource() const
static SpecialMailCollections * self()
static AgentManager * self()
bool isValid() const
int error() const
bool contains(QChar ch, Qt::CaseSensitivity cs) const const
const QList< QKeySequence > & end()
The filter dialog.
bool folderIsTrash(const Akonadi::Collection &collection)
Returns true if the folder is a trash folder.
Definition: mailkernel.cpp:313
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Oct 1 2022 04:00:53 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.