File indexing completed on 2024-05-26 05:22:14

0001 /*
0002  * This file is part of KMail.
0003  * SPDX-FileCopyrightText: 2011-2024 Laurent Montel <montel@kde.org>
0004  *
0005  * SPDX-FileCopyrightText: 2009 Constantin Berzan <exit3219@gmail.com>
0006  *
0007  * Based on KMail code by:
0008  * SPDX-FileCopyrightText: 1997 Markus Wuebben <markus.wuebben@kde.org>
0009  *
0010  * SPDX-License-Identifier: GPL-2.0-or-later
0011  */
0012 
0013 #pragma once
0014 
0015 // KMail includes
0016 #include "editor/composer.h"
0017 #include "editor/encryptionstate.h"
0018 #include <MessageComposer/PluginEditorConvertTextInterface>
0019 // Qt includes
0020 #include <QFont>
0021 #include <QList>
0022 
0023 #include <MessageComposer/ComposerViewBase>
0024 #include <MessageComposer/RichTextComposerNg>
0025 
0026 #include <MessageComposer/MessageSender>
0027 
0028 #include <KMime/Headers>
0029 #include <KMime/KMimeMessage>
0030 
0031 // Other includes
0032 #include <Libkleo/Enum>
0033 #include <Libkleo/KeyResolverCore>
0034 
0035 class QUrl;
0036 
0037 class QByteArray;
0038 class QGridLayout;
0039 class QLabel;
0040 class QSplitter;
0041 class KSplitterCollapserButton;
0042 class KMComposerWin;
0043 class KMComposerEditor;
0044 class KSelectAction;
0045 class QAction;
0046 class KJob;
0047 class KToggleAction;
0048 class QUrl;
0049 class KRecentFilesAction;
0050 class AttachmentMissingWarning;
0051 class ExternalEditorWarning;
0052 class CryptoStateIndicatorWidget;
0053 class PotentialPhishingEmailWarning;
0054 class KMComposerGlobalAction;
0055 class KMailPluginEditorManagerInterface;
0056 class KMailPluginEditorCheckBeforeSendManagerInterface;
0057 class KMailPluginEditorInitManagerInterface;
0058 class IncorrectIdentityFolderWarning;
0059 class KMailPluginEditorConvertTextManagerInterface;
0060 class KMailPluginGrammarEditorManagerInterface;
0061 class AttachmentAddedFromExternalWarning;
0062 class NearExpiryWarning;
0063 class KHamburgerMenu;
0064 class TooManyRecipientsWarning;
0065 class SubjectLineEditWithAutoCorrection;
0066 namespace MailTransport
0067 {
0068 class Transport;
0069 }
0070 
0071 namespace KIdentityManagementCore
0072 {
0073 class Identity;
0074 }
0075 
0076 namespace Kleo
0077 {
0078 class KeyCache;
0079 }
0080 
0081 namespace TextCustomEditor
0082 {
0083 class RichTextEditorWidget;
0084 }
0085 
0086 namespace KIO
0087 {
0088 class Job;
0089 }
0090 
0091 namespace MessageComposer
0092 {
0093 class ComposerLineEdit;
0094 class Composer;
0095 class StatusBarLabelToggledState;
0096 class RecipientLineNG;
0097 }
0098 
0099 namespace MailCommon
0100 {
0101 class FolderRequester;
0102 class SnippetTreeView;
0103 struct SnippetInfo;
0104 }
0105 
0106 namespace PimCommon
0107 {
0108 class CustomToolsWidgetNg;
0109 class LineEditWithAutoCorrection;
0110 class PurposeMenuMessageWidget;
0111 }
0112 
0113 namespace GpgME
0114 {
0115 class Key;
0116 }
0117 
0118 //-----------------------------------------------------------------------------
0119 class KMComposerWin : public KMail::Composer
0120 {
0121     Q_OBJECT
0122     Q_CLASSINFO("D-Bus Interface", "org.kde.kmail.mailcomposer")
0123 
0124     friend class ::KMComposerEditor;
0125 
0126 private: // mailserviceimpl, kmkernel, kmcommands, callback, kmmainwidget
0127     explicit KMComposerWin(const KMime::Message::Ptr &msg,
0128                            bool lastSignState,
0129                            bool lastEncryptState,
0130                            TemplateContext context = NoTemplate,
0131                            uint identity = 0,
0132                            const QString &textSelection = QString(),
0133                            const QString &customTemplate = QString());
0134     ~KMComposerWin() override;
0135 
0136 public:
0137     enum ModeType {
0138         ComposerType = 0,
0139         TemplateType,
0140     };
0141     Q_ENUM(ModeType)
0142 
0143     static Composer *create(const KMime::Message::Ptr &msg,
0144                             bool lastSignState,
0145                             bool lastEncryptState,
0146                             TemplateContext context = NoTemplate,
0147                             uint identity = 0,
0148                             const QString &textSelection = QString(),
0149                             const QString &customTemplate = QString());
0150 
0151     [[nodiscard]] QString dbusObjectPath() const override;
0152     [[nodiscard]] QString smartQuote(const QString &msg);
0153 
0154     /**
0155      * Start of D-Bus callable stuff. The D-Bus methods need to be public slots,
0156      * otherwise they can't be accessed.
0157      */
0158 public Q_SLOTS:
0159 
0160     Q_SCRIPTABLE void send(int how) override;
0161     /**
0162      * End of D-Bus callable stuff
0163      */
0164 
0165     void addAttachmentsAndSend(const QList<QUrl> &urls, const QString &comment, int how) override;
0166 
0167     void addAttachment(const QList<KMail::Composer::AttachmentInfo> &infos, bool showWarning) override;
0168 
0169     void addAttachment(const QString &name,
0170                        KMime::Headers::contentEncoding cte,
0171                        const QString &charset,
0172                        const QByteArray &data,
0173                        const QByteArray &mimeType) override;
0174 
0175 Q_SIGNALS:
0176     void identityChanged(const KIdentityManagementCore::Identity &identity);
0177 
0178 public: // kmkernel, kmcommands, callback
0179     /**
0180      * Set the message the composer shall work with. This discards
0181      * previous messages without calling applyChanges() on them before.
0182      */
0183     void setMessage(const KMime::Message::Ptr &newMsg,
0184                     bool lastSignState = false,
0185                     bool lastEncryptState = false,
0186                     bool mayAutoSign = true,
0187                     bool allowDecryption = false,
0188                     bool isModified = false) override;
0189 
0190     void setCurrentTransport(int transportId) override;
0191 
0192     /**
0193      * Use the given folder as sent-mail folder if the given folder exists.
0194      * Else show an error message and use the default sent-mail folder as
0195      * sent-mail folder.
0196      */
0197     void setFcc(const QString &idString) override;
0198 
0199     /**
0200      * Disables word wrap completely. No wrapping at all will occur, not even
0201      * at the right end of the editor.
0202      * This is useful when sending invitations.
0203      */
0204     void disableWordWrap() override;
0205 
0206     /**
0207      * Disables HTML completely. It disables HTML at the point of calling this and disables it
0208      * again when sending the message, to be sure. Useful when sending invitations.
0209      * This will <b>not</b> remove the actions for activating HTML mode again, it is only
0210      * meant for automatic invitation sending.
0211      * Also calls @sa disableHtml() internally.
0212      */
0213     void forceDisableHtml() override;
0214 
0215     /**
0216      * Returns @c true while the message composing is in progress.
0217      */
0218     [[nodiscard]] bool isComposing() const override;
0219 
0220     /** Disabled signing and encryption completely for this composer window. */
0221     void setSigningAndEncryptionDisabled(bool v) override;
0222     /**
0223      * If this folder is set, the original message is inserted back after
0224      * canceling
0225      */
0226     void setFolder(const Akonadi::Collection &aFolder) override;
0227     /**
0228      * Sets the focus to the edit-widget.
0229      */
0230     void setFocusToEditor() override;
0231 
0232     /**
0233      * Sets the focus to the subject line edit. For use when creating a
0234      * message to a known recipient.
0235      */
0236     void setFocusToSubject() override;
0237 
0238     bool insertFromMimeData(const QMimeData *source, bool forceAttachment = false);
0239 
0240     void setCollectionForNewMessage(const Akonadi::Collection &folder) override;
0241 
0242     void addExtraCustomHeaders(const QMap<QByteArray, QString> &header) override;
0243 
0244     [[nodiscard]] MessageComposer::PluginEditorConvertTextInterface::ConvertTextStatus convertPlainText(MessageComposer::TextPart *textPart);
0245     [[nodiscard]] bool processModifyText(QKeyEvent *event);
0246 
0247 private:
0248     /**
0249      * Write settings to app's config file.
0250      */
0251     void writeConfig();
0252 
0253     /**
0254      * Returns true if the message was modified by the user.
0255      */
0256     [[nodiscard]] bool isModified() const;
0257     [[nodiscard]] bool isComposerModified() const;
0258     void changeModifiedState(bool modified);
0259 
0260 public Q_SLOTS: // kmkernel, callback
0261     void slotSendNow() override;
0262     /**
0263      * Switch wordWrap on/off
0264      */
0265     void slotWordWrapToggled(bool);
0266 
0267     void slotToggleMarkup();
0268     void slotTextModeChanged(MessageComposer::RichTextComposerNg::Mode mode);
0269     void htmlToolBarVisibilityChanged(bool visible);
0270     void slotSpellcheckDoneClearStatus();
0271     void autoSaveMessage(bool force = false) override;
0272     /**
0273      * Set whether the message should be treated as modified or not.
0274      */
0275     void setModified(bool modified) override;
0276     void slotFetchJob(KJob *);
0277 
0278 private Q_SLOTS:
0279     /**
0280      * Disables the HTML mode, by hiding the HTML toolbar and unchecking the
0281      * "Formatting" action. Also, removes all rich-text formatting.
0282      */
0283     void disableHtml(MessageComposer::ComposerViewBase::Confirmation confirmation);
0284     /**
0285      * Enables HTML mode, by showing the HTML toolbar and checking the
0286      * "Formatting" action
0287      */
0288     void enableHtml();
0289 
0290     /**
0291      * Actions:
0292      */
0293     void slotPrint();
0294     void slotPrintPreview();
0295 
0296     void slotInsertRecentFile(const QUrl &);
0297     void slotRecentListFileClear();
0298 
0299     void slotSendNowVia(MailTransport::Transport *transport);
0300     void slotSendLater();
0301     void slotSendLaterVia(MailTransport::Transport *transport);
0302 
0303     /**
0304      * Returns true when saving was successful.
0305      */
0306     void slotSaveDraft();
0307     void slotSaveTemplate();
0308     void slotNewComposer();
0309     void slotClose();
0310     void slotPasteAsAttachment();
0311     void slotFolderRemoved(const Akonadi::Collection &);
0312     void slotDictionaryLanguageChanged(const QString &language);
0313     void slotFccFolderChanged(const Akonadi::Collection &);
0314     void slotEditorTextChanged();
0315     void slotOverwriteModeChanged();
0316     /**
0317      * toggle fixed width font.
0318      */
0319     void slotUpdateFont();
0320 
0321     /**
0322      * Open addressbook editor dialog.
0323      */
0324     void slotAddressBook();
0325 
0326     /**
0327      * Insert a file to the end of the text in the editor.
0328      */
0329     void slotInsertFile();
0330 
0331     /**
0332      * Check spelling of text.
0333      */
0334     void slotSpellcheckConfig();
0335 
0336     /**
0337      * Change crypto plugin to be used for signing/encrypting messages,
0338      * or switch to built-in OpenPGP code.
0339      */
0340     void slotSelectCryptoModule(bool init);
0341 
0342     /**
0343      * XML-GUI stuff
0344      */
0345     void slotEditToolbars();
0346     void slotUpdateToolbars();
0347     void slotEditKeys();
0348 
0349     /**
0350      * Change window title to given string.
0351      */
0352     void slotUpdateWindowTitle();
0353 
0354     /**
0355      * Change states of all sign check boxes in the attachments listview
0356      */
0357     void slotSignToggled(bool);
0358 
0359     void slotUpdateView();
0360 
0361     /**
0362      * Update composer field to reflect new identity
0363      * @param initalChange if true, don't apply the template. This is useful when calling
0364      *                     this function from setMsg(), because there, the message already has the
0365      *                     template, and we want to avoid calling the template parser unnecessarily.
0366      */
0367     void slotIdentityChanged(uint uoid, bool initalChange = false);
0368 
0369     void slotCursorPositionChanged();
0370 
0371     void slotSpellCheckingStatus(const QString &status);
0372 
0373     void slotDelayedApplyTemplate(KJob *);
0374 
0375     void recipientEditorSizeHintChanged();
0376     void setMaximumHeaderSize();
0377     void slotDoDelayedSend(KJob *);
0378 
0379     void slotCompletionModeChanged(KCompletion::CompletionMode);
0380     void slotConfigChanged();
0381 
0382     void slotPrintComposeResult(KJob *job);
0383 
0384     void slotSendFailed(const QString &msg, MessageComposer::ComposerViewBase::FailedType type);
0385     void slotSendSuccessful(Akonadi::Item::Id id);
0386 
0387     /**
0388      *  toggle automatic spellchecking
0389      */
0390     void slotAutoSpellCheckingToggled(bool);
0391 
0392     void showAndActivateComposer() override;
0393 
0394     void setAutoSaveFileName(const QString &fileName) override;
0395     void slotSpellCheckingLanguage(const QString &language);
0396     void forceAutoSaveMessage();
0397     void slotSaveAsFile();
0398 
0399     void slotAttachMissingFile();
0400     void slotExplicitClosedMissingAttachment();
0401     void slotVerifyMissingAttachmentTimeout();
0402     void slotCheckSendNow();
0403 
0404     void slotExternalEditorStarted();
0405     void slotExternalEditorClosed();
0406 
0407     void slotInsertShortUrl(const QString &url);
0408 
0409     void slotTransportChanged();
0410     void slotFollowUpMail(bool toggled);
0411     void slotSendNowByShortcut();
0412     void slotSnippetWidgetVisibilityChanged(bool b);
0413     void slotOverwriteModeWasChanged(bool state);
0414     void slotExpandGroupResult(KJob *job);
0415     void slotCheckSendNowStep2();
0416     void slotPotentialPhishingEmailsFound(const QStringList &list);
0417     void slotInsertTextFile(KJob *job);
0418 
0419     void slotRecipientEditorLineAdded(KPIM::MultiplyingLine *line);
0420     void slotRecipientEditorFocusChanged();
0421     void slotRecipientAdded(MessageComposer::RecipientLineNG *line);
0422     void slotRecipientLineIconClicked(MessageComposer::RecipientLineNG *line);
0423     void slotRecipientFocusLost(MessageComposer::RecipientLineNG *line);
0424 
0425     void slotDelayedCheckSendNow();
0426     void slotUpdateComposer(const KIdentityManagementCore::Identity &ident, const KMime::Message::Ptr &msg, uint uoid, uint uoldId, bool wasModified);
0427 
0428     void slotEncryptionButtonIconUpdate();
0429 
0430 public: // kmcommand
0431     void addAttach(KMime::Content *msgPart) override;
0432 
0433     const KIdentityManagementCore::Identity &identity() const;
0434     [[nodiscard]] bool pgpAutoSign() const;
0435     [[nodiscard]] bool pgpAutoEncrypt() const;
0436 
0437     /** Don't check for forgotten attachments for a mail, eg. when sending out invitations. */
0438     void disableForgottenAttachmentsCheck() override;
0439 
0440     [[nodiscard]] uint currentIdentity() const;
0441     QList<KToggleAction *> customToolsList() const;
0442     QList<QAction *> pluginToolsActionListForPopupMenu() const;
0443 
0444     [[nodiscard]] ModeType modeType() const;
0445     void setModeType(KMComposerWin::ModeType modeType);
0446 
0447 protected:
0448     bool eventFilter(QObject *obj, QEvent *event) override;
0449 
0450 private:
0451     void enableDisablePluginActions(bool richText);
0452     /**
0453      * Read settings from app's config file.
0454      */
0455     void readConfig(bool reload = false);
0456 
0457     [[nodiscard]] QUrl insertFile();
0458     /**
0459      * Updates the visibility and text of the signature and encryption state indicators.
0460      */
0461     void updateSignatureAndEncryptionStateIndicators();
0462 
0463     void confirmBeforeSend();
0464     void sendNow(bool shortcutUsed);
0465 
0466     void updateSignature(uint uoid, uint uOldId);
0467     [[nodiscard]] Kleo::CryptoMessageFormat cryptoMessageFormat() const;
0468     void printComposeResult(KJob *job, bool preview);
0469     void printComposer(bool preview);
0470     /**
0471      * Install grid management and header fields. If fields exist that
0472      * should not be there they are removed. Those that are needed are
0473      * created if necessary.
0474      */
0475     void rethinkFields(bool fromslot = false, bool forceAllHeaders = false);
0476 
0477     /**
0478       Connect signals for moving focus by arrow keys. Returns next edit.
0479     */
0480     QWidget *connectFocusMoving(QWidget *prev, QWidget *next);
0481 
0482     /**
0483      * Show or hide header lines
0484      */
0485     void rethinkHeaderLine(int value, int mask, int &row, QLabel *lbl, QWidget *cbx);
0486 
0487     /**
0488      * Apply template to new or unmodified message.
0489      */
0490     void applyTemplate(uint uoid, uint uOldId, const KIdentityManagementCore::Identity &ident, bool wasModified);
0491 
0492     /**
0493      * Set the quote prefix according to identity.
0494      */
0495     void setQuotePrefix(uint uoid);
0496 
0497     /**
0498      * Checks how many recipients are and warns if there are too many.
0499      * @return true, if the user accepted the warning and the message should be sent
0500      */
0501     [[nodiscard]] bool checkRecipientNumber() const;
0502 
0503     /**
0504      * Initialization methods
0505      */
0506     void setupActions();
0507     void setupStatusBar(QWidget *w);
0508     void setupEditor();
0509 
0510     /**
0511      * Header fields.
0512      */
0513     [[nodiscard]] QString subject() const;
0514     [[nodiscard]] QString from() const;
0515 
0516     /**
0517      * Ask for confirmation if the message was changed before close.
0518      */
0519     [[nodiscard]] bool queryClose() override;
0520 
0521     /**
0522      * Turn signing on/off. If setByUser is true then a message box is shown
0523      * in case signing isn't possible.
0524      */
0525     void setSigning(bool sign, bool setByUser = false);
0526 
0527     [[nodiscard]] MessageComposer::ComposerViewBase::MissingAttachment userForgotAttachment();
0528     /**
0529      * Send the message.
0530      */
0531     void doSend(MessageComposer::MessageSender::SendMethod method = MessageComposer::MessageSender::SendDefault,
0532                 MessageComposer::MessageSender::SaveIn saveIn = MessageComposer::MessageSender::SaveInNone,
0533                 bool willSendItWithoutReediting = false);
0534 
0535     void doDelayedSend(MessageComposer::MessageSender::SendMethod method, MessageComposer::MessageSender::SaveIn saveIn);
0536 
0537     void changeCryptoAction();
0538     void applyComposerSetting(MessageComposer::ComposerViewBase *mComposerBase);
0539     /**
0540      * Creates a simple composer that creates a KMime::Message out of the composer content.
0541      * Crypto handling is not done, therefore the name "simple".
0542      * This is used when autosaving or printing a message.
0543      *
0544      * The caller takes ownership of the composer.
0545      */
0546     [[nodiscard]] MessageComposer::Composer *createSimpleComposer();
0547 
0548     [[nodiscard]] bool canSignEncryptAttachments() const;
0549 
0550     // helper method for rethinkFields
0551     [[nodiscard]] int calcColumnWidth(int which, long allShowing, int width) const;
0552 
0553 private:
0554     enum CryptoKeyState {
0555         NoState = 0,
0556         InProgress,
0557         KeyOk,
0558         NoKey,
0559     };
0560     void slotToggleMenubar(bool dontShowWarning);
0561 
0562     void slotCryptoModuleSelected();
0563     void slotFccIsInvalid();
0564     void slotIdentityDeleted(uint uoid);
0565     void slotInvalidIdentity();
0566     void slotTransportRemoved(int id, const QString &name);
0567 
0568     void updateComposerAfterIdentityChanged(const KIdentityManagementCore::Identity &ident, uint uoid, bool wasModified);
0569     void checkOwnKeyExpiry(const KIdentityManagementCore::Identity &ident);
0570 
0571     void insertUrls(const QMimeData *source, const QList<QUrl> &urlList);
0572     void initializePluginActions();
0573     bool showErrorMessage(KJob *job);
0574     [[nodiscard]] int validateLineWrapWidth() const;
0575     void slotSelectionChanged();
0576     void slotMessage(const QString &str);
0577     void slotEditorPluginInsertText(const QString &str);
0578     void insertSnippetInfo(const MailCommon::SnippetInfo &info);
0579     [[nodiscard]] bool sendLaterRegistered() const;
0580     void slotRecipientEditorLineFocused();
0581     void updateHamburgerMenu();
0582     void addFaceHeaders(const KIdentityManagementCore::Identity &ident, const KMime::Message::Ptr &msg);
0583     void slotTooManyRecipients(bool b);
0584 
0585     [[nodiscard]] bool sign() const;
0586 
0587     std::unique_ptr<Kleo::KeyResolverCore> fillKeyResolver();
0588     void runKeyResolver();
0589     void annotateRecipientEditorLineWithCryptoInfo(MessageComposer::RecipientLineNG *line, bool autocryptKey, bool gossipKey);
0590 
0591     Akonadi::Collection mCollectionForNewMessage;
0592     QMap<QByteArray, QString> mExtraHeaders;
0593 
0594     EncryptionState mEncryptionState;
0595 
0596     QWidget *mMainWidget = nullptr;
0597     MessageComposer::ComposerLineEdit *mEdtFrom = nullptr;
0598     SubjectLineEditWithAutoCorrection *mEdtSubject = nullptr;
0599     QLabel *mLblIdentity = nullptr;
0600     QLabel *mLblTransport = nullptr;
0601     QLabel *mLblFcc = nullptr;
0602     QLabel *mLblFrom = nullptr;
0603     QLabel *mLblSubject = nullptr;
0604     QLabel *mDictionaryLabel = nullptr;
0605     QLabel *mCursorLineLabel = nullptr;
0606     QLabel *mCursorColumnLabel = nullptr;
0607     QLabel *mStatusbarLabel = nullptr;
0608     bool mDone = false;
0609 
0610     KMime::Message::Ptr mMsg;
0611     QGridLayout *mGrid = nullptr;
0612     const QString mTextSelection;
0613     const QString mCustomTemplate;
0614     bool mLastSignActionState = false;
0615     bool mLastEncryptActionState = false;
0616     bool mSigningAndEncryptionExplicitlyDisabled = false;
0617     bool mLastIdentityHasSigningKey = false;
0618     bool mLastIdentityHasEncryptionKey = false;
0619     Akonadi::Collection mFolder;
0620     long mShowHeaders = 0;
0621     bool mForceDisableHtml = false; // Completely disable any HTML. Useful when sending invitations in the
0622     // mail body.
0623     int mNumHeaders = 0;
0624     QFont mBodyFont;
0625     QFont mFixedFont;
0626     uint mId = 0;
0627     const TemplateContext mContext = NoTemplate;
0628 
0629     KRecentFilesAction *mRecentAction = nullptr;
0630 
0631     KToggleAction *mSignAction = nullptr;
0632     KToggleAction *mEncryptAction = nullptr;
0633     KToggleAction *mRequestMDNAction = nullptr;
0634     KToggleAction *mRequestDeliveryConfirmation = nullptr;
0635     KToggleAction *mUrgentAction = nullptr;
0636     KToggleAction *mAllFieldsAction = nullptr;
0637     KToggleAction *mFromAction = nullptr;
0638     KToggleAction *mSubjectAction = nullptr;
0639     KToggleAction *mIdentityAction = nullptr;
0640     KToggleAction *mTransportAction = nullptr;
0641     KToggleAction *mFccAction = nullptr;
0642     KToggleAction *mWordWrapAction = nullptr;
0643     KToggleAction *mFixedFontAction = nullptr;
0644     KToggleAction *mAutoSpellCheckingAction = nullptr;
0645     KToggleAction *mDictionaryAction = nullptr;
0646     KToggleAction *mSnippetAction = nullptr;
0647     KToggleAction *mShowMenuBarAction = nullptr;
0648     QAction *mAppendSignature = nullptr;
0649     QAction *mPrependSignature = nullptr;
0650     QAction *mInsertSignatureAtCursorPosition = nullptr;
0651 
0652     KToggleAction *mMarkupAction = nullptr;
0653 
0654     KSelectAction *mCryptoModuleAction = nullptr;
0655 
0656     QAction *mFindText = nullptr;
0657     QAction *mFindNextText = nullptr;
0658     QAction *mReplaceText = nullptr;
0659     QAction *mSelectAll = nullptr;
0660 
0661     QSplitter *mHeadersToEditorSplitter = nullptr;
0662     QWidget *mHeadersArea = nullptr;
0663     QSplitter *mSplitter = nullptr;
0664     QSplitter *mSnippetSplitter = nullptr;
0665 
0666     MessageComposer::Composer *mDummyComposer = nullptr;
0667     // used for auto saving, printing, etc. Not for sending, which happens in ComposerViewBase
0668     QList<MessageComposer::Composer *> mMiscComposers;
0669 
0670     int mLabelWidth = 0;
0671 
0672     QString mdbusObjectPath;
0673     static int s_composerNumber;
0674     QMetaObject::Connection mIdentityConnection;
0675     QMetaObject::Connection mUpdateWindowTitleConnection;
0676 
0677     MessageComposer::ComposerViewBase *mComposerBase = nullptr;
0678 
0679     MailCommon::SnippetTreeView *mSnippetWidget = nullptr;
0680     PimCommon::CustomToolsWidgetNg *mCustomToolsWidget = nullptr;
0681     AttachmentMissingWarning *const mAttachmentMissing;
0682     ExternalEditorWarning *const mExternalEditorWarning;
0683     TooManyRecipientsWarning *const mTooMyRecipientWarning;
0684     NearExpiryWarning *const mNearExpiryWarning;
0685     QTimer *mVerifyMissingAttachment = nullptr;
0686     QTimer *mRunKeyResolverTimer = nullptr;
0687     MailCommon::FolderRequester *mFccFolder = nullptr;
0688     bool mPreventFccOverwrite = false;
0689     bool mCheckForForgottenAttachments = true;
0690     bool mWasModified = false;
0691     CryptoStateIndicatorWidget *const mCryptoStateIndicatorWidget;
0692     bool mSendNowByShortcutUsed = false;
0693     KSplitterCollapserButton *mSnippetSplitterCollapser = nullptr;
0694     KToggleAction *mFollowUpToggleAction = nullptr;
0695     MessageComposer::StatusBarLabelToggledState *mStatusBarLabelToggledOverrideMode = nullptr;
0696     MessageComposer::StatusBarLabelToggledState *mStatusBarLabelSpellCheckingChangeMode = nullptr;
0697     PotentialPhishingEmailWarning *const mPotentialPhishingEmailWarning;
0698     IncorrectIdentityFolderWarning *const mIncorrectIdentityFolderWarning;
0699     KMComposerGlobalAction *mGlobalAction = nullptr;
0700     TextCustomEditor::RichTextEditorWidget *mRichTextEditorWidget = nullptr;
0701 
0702     KMailPluginEditorManagerInterface *const mPluginEditorManagerInterface;
0703     KMailPluginEditorCheckBeforeSendManagerInterface *mPluginEditorCheckBeforeSendManagerInterface = nullptr;
0704     KMailPluginEditorInitManagerInterface *mPluginEditorInitManagerInterface = nullptr;
0705     KMailPluginEditorConvertTextManagerInterface *mPluginEditorConvertTextManagerInterface = nullptr;
0706     KMailPluginGrammarEditorManagerInterface *const mPluginEditorGrammarManagerInterface;
0707 
0708     AttachmentAddedFromExternalWarning *const mAttachmentFromExternalMissing;
0709     KHamburgerMenu *mHamburgerMenu = nullptr;
0710     PimCommon::PurposeMenuMessageWidget *const mPluginEditorMessageWidget;
0711 
0712     std::shared_ptr<Kleo::KeyCache> mKeyCache;
0713 
0714     ModeType mModeType = ModeType::ComposerType;
0715 };