File indexing completed on 2024-11-17 04:51:14
0001 /* 0002 SPDX-FileCopyrightText: 2015-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 #pragma once 0007 0008 #include "mailcommon_export.h" 0009 #include <Akonadi/SearchQuery> 0010 0011 #include <Akonadi/Item> 0012 0013 class KConfigGroup; 0014 namespace MailCommon 0015 { 0016 /** 0017 * @short This class represents one search pattern rule. 0018 * Incoming mail is sent through the list of mail filter 0019 * rules before it is placed in the associated mail folder (usually "inbox"). 0020 * This class represents one mail filter rule. It is also used to represent 0021 * a search rule as used by the search dialog and folders. 0022 */ 0023 class MAILCOMMON_EXPORT SearchRule 0024 { 0025 public: 0026 /** 0027 * Defines a pointer to a search rule. 0028 */ 0029 using Ptr = std::shared_ptr<SearchRule>; 0030 0031 /** 0032 * Describes operators for comparison of field and contents. 0033 * 0034 * If you change the order or contents of the enum: do not forget 0035 * to change funcConfigNames[], sFilterFuncList and matches() 0036 * in SearchRule, too. 0037 * Also, it is assumed that these functions come in pairs of logical 0038 * opposites (ie. "=" <-> "!=", ">" <-> "<=", etc.). 0039 */ 0040 enum Function { 0041 FuncNone = -1, 0042 FuncContains = 0, 0043 FuncContainsNot, 0044 FuncEquals, 0045 FuncNotEqual, 0046 FuncRegExp, 0047 FuncNotRegExp, 0048 FuncIsGreater, 0049 FuncIsLessOrEqual, 0050 FuncIsLess, 0051 FuncIsGreaterOrEqual, 0052 FuncIsInAddressbook, 0053 FuncIsNotInAddressbook, 0054 FuncIsInCategory, 0055 FuncIsNotInCategory, 0056 FuncHasAttachment, 0057 FuncHasNoAttachment, 0058 FuncStartWith, 0059 FuncNotStartWith, 0060 FuncEndWith, 0061 FuncNotEndWith 0062 }; 0063 0064 /** 0065 * @enum RequiredPart 0066 * @brief Possible required parts. 0067 */ 0068 enum RequiredPart { 0069 Envelope = 0, ///< Envelope 0070 Header, ///< Header 0071 CompleteMessage ///< Whole message 0072 }; 0073 0074 /** 0075 * Creates new new search rule. 0076 * 0077 * @param field The field to search in. 0078 * @param function The function to use for searching. 0079 * @param contents The contents to search for. 0080 */ 0081 explicit SearchRule(const QByteArray &field = QByteArray(), Function function = FuncContains, const QString &contents = QString()); 0082 0083 /** 0084 * Creates a new search rule from an @p other rule. 0085 */ 0086 SearchRule(const SearchRule &other); 0087 0088 /** 0089 * Initializes this rule with an @p other rule. 0090 */ 0091 const SearchRule &operator=(const SearchRule &other); 0092 0093 /** 0094 * Creates a new search rule of a certain type by instantiating the 0095 * appropriate subclass depending on the @p field. 0096 * 0097 * @param field The field to search in. 0098 * @param function The function to use for searching. 0099 * @param contents The contents to search for. 0100 */ 0101 static SearchRule::Ptr createInstance(const QByteArray &field = QByteArray(), Function function = FuncContains, const QString &contents = QString()); 0102 0103 /** 0104 * Creates a new search rule of a certain type by instantiating the 0105 * appropriate subclass depending on the @p field. 0106 * 0107 * @param field The field to search in. 0108 * @param function The name of the function to use for searching. 0109 * @param contents The contents to search for. 0110 */ 0111 static SearchRule::Ptr createInstance(const QByteArray &field, const char *function, const QString &contents); 0112 0113 /** 0114 * Creates a new search rule by cloning an @p other rule. 0115 */ 0116 static SearchRule::Ptr createInstance(const SearchRule &other); 0117 0118 /** 0119 * Creates a new search rule by deseralizing its structure from a data @p stream. 0120 */ 0121 static SearchRule::Ptr createInstance(QDataStream &stream); 0122 0123 /** 0124 * Creates a new search rule from a given config @p group. 0125 * 0126 * @param group The config group to read the structure from. 0127 * @param index The identifier that is used to distinguish 0128 * rules within a single config group. 0129 * 0130 * @note This function does no validation of the data obtained 0131 * from the config file. You should call isEmpty yourself 0132 * if you need valid rules. 0133 */ 0134 static SearchRule::Ptr createInstanceFromConfig(const KConfigGroup &group, int index); 0135 0136 /** 0137 * Destroys the search rule. 0138 */ 0139 virtual ~SearchRule(); 0140 0141 /** 0142 * Tries to match the rule against the KMime::Message in the 0143 * given @p item. 0144 * 0145 * @return true if the rule matched, false otherwise. 0146 * 0147 * @note Must be implemented by subclasses. 0148 */ 0149 virtual bool matches(const Akonadi::Item &item) const = 0; 0150 0151 /** 0152 * Determines whether the rule is worth considering. 0153 * It isn't if either the field is not set or the contents is empty. 0154 * The calling code should make sure that it's rule list contains 0155 * only non-empty rules, as matches doesn't check this. 0156 */ 0157 virtual bool isEmpty() const = 0; 0158 0159 /** 0160 * Returns the required part from the item that is needed for the search to 0161 * operate. See @ref RequiredPart */ 0162 virtual SearchRule::RequiredPart requiredPart() const = 0; 0163 0164 /** 0165 * Saves the object into a given config @p group. 0166 * 0167 * @param group The config group. 0168 * @param index The identifier that is used to distinguish 0169 * rules within a single config group. 0170 * 0171 * @note This function will happily write itself even when it's 0172 * not valid, assuming higher layers to Do The Right Thing(TM). 0173 */ 0174 void writeConfig(KConfigGroup &group, int index) const; 0175 0176 void generateSieveScript(QStringList &requireModules, QString &code); 0177 0178 /** 0179 * Sets the filter @p function of the rule. 0180 */ 0181 void setFunction(Function function); 0182 0183 /** 0184 * Returns the filter function of the rule. 0185 */ 0186 Function function() const; 0187 0188 /** 0189 * Sets the message header field @p name. 0190 * 0191 * @note Make sure the name contains no trailing ':'. 0192 */ 0193 void setField(const QByteArray &name); 0194 0195 /** 0196 * Returns the message header field name (without the trailing ':'). 0197 * 0198 * There are also six pseudo-headers: 0199 * @li \<message\>: Try to match against the whole message. 0200 * @li \<body\>: Try to match against the body of the message. 0201 * @li \<any header\>: Try to match against any header field. 0202 * @li \<recipients\>: Try to match against both To: and Cc: header fields. 0203 * @li \<size\>: Try to match against size of message (numerical). 0204 * @li \<age in days\>: Try to match against age of message (numerical). 0205 * @li \<status\>: Try to match against status of message (status). 0206 * @li \<tag\>: Try to match against message tags. 0207 */ 0208 QByteArray field() const; 0209 0210 /** 0211 * Set the @p contents of the rule. 0212 * 0213 * This can be either a substring to search for in 0214 * or a regexp pattern to match against the header. 0215 */ 0216 void setContents(const QString &contents); 0217 0218 /** 0219 * Returns the contents of the rule. 0220 */ 0221 QString contents() const; 0222 0223 /** 0224 * Returns the rule as string for debugging purpose 0225 */ 0226 const QString asString() const; 0227 0228 /** 0229 * Adds query terms to the given term group. 0230 */ 0231 virtual void addQueryTerms(Akonadi::SearchTerm &groupTerm, bool &emptyIsNotAnError) const 0232 { 0233 Q_UNUSED(groupTerm) 0234 Q_UNUSED(emptyIsNotAnError) 0235 } 0236 0237 QDataStream &operator>>(QDataStream &) const; 0238 virtual QString informationAboutNotValidRules() const 0239 { 0240 return {}; 0241 } 0242 0243 protected: 0244 /** 0245 * Helper that returns whether the rule has a negated function. 0246 */ 0247 bool isNegated() const; 0248 0249 /** 0250 * Converts the rule function into the corresponding Akonadi query operator. 0251 */ 0252 Akonadi::SearchTerm::Condition akonadiComparator() const; 0253 0254 private: 0255 static Function configValueToFunc(const char *); 0256 static QString functionToString(Function); 0257 MAILCOMMON_NO_EXPORT QString conditionToString(Function function); 0258 0259 QByteArray mField; 0260 Function mFunction; 0261 QString mContents; 0262 }; 0263 }