Mailcommon

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

KDE's Doxygen guidelines are available online.