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

0001 /*
0002   Filter Dialog
0003 
0004   SPDX-FileCopyrightText: Marc Mutz <mutz@kde.org>
0005   SPDX-FileCopyrightText: 2011-2024 Laurent Montel <montel@kde.org>
0006 
0007   based upon work by Stefan Taferner <taferner@kde.org>
0008 
0009   SPDX-License-Identifier: GPL-2.0-or-later
0010 */
0011 
0012 #pragma once
0013 
0014 #include "filterimporterexporter.h"
0015 #include "mailcommon/filteraction.h"
0016 #include "mailcommon/searchpattern.h"
0017 #include "mailcommon_export.h"
0018 #include "mailfilter.h"
0019 
0020 #include <QDialog>
0021 
0022 #include <QList>
0023 
0024 class KActionCollection;
0025 class KIconButton;
0026 class KKeySequenceWidget;
0027 
0028 class QCheckBox;
0029 class QPushButton;
0030 class QRadioButton;
0031 class QPushButton;
0032 class QGroupBox;
0033 namespace MailCommon
0034 {
0035 class SearchPatternEdit;
0036 class FilterActionWidgetLister;
0037 class FolderRequester;
0038 class KMFilterAccountList;
0039 class KMFilterListBox;
0040 }
0041 
0042 class KJob;
0043 
0044 /**
0045  * The filter dialog. This is a non-modal dialog used to manage the filters.
0046  * It should only be called through KMFilterMgr::openDialog. The dialog
0047  * consists of three main parts:
0048  *
0049  * @li The KMFilterListBox in the left half allows the user to
0050  * select a filter to be displayed using the widgets on the right
0051  * half. It also has buttons to delete filters, add new ones, to
0052  * rename them and to change their order (maybe you will be able to
0053  * move the filters around by dragging later, and to optimize the
0054  * filters by trying to apply them to all locally available
0055  * KMMessage in turn and thus profiling which filters (and which
0056  * rules of the search patterns) matches most often and sorting the
0057  * filter/rules list according to the results, but I first want the
0058  * basic functionality in place).
0059  *
0060  * @li The SearchPatternEdit in the upper-right quarter allows
0061  * the user to modify the filter criteria.
0062  *
0063  * @li The KMFilterActionEdit in the lower-right quarter allows
0064  * the user to select the actions that will be executed for any
0065  * message that matches the search pattern.
0066  *
0067  * @li (tbi) There will be another widget that will allow the user to
0068  * select to which folders the filter may be applied and whether it
0069  * should be applied on outbound or inbound message transfers or both
0070  * or none (meaning the filter is only applied when the user
0071  * explicitly hits CTRL-J). I'm not sure whether there should be a
0072  * per-folder filter list or a single list where you can select the
0073  * names of folders this rule will be applied to.
0074  *
0075  * Upon creating the dialog, a (deep) copy of the current filter list
0076  * is made by KMFilterListBox. The changed filters are local to
0077  * KMFilterListBox until the user clicks the 'Apply' button.
0078  *
0079  * NOTE: Though this dialog is non-modal, it completely ignores all
0080  * the stuff that goes on behind the scenes with folders esp. folder
0081  * creation, move and create. The widgets that depend on the filter
0082  * list and the filters that use folders as parameters are not
0083  * updated as you expect. I hope this will change sometime soon.
0084  *
0085  * KMFilterDialog supports the creation of new filters through context
0086  * menus, dubbed "rapid filters". Call KMFilterMgr::createFilter
0087  * to use this. That call will be delivered to this dialog, which in
0088  * turn delivers it to the KMFilterListBox.
0089  *
0090  * If you change the (DocBook) anchor for the filter dialog help,
0091  * make sure to change @p const @p QString @p KMFilterDialogHelpAnchor
0092  * in kmfilterdlg.cpp accordingly.
0093  *
0094  * @short The filter dialog.
0095  * @author Marc Mutz <mutz@kde.org>, based upon work by Stefan Taferner <taferner@kde.org>.
0096  * @see MailCommon::MailFilter KMFilterActionEdit SearchPatternEdit KMFilterListBox
0097  */
0098 namespace MailCommon
0099 {
0100 class MAILCOMMON_EXPORT KMFilterDialog : public QDialog
0101 {
0102     Q_OBJECT
0103 
0104 public:
0105     /**
0106      * Creates the filter dialog. The only class which should be able
0107      * to do this is KMFilterMgr. This ensures that there is only a
0108      * single filter dialog.
0109      */
0110     explicit KMFilterDialog(const QList<KActionCollection *> &actionCollection, QWidget *parent = nullptr, bool createDummyFilter = true);
0111 
0112     /**
0113      * Called from KMFilterMgr. Creates a new filter and presets
0114      * the first rule with "field equals value". Internally forwarded to
0115      * KMFilterListBox::createFilter. You should instead call
0116      * KMFilterMgr::createFilter.
0117      */
0118     void createFilter(const QByteArray &field, const QString &value);
0119 
0120 public Q_SLOTS:
0121     /**
0122      * Internally connected to KMFilterListBox::filterSelected.
0123      * Just does a simple check and then calls
0124      * SearchPatternEdit::setSearchPattern and
0125      * KMFilterActionEdit::setActionList.
0126      */
0127     void slotFilterSelected(MailCommon::MailFilter *aFilter);
0128 
0129     /** Override QDialog::accept to allow disabling close */
0130     void accept() override;
0131 
0132 protected Q_SLOTS:
0133     void slotApplicabilityChanged();
0134     void slotApplicableAccountsChanged();
0135     void slotStopProcessingButtonToggled(bool aChecked);
0136     void slotShortcutChanged(const QKeySequence &newSeq);
0137     void slotConfigureToolbarButtonToggled(bool aChecked);
0138     void slotFilterActionIconChanged(const QString &icon);
0139     void slotReset();
0140     void slotUpdateFilter();
0141     void slotSaveSize();
0142 
0143     /**
0144      * Called when the dialog is closed (finished).
0145      */
0146     void slotFinished();
0147 
0148     /**
0149      * Update the list of accounts shown in the advanced tab.
0150      */
0151     void slotUpdateAccountList();
0152 
0153     /**
0154      * Called when a user clicks the import filters button. Pops up
0155      * a dialog asking the user which file to import from and which
0156      * of the filters in that file to import.
0157      */
0158     void slotImportFilter(QAction *);
0159 
0160     /**
0161      * Called when a user clicks the export filters button. Pops up
0162      * a dialog asking the user which filters to export and which
0163      * file to export to.
0164      */
0165     void slotExportFilters();
0166 
0167     /**
0168      * Called when a user decides to continue editing invalid filters
0169      */
0170     void slotDisableAccept();
0171 
0172     /**
0173      * Called whenever a change in the filters configuration is detected,
0174      * to enable the Apply button.
0175      */
0176     void slotDialogUpdated();
0177 
0178     /**
0179      * Called wherenever the apply button is pressed.
0180      */
0181     void slotApply();
0182 
0183     void slotRunFilters();
0184 
0185     void slotFetchItemsForFolderDone(KJob *job);
0186 
0187     void slotFolderChanged(const Akonadi::Collection &);
0188 
0189 private:
0190     MAILCOMMON_NO_EXPORT void slotExportAsSieveScript();
0191     MAILCOMMON_NO_EXPORT void slotHelp();
0192     MAILCOMMON_NO_EXPORT void importFilters(MailCommon::FilterImporterExporter::FilterType type);
0193 
0194 protected:
0195     bool event(QEvent *e) override;
0196 
0197     /** The widget that contains the ListBox showing the filters, and the
0198         controls to remove filters, add new ones and to change their order. */
0199     KMFilterListBox *mFilterList = nullptr;
0200 
0201     /** The widget that allows editing of the filter pattern. */
0202     MailCommon::SearchPatternEdit *mPatternEdit = nullptr;
0203 
0204     /** The widget that allows editing of the filter actions. */
0205     MailCommon::FilterActionWidgetLister *mActionLister = nullptr;
0206 
0207     /** Lets the user select whether to apply this filter on
0208        inbound/outbound messages, both, or only on explicit CTRL-J. */
0209     QCheckBox *mApplyOnIn = nullptr;
0210     QCheckBox *mApplyOnOut = nullptr;
0211     QCheckBox *mApplyBeforeOut = nullptr;
0212     QCheckBox *mApplyOnCtrlJ = nullptr;
0213     QCheckBox *mApplyOnAllFolders = nullptr;
0214 
0215     /** For a filter applied to inbound messages selects whether to apply
0216         this filter to all accounts or to selected accounts only. */
0217     QRadioButton *mApplyOnForAll = nullptr;
0218     QRadioButton *mApplyOnForTraditional = nullptr;
0219     QRadioButton *mApplyOnForChecked = nullptr;
0220 
0221     /** ListView that shows the accounts in the advanced tab */
0222     KMFilterAccountList *mAccountList = nullptr;
0223 
0224     QCheckBox *mStopProcessingHere = nullptr;
0225     QCheckBox *mConfigureShortcut = nullptr;
0226     QCheckBox *mConfigureToolbar = nullptr;
0227     KIconButton *mFilterActionIconButton = nullptr;
0228     KKeySequenceWidget *mKeySeqWidget = nullptr;
0229     QGroupBox *mAdvOptsGroup = nullptr;
0230 
0231     MailCommon::MailFilter *mFilter = nullptr;
0232     MailCommon::FolderRequester *mFolderRequester = nullptr;
0233     QPushButton *mRunNow = nullptr;
0234     QPushButton *mApplyButton = nullptr;
0235     bool mDoNotClose = false;
0236     bool mIgnoreFilterUpdates = true;
0237     QWidget *mInMenuWidget = nullptr;
0238 };
0239 }