File indexing completed on 2024-06-23 05:18:30
0001 /* 0002 SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com 0003 SPDX-FileCopyrightText: 2010 Leo Franchi <lfranchi@kde.org> 0004 SPDX-FileCopyrightText: 2017-2024 Laurent Montel <montel@kde.org> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #pragma once 0010 0011 #include "messagecomposer_export.h" 0012 #include <KMime/KMimeMessage> 0013 #include <KMime/MDN> 0014 0015 #include <Akonadi/Collection> 0016 #include <Akonadi/Item> 0017 #include <Akonadi/MessageStatus> 0018 #include <QList> 0019 0020 namespace KIdentityManagementCore 0021 { 0022 class IdentityManager; 0023 } 0024 0025 namespace MessageComposer 0026 { 0027 /** 0028 * Enumeration that defines the available reply "modes" 0029 */ 0030 enum ReplyStrategy { 0031 ReplySmart = 0, //< Attempt to automatically guess the best recipient for the reply 0032 ReplyAuthor, //< Reply to the author of the message (possibly NOT the mailing list, if any) 0033 ReplyList, //< Reply to the mailing list (and not the author of the message) 0034 ReplyAll, //< Reply to author and all the recipients in CC 0035 ReplyNone, //< Don't set reply addresses: they will be set manually 0036 }; 0037 0038 enum MDNAdvice { 0039 MDNIgnore, 0040 MDNSendDenied, 0041 MDNSend, 0042 }; 0043 /** 0044 * Contains various factory methods for creating new messages such as replies, MDNs, forwards, etc. 0045 */ 0046 class MESSAGECOMPOSER_EXPORT MessageFactoryNG : public QObject 0047 { 0048 Q_OBJECT 0049 public: 0050 /// Small helper structure which encapsulates the KMime::Message created when creating a reply, and 0051 /// the reply mode 0052 struct MessageReply { 0053 KMime::Message::Ptr msg = nullptr; ///< The actual reply message 0054 bool replyAll = false; ///< If true, the "reply all" template was used, otherwise the normal reply 0055 /// template 0056 }; 0057 0058 explicit MessageFactoryNG(const KMime::Message::Ptr &origMsg, 0059 Akonadi::Item::Id id, 0060 const Akonadi::Collection &col = Akonadi::Collection(), 0061 QObject *parent = nullptr); 0062 ~MessageFactoryNG() override; 0063 0064 /** 0065 * Create a new message that is a reply to this message, filling all 0066 * required header fields with the proper values. The returned message 0067 * is not stored in any folder. Marks this message as replied. 0068 * 0069 */ 0070 void createReplyAsync(); 0071 0072 /** Create a new message that is a forward of this message, filling all 0073 required header fields with the proper values. The returned message 0074 is not stored in any folder. Marks this message as forwarded. */ 0075 void createForwardAsync(); 0076 0077 /** 0078 * Create a forward from the given list of messages, attaching each 0079 * message to be forwarded to the new forwarded message. 0080 * 0081 * If no list is passed, use the original message passed in the MessageFactoryNG 0082 * constructor. 0083 */ 0084 [[nodiscard]] QPair<KMime::Message::Ptr, QList<KMime::Content *>> createAttachedForward(const Akonadi::Item::List &items = Akonadi::Item::List()); 0085 0086 /** Create a new message that is a redirect to this message, filling all 0087 required header fields with the proper values. The returned message 0088 is not stored in any folder. Marks this message as replied. 0089 Redirects differ from forwards so they are forwarded to some other 0090 user, mail is not changed and the reply-to field is set to 0091 the email address of the original sender. 0092 */ 0093 [[nodiscard]] KMime::Message::Ptr createRedirect(const QString &toStr, 0094 const QString &ccStr = QString(), 0095 const QString &bccStr = QString(), 0096 int transportId = -1, 0097 const QString &fcc = QString(), 0098 int identity = -1); 0099 0100 [[nodiscard]] KMime::Message::Ptr createResend(); 0101 0102 /** Create a new message that is a delivery receipt of this message, 0103 filling required header fields with the proper values. The 0104 returned message is not stored in any folder. */ 0105 [[nodiscard]] KMime::Message::Ptr createDeliveryReceipt(); 0106 0107 /** Create a new message that is a MDN for this message, filling all 0108 required fields with proper values. The returned message is not 0109 stored in any folder. 0110 0111 @param a Use AutomaticAction for filtering and ManualAction for 0112 user-induced events. 0113 @param d See docs for KMime::MDN::DispositionType 0114 @param s See docs for KMime::MDN::SendingMode (in KMail, use MDNAdvideDialog to ask the user for this parameter) 0115 @param m See docs for KMime::MDN::DispositionModifier 0116 0117 @return The notification message or 0, if none should be sent, as well as the state of the MDN operation. 0118 **/ 0119 [[nodiscard]] KMime::Message::Ptr createMDN(KMime::MDN::ActionMode a, 0120 KMime::MDN::DispositionType d, 0121 KMime::MDN::SendingMode s, 0122 int mdnQuoteOriginal = 0, 0123 const QList<KMime::MDN::DispositionModifier> &m = QList<KMime::MDN::DispositionModifier>()); 0124 0125 /** 0126 * Create a new forwarded MIME digest. If the user is trying to forward multiple messages 0127 * at once all inline, they can choose to have them be compiled into a single digest 0128 * message. 0129 * 0130 * This will return a header message and individual message parts to be set as 0131 * attachments. 0132 * 0133 * @param msgs List of messages to be composed into a digest 0134 */ 0135 [[nodiscard]] QPair<KMime::Message::Ptr, KMime::Content *> createForwardDigestMIME(const Akonadi::Item::List &items); 0136 0137 /** 0138 * Set the identity manager to be used when creating messages. 0139 * Required to be set before create* is called, otherwise the created messages 0140 * might have the wrong identity data. 0141 */ 0142 void setIdentityManager(KIdentityManagementCore::IdentityManager *ident); 0143 0144 /** 0145 * Set the reply strategy to use. Default is ReplySmart. 0146 */ 0147 void setReplyStrategy(MessageComposer::ReplyStrategy replyStrategy); 0148 0149 /** 0150 * Set the selection to be used to base the reply on. 0151 */ 0152 void setSelection(const QString &selection); 0153 0154 /** 0155 * Whether to quote the original message in the reply. 0156 * Default is to quote. 0157 */ 0158 void setQuote(bool quote); 0159 0160 /** 0161 * Set the template to be used when creating the reply. Default is to not 0162 * use any template at all. 0163 */ 0164 void setTemplate(const QString &templ); 0165 0166 /** 0167 * Set extra mailinglist addresses to send the created message to. 0168 * Any mailing-list addresses specified in the original message 0169 * itself will be added by MessageFactoryNG, so no need to add those manually. 0170 */ 0171 void setMailingListAddresses(const KMime::Types::Mailbox::List &listAddresses); 0172 0173 /** 0174 * Set the identity that is set for the folder in which the given message is. 0175 * It is used as a fallback when finding the identity if it can't be found in 0176 * any other way. 0177 * @param folderIdentityId an uoid of KIdentityManagementCore::Identity 0178 */ 0179 void setFolderIdentity(uint folderIdentityId); 0180 0181 /** 0182 * Whether or not to put the reply to a message in the same folder as the message itself. 0183 * If so, specify the folder id in which to put them. Default is -1, which means to not put 0184 * replies in the same folder at all. 0185 */ 0186 void putRepliesInSameFolder(Akonadi::Item::Id parentColId = -1); 0187 0188 /** 0189 * When creating MDNs, the user needs to be asked for confirmation in specific 0190 * cases according to RFC 2298. 0191 */ 0192 [[nodiscard]] static bool MDNRequested(const KMime::Message::Ptr &msg); 0193 0194 /** 0195 * If sending an MDN requires confirmation due to multiple addresses. 0196 * 0197 * RFC 2298: [ Confirmation from the user SHOULD be obtained (or no 0198 * MDN sent) ] if there is more than one distinct address in the 0199 * Disposition-Notification-To header. 0200 */ 0201 [[nodiscard]] static bool MDNConfirmMultipleRecipients(const KMime::Message::Ptr &msg); 0202 0203 /** 0204 * 0205 * If sending an MDN requires confirmation due to discrepancy between MDN 0206 * header and Return-Path header. 0207 * 0208 * RFC 2298: MDNs SHOULD NOT be sent automatically if the address in 0209 * the Disposition-Notification-To header differs from the address 0210 * in the Return-Path header. [...] Confirmation from the user 0211 * SHOULD be obtained (or no MDN sent) if there is no Return-Path 0212 * header in the message [...] 0213 */ 0214 [[nodiscard]] static bool MDNReturnPathEmpty(const KMime::Message::Ptr &msg); 0215 [[nodiscard]] static bool MDNReturnPathNotInRecieptTo(const KMime::Message::Ptr &msg); 0216 0217 /** 0218 * If the MDN headers contain options that KMail can't parse 0219 */ 0220 [[nodiscard]] static bool MDNMDNUnknownOption(const KMime::Message::Ptr &msg); 0221 0222 [[nodiscard]] bool replyAsHtml() const; 0223 void setReplyAsHtml(bool replyAsHtml); 0224 0225 Q_SIGNALS: 0226 void createReplyDone(const MessageComposer::MessageFactoryNG::MessageReply &reply); 0227 void createForwardDone(const KMime::Message::Ptr &msg); 0228 0229 private Q_SLOTS: 0230 MESSAGECOMPOSER_NO_EXPORT void slotCreateReplyDone(const KMime::Message::Ptr &msg, bool replyAll); 0231 MESSAGECOMPOSER_NO_EXPORT void slotCreateForwardDone(const KMime::Message::Ptr &msg); 0232 0233 private: 0234 /** @return the UOID of the identity for this message. 0235 Searches the "x-kmail-identity" header and if that fails, 0236 searches with KIdentityManagementCore::IdentityManager::identityForAddress() 0237 **/ 0238 [[nodiscard]] MESSAGECOMPOSER_NO_EXPORT uint identityUoid(const KMime::Message::Ptr &msg); 0239 0240 [[nodiscard]] MESSAGECOMPOSER_NO_EXPORT QString replaceHeadersInString(const KMime::Message::Ptr &msg, const QString &s); 0241 0242 [[nodiscard]] MESSAGECOMPOSER_NO_EXPORT QByteArray getRefStr(const KMime::Message::Ptr &msg); 0243 MESSAGECOMPOSER_NO_EXPORT KMime::Content *createForwardAttachmentMessage(const KMime::Message::Ptr &fwdMsg); 0244 0245 KIdentityManagementCore::IdentityManager *mIdentityManager = nullptr; 0246 // Required parts to create messages 0247 KMime::Message::Ptr mOrigMsg; 0248 uint mFolderId; 0249 Akonadi::Item::Id mParentFolderId; 0250 0251 Akonadi::Collection mCollection; 0252 0253 // Optional settings the calling class may set 0254 MessageComposer::ReplyStrategy mReplyStrategy; 0255 QString mSelection; 0256 QString mTemplate; 0257 bool mQuote = true; 0258 bool mReplyAsHtml = false; 0259 KMime::Types::Mailbox::List mMailingListAddresses; 0260 Akonadi::Item::Id mId; 0261 }; 0262 } 0263 0264 Q_DECLARE_METATYPE(MessageComposer::ReplyStrategy) 0265 Q_DECLARE_METATYPE(MessageComposer::MessageFactoryNG::MessageReply)