File indexing completed on 2024-06-23 05:18:27
0001 /* 0002 SPDX-FileCopyrightText: 2010 Klaralvdalens Datakonsult AB, a KDAB Group company, info@kdab.com 0003 SPDX-FileCopyrightText: 2010 Leo Franchi <lfranchi@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #pragma once 0009 0010 #include "MessageComposer/Recipient" 0011 #include "messagecomposer/messagesender.h" 0012 #include "messagecomposer_export.h" 0013 #include <Akonadi/Collection> 0014 #include <Akonadi/Item> 0015 #include <KMime/Message> 0016 0017 #include <Libkleo/Enum> 0018 #include <QList> 0019 #include <QObject> 0020 #include <QUrl> 0021 0022 class QTimer; 0023 class KJob; 0024 class QWidget; 0025 0026 class ComposerViewBaseTest; 0027 0028 namespace Sonnet 0029 { 0030 class DictionaryComboBox; 0031 } 0032 0033 namespace Akonadi 0034 { 0035 class CollectionComboBox; 0036 } 0037 0038 namespace MailTransport 0039 { 0040 class TransportComboBox; 0041 } 0042 namespace KIdentityManagementWidgets 0043 { 0044 class IdentityCombo; 0045 } 0046 namespace KIdentityManagementCore 0047 { 0048 class Identity; 0049 class IdentityManager; 0050 } 0051 0052 namespace Kleo 0053 { 0054 class ExpiryChecker; 0055 class KeyResolver; 0056 } 0057 0058 namespace MessageComposer 0059 { 0060 class RecipientsEditor; 0061 class RichTextComposerNg; 0062 class InfoPart; 0063 class GlobalPart; 0064 class Composer; 0065 class AttachmentControllerBase; 0066 class AttachmentModel; 0067 class SignatureController; 0068 class SendLaterInfo; 0069 /** 0070 * @brief The ComposerViewBase class 0071 */ 0072 class MESSAGECOMPOSER_EXPORT ComposerViewBase : public QObject 0073 { 0074 Q_OBJECT 0075 public: 0076 explicit ComposerViewBase(QObject *parent = nullptr, QWidget *widget = nullptr); 0077 ~ComposerViewBase() override; 0078 0079 enum Confirmation { 0080 LetUserConfirm, 0081 NoConfirmationNeeded, 0082 }; 0083 enum MissingAttachment { 0084 NoMissingAttachmentFound, 0085 FoundMissingAttachmentAndSending, 0086 FoundMissingAttachmentAndAddedAttachment, 0087 FoundMissingAttachmentAndCancel, 0088 }; 0089 0090 enum FailedType { 0091 Sending, 0092 AutoSave, 0093 }; 0094 0095 /** 0096 * Set the message to be opened in the composer window, and set the internal data structures to 0097 * keep track of it. 0098 */ 0099 void setMessage(const KMime::Message::Ptr &newMsg, bool allowDecryption); 0100 0101 void updateTemplate(const KMime::Message::Ptr &msg); 0102 0103 /** 0104 * Send the message with the specified method, saving it in the specified folder. 0105 */ 0106 void send(MessageComposer::MessageSender::SendMethod method, MessageComposer::MessageSender::SaveIn saveIn, bool checkMailDispatcher = true); 0107 0108 /** 0109 * Returns true if there is at least one composer job running. 0110 */ 0111 [[nodiscard]] bool isComposing() const; 0112 0113 /** 0114 * Add the given attachment to the message. 0115 */ 0116 void addAttachment(const QUrl &url, const QString &comment, bool sync); 0117 void addAttachment(const QString &name, const QString &filename, const QString &charset, const QByteArray &data, const QByteArray &mimeType); 0118 void addAttachmentPart(KMime::Content *part); 0119 0120 void fillComposer(MessageComposer::Composer *composer); 0121 0122 /** 0123 * Header fields in recipients editor. 0124 */ 0125 [[nodiscard]] QString to() const; 0126 [[nodiscard]] QString cc() const; 0127 [[nodiscard]] QString bcc() const; 0128 [[nodiscard]] QString from() const; 0129 [[nodiscard]] QString replyTo() const; 0130 [[nodiscard]] QString subject() const; 0131 0132 [[nodiscard]] const KIdentityManagementCore::Identity ¤tIdentity() const; 0133 [[nodiscard]] bool autocryptEnabled() const; 0134 0135 /** 0136 * The following are for setting the various options and widgets in the 0137 * composer. 0138 */ 0139 void setAttachmentModel(MessageComposer::AttachmentModel *model); 0140 [[nodiscard]] MessageComposer::AttachmentModel *attachmentModel(); 0141 0142 void setAttachmentController(MessageComposer::AttachmentControllerBase *controller); 0143 [[nodiscard]] MessageComposer::AttachmentControllerBase *attachmentController(); 0144 0145 void setRecipientsEditor(MessageComposer::RecipientsEditor *recEditor); 0146 [[nodiscard]] MessageComposer::RecipientsEditor *recipientsEditor(); 0147 0148 void setSignatureController(MessageComposer::SignatureController *sigController); 0149 [[nodiscard]] MessageComposer::SignatureController *signatureController(); 0150 0151 void setIdentityCombo(KIdentityManagementWidgets::IdentityCombo *identCombo); 0152 [[nodiscard]] KIdentityManagementWidgets::IdentityCombo *identityCombo(); 0153 0154 void setIdentityManager(KIdentityManagementCore::IdentityManager *identMan); 0155 [[nodiscard]] KIdentityManagementCore::IdentityManager *identityManager(); 0156 0157 void setEditor(MessageComposer::RichTextComposerNg *editor); 0158 [[nodiscard]] MessageComposer::RichTextComposerNg *editor() const; 0159 0160 void setTransportCombo(MailTransport::TransportComboBox *transpCombo); 0161 [[nodiscard]] MailTransport::TransportComboBox *transportComboBox() const; 0162 0163 void setFccCombo(Akonadi::CollectionComboBox *fcc); 0164 [[nodiscard]] Akonadi::CollectionComboBox *fccCombo() const; 0165 void setFcc(const Akonadi::Collection &id); 0166 0167 [[nodiscard]] Sonnet::DictionaryComboBox *dictionary() const; 0168 void setDictionary(Sonnet::DictionaryComboBox *dictionary); 0169 0170 /** 0171 * Widgets for editing differ in client classes, so 0172 * values are set before sending. 0173 */ 0174 void setFrom(const QString &from); 0175 void setSubject(const QString &subject); 0176 0177 /** 0178 * The following are various settings the user can modify when composing a message. If they are not set, 0179 * the default values will be used. 0180 */ 0181 void setCryptoOptions(bool sign, bool encrypt, Kleo::CryptoMessageFormat format, bool neverEncryptDrafts = false); 0182 void setCharsets(const QList<QByteArray> &charsets); 0183 void setMDNRequested(bool mdnRequested); 0184 void setUrgent(bool urgent); 0185 0186 void setAutoSaveInterval(int interval); 0187 void setCustomHeader(const QMap<QByteArray, QString> &customHeader); 0188 0189 /** 0190 * Enables/disables autosaving depending on the value of the autosave 0191 * interval. 0192 */ 0193 void updateAutoSave(); 0194 0195 /** 0196 * Sets the filename to use when autosaving something. This is used when the client recovers 0197 * the autosave files: It calls this method, so that the composer uses the same filename again. 0198 * That way, the recovered autosave file is properly cleaned up in cleanupAutoSave(): 0199 */ 0200 void setAutoSaveFileName(const QString &fileName); 0201 0202 /** 0203 * Stop autosaving and delete the autosaved message. 0204 */ 0205 void cleanupAutoSave(); 0206 0207 void setParentWidgetForGui(QWidget *); 0208 0209 /** 0210 * Check if the mail has references to attachments, but no attachments are added to it. 0211 * If missing attachments are found, a dialog to add new attachments is shown. 0212 * @param attachmentKeywords a list with the keywords that indicate an attachment should be present 0213 * @return NoMissingAttachmentFound, if there is attachment in email 0214 * FoundMissingAttachmentAndCancelSending, if mail might miss attachment but sending 0215 * FoundMissingAttachmentAndAddedAttachment, if mail might miss attachment and we added an attachment 0216 * FoundMissingAttachmentAndCancel, if mail might miss attachment and cancel sending 0217 */ 0218 [[nodiscard]] ComposerViewBase::MissingAttachment checkForMissingAttachments(const QStringList &attachmentKeywords); 0219 0220 [[nodiscard]] bool hasMissingAttachments(const QStringList &attachmentKeywords); 0221 0222 void setSendLaterInfo(SendLaterInfo *info); 0223 [[nodiscard]] SendLaterInfo *sendLaterInfo() const; 0224 void saveMailSettings(); 0225 0226 [[nodiscard]] QDate followUpDate() const; 0227 void setFollowUpDate(const QDate &followUpDate); 0228 0229 void clearFollowUp(); 0230 0231 [[nodiscard]] Akonadi::Collection followUpCollection() const; 0232 void setFollowUpCollection(const Akonadi::Collection &followUpCollection); 0233 0234 [[nodiscard]] KMime::Message::Ptr msg() const; 0235 0236 [[nodiscard]] bool requestDeleveryConfirmation() const; 0237 void setRequestDeleveryConfirmation(bool requestDeleveryConfirmation); 0238 0239 [[nodiscard]] std::shared_ptr<Kleo::ExpiryChecker> expiryChecker(); 0240 0241 public Q_SLOTS: 0242 void identityChanged(const KIdentityManagementCore::Identity &ident, const KIdentityManagementCore::Identity &oldIdent, bool msgCleared = false); 0243 0244 /** 0245 * Save the message. 0246 */ 0247 void autoSaveMessage(); 0248 0249 Q_SIGNALS: 0250 /** 0251 * Message sending completed successfully. 0252 */ 0253 void sentSuccessfully(Akonadi::Item::Id id); 0254 /** 0255 * Message sending failed with given error message. 0256 */ 0257 void failed(const QString &errorMessage, MessageComposer::ComposerViewBase::FailedType type = Sending); 0258 0259 /** 0260 * The composer was modified. This can happen behind the users' back 0261 * when, for example, and autosaved message was recovered. 0262 */ 0263 void modified(bool isModified); 0264 0265 /** 0266 * Enabling or disabling HTML in the editor is affected 0267 * by various client options, so when that would otherwise happen, 0268 * hand it off to the client to enact it for real. 0269 */ 0270 void disableHtml(MessageComposer::ComposerViewBase::Confirmation); 0271 void enableHtml(); 0272 void tooManyRecipient(bool); 0273 0274 private Q_SLOTS: 0275 void slotEmailAddressResolved(KJob *); 0276 void slotSendComposeResult(KJob *); 0277 void slotQueueResult(KJob *job); 0278 void slotCreateItemResult(KJob *); 0279 void slotAutoSaveComposeResult(KJob *job); 0280 void slotFccCollectionCheckResult(KJob *job); 0281 void slotSaveMessage(KJob *job); 0282 0283 private: 0284 [[nodiscard]] Akonadi::Collection defaultSpecialTarget() const; 0285 /** 0286 * Searches the mime tree, where root is the root node, for embedded images, 0287 * extracts them froom the body and adds them to the editor. 0288 */ 0289 void collectImages(KMime::Content *root); 0290 [[nodiscard]] bool inlineSigningEncryptionSelected() const; 0291 /** 0292 * Applies the user changes to the message object of the composer 0293 * and signs/encrypts the message if activated. 0294 * Disables the controls of the composer window. 0295 */ 0296 void readyForSending(); 0297 0298 enum RecipientExpansion { 0299 UseExpandedRecipients, 0300 UseUnExpandedRecipients, 0301 }; 0302 void fillComposer(MessageComposer::Composer *composer, ComposerViewBase::RecipientExpansion expansion, bool autoresize); 0303 [[nodiscard]] QList<MessageComposer::Composer *> generateCryptoMessages(bool &wasCanceled); 0304 void fillGlobalPart(MessageComposer::GlobalPart *globalPart); 0305 void fillInfoPart(MessageComposer::InfoPart *part, RecipientExpansion expansion); 0306 void queueMessage(const KMime::Message::Ptr &message, MessageComposer::Composer *composer); 0307 void saveMessage(const KMime::Message::Ptr &message, MessageComposer::MessageSender::SaveIn saveIn); 0308 void saveRecentAddresses(const KMime::Message::Ptr &ptr); 0309 void 0310 updateRecipients(const KIdentityManagementCore::Identity &ident, const KIdentityManagementCore::Identity &oldIdent, MessageComposer::Recipient::Type type); 0311 0312 void markAllAttachmentsForSigning(bool sign); 0313 void markAllAttachmentsForEncryption(bool encrypt); 0314 bool determineWhetherToSign(bool doSignCompletely, Kleo::KeyResolver *keyResolver, bool signSomething, bool &result, bool &canceled); 0315 bool determineWhetherToEncrypt(bool doEncryptCompletely, 0316 Kleo::KeyResolver *keyResolver, 0317 bool encryptSomething, 0318 bool signSomething, 0319 bool &result, 0320 bool &canceled); 0321 0322 /** 0323 * Writes out autosave data to the disk from the KMime::Message message. 0324 * Also appends the msgNum to the filename as a message can have a number of 0325 * KMime::Messages 0326 */ 0327 void writeAutoSaveToDisk(const KMime::Message::Ptr &message); 0328 0329 /** 0330 * Returns the autosave interval in milliseconds (as needed for QTimer). 0331 */ 0332 int autoSaveInterval() const; 0333 0334 /** 0335 * Initialize autosaving (timer and filename). 0336 */ 0337 void initAutoSave(); 0338 void addFollowupReminder(const QString &messageId); 0339 void addSendLaterItem(const Akonadi::Item &item); 0340 0341 bool addKeysToContext(const QString &gnupgHome, 0342 const QList<QPair<QStringList, std::vector<GpgME::Key>>> &data, 0343 const std::map<QByteArray, QString> &autocryptMap); 0344 0345 void setAkonadiLookupEnabled(bool akonadiLookupEnabled); 0346 0347 KMime::Message::Ptr m_msg; 0348 MessageComposer::AttachmentControllerBase *m_attachmentController = nullptr; 0349 MessageComposer::AttachmentModel *m_attachmentModel = nullptr; 0350 MessageComposer::SignatureController *m_signatureController = nullptr; 0351 MessageComposer::RecipientsEditor *m_recipientsEditor = nullptr; 0352 KIdentityManagementWidgets::IdentityCombo *m_identityCombo = nullptr; 0353 KIdentityManagementCore::IdentityManager *m_identMan = nullptr; 0354 MessageComposer::RichTextComposerNg *m_editor = nullptr; 0355 MailTransport::TransportComboBox *m_transport = nullptr; 0356 Sonnet::DictionaryComboBox *m_dictionary = nullptr; 0357 Akonadi::CollectionComboBox *m_fccCombo = nullptr; 0358 Akonadi::Collection m_fccCollection; 0359 QWidget *m_parentWidget = nullptr; 0360 0361 // List of active composer jobs. For example, saving as draft, autosaving and printing 0362 // all create a composer, which is added to this list as long as it is active. 0363 // Used mainly to prevent closing the window if a composer is active 0364 QList<MessageComposer::Composer *> m_composers; 0365 0366 bool m_sign = false; 0367 bool m_encrypt = false; 0368 bool m_neverEncrypt = false; 0369 bool m_mdnRequested = false; 0370 bool m_urgent = false; 0371 bool m_requestDeleveryConfirmation = false; 0372 bool m_akonadiLookupEnabled = true; 0373 Kleo::CryptoMessageFormat m_cryptoMessageFormat; 0374 QString mExpandedFrom; 0375 QString m_from; 0376 QString m_subject; 0377 QStringList mExpandedTo, mExpandedCc, mExpandedBcc, mExpandedReplyTo; 0378 QList<QByteArray> m_charsets; 0379 QMap<QByteArray, QString> m_customHeader; 0380 0381 int m_pendingQueueJobs = 0; 0382 0383 QTimer *m_autoSaveTimer = nullptr; 0384 QString m_autoSaveUUID; 0385 bool m_autoSaveErrorShown = false; // Stops an error message being shown every time autosave is executed. 0386 int m_autoSaveInterval; 0387 0388 MessageComposer::MessageSender::SendMethod mSendMethod; 0389 MessageComposer::MessageSender::SaveIn mSaveIn; 0390 0391 std::shared_ptr<Kleo::ExpiryChecker> mExpiryChecker; 0392 0393 QDate mFollowUpDate; 0394 Akonadi::Collection mFollowUpCollection; 0395 0396 std::unique_ptr<SendLaterInfo> mSendLaterInfo; 0397 0398 friend ComposerViewBaseTest; 0399 }; 0400 } // namespace