File indexing completed on 2024-05-12 05:20:40

0001 //
0002 
0003 #pragma once
0004 #include <MailCommon/MailInterfaces>
0005 
0006 #include <QDBusObjectPath>
0007 #include <QList>
0008 #include <QObject>
0009 #include <QPointer>
0010 
0011 #include <QUrl>
0012 
0013 #include "kmail_export.h"
0014 #include "settings/kmailsettings.h"
0015 #include <Akonadi/ServerManager>
0016 #include <Libkdepim/ProgressManager>
0017 #include <MessageViewer/Viewer>
0018 
0019 #include <memory>
0020 
0021 #define kmkernel KMKernel::self()
0022 #define kmconfig KMKernel::config()
0023 
0024 class QAbstractItemModel;
0025 namespace Akonadi
0026 {
0027 class Collection;
0028 class ChangeRecorder;
0029 class EntityTreeModel;
0030 class EntityMimeTypeFilterModel;
0031 }
0032 
0033 namespace Akonadi
0034 {
0035 namespace Search
0036 {
0037 namespace PIM
0038 {
0039 class IndexedItems;
0040 }
0041 }
0042 }
0043 
0044 namespace KIO
0045 {
0046 class Job;
0047 }
0048 
0049 namespace MessageComposer
0050 {
0051 class MessageSender;
0052 }
0053 namespace TextAutoCorrectionCore
0054 {
0055 class AutoCorrection;
0056 }
0057 
0058 /** The KMail namespace contains classes used for KMail.
0059  * This is to keep them out of the way from all the other
0060  * un-namespaced classes in libs and the rest of PIM.
0061  */
0062 namespace KMail
0063 {
0064 class MailServiceImpl;
0065 class UndoStack;
0066 class UnityServiceManager;
0067 }
0068 namespace MessageComposer
0069 {
0070 class AkonadiSender;
0071 }
0072 
0073 namespace KIdentityManagementCore
0074 {
0075 class Identity;
0076 class IdentityManager;
0077 }
0078 
0079 namespace MailCommon
0080 {
0081 class Kernel;
0082 class FolderSettings;
0083 class FolderCollectionMonitor;
0084 class JobScheduler;
0085 class KMFilterDialog;
0086 class MailCommonSettings;
0087 }
0088 
0089 #ifdef WITH_KUSERFEEDBACK
0090 class KMailUserFeedbackProvider;
0091 namespace KUserFeedback
0092 {
0093 class Provider;
0094 }
0095 #endif
0096 
0097 namespace Kleo
0098 {
0099 class KeyCache;
0100 }
0101 
0102 class QTimer;
0103 class KMainWindow;
0104 class KMMainWidget;
0105 class ConfigureDialog;
0106 class FolderArchiveManager;
0107 class CheckIndexingManager;
0108 
0109 /**
0110  * @short Central point of coordination in KMail
0111  *
0112  * The KMKernel class represents the core of KMail, where the different parts
0113  * come together and are coordinated. It is currently also the class which exports
0114  * KMail's main D-BUS interfaces.
0115  *
0116  * The kernel is responsible for creating various
0117  * (singleton) objects such as the identity manager and the message sender.
0118  *
0119  * The kernel also creates an Akonadi Session, Monitor and EntityTreeModel. These
0120  * are shared so that other objects in KMail have access to it. Having only one EntityTreeModel
0121  * instead of many reduces the overall communication with the Akonadi server.
0122  *
0123  * The kernel also manages some stuff that should be factored out:
0124  * - default collection handling, like inboxCollectionFolder()
0125  * - job handling, like jobScheduler()
0126  * - handling of some config settings, like wrapCol()
0127  * - various other stuff
0128  */
0129 class KMAIL_EXPORT KMKernel : public QObject, public MailCommon::IKernel, public MailCommon::ISettings, public MailCommon::IFilter
0130 {
0131     Q_OBJECT
0132     Q_CLASSINFO("D-Bus Interface", "org.kde.kmail.kmail")
0133 
0134 public:
0135     explicit KMKernel(QObject *parent = nullptr);
0136     ~KMKernel() override;
0137 
0138     /**
0139      * Start of D-Bus callable stuff. The D-Bus methods need to be public slots,
0140      * otherwise they can't be accessed.
0141      */
0142 public Q_SLOTS:
0143 
0144     Q_SCRIPTABLE void checkMail();
0145     Q_SCRIPTABLE void openReader();
0146 
0147     /**
0148      * Pauses all background jobs and does not
0149      * allow new background jobs to be started.
0150      */
0151     Q_SCRIPTABLE void pauseBackgroundJobs();
0152 
0153     /**
0154      * Resumes all background jobs and allows
0155      * new jobs to be started.
0156      */
0157     Q_SCRIPTABLE void resumeBackgroundJobs();
0158 
0159     /**
0160      * Stops all network related jobs and enter offline mode
0161      * New network jobs cannot be started.
0162      */
0163     Q_SCRIPTABLE void stopNetworkJobs();
0164 
0165     /**
0166      * Resumes all network related jobs and enter online mode
0167      * New network jobs can be started.
0168      */
0169     Q_SCRIPTABLE void resumeNetworkJobs();
0170 
0171     Q_SCRIPTABLE QStringList accounts() const;
0172 
0173     Q_SCRIPTABLE void makeResourceOnline(MessageViewer::Viewer::ResourceOnlineMode mode);
0174 
0175     /**
0176      * Checks the account with the specified name for new mail.
0177      * If the account name is empty, all accounts not excluded from manual
0178      * mail check will be checked.
0179      */
0180     Q_SCRIPTABLE void checkAccount(const QString &account);
0181 
0182     Q_SCRIPTABLE bool selectFolder(const QString &folder);
0183 
0184     Q_SCRIPTABLE bool canQueryClose();
0185 
0186     Q_SCRIPTABLE bool handleCommandLine(bool noArgsOpensReader, const QStringList &args, const QString &workingDir);
0187 
0188     /**
0189      * Opens a composer window and prefills it with different
0190      * message parts.
0191      *
0192      *
0193      * @param to A comma separated list of To addresses.
0194      * @param cc A comma separated list of CC addresses.
0195      * @param bcc A comma separated list of BCC addresses.
0196      * @param subject The message subject.
0197      * @param body The message body.
0198      * @param hidden Whether the composer window shall initially be hidden.
0199      * @param messageFile A message file that will be used as message body.
0200      * @param attachmentPaths A list of files that will be attached to the message.
0201      * @param customHeaders A list of custom headers.
0202      * @param replyTo A list of reply-to headers.
0203      * @param inReplyTo A list of in-reply-to headers.
0204      * @param identity The mail identity.
0205      */
0206     Q_SCRIPTABLE void openComposer(const QString &to,
0207                                    const QString &cc,
0208                                    const QString &bcc,
0209                                    const QString &subject,
0210                                    const QString &body,
0211                                    bool hidden,
0212                                    const QString &messageFile,
0213                                    const QStringList &attachmentPaths,
0214                                    const QStringList &customHeaders,
0215                                    const QString &replyTo = QString(),
0216                                    const QString &inReplyTo = QString(),
0217                                    const QString &identity = QString());
0218 
0219     /**
0220      * Opens a composer window and prefills it with different
0221      * message parts.
0222      *
0223      * @param to A comma separated list of To addresses.
0224      * @param cc A comma separated list of CC addresses.
0225      * @param bcc A comma separated list of BCC addresses.
0226      * @param subject The message subject.
0227      * @param body The message body.
0228      * @param hidden Whether the composer window shall initially be hidden.
0229      * @param attachName The name of the attachment.
0230      * @param attachCte The content transfer encoding of the attachment.
0231      * @param attachData The raw data of the attachment.
0232      * @param attachType The mime type of the attachment.
0233      * @param attachSubType The sub mime type of the attachment.
0234      * @param attachParamAttr The parameter attribute of the attachment.
0235      * @param attachParamValue The parameter value of the attachment.
0236      * @param attachContDisp The content display type of the attachment.
0237      * @param attachCharset The charset of the attachment.
0238      * @param identity The identity identifier which will be used as sender identity.
0239      */
0240     Q_SCRIPTABLE void openComposer(const QString &to,
0241                                    const QString &cc,
0242                                    const QString &bcc,
0243                                    const QString &subject,
0244                                    const QString &body,
0245                                    bool hidden,
0246                                    const QString &attachName,
0247                                    const QByteArray &attachCte,
0248                                    const QByteArray &attachData,
0249                                    const QByteArray &attachType,
0250                                    const QByteArray &attachSubType,
0251                                    const QByteArray &attachParamAttr,
0252                                    const QString &attachParamValue,
0253                                    const QByteArray &attachContDisp,
0254                                    const QByteArray &attachCharset,
0255                                    unsigned int identity);
0256 
0257     /**
0258      * Opens a composer window and prefills it with different
0259      * message parts.
0260      * @since 5.0
0261      *
0262      * @param to A comma separated list of To addresses.
0263      * @param cc A comma separated list of CC addresses.
0264      * @param bcc A comma separated list of BCC addresses.
0265      * @param subject The message subject.
0266      * @param body The message body.
0267      * @param attachName The name of the attachment.
0268      * @param attachCte The content transfer encoding of the attachment.
0269      * @param attachData The raw data of the attachment.
0270      * @param attachType The mime type of the attachment.
0271      * @param attachSubType The sub mime type of the attachment.
0272      * @param attachParamAttr The parameter attribute of the attachment.
0273      * @param attachParamValue The parameter value of the attachment.
0274      * @param attachContDisp The content display type of the attachment.
0275      * @param attachCharset The charset of the attachment.
0276      * @param identity The identity identifier which will be used as sender identity.
0277      */
0278     Q_SCRIPTABLE void openComposer(const QString &to,
0279                                    const QString &cc,
0280                                    const QString &bcc,
0281                                    const QString &subject,
0282                                    const QString &body,
0283                                    const QString &attachName,
0284                                    const QByteArray &attachCte,
0285                                    const QByteArray &attachData,
0286                                    const QByteArray &attachType,
0287                                    const QByteArray &attachSubType,
0288                                    const QByteArray &attachParamAttr,
0289                                    const QString &attachParamValue,
0290                                    const QByteArray &attachContDisp,
0291                                    const QByteArray &attachCharset,
0292                                    unsigned int identity);
0293 
0294     /**
0295      * Opens a composer window and prefills it with different
0296      * message parts.
0297      *
0298      *
0299      * @param to A comma separated list of To addresses.
0300      * @param cc A comma separated list of CC addresses.
0301      * @param bcc A comma separated list of BCC addresses.
0302      * @param subject The message subject.
0303      * @param body The message body.
0304      * @param hidden Whether the composer window shall initially be hidden.
0305      */
0306     Q_SCRIPTABLE void openComposer(const QString &to, const QString &cc, const QString &bcc, const QString &subject, const QString &body, bool hidden);
0307 
0308     /**
0309      * Opens a composer window and prefills it with different
0310      * message parts.
0311      *
0312      * @returns The DBus object path for the composer.
0313      *
0314      * @param to A comma separated list of To addresses.
0315      * @param cc A comma separated list of CC addresses.
0316      * @param bcc A comma separated list of BCC addresses.
0317      * @param hidden Whether the composer window shall initially be hidden.
0318      * @param useFolderId The id of the folder whose associated identity will be used.
0319      * @param messageFile A message file that will be used as message body.
0320      * @param attachURL The URL to the file that will be attached to the message.
0321      */
0322     Q_SCRIPTABLE void
0323     newMessage(const QString &to, const QString &cc, const QString &bcc, bool hidden, bool useFolderId, const QString &messageFile, const QString &attachURL);
0324 
0325     Q_SCRIPTABLE bool showMail(qint64 serialNumber);
0326 
0327     Q_SCRIPTABLE int viewMessage(const QString &messageFile);
0328 
0329     Q_SCRIPTABLE void updateConfig();
0330 
0331     Q_SCRIPTABLE void showFolder(const QString &collectionId);
0332 
0333     Q_SCRIPTABLE void reloadFolderArchiveConfig();
0334 
0335     Q_SCRIPTABLE bool replyMail(qint64 serialNumber, bool replyToAll);
0336 
0337     /**
0338      * End of D-Bus callable stuff
0339      */
0340 
0341 public:
0342     void checkMailOnStartup();
0343 
0344     /** A static helper function that asks the user
0345      * if they want to go online.
0346      * @return true if the user wants to go online
0347      * @return false if the user wants to stay offline
0348      */
0349     static bool askToGoOnline();
0350 
0351     /** Checks if the current network state is online or offline
0352      * @return true if the network state is offline
0353      * @return false if the network state is online
0354      */
0355     static bool isOffline();
0356 
0357     /** normal control stuff */
0358 
0359     static KMKernel *self();
0360     KSharedConfig::Ptr config() override;
0361     void syncConfig() override;
0362 
0363     void init();
0364     void setupDBus();
0365 
0366     void expunge(Akonadi::Collection::Id col, bool sync) override;
0367     Akonadi::ChangeRecorder *folderCollectionMonitor() const override;
0368 
0369     /**
0370      * Returns the main model, which contains all folders and the items of recently opened folders.
0371      */
0372     Akonadi::EntityTreeModel *entityTreeModel() const;
0373 
0374     /**
0375      * Returns a model of all folders in KMail. This is basically the same as entityTreeModel(),
0376      * but with items filtered out, the model contains only collections.
0377      */
0378     [[nodiscard]] Akonadi::EntityMimeTypeFilterModel *collectionModel() const override;
0379 
0380     void recoverDeadLetters();
0381     void closeAllKMailWindows();
0382     void cleanup();
0383     void quit();
0384     void doSessionManagement();
0385     [[nodiscard]] bool firstInstance() const;
0386     void setFirstInstance(bool value);
0387     void action(bool mailto,
0388                 bool check,
0389                 bool startInTray,
0390                 const QString &to,
0391                 const QString &cc,
0392                 const QString &bcc,
0393                 const QString &subj,
0394                 const QString &body,
0395                 const QUrl &messageFile,
0396                 const QList<QUrl> &attach,
0397                 const QStringList &customHeaders,
0398                 const QString &replyTo,
0399                 const QString &inReplyTo,
0400                 const QString &identity);
0401 
0402     // sets online status for akonadi accounts. true for online, false for offline
0403     void setAccountStatus(bool);
0404 
0405     [[nodiscard]] const QString xmlGuiInstanceName() const;
0406     void setXmlGuiInstanceName(const QString &instance);
0407 
0408     [[nodiscard]] KMail::UndoStack *undoStack() const;
0409     MessageComposer::MessageSender *msgSender() override;
0410 
0411     void openFilterDialog(bool createDummyFilter = true) override;
0412     void createFilter(const QByteArray &field, const QString &value) override;
0413 
0414     /** return the pointer to the identity manager */
0415     KIdentityManagementCore::IdentityManager *identityManager() override;
0416 
0417     MailCommon::JobScheduler *jobScheduler() const override;
0418 
0419     /** Expire all folders, used for the gui action */
0420     void expireAllFoldersNow();
0421 
0422     [[nodiscard]] bool firstStart() const;
0423     [[nodiscard]] bool shuttingDown() const;
0424     void setShuttingDown(bool flag);
0425 
0426     /** Returns true if we have a system tray applet. This is needed in order
0427      *  to know whether the application should be allowed to exit in case the
0428      *  last visible composer or separate message window is closed.
0429      */
0430     [[nodiscard]] bool haveSystemTrayApplet() const;
0431 
0432     void setSystemTryAssociatedWindow(QWindow *window);
0433 
0434     /** returns a reference to the first Mainwin or a temporary Mainwin */
0435     KMainWindow *mainWin();
0436 
0437     /** Get first mainwidget */
0438     KMMainWidget *getKMMainWidget() const;
0439 
0440     /**
0441      * Returns a list of all currently loaded folders. Since folders are loaded async, this
0442      * is empty at startup.
0443      */
0444     [[nodiscard]] Akonadi::Collection::List allFolders() const;
0445 
0446     /**
0447      * Includes all subfolders of @p col, including the @p col itself.
0448      */
0449     [[nodiscard]] Akonadi::Collection::List subfolders(const Akonadi::Collection &col) const;
0450 
0451     //
0452     void selectCollectionFromId(Akonadi::Collection::Id id);
0453 
0454     void raise();
0455 
0456     void stopAgentInstance();
0457 
0458     // ISettings
0459     [[nodiscard]] bool showPopupAfterDnD() override;
0460 
0461     bool excludeImportantMailFromExpiry() override;
0462 
0463     qreal closeToQuotaThreshold() override;
0464 
0465     [[nodiscard]] Akonadi::Collection::Id lastSelectedFolder() override;
0466     void setLastSelectedFolder(Akonadi::Collection::Id col) override;
0467 
0468     QStringList customTemplates() override;
0469 
0470     void checkFolderFromResources(const Akonadi::Collection::List &collectionList);
0471 
0472     [[nodiscard]] const QAbstractItemModel *treeviewModelSelection();
0473 
0474     void savePaneSelection();
0475 
0476     void updatePaneTagComboBox();
0477     [[nodiscard]] TextAutoCorrectionCore::AutoCorrection *composerAutoCorrection();
0478 
0479     void toggleSystemTray();
0480     FolderArchiveManager *folderArchiveManager() const;
0481 
0482     [[nodiscard]] bool allowToDebug() const;
0483 
0484     [[nodiscard]] Akonadi::Search::PIM::IndexedItems *indexedItems() const;
0485 
0486     void cleanupTemporaryFiles();
0487     [[nodiscard]] MailCommon::MailCommonSettings *mailCommonSettings() const;
0488 #ifdef WITH_KUSERFEEDBACK
0489     KUserFeedback::Provider *userFeedbackProvider() const;
0490 #endif
0491 protected:
0492     void agentInstanceBroken(const Akonadi::AgentInstance &instance);
0493 
0494 public Q_SLOTS:
0495 
0496     void updateSystemTray() override;
0497 
0498     /** Custom templates have changed, so all windows using them need
0499       to regenerate their menus */
0500     void updatedTemplates();
0501 
0502     /// Save contents of all open composer windows to ~/dead.letter
0503     void dumpDeadLetters();
0504 
0505     /** Call this slot instead of directly KConfig::sync() to
0506       minimize the overall config writes. Calling this slot will
0507       schedule a sync of the application config file using a timer, so
0508       that many consecutive calls can be condensed into a single
0509       sync, which is more efficient. */
0510     void slotRequestConfigSync();
0511 
0512     /**
0513      * Sync the config immediatley
0514      */
0515     void slotSyncConfig();
0516 
0517     void slotShowConfigurationDialog();
0518     void slotRunBackgroundTasks();
0519 
0520     void slotConfigChanged();
0521 Q_SIGNALS:
0522     void configChanged();
0523     void onlineStatusChanged(KMailSettings::EnumNetworkState::type);
0524     void customTemplatesChanged();
0525 
0526     void startCheckMail();
0527     void endCheckMail();
0528 
0529     void incomingAccountsChanged();
0530 private Q_SLOTS:
0531     /** Updates identities when a transport has been deleted. */
0532     void transportRemoved(int id, const QString &name);
0533     /** Updates identities when a transport has been renamed. */
0534     void transportRenamed(int id, const QString &oldName, const QString &newName);
0535     void itemDispatchStarted();
0536     void instanceStatusChanged(const Akonadi::AgentInstance &);
0537 
0538     void akonadiStateChanged(Akonadi::ServerManager::State);
0539     void slotProgressItemCompletedOrCanceled(KPIM::ProgressItem *item);
0540     void slotInstanceError(const Akonadi::AgentInstance &instance, const QString &message);
0541     void slotInstanceWarning(const Akonadi::AgentInstance &instance, const QString &message);
0542     void slotCollectionRemoved(const Akonadi::Collection &col);
0543     void slotDeleteIdentity(uint identity);
0544     void slotInstanceRemoved(const Akonadi::AgentInstance &);
0545     void slotInstanceAdded(const Akonadi::AgentInstance &);
0546     void slotSystemNetworkStatusChanged(bool isOnline);
0547     void slotCollectionChanged(const Akonadi::Collection &, const QSet<QByteArray> &set);
0548 
0549     void slotCheckAccount(Akonadi::ServerManager::State state);
0550 
0551 private:
0552     void viewMessage(const QUrl &url);
0553     [[nodiscard]] Akonadi::Collection currentCollection() const;
0554 
0555     /*
0556      * Fills a composer cWin
0557      *
0558      */
0559     void fillComposer(bool hidden,
0560                       const QString &to,
0561                       const QString &cc,
0562                       const QString &bcc,
0563                       const QString &subject,
0564                       const QString &body,
0565                       const QString &attachName,
0566                       const QByteArray &attachCte,
0567                       const QByteArray &attachData,
0568                       const QByteArray &attachType,
0569                       const QByteArray &attachSubType,
0570                       const QByteArray &attachParamAttr,
0571                       const QString &attachParamValue,
0572                       const QByteArray &attachContDisp,
0573                       const QByteArray &attachCharset,
0574                       unsigned int identity,
0575                       bool forceShowWindow);
0576 
0577     void verifyAccount();
0578     void resourceGoOnLine();
0579     void openReader(bool onlyCheck, bool startInTray);
0580     QSharedPointer<MailCommon::FolderSettings> currentFolderCollection();
0581     void saveConfig();
0582 
0583     KMail::UndoStack *the_undoStack = nullptr;
0584     MessageComposer::AkonadiSender *the_msgSender = nullptr;
0585     /** is this the first start?  read from config */
0586     bool the_firstStart = false;
0587     /** are we going down? set from here */
0588     bool the_shuttingDown = false;
0589     /** true unles kmail is closed by session management */
0590     bool the_firstInstance = false;
0591 
0592     KSharedConfig::Ptr mConfig;
0593     QString mXmlGuiInstance;
0594     ConfigureDialog *mConfigureDialog = nullptr;
0595 
0596     QTimer *mBackgroundTasksTimer = nullptr;
0597     MailCommon::JobScheduler *const mJobScheduler;
0598     KMail::MailServiceImpl *mMailService = nullptr;
0599 
0600     bool mSystemNetworkStatus = true;
0601 
0602     KMail::UnityServiceManager *mUnityServiceManager = nullptr;
0603     QHash<QString, KPIM::ProgressItem::CryptoStatus> mResourceCryptoSettingCache;
0604     MailCommon::FolderCollectionMonitor *mFolderCollectionMonitor = nullptr;
0605     Akonadi::EntityTreeModel *mEntityTreeModel = nullptr;
0606     Akonadi::EntityMimeTypeFilterModel *mCollectionModel = nullptr;
0607 
0608     /// List of Akonadi resources that are currently being checked.
0609     QStringList mResourcesBeingChecked;
0610 
0611     QPointer<MailCommon::KMFilterDialog> mFilterEditDialog;
0612     TextAutoCorrectionCore::AutoCorrection *mAutoCorrection = nullptr;
0613     FolderArchiveManager *const mFolderArchiveManager;
0614     CheckIndexingManager *mCheckIndexingManager = nullptr;
0615     Akonadi::Search::PIM::IndexedItems *mIndexedItems = nullptr;
0616     MailCommon::MailCommonSettings *mMailCommonSettings = nullptr;
0617 #ifdef WITH_KUSERFEEDBACK
0618     KMailUserFeedbackProvider *mUserFeedbackProvider = nullptr;
0619 #endif
0620     std::shared_ptr<const Kleo::KeyCache> mKeyCache;
0621 
0622     bool mDebug = false;
0623 };