Warning, file /pim/mailcommon/src/folder/foldersettings.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002 
0003   SPDX-FileCopyrightText: 2009-2024 Laurent Montel <montel@kde.org>
0004 
0005   SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "foldersettings.h"
0009 #include "kernel/mailkernel.h"
0010 #include "util/resourcereadconfigfile.h"
0011 #include <Akonadi/CollectionModifyJob>
0012 #include <Akonadi/ItemFetchJob>
0013 #include <Akonadi/ItemFetchScope>
0014 #include <Akonadi/NewMailNotifierAttribute>
0015 #include <PimCommon/PimUtil>
0016 
0017 using namespace Akonadi;
0018 
0019 #include <KIdentityManagementCore/Identity>
0020 #include <KIdentityManagementCore/IdentityManager>
0021 
0022 #include <QMutex>
0023 #include <QMutexLocker>
0024 #include <QSharedPointer>
0025 
0026 namespace MailCommon
0027 {
0028 static QMutex mapMutex;
0029 static QMap<Collection::Id, QSharedPointer<FolderSettings>> fcMap;
0030 
0031 QSharedPointer<FolderSettings> FolderSettings::forCollection(const Akonadi::Collection &coll, bool writeConfig)
0032 {
0033     QMutexLocker lock(&mapMutex);
0034 
0035     QSharedPointer<FolderSettings> sptr = fcMap.value(coll.id());
0036 
0037     if (sptr.isNull()) {
0038         sptr = QSharedPointer<FolderSettings>(new FolderSettings(coll, writeConfig));
0039         fcMap.insert(coll.id(), sptr);
0040     } else {
0041         sptr->setCollection(coll);
0042         if (!sptr->isWriteConfig() && writeConfig) {
0043             sptr->setWriteConfig(true);
0044         }
0045     }
0046 
0047     return sptr;
0048 }
0049 
0050 FolderSettings::FolderSettings(const Akonadi::Collection &col, bool writeconfig)
0051     : mCollection(col)
0052     , mWriteConfig(writeconfig)
0053 {
0054     Q_ASSERT(col.isValid());
0055     mIdentity = KernelIf->identityManager()->defaultIdentity().uoid();
0056 
0057     readConfig();
0058     connect(KernelIf->identityManager(), qOverload<>(&KIdentityManagementCore::IdentityManager::changed), this, &FolderSettings::slotIdentitiesChanged);
0059 }
0060 
0061 FolderSettings::~FolderSettings()
0062 {
0063     // qCDebug(MAILCOMMON_LOG)<<" FolderCollection::~FolderCollection"<<this;
0064     if (mWriteConfig) {
0065         writeConfig();
0066     }
0067 }
0068 
0069 MessageViewer::Viewer::DisplayFormatMessage FolderSettings::formatMessage() const
0070 {
0071     return mFormatMessage;
0072 }
0073 
0074 void FolderSettings::setFormatMessage(MessageViewer::Viewer::DisplayFormatMessage formatMessage)
0075 {
0076     mFormatMessage = formatMessage;
0077 }
0078 
0079 void FolderSettings::clearCache()
0080 {
0081     QMutexLocker lock(&mapMutex);
0082     fcMap.clear();
0083 }
0084 
0085 void FolderSettings::resetHtmlFormat()
0086 {
0087     QMutexLocker lock(&mapMutex);
0088     QMap<Collection::Id, QSharedPointer<FolderSettings>>::const_iterator i = fcMap.constBegin();
0089     while (i != fcMap.constEnd()) {
0090         i.value()->setFormatMessage(MessageViewer::Viewer::UseGlobalSetting);
0091         ++i;
0092     }
0093 }
0094 
0095 bool FolderSettings::isWriteConfig() const
0096 {
0097     return mWriteConfig;
0098 }
0099 
0100 void FolderSettings::setWriteConfig(bool writeConfig)
0101 {
0102     mWriteConfig = writeConfig;
0103 }
0104 
0105 QString FolderSettings::name() const
0106 {
0107     return mCollection.name();
0108 }
0109 
0110 bool FolderSettings::isSystemFolder() const
0111 {
0112     return Kernel::self()->isSystemFolderCollection(mCollection);
0113 }
0114 
0115 bool FolderSettings::isStructural() const
0116 {
0117     return mCollection.contentMimeTypes().isEmpty();
0118 }
0119 
0120 bool FolderSettings::isReadOnly() const
0121 {
0122     return mCollection.rights() & Akonadi::Collection::ReadOnly;
0123 }
0124 
0125 bool FolderSettings::canDeleteMessages() const
0126 {
0127     return mCollection.rights() & Akonadi::Collection::CanDeleteItem;
0128 }
0129 
0130 bool FolderSettings::canCreateMessages() const
0131 {
0132     return mCollection.rights() & Akonadi::Collection::CanCreateItem;
0133 }
0134 
0135 qint64 FolderSettings::count() const
0136 {
0137     return mCollection.statistics().count();
0138 }
0139 
0140 Akonadi::Collection::Rights FolderSettings::rights() const
0141 {
0142     return mCollection.rights();
0143 }
0144 
0145 Akonadi::CollectionStatistics FolderSettings::statistics() const
0146 {
0147     return mCollection.statistics();
0148 }
0149 
0150 void FolderSettings::setCollection(const Akonadi::Collection &collection)
0151 {
0152     mCollection = collection;
0153 }
0154 
0155 void FolderSettings::slotIdentitiesChanged()
0156 {
0157     uint defaultIdentity = KernelIf->identityManager()->defaultIdentity().uoid();
0158     // The default identity may have changed, therefore set it again if necessary
0159     if (mUseDefaultIdentity) {
0160         mIdentity = defaultIdentity;
0161     }
0162 
0163     // Fall back to the default identity if the one used currently is invalid
0164     if (KernelIf->identityManager()->identityForUoid(mIdentity).isNull()) {
0165         mIdentity = defaultIdentity;
0166         mUseDefaultIdentity = true;
0167     }
0168 }
0169 
0170 QString FolderSettings::configGroupName(const Akonadi::Collection &col)
0171 {
0172     return QStringLiteral("Folder-%1").arg(QString::number(col.id()));
0173 }
0174 
0175 void FolderSettings::readConfig()
0176 {
0177     KConfigGroup configGroup(KernelIf->config(), configGroupName(mCollection));
0178     mMailingListEnabled = configGroup.readEntry("MailingListEnabled", false);
0179     mMailingList.readConfig(configGroup);
0180 
0181     mUseDefaultIdentity = configGroup.readEntry("UseDefaultIdentity", true);
0182     uint defaultIdentity = KernelIf->identityManager()->defaultIdentity().uoid();
0183     mIdentity = configGroup.readEntry("Identity", defaultIdentity);
0184     slotIdentitiesChanged();
0185 
0186     mPutRepliesInSameFolder = configGroup.readEntry("PutRepliesInSameFolder", false);
0187     mHideInSelectionDialog = configGroup.readEntry("HideInSelectionDialog", false);
0188 
0189     if (configGroup.hasKey(QStringLiteral("IgnoreNewMail"))) {
0190         if (configGroup.readEntry(QStringLiteral("IgnoreNewMail"), false)) {
0191             // migrate config.
0192             auto newMailNotifierAttr = mCollection.attribute<Akonadi::NewMailNotifierAttribute>(Akonadi::Collection::AddIfMissing);
0193             newMailNotifierAttr->setIgnoreNewMail(true);
0194             new Akonadi::CollectionModifyJob(mCollection, this);
0195             // TODO verify if it works;
0196         }
0197         configGroup.deleteEntry("IgnoreNewMail");
0198     }
0199 
0200     const QString shortcut(configGroup.readEntry("Shortcut"));
0201     if (!shortcut.isEmpty()) {
0202         QKeySequence sc(shortcut);
0203         setShortcut(sc);
0204     }
0205 
0206     mFormatMessage = static_cast<MessageViewer::Viewer::DisplayFormatMessage>(
0207         configGroup.readEntry("displayFormatOverride", static_cast<int>(MessageViewer::Viewer::UseGlobalSetting)));
0208 
0209     mFolderHtmlLoadExtPreference = configGroup.readEntry("htmlLoadExternalOverride", false);
0210 }
0211 
0212 bool FolderSettings::isValid() const
0213 {
0214     return mCollection.isValid();
0215 }
0216 
0217 void FolderSettings::writeConfig() const
0218 {
0219     const QString res = resource();
0220     if (res.isEmpty()) {
0221         return;
0222     }
0223     KConfigGroup configGroup(KernelIf->config(), configGroupName(mCollection));
0224 
0225     if (mMailingListEnabled) {
0226         configGroup.writeEntry("MailingListEnabled", mMailingListEnabled);
0227     } else {
0228         configGroup.deleteEntry("MailingListEnabled");
0229     }
0230     mMailingList.writeConfig(configGroup);
0231 
0232     if (!mUseDefaultIdentity) {
0233         configGroup.writeEntry("UseDefaultIdentity", mUseDefaultIdentity);
0234         uint defaultIdentityId = -1;
0235 
0236         if (PimCommon::Util::isImapResource(res)) {
0237             MailCommon::ResourceReadConfigFile resourceFile(res);
0238             KConfigGroup grp = resourceFile.group(QStringLiteral("cache"));
0239             if (grp.isValid()) {
0240                 defaultIdentityId = grp.readEntry(QStringLiteral("AccountIdentity"), -1);
0241             }
0242         } else {
0243             defaultIdentityId = KernelIf->identityManager()->defaultIdentity().uoid();
0244         }
0245 
0246         if (mIdentity != defaultIdentityId) {
0247             configGroup.writeEntry("Identity", mIdentity);
0248         } else {
0249             configGroup.deleteEntry("Identity");
0250         }
0251     } else {
0252         configGroup.deleteEntry("Identity");
0253         configGroup.deleteEntry("UseDefaultIdentity");
0254     }
0255 
0256     if (mPutRepliesInSameFolder) {
0257         configGroup.writeEntry("PutRepliesInSameFolder", mPutRepliesInSameFolder);
0258     } else {
0259         configGroup.deleteEntry("PutRepliesInSameFolder");
0260     }
0261     if (mHideInSelectionDialog) {
0262         configGroup.writeEntry("HideInSelectionDialog", mHideInSelectionDialog);
0263     } else {
0264         configGroup.deleteEntry("HideInSelectionDialog");
0265     }
0266 
0267     if (!mShortcut.isEmpty()) {
0268         configGroup.writeEntry("Shortcut", mShortcut.toString());
0269     } else {
0270         configGroup.deleteEntry("Shortcut");
0271     }
0272 
0273     if (mFormatMessage != MessageViewer::Viewer::Unknown) {
0274         if (mFormatMessage == MessageViewer::Viewer::UseGlobalSetting) {
0275             configGroup.deleteEntry("displayFormatOverride");
0276         } else {
0277             configGroup.writeEntry("displayFormatOverride", static_cast<int>(mFormatMessage));
0278         }
0279     }
0280     if (mFolderHtmlLoadExtPreference) {
0281         configGroup.writeEntry("htmlLoadExternalOverride", mFolderHtmlLoadExtPreference);
0282     } else {
0283         configGroup.deleteEntry("htmlLoadExternalOverride");
0284     }
0285 }
0286 
0287 void FolderSettings::setShortcut(const QKeySequence &sc)
0288 {
0289     mShortcut = sc;
0290 }
0291 
0292 const QKeySequence &FolderSettings::shortcut() const
0293 {
0294     return mShortcut;
0295 }
0296 
0297 void FolderSettings::setUseDefaultIdentity(bool useDefaultIdentity)
0298 {
0299     if (mUseDefaultIdentity != useDefaultIdentity) {
0300         mUseDefaultIdentity = useDefaultIdentity;
0301         if (mUseDefaultIdentity) {
0302             mIdentity = KernelIf->identityManager()->defaultIdentity().uoid();
0303         }
0304         KernelIf->syncConfig();
0305     }
0306 }
0307 
0308 bool FolderSettings::useDefaultIdentity() const
0309 {
0310     return mUseDefaultIdentity;
0311 }
0312 
0313 void FolderSettings::setIdentity(uint identity)
0314 {
0315     if (mIdentity != identity) {
0316         mIdentity = identity;
0317         KernelIf->syncConfig();
0318     }
0319 }
0320 
0321 QString FolderSettings::resource() const
0322 {
0323     const QString resource = mCollection.resource();
0324     if (resource.isEmpty()) {
0325         const Collection col = CommonKernel->collectionFromId(mCollection.id());
0326         if (col.isValid()) {
0327             Q_ASSERT(!col.resource().isEmpty());
0328             return col.resource();
0329         }
0330     }
0331     return resource;
0332 }
0333 
0334 bool FolderSettings::folderHtmlLoadExtPreference() const
0335 {
0336     return mFolderHtmlLoadExtPreference;
0337 }
0338 
0339 void FolderSettings::setFolderHtmlLoadExtPreference(bool folderHtmlLoadExtPreference)
0340 {
0341     mFolderHtmlLoadExtPreference = folderHtmlLoadExtPreference;
0342 }
0343 
0344 uint FolderSettings::fallBackIdentity() const
0345 {
0346     int identityId = -1;
0347     MailCommon::ResourceReadConfigFile resourceFile(resource());
0348     KConfigGroup grp = resourceFile.group(QStringLiteral("cache"));
0349     if (grp.isValid()) {
0350         const bool useDefault = grp.readEntry(QStringLiteral("UseDefaultIdentity"), true);
0351         if (useDefault) {
0352             return mIdentity;
0353         }
0354         const int remoteAccountIdent = grp.readEntry(QStringLiteral("AccountIdentity"), -1);
0355         if (remoteAccountIdent > 0) {
0356             identityId = remoteAccountIdent;
0357         }
0358     }
0359     if (identityId != -1 && !KernelIf->identityManager()->identityForUoid(identityId).isNull()) {
0360         return identityId;
0361     }
0362     return mIdentity;
0363 }
0364 
0365 uint FolderSettings::identity() const
0366 {
0367     if (mUseDefaultIdentity) {
0368         return fallBackIdentity();
0369     }
0370     return mIdentity;
0371 }
0372 
0373 QString FolderSettings::mailingListPostAddress() const
0374 {
0375     if (mMailingList.features() & MailingList::Post) {
0376         QList<QUrl> post = mMailingList.postUrls();
0377         QList<QUrl>::const_iterator end(post.constEnd());
0378         for (QList<QUrl>::const_iterator it = post.constBegin(); it != end; ++it) {
0379             // We check for isEmpty because before 3.3 postAddress was just an
0380             // email@kde.org and that leaves protocol() field in the qurl class
0381             const QString protocol = (*it).scheme();
0382             if (protocol == QLatin1StringView("mailto") || protocol.isEmpty()) {
0383                 return (*it).path();
0384             }
0385         }
0386     }
0387     return {};
0388 }
0389 
0390 void FolderSettings::setMailingListEnabled(bool enabled)
0391 {
0392     if (mMailingListEnabled != enabled) {
0393         mMailingListEnabled = enabled;
0394         writeConfig();
0395     }
0396 }
0397 
0398 bool FolderSettings::isMailingListEnabled() const
0399 {
0400     return mMailingListEnabled;
0401 }
0402 
0403 void FolderSettings::setMailingList(const MailingList &mlist)
0404 {
0405     if (mMailingList == mlist) {
0406         return;
0407     }
0408 
0409     mMailingList = mlist;
0410     writeConfig();
0411 }
0412 
0413 MessageCore::MailingList FolderSettings::mailingList() const
0414 {
0415     return mMailingList;
0416 }
0417 
0418 bool FolderSettings::putRepliesInSameFolder() const
0419 {
0420     return mPutRepliesInSameFolder;
0421 }
0422 
0423 void FolderSettings::setPutRepliesInSameFolder(bool b)
0424 {
0425     mPutRepliesInSameFolder = b;
0426 }
0427 
0428 bool FolderSettings::hideInSelectionDialog() const
0429 {
0430     return mHideInSelectionDialog;
0431 }
0432 
0433 void FolderSettings::setHideInSelectionDialog(bool hide)
0434 {
0435     mHideInSelectionDialog = hide;
0436 }
0437 }
0438 
0439 #include "moc_foldersettings.cpp"