File indexing completed on 2024-09-22 04:50:06

0001 /*
0002  * kmail: KDE mail client
0003  * SPDX-FileCopyrightText: 1996-1998 Stefan Taferner <taferner@kde.org>
0004  *
0005  * SPDX-License-Identifier: GPL-2.0-or-later
0006  *
0007  */
0008 #pragma once
0009 
0010 #include "mailcommon_export.h"
0011 
0012 #include "mailcommon/filteraction.h"
0013 #include "mailcommon/searchpattern.h"
0014 
0015 #include <Akonadi/Collection>
0016 #include <QKeySequence>
0017 
0018 #include <QDataStream>
0019 #include <QList>
0020 
0021 class KConfigGroup;
0022 
0023 namespace MailCommon
0024 {
0025 /**
0026  * @brief The MailFilter class
0027  */
0028 class MAILCOMMON_EXPORT MailFilter
0029 {
0030     friend MAILCOMMON_EXPORT QDataStream &operator<<(QDataStream &stream, const MailFilter &filter);
0031     friend MAILCOMMON_EXPORT QDataStream &operator>>(QDataStream &stream, MailFilter &filter);
0032 
0033 public:
0034     /** Result codes returned by process. They mean:
0035 
0036       @param GoOn Everything OK. You are still the owner of the
0037       message and you should continue applying filter actions to this
0038       message.
0039 
0040       @param CriticalError A critical error occurred (e.g. "disk full").
0041 
0042       @param NoResult For internal use only!
0043 
0044     */
0045     enum ReturnCode { NoResult, GoOn, CriticalError };
0046 
0047     /** Account type codes used by setApplicability. They mean:
0048 
0049       @param All Apply to all accounts
0050 
0051       @param ButImap Apply to all but IMAP accounts
0052 
0053       @param Checked apply to all accounts specified by setApplyOnAccount
0054 
0055     */
0056     enum AccountType {
0057         All,
0058         ButImap,
0059         Checked,
0060     };
0061 
0062     /** Constructor that initializes basic settings. */
0063     MailFilter();
0064 
0065     /** Constructor that initializes from given config group.
0066      * Filters are stored one by one in config groups, i.e.
0067      * one filter, one group. */
0068     explicit MailFilter(const KConfigGroup &aConfig, bool internal, bool &needUpdate);
0069 
0070     /** Copy constructor. Constructs a deep copy of @p aFilter. */
0071     MailFilter(const MailFilter &other);
0072 
0073     /** Cleanup. */
0074     ~MailFilter();
0075 
0076     static int filterActionsMaximumSize();
0077     void generateRandomIdentifier();
0078 
0079     /**
0080      * Returns the unique identifier of this filter.
0081      */
0082     [[nodiscard]] QString identifier() const;
0083 
0084     /** Equivalent to @p pattern()->name(). @return name of the filter */
0085     [[nodiscard]] QString name() const;
0086 
0087     /** Execute the filter action(s) on the given message.
0088       Returns:
0089       @li 2 if a critical error occurred,
0090       @li 1 if the caller is still
0091       the owner of the message,
0092       @li 0 if processed successfully.
0093       @param context The context that contains the item to which the actions should be applied.
0094       @param stopIt Contains @c true if the caller may apply other filters and @c false if he shall
0095       stop the filtering of this message.
0096       @param applyOnOutbound Defines whether to apply the rules on the outbound.
0097     */
0098     [[nodiscard]] ReturnCode execActions(ItemContext &context, bool &stopIt, bool applyOnOutbound) const;
0099 
0100     /**
0101      * Returns the required part from the item that is needed for the filter to
0102      * operate. See @ref SearchRule::RequiredPart */
0103     [[nodiscard]] SearchRule::RequiredPart requiredPart(const QString &id) const;
0104 
0105     /** Write contents to given config group. */
0106     void writeConfig(KConfigGroup &config, bool exportFilter) const;
0107 
0108     /** Initialize from given config group. */
0109     [[nodiscard]] bool readConfig(const KConfigGroup &config, bool interactive = false);
0110 
0111     /** Remove empty rules (and actions one day). */
0112     QString purify(bool removeAction = true);
0113 
0114     /** Check for empty pattern and action list. */
0115     bool isEmpty() const;
0116 
0117     /** Provides a reference to the internal action list. If your used
0118       the @p setAction() and @p action() functions before, please
0119       convert to using myFilter->actions()->at() and friends now. */
0120     QList<FilterAction *> *actions();
0121 
0122     /** Provides a reference to the internal action list. Const version. */
0123     const QList<FilterAction *> *actions() const;
0124 
0125     /** Provides a reference to the internal pattern. If you used the
0126       @p matches() function before, please convert to using
0127       myFilter->pattern()->matches() now. */
0128     [[nodiscard]] SearchPattern *pattern();
0129 
0130     /** Provides a reference to the internal pattern. If you used the
0131       @p matches() function before, please convert to using
0132       myFilter->pattern()->matches() now. */
0133     const SearchPattern *pattern() const;
0134 
0135     /** Set whether this filter should be applied on
0136       outbound messages (@p aApply == true) or not.
0137       See applyOnOutbound applyOnInbound setApplyOnInbound
0138     */
0139     void setApplyOnOutbound(bool aApply);
0140 
0141     /** Set whether this filter should be applied on
0142       outbound messages before sending (@p aApply == TRUE) or not.
0143       See applyOnOutbound applyOnInbound setApplyOnInbound
0144     */
0145     void setApplyBeforeOutbound(bool aApply);
0146 
0147     /** @return true if this filter should be applied on
0148       outbound messages, false otherwise.
0149       @see setApplyOnOutbound applyOnInbound setApplyOnInbound
0150     */
0151     [[nodiscard]] bool applyOnOutbound() const;
0152 
0153     /** @return TRUE if this filter should be applied on
0154       outbound messages before they are sent, FALSE otherwise.
0155       @see setApplyOnOutbound applyOnInbound setApplyOnInbound
0156     */
0157     [[nodiscard]] bool applyBeforeOutbound() const;
0158 
0159     /** Set whether this filter should be applied on
0160       inbound messages (@p aApply == true) or not.
0161       @see setApplyOnOutbound applyOnInbound applyOnOutbound
0162     */
0163     void setApplyOnInbound(bool aApply);
0164 
0165     /** @return true if this filter should be applied on
0166       inbound messages, false otherwise.
0167       @see setApplyOnOutbound applyOnOutbound setApplyOnInbound
0168     */
0169     [[nodiscard]] bool applyOnInbound() const;
0170 
0171     /** Set whether this filter should be applied on
0172       explicit (CTRL-J) filtering (@p aApply == true) or not.
0173       @see setApplyOnOutbound applyOnInbound applyOnOutbound
0174     */
0175     void setApplyOnExplicit(bool aApply);
0176 
0177     /** @return true if this filter should be applied on
0178       explicit (CTRL-J) filtering, false otherwise.
0179       @see setApplyOnOutbound applyOnOutbound setApplyOnInbound
0180     */
0181     [[nodiscard]] bool applyOnExplicit() const;
0182 
0183     /** Set whether this filter should be applied on
0184       inbound messages for all accounts (@p aApply == All) or
0185       inbound messages for all but IMAP accounts (@p aApply == ButImap) or
0186       for a specified set of accounts only.
0187       Only applicable to filters that are applied on inbound messages.
0188       @see setApplyOnInbound setApplyOnAccount
0189     */
0190     void setApplicability(AccountType aApply = All);
0191 
0192     /** Sets whether the filter should be applied on inbound emails in all
0193       folders, not just Inbox.
0194     */
0195     void setApplyOnAllFoldersInbound(bool aApply);
0196 
0197     /** Returns whether the filter should be applied on inbound emails in all
0198       folders, not just Inbox.
0199     */
0200     [[nodiscard]] bool applyOnAllFoldersInbound() const;
0201 
0202     /** @return true if this filter should be applied on
0203       inbound messages for all accounts, or false if this filter
0204       is to be applied on a specified set of accounts only.
0205       Only applicable to filters that are applied on inbound messages.
0206       @see setApplicability
0207     */
0208     [[nodiscard]] AccountType applicability() const;
0209 
0210     /** Set whether this filter should be applied on
0211       inbound messages for the account with id (@p id).
0212       Only applicable to filters that are only applied to a specified
0213       set of accounts.
0214       @see setApplicability applyOnAccount
0215     */
0216     void setApplyOnAccount(const QString &id, bool aApply = true);
0217 
0218     /** @return true if this filter should be applied on
0219       inbound messages from the account with id (@p id), false otherwise.
0220       @see setApplicability
0221     */
0222     [[nodiscard]] bool applyOnAccount(const QString &id) const;
0223 
0224     void setStopProcessingHere(bool aStop);
0225     bool stopProcessingHere() const;
0226 
0227     /** Set whether this filter should be plugged into the filter menu.
0228      */
0229     void setConfigureShortcut(bool aShort);
0230 
0231     /** @return true if this filter should be plugged into the filter menu,
0232       false otherwise.
0233       @see setConfigureShortcut
0234     */
0235     [[nodiscard]] bool configureShortcut() const;
0236 
0237     /** Set whether this filter should be plugged into the toolbar.
0238       This can be done only if a shortcut is defined.
0239       @see setConfigureShortcut
0240     */
0241     void setConfigureToolbar(bool aTool);
0242 
0243     /** @return true if this filter should be plugged into the toolbar,
0244       false otherwise.
0245       @see setConfigureToolbar
0246     */
0247     [[nodiscard]] bool configureToolbar() const;
0248 
0249     /** @return The toolbar name of this filter.
0250      *  @see setToolbarName
0251      */
0252     QString toolbarName() const;
0253 
0254     /** This sets the toolbar name for this filter.
0255      *  The toolbar name is the text to be displayed underneath the toolbar icon
0256      *  for this filter. This is usually the same as name(),  expect when
0257      *  explicitly set by this function.
0258      *  This is useful if the normal filter mame is too long for the toolbar.
0259      *  @see toolbarName, name
0260      */
0261     void setToolbarName(const QString &toolbarName);
0262 
0263     /** Set the shortcut to be used if plugged into the filter menu
0264       or toolbar. Default is no shortcut.
0265       @see setConfigureShortcut setConfigureToolbar
0266     */
0267     void setShortcut(const QKeySequence &shortcut);
0268 
0269     /** @return The shortcut assigned to the filter.
0270       @see setShortcut
0271     */
0272     const QKeySequence &shortcut() const;
0273 
0274     /** Set the icon to be used if plugged into the filter menu
0275       or toolbar. Default is the gear icon.
0276       @see setConfigureShortcut setConfigureToolbar
0277     */
0278     void setIcon(const QString &icon);
0279 
0280     /** @return The name of the icon to be used.
0281       @see setIcon
0282     */
0283     [[nodiscard]] QString icon() const;
0284 
0285     /**
0286      * Called from the filter manager when a folder is moved.
0287      * Tests if the folder aFolder is used in any action. Changes it
0288      * to aNewFolder folder in this case.
0289      * @return true if a change in some action occurred,
0290      * false if no action was affected.
0291      */
0292     void folderRemoved(const Akonadi::Collection &aFolder, const Akonadi::Collection &aNewFolder);
0293 
0294     /** Returns the filter in a human-readable form. useful for
0295       debugging but not much else. Don't use, as it may well go away
0296       in the future... */
0297     const QString asString() const;
0298 
0299     /** Set the mode for using automatic naming for the filter.
0300       If the feature is enabled, the name is derived from the
0301       first filter rule.
0302     */
0303     void setAutoNaming(bool useAutomaticNames);
0304 
0305     /** @return Tells, if an automatic name is used for the filter
0306      */
0307     [[nodiscard]] bool isAutoNaming() const;
0308 
0309     /** Return if filter is enabled or not
0310      */
0311     [[nodiscard]] bool isEnabled() const;
0312     void setEnabled(bool);
0313 
0314     void generateSieveScript(QStringList &requiresModules, QString &code);
0315 
0316     void clearApplyOnAccount();
0317     void agentRemoved(const QString &identifier);
0318 
0319 private:
0320     QString mIdentifier;
0321     SearchPattern mPattern;
0322     QList<FilterAction *> mActions;
0323     QStringList mAccounts;
0324     QString mIcon;
0325     QString mToolbarName;
0326     QKeySequence mShortcut;
0327     bool bApplyOnInbound : 1;
0328     bool bApplyBeforeOutbound : 1;
0329     bool bApplyOnOutbound : 1;
0330     bool bApplyOnExplicit : 1;
0331     bool bApplyOnAllFolders : 1;
0332     bool bStopProcessingHere : 1;
0333     bool bConfigureShortcut : 1;
0334     bool bConfigureToolbar : 1;
0335     bool bAutoNaming : 1;
0336     bool bEnabled : 1;
0337     AccountType mApplicability;
0338 };
0339 
0340 MAILCOMMON_EXPORT QDataStream &operator<<(QDataStream &stream, const MailFilter &filter);
0341 MAILCOMMON_EXPORT QDataStream &operator>>(QDataStream &stream, MailFilter &filter);
0342 }