Mailcommon

foldersettings.cpp
1 /*
2 
3  SPDX-FileCopyrightText: 2009-2022 Laurent Montel <[email protected]>
4 
5  SPDX-License-Identifier: GPL-2.0-or-later
6 */
7 
8 #include "foldersettings.h"
9 #include "kernel/mailkernel.h"
10 #include "mailcommon_debug.h"
11 #include "util/mailutil.h"
12 #include "util/resourcereadconfigfile.h"
13 #include <Akonadi/CollectionModifyJob>
14 #include <Akonadi/ItemFetchJob>
15 #include <Akonadi/ItemFetchScope>
16 #include <Akonadi/NewMailNotifierAttribute>
17 #include <PimCommon/PimUtil>
18 
19 using namespace Akonadi;
20 
21 #include <KIdentityManagement/Identity>
22 #include <KIdentityManagement/IdentityManager>
23 
24 #include <QMutex>
25 #include <QMutexLocker>
26 #include <QSharedPointer>
27 
28 namespace MailCommon
29 {
30 static QMutex mapMutex;
32 
33 QSharedPointer<FolderSettings> FolderSettings::forCollection(const Akonadi::Collection &coll, bool writeConfig)
34 {
35  QMutexLocker lock(&mapMutex);
36 
37  QSharedPointer<FolderSettings> sptr = fcMap.value(coll.id());
38 
39  if (sptr.isNull()) {
40  sptr = QSharedPointer<FolderSettings>(new FolderSettings(coll, writeConfig));
41  fcMap.insert(coll.id(), sptr);
42  } else {
43  sptr->setCollection(coll);
44  if (!sptr->isWriteConfig() && writeConfig) {
45  sptr->setWriteConfig(true);
46  }
47  }
48 
49  return sptr;
50 }
51 
52 FolderSettings::FolderSettings(const Akonadi::Collection &col, bool writeconfig)
53  : mCollection(col)
54  , mWriteConfig(writeconfig)
55 {
56  Q_ASSERT(col.isValid());
57  mIdentity = KernelIf->identityManager()->defaultIdentity().uoid();
58 
59  readConfig();
60  connect(KernelIf->identityManager(), qOverload<>(&KIdentityManagement::IdentityManager::changed), this, &FolderSettings::slotIdentitiesChanged);
61 }
62 
63 FolderSettings::~FolderSettings()
64 {
65  // qCDebug(MAILCOMMON_LOG)<<" FolderCollection::~FolderCollection"<<this;
66  if (mWriteConfig) {
67  writeConfig();
68  }
69 }
70 
71 MessageViewer::Viewer::DisplayFormatMessage FolderSettings::formatMessage() const
72 {
73  return mFormatMessage;
74 }
75 
76 void FolderSettings::setFormatMessage(MessageViewer::Viewer::DisplayFormatMessage formatMessage)
77 {
78  mFormatMessage = formatMessage;
79 }
80 
81 void FolderSettings::clearCache()
82 {
83  QMutexLocker lock(&mapMutex);
84  fcMap.clear();
85 }
86 
87 void FolderSettings::resetHtmlFormat()
88 {
89  QMutexLocker lock(&mapMutex);
90  QMap<Collection::Id, QSharedPointer<FolderSettings>>::const_iterator i = fcMap.constBegin();
91  while (i != fcMap.constEnd()) {
92  i.value()->setFormatMessage(MessageViewer::Viewer::UseGlobalSetting);
93  ++i;
94  }
95 }
96 
97 bool FolderSettings::isWriteConfig() const
98 {
99  return mWriteConfig;
100 }
101 
102 void FolderSettings::setWriteConfig(bool writeConfig)
103 {
104  mWriteConfig = writeConfig;
105 }
106 
107 QString FolderSettings::name() const
108 {
109  return mCollection.name();
110 }
111 
112 bool FolderSettings::isSystemFolder() const
113 {
114  return Kernel::self()->isSystemFolderCollection(mCollection);
115 }
116 
117 bool FolderSettings::isStructural() const
118 {
119  return mCollection.contentMimeTypes().isEmpty();
120 }
121 
122 bool FolderSettings::isReadOnly() const
123 {
124  return mCollection.rights() & Akonadi::Collection::ReadOnly;
125 }
126 
127 bool FolderSettings::canDeleteMessages() const
128 {
129  return mCollection.rights() & Akonadi::Collection::CanDeleteItem;
130 }
131 
132 bool FolderSettings::canCreateMessages() const
133 {
134  return mCollection.rights() & Akonadi::Collection::CanCreateItem;
135 }
136 
137 qint64 FolderSettings::count() const
138 {
139  return mCollection.statistics().count();
140 }
141 
142 Akonadi::Collection::Rights FolderSettings::rights() const
143 {
144  return mCollection.rights();
145 }
146 
147 Akonadi::CollectionStatistics FolderSettings::statistics() const
148 {
149  return mCollection.statistics();
150 }
151 
152 void FolderSettings::setCollection(const Akonadi::Collection &collection)
153 {
154  mCollection = collection;
155 }
156 
157 void FolderSettings::slotIdentitiesChanged()
158 {
159  uint defaultIdentity = KernelIf->identityManager()->defaultIdentity().uoid();
160  // The default identity may have changed, therefore set it again if necessary
161  if (mUseDefaultIdentity) {
162  mIdentity = defaultIdentity;
163  }
164 
165  // Fall back to the default identity if the one used currently is invalid
166  if (KernelIf->identityManager()->identityForUoid(mIdentity).isNull()) {
167  mIdentity = defaultIdentity;
168  mUseDefaultIdentity = true;
169  }
170 }
171 
172 QString FolderSettings::configGroupName(const Akonadi::Collection &col)
173 {
174  return QStringLiteral("Folder-%1").arg(QString::number(col.id()));
175 }
176 
177 void FolderSettings::readConfig()
178 {
179  KConfigGroup configGroup(KernelIf->config(), configGroupName(mCollection));
180  mMailingListEnabled = configGroup.readEntry("MailingListEnabled", false);
181  mMailingList.readConfig(configGroup);
182 
183  mUseDefaultIdentity = configGroup.readEntry("UseDefaultIdentity", true);
184  uint defaultIdentity = KernelIf->identityManager()->defaultIdentity().uoid();
185  mIdentity = configGroup.readEntry("Identity", defaultIdentity);
186  slotIdentitiesChanged();
187 
188  mPutRepliesInSameFolder = configGroup.readEntry("PutRepliesInSameFolder", false);
189  mHideInSelectionDialog = configGroup.readEntry("HideInSelectionDialog", false);
190 
191  if (configGroup.hasKey(QStringLiteral("IgnoreNewMail"))) {
192  if (configGroup.readEntry(QStringLiteral("IgnoreNewMail"), false)) {
193  // migrate config.
194  auto *newMailNotifierAttr = mCollection.attribute<Akonadi::NewMailNotifierAttribute>(Akonadi::Collection::AddIfMissing);
195  newMailNotifierAttr->setIgnoreNewMail(true);
196  new Akonadi::CollectionModifyJob(mCollection, this);
197  // TODO verify if it works;
198  }
199  configGroup.deleteEntry("IgnoreNewMail");
200  }
201 
202  const QString shortcut(configGroup.readEntry("Shortcut"));
203  if (!shortcut.isEmpty()) {
204  QKeySequence sc(shortcut);
205  setShortcut(sc);
206  }
207 
208  mFormatMessage = static_cast<MessageViewer::Viewer::DisplayFormatMessage>(
209  configGroup.readEntry("displayFormatOverride", static_cast<int>(MessageViewer::Viewer::UseGlobalSetting)));
210 
211  mFolderHtmlLoadExtPreference = configGroup.readEntry("htmlLoadExternalOverride", false);
212 }
213 
214 bool FolderSettings::isValid() const
215 {
216  return mCollection.isValid();
217 }
218 
219 void FolderSettings::writeConfig() const
220 {
221  const QString res = resource();
222  KConfigGroup configGroup(KernelIf->config(), configGroupName(mCollection));
223 
224  if (mMailingListEnabled) {
225  configGroup.writeEntry("MailingListEnabled", mMailingListEnabled);
226  } else {
227  configGroup.deleteEntry("MailingListEnabled");
228  }
229  mMailingList.writeConfig(configGroup);
230 
231  if (!mUseDefaultIdentity) {
232  configGroup.writeEntry("UseDefaultIdentity", mUseDefaultIdentity);
233  uint defaultIdentityId = -1;
234 
235  if (PimCommon::Util::isImapResource(res)) {
236  MailCommon::ResourceReadConfigFile resourceFile(res);
237  KConfigGroup grp = resourceFile.group(QStringLiteral("cache"));
238  if (grp.isValid()) {
239  defaultIdentityId = grp.readEntry(QStringLiteral("AccountIdentity"), -1);
240  }
241  } else {
242  defaultIdentityId = KernelIf->identityManager()->defaultIdentity().uoid();
243  }
244 
245  if (mIdentity != defaultIdentityId) {
246  configGroup.writeEntry("Identity", mIdentity);
247  } else {
248  configGroup.deleteEntry("Identity");
249  }
250  } else {
251  configGroup.deleteEntry("Identity");
252  configGroup.deleteEntry("UseDefaultIdentity");
253  }
254 
255  if (mPutRepliesInSameFolder) {
256  configGroup.writeEntry("PutRepliesInSameFolder", mPutRepliesInSameFolder);
257  } else {
258  configGroup.deleteEntry("PutRepliesInSameFolder");
259  }
260  if (mHideInSelectionDialog) {
261  configGroup.writeEntry("HideInSelectionDialog", mHideInSelectionDialog);
262  } else {
263  configGroup.deleteEntry("HideInSelectionDialog");
264  }
265 
266  if (!mShortcut.isEmpty()) {
267  configGroup.writeEntry("Shortcut", mShortcut.toString());
268  } else {
269  configGroup.deleteEntry("Shortcut");
270  }
271 
272  if (mFormatMessage != MessageViewer::Viewer::Unknown) {
273  if (mFormatMessage == MessageViewer::Viewer::UseGlobalSetting) {
274  configGroup.deleteEntry("displayFormatOverride");
275  } else {
276  configGroup.writeEntry("displayFormatOverride", static_cast<int>(mFormatMessage));
277  }
278  }
279  if (mFolderHtmlLoadExtPreference) {
280  configGroup.writeEntry("htmlLoadExternalOverride", mFolderHtmlLoadExtPreference);
281  } else {
282  configGroup.deleteEntry("htmlLoadExternalOverride");
283  }
284 }
285 
286 void FolderSettings::setShortcut(const QKeySequence &sc)
287 {
288  mShortcut = sc;
289 }
290 
291 const QKeySequence &FolderSettings::shortcut() const
292 {
293  return mShortcut;
294 }
295 
296 void FolderSettings::setUseDefaultIdentity(bool useDefaultIdentity)
297 {
298  if (mUseDefaultIdentity != useDefaultIdentity) {
299  mUseDefaultIdentity = useDefaultIdentity;
300  if (mUseDefaultIdentity) {
301  mIdentity = KernelIf->identityManager()->defaultIdentity().uoid();
302  }
303  KernelIf->syncConfig();
304  }
305 }
306 
307 bool FolderSettings::useDefaultIdentity() const
308 {
309  return mUseDefaultIdentity;
310 }
311 
312 void FolderSettings::setIdentity(uint identity)
313 {
314  if (mIdentity != identity) {
315  mIdentity = identity;
316  KernelIf->syncConfig();
317  }
318 }
319 
320 QString FolderSettings::resource() const
321 {
322  const QString resource = mCollection.resource();
323  if (resource.isEmpty()) {
324  const Collection col = CommonKernel->collectionFromId(mCollection.id());
325  Q_ASSERT(col.isValid());
326  Q_ASSERT(!col.resource().isEmpty());
327  return col.resource();
328  }
329  return resource;
330 }
331 
332 bool FolderSettings::folderHtmlLoadExtPreference() const
333 {
334  return mFolderHtmlLoadExtPreference;
335 }
336 
337 void FolderSettings::setFolderHtmlLoadExtPreference(bool folderHtmlLoadExtPreference)
338 {
339  mFolderHtmlLoadExtPreference = folderHtmlLoadExtPreference;
340 }
341 
342 uint FolderSettings::fallBackIdentity() const
343 {
344  int identityId = -1;
345  MailCommon::ResourceReadConfigFile resourceFile(resource());
346  KConfigGroup grp = resourceFile.group(QStringLiteral("cache"));
347  if (grp.isValid()) {
348  const bool useDefault = grp.readEntry(QStringLiteral("UseDefaultIdentity"), true);
349  if (useDefault) {
350  return mIdentity;
351  }
352  const int remoteAccountIdent = grp.readEntry(QStringLiteral("AccountIdentity"), -1);
353  if (remoteAccountIdent > 0) {
354  identityId = remoteAccountIdent;
355  }
356  }
357  if (identityId != -1 && !KernelIf->identityManager()->identityForUoid(identityId).isNull()) {
358  return identityId;
359  }
360  return mIdentity;
361 }
362 
363 uint FolderSettings::identity() const
364 {
365  if (mUseDefaultIdentity) {
366  return fallBackIdentity();
367  }
368  return mIdentity;
369 }
370 
371 QString FolderSettings::mailingListPostAddress() const
372 {
373  if (mMailingList.features() & MailingList::Post) {
374  QList<QUrl> post = mMailingList.postUrls();
376  for (QList<QUrl>::const_iterator it = post.constBegin(); it != end; ++it) {
377  // We check for isEmpty because before 3.3 postAddress was just an
378  // [email protected] and that leaves protocol() field in the qurl class
379  const QString protocol = (*it).scheme();
380  if (protocol == QLatin1String("mailto") || protocol.isEmpty()) {
381  return (*it).path();
382  }
383  }
384  }
385  return {};
386 }
387 
389 {
390  if (mMailingListEnabled != enabled) {
391  mMailingListEnabled = enabled;
392  writeConfig();
393  }
394 }
395 
396 bool FolderSettings::isMailingListEnabled() const
397 {
398  return mMailingListEnabled;
399 }
400 
401 void FolderSettings::setMailingList(const MailingList &mlist)
402 {
403  if (mMailingList == mlist) {
404  return;
405  }
406 
407  mMailingList = mlist;
408  writeConfig();
409 }
410 
411 MessageCore::MailingList FolderSettings::mailingList() const
412 {
413  return mMailingList;
414 }
415 
417 {
418  return mPutRepliesInSameFolder;
419 }
420 
421 void FolderSettings::setPutRepliesInSameFolder(bool b)
422 {
423  mPutRepliesInSameFolder = b;
424 }
425 
427 {
428  return mHideInSelectionDialog;
429 }
430 
431 void FolderSettings::setHideInSelectionDialog(bool hide)
432 {
433  mHideInSelectionDialog = hide;
434 }
435 }
QString readEntry(const char *key, const char *aDefault=nullptr) const
QString number(int n, int base)
bool isNull() const const
const T value(const Key &key, const T &defaultValue) const const
QList< QUrl > postUrls() const
bool isValid() const
QList::const_iterator constBegin() const const
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
bool putRepliesInSameFolder() const
Returns true if the replies to mails from this folder should be put in the same folder.
void setUseDefaultIdentity(bool useDefaultIdentity)
Get / set whether the default identity should be used instead of the identity specified by setIdentit...
void setMailingListEnabled(bool enabled)
Returns true if this folder is associated with a mailing-list.
bool hideInSelectionDialog() const
Returns true if this folder should be hidden from all folder selection dialogs.
bool isEmpty() const const
QString toString(QKeySequence::SequenceFormat format) const const
const T * attribute() const
KConfigGroup group(const char *group)
bool isEmpty() const const
Rights rights() const
QStringList contentMimeTypes() const
void writeConfig(KConfigGroup &group) const
Features features() const
QList::const_iterator constEnd() const const
QString arg(qlonglong a, int fieldWidth, int base, QChar fillChar) const const
CollectionStatistics statistics() const
QString resource() const
bool isValid() const
void readConfig(const KConfigGroup &group)
bool isEmpty() const const
const QList< QKeySequence > & end()
The filter dialog.
QString name() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sat Sep 24 2022 03:58:15 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.