File indexing completed on 2024-12-22 05:01:14

0001 /*
0002  * kmail: KDE mail client
0003  * SPDX-FileCopyrightText: 1996-1998 Stefan Taferner <taferner@kde.org>
0004  * SPDX-FileCopyrightText: 2001 Aaron J. Seigo <aseigo@kde.org>
0005  *
0006  * SPDX-License-Identifier: GPL-2.0-or-later
0007  *
0008  */
0009 
0010 #pragma once
0011 
0012 #include "ui_searchwindow.h"
0013 #include <MailCommon/SearchPattern>
0014 
0015 #include <Akonadi/Collection>
0016 #include <Akonadi/Item>
0017 #include <KGuiItem>
0018 #include <KXMLGUIClient>
0019 #include <QDialog>
0020 #include <QTimer>
0021 
0022 class QCloseEvent;
0023 class QKeyEvent;
0024 class KActionMenu;
0025 class KJob;
0026 class KMMainWidget;
0027 class KMSearchMessageModel;
0028 
0029 namespace PimCommon
0030 {
0031 class SelectMultiCollectionDialog;
0032 }
0033 
0034 namespace Akonadi
0035 {
0036 class StandardMailActionManager;
0037 }
0038 
0039 namespace KMime
0040 {
0041 class Message;
0042 }
0043 
0044 namespace KMail
0045 {
0046 /**
0047  * The SearchWindow class provides a dialog for triggering a search on
0048  * folders and storing that search as a search folder. It shows the search
0049  * results in a listview and allows triggering of operations such as printing
0050  * or moving on them.
0051  */
0052 class SearchPatternWarning;
0053 class SearchWindow : public QDialog, public KXMLGUIClient
0054 {
0055     Q_OBJECT
0056 
0057 public:
0058     /**
0059      * Creates a new search window.
0060      *
0061      * @param parent The parent widget.
0062      * @param collection The folder which will be pre-selected as the base folder
0063      *                   of search operations.
0064      */
0065     explicit SearchWindow(KMMainWidget *parent, const Akonadi::Collection &collection = Akonadi::Collection());
0066 
0067     /**
0068      * Destroys the search window.
0069      */
0070     ~SearchWindow() override;
0071 
0072     /**
0073      * Changes the base folder for search operations to a different folder.
0074      *
0075      * @param folder The folder to use as the new base for searches.
0076      */
0077     void activateFolder(const Akonadi::Collection &folder);
0078 
0079     /**
0080      * Provides access to the list of currently selected message in the listview.
0081      *
0082      * @return The list of currently selected search result messages.
0083      */
0084     [[nodiscard]] Akonadi::Item::List selectedMessages() const;
0085 
0086     /**
0087      * Provides access to the currently selected message.
0088      *
0089      * @return the currently selected message.
0090      */
0091     [[nodiscard]] Akonadi::Item selectedMessage() const;
0092 
0093     /**
0094      * Loads a search pattern into the search window, appending its rules to the current one.
0095      */
0096     void addRulesToSearchPattern(const MailCommon::SearchPattern &pattern);
0097 
0098 protected:
0099     /** Reimplemented to react to Escape. */
0100     void keyPressEvent(QKeyEvent *) override;
0101 
0102     /** Reimplemented to stop searching when the window is closed */
0103     void closeEvent(QCloseEvent *) override;
0104 
0105     void createSearchModel();
0106 
0107 private:
0108     void updateCollectionStatistic(Akonadi::Collection::Id, const Akonadi::CollectionStatistics &);
0109 
0110     void slotClose();
0111     void slotSearch();
0112     void slotStop();
0113     void scheduleRename(const QString &);
0114     void renameSearchFolder();
0115     void openSearchFolder();
0116     void slotViewSelectedMsg();
0117     void slotViewMsg(const Akonadi::Item &);
0118     void slotCurrentChanged(const Akonadi::Item &);
0119     void updateContextMenuActions();
0120     void slotFolderActivated();
0121     void slotClearSelection();
0122     void slotReplyToMsg();
0123     void slotReplyAllToMsg();
0124     void slotReplyListToMsg();
0125     void slotForwardMsg();
0126     void slotForwardAttachedMsg();
0127     void slotSaveMsg();
0128     void slotSaveAttachments();
0129     void slotPrintMsg();
0130 
0131     /** GUI cleanup after search */
0132     void slotCollectionStatisticsRetrieved(KJob *job);
0133     void searchDone(KJob *);
0134     void enableGUI();
0135 
0136     void setEnabledSearchButton(bool);
0137     void slotSearchFolderRenameDone(KJob *);
0138 
0139     void slotContextMenuRequested(const QPoint &);
0140     void slotSelectMultipleFolders();
0141 
0142     void slotSearchCollectionsFetched(KJob *job);
0143 
0144     void slotJumpToFolder();
0145 
0146 private:
0147     void doSearch();
0148     QList<qint64> checkIncompleteIndex(const Akonadi::Collection::List &searchCols, bool recursive);
0149     Akonadi::Collection::List searchCollectionsRecursive(const Akonadi::Collection::List &cols) const;
0150     QPointer<PimCommon::SelectMultiCollectionDialog> mSelectMultiCollectionDialog;
0151     QList<Akonadi::Collection> mCollectionId;
0152     Akonadi::SearchQuery mQuery;
0153     Qt::SortOrder mSortOrder = Qt::AscendingOrder;
0154     Akonadi::Collection mFolder;
0155 
0156     Ui_SearchWindow mUi;
0157     KGuiItem mStartSearchGuiItem;
0158     KGuiItem mStopSearchGuiItem;
0159     MailCommon::SearchPattern mSearchPattern;
0160 
0161     bool mCloseRequested = false;
0162     int mSortColumn = 0;
0163 
0164     KJob *mSearchJob = nullptr;
0165     KMSearchMessageModel *mResultModel = nullptr;
0166     QPushButton *const mSearchButton;
0167 
0168     QAction *mReplyAction = nullptr;
0169     QAction *mReplyAllAction = nullptr;
0170     QAction *mReplyListAction = nullptr;
0171     QAction *mSaveAsAction = nullptr;
0172     QAction *mForwardInlineAction = nullptr;
0173     QAction *mForwardAttachedAction = nullptr;
0174     QAction *mPrintAction = nullptr;
0175     QAction *mClearAction = nullptr;
0176     QAction *mSaveAtchAction = nullptr;
0177     QAction *mJumpToFolderAction = nullptr;
0178     KActionMenu *mForwardActionMenu = nullptr;
0179     QTimer mRenameTimer;
0180     QByteArray mHeaderState;
0181     // not owned by us
0182     KMMainWidget *const mKMMainWidget;
0183     SearchPatternWarning *mSearchPatternWidget = nullptr;
0184 
0185     Akonadi::StandardMailActionManager *mAkonadiStandardAction = nullptr;
0186 };
0187 }