File indexing completed on 2024-12-01 04:46:45

0001 /*
0002    SPDX-FileCopyrightText: 2021-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "confirmbeforedeletingrule.h"
0008 #include "confirmbeforedeletingplugin_debug.h"
0009 #include <Akonadi/MessageStatus>
0010 #include <KLocalizedString>
0011 
0012 ConfirmBeforeDeletingRule::ConfirmBeforeDeletingRule() = default;
0013 
0014 ConfirmBeforeDeletingRule::~ConfirmBeforeDeletingRule() = default;
0015 
0016 const QString &ConfirmBeforeDeletingRule::pattern() const
0017 {
0018     return mPattern;
0019 }
0020 
0021 void ConfirmBeforeDeletingRule::setPattern(const QString &newPattern)
0022 {
0023     mPattern = newPattern;
0024 }
0025 
0026 ConfirmBeforeDeletingRule::RuleType ConfirmBeforeDeletingRule::ruleType() const
0027 {
0028     return mRuleType;
0029 }
0030 
0031 void ConfirmBeforeDeletingRule::setRuleType(RuleType newRuleType)
0032 {
0033     mRuleType = newRuleType;
0034 }
0035 
0036 void ConfirmBeforeDeletingRule::load(const KConfigGroup &group)
0037 {
0038     const QString pattern = group.readEntry(QStringLiteral("Pattern"), QString());
0039     const QString checkType = group.readEntry(QStringLiteral("Type"), QString());
0040     setPattern(pattern);
0041     setRuleType(stringToRuleType(checkType));
0042 }
0043 
0044 bool ConfirmBeforeDeletingRule::isValid() const
0045 {
0046     return (!mPattern.isEmpty() && (mRuleType != Unknown)) || (mRuleType == Unread) || (mRuleType == Important);
0047 }
0048 
0049 void ConfirmBeforeDeletingRule::save(KConfigGroup &group) const
0050 {
0051     group.writeEntry(QStringLiteral("Pattern"), mPattern);
0052     group.writeEntry(QStringLiteral("Type"), ruleTypeToString(mRuleType));
0053 }
0054 
0055 ConfirmBeforeDeletingRule::RuleType ConfirmBeforeDeletingRule::stringToRuleType(const QString &str)
0056 {
0057     if (str == QLatin1StringView("body")) {
0058         return Body;
0059     } else if (str == QLatin1StringView("subject")) {
0060         return Subject;
0061     } else if (str == QLatin1StringView("to")) {
0062         return To;
0063     } else if (str == QLatin1StringView("cc")) {
0064         return Cc;
0065     } else if (str == QLatin1StringView("bcc")) {
0066         return Bcc;
0067     } else if (str == QLatin1StringView("unread")) {
0068         return Unread;
0069     } else if (str == QLatin1StringView("important")) {
0070         return Important;
0071     }
0072     return Unknown;
0073 }
0074 
0075 bool ConfirmBeforeDeletingRule::operator==(const ConfirmBeforeDeletingRule &other) const
0076 {
0077     return mPattern == other.pattern() && mRuleType == other.ruleType();
0078 }
0079 
0080 QString ConfirmBeforeDeletingRule::ruleTypeToString(ConfirmBeforeDeletingRule::RuleType r)
0081 {
0082     QString tmp;
0083     switch (r) {
0084     case Unknown:
0085         break;
0086     case Body:
0087         tmp = QStringLiteral("body");
0088         break;
0089     case Subject:
0090         tmp = QStringLiteral("subject");
0091         break;
0092     case To:
0093         tmp = QStringLiteral("to");
0094         break;
0095     case Cc:
0096         tmp = QStringLiteral("cc");
0097         break;
0098     case Bcc:
0099         tmp = QStringLiteral("bcc");
0100         break;
0101     case Unread:
0102         tmp = QStringLiteral("unread");
0103         break;
0104     case Important:
0105         tmp = QStringLiteral("important");
0106         break;
0107     }
0108     return tmp;
0109 }
0110 
0111 bool ConfirmBeforeDeletingRule::deletingNeedToConfirm(const Akonadi::Item &item, QString &checkFoundInfo) const
0112 {
0113     bool needToConfirm = false;
0114     if (item.hasPayload<KMime::Message::Ptr>()) {
0115         auto msg = item.payload<KMime::Message::Ptr>();
0116         switch (mRuleType) {
0117         case Body: {
0118             const auto ba = msg->body();
0119             if (QString::fromUtf8(ba).contains(pattern())) {
0120                 needToConfirm = true;
0121                 generateConfirmMessageInfo(msg, checkFoundInfo);
0122             }
0123             break;
0124         }
0125         case Subject: {
0126             if (auto subject = msg->subject(false)) {
0127                 const QString subjectStr = subject->asUnicodeString();
0128                 if (subjectStr.contains(pattern())) {
0129                     needToConfirm = true;
0130                     generateConfirmMessageInfo(msg, checkFoundInfo);
0131                 }
0132             }
0133             break;
0134         }
0135         case To: {
0136             if (auto to = msg->to(false)) {
0137                 const QString toStr = to->asUnicodeString();
0138                 if (toStr.contains(pattern())) {
0139                     needToConfirm = true;
0140                     generateConfirmMessageInfo(msg, checkFoundInfo);
0141                 }
0142             }
0143             break;
0144         }
0145         case Cc: {
0146             if (auto cc = msg->cc(false)) {
0147                 const QString ccStr = cc->asUnicodeString();
0148                 if (ccStr.contains(pattern())) {
0149                     needToConfirm = true;
0150                     generateConfirmMessageInfo(msg, checkFoundInfo);
0151                 }
0152             }
0153             break;
0154         }
0155         case Bcc: {
0156             if (auto bcc = msg->bcc(false)) {
0157                 const QString bccStr = bcc->asUnicodeString();
0158                 if (bccStr.contains(pattern())) {
0159                     needToConfirm = true;
0160                     generateConfirmMessageInfo(msg, checkFoundInfo);
0161                 }
0162             }
0163             break;
0164         }
0165         case Unread: {
0166             Akonadi::MessageStatus status;
0167             status.setStatusFromFlags(item.flags());
0168             if (!status.isRead()) {
0169                 needToConfirm = true;
0170                 generateConfirmMessageInfoFromStatus(msg, checkFoundInfo, i18n("Unread"));
0171             }
0172             break;
0173         }
0174         case Important: {
0175             Akonadi::MessageStatus status;
0176             status.setStatusFromFlags(item.flags());
0177             if (status.isImportant()) {
0178                 needToConfirm = true;
0179                 generateConfirmMessageInfoFromStatus(msg, checkFoundInfo, i18n("Important"));
0180             }
0181             break;
0182         }
0183 
0184         case Unknown:
0185             qCWarning(KMAIL_CONFIRMBEFOREDELETING_PLUGIN_LOG) << "Invalid rules!";
0186             break;
0187         }
0188     }
0189 
0190     return needToConfirm;
0191 }
0192 
0193 void ConfirmBeforeDeletingRule::generateConfirmMessageInfo(const KMime::Message::Ptr &msg, QString &checkFoundInfo) const
0194 {
0195     QString subjectStr;
0196     if (auto subject = msg->subject(false)) {
0197         subjectStr = subject->asUnicodeString();
0198     }
0199     checkFoundInfo = i18n("The message with subject \'%2\' contains \'%1\'", pattern(), subjectStr);
0200 }
0201 
0202 void ConfirmBeforeDeletingRule::generateConfirmMessageInfoFromStatus(const KMime::Message::Ptr &msg, QString &checkFoundInfo, const QString &statusStr) const
0203 {
0204     QString subjectStr;
0205     if (auto subject = msg->subject(false)) {
0206         subjectStr = subject->asUnicodeString();
0207     }
0208     checkFoundInfo = i18n("The message with subject \'%1\' is %2", subjectStr, statusStr);
0209 }
0210 
0211 QDebug operator<<(QDebug d, const ConfirmBeforeDeletingRule &t)
0212 {
0213     d << "Pattern " << t.pattern();
0214     d << "mRuleType " << t.ruleType();
0215     return d;
0216 }
0217 
0218 #include "moc_confirmbeforedeletingrule.cpp"