SVN_SILENT made messages (after extraction)
[kdepim.git] / templateparser / src / templateparser.h
blob83fb6dfbb4790ade7000415a8f9395bb2810be16
1 /*
2 * Copyright (C) 2006 Dmitry Morozhnikov <dmiceman@mail.ru>
3 * Copyright (C) 2011 Sudhendu Kumar <sudhendu.kumar.roy@gmail.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 #ifndef TEMPLATEPARSER_TEMPLATEPARSER_H
22 #define TEMPLATEPARSER_TEMPLATEPARSER_H
24 #include "templateparser_export.h"
26 #include <MessageViewer/ObjectTreeEmptySource>
28 #include <AkonadiCore/Collection>
29 #include <KMime/KMimeMessage>
31 #include <QObject>
33 namespace MessageViewer
35 class ObjectTreeParser;
38 namespace KIdentityManagement
40 class IdentityManager;
43 namespace MessageCore
45 class ImageCollector;
48 namespace TemplateParser
51 /**
52 * \brief The TemplateParser transforms a message with a given template.
54 * \par Introduction
55 * The TemplateParser transforms a message with a given template.
56 * A template contains text and commands, such as %QUOTE or %ODATE, which will be
57 * replaced with the real values in process().
59 * \par Basics
60 * The message given in the templateparser constructor amsg, is the message that
61 * is being transformed.
62 * aorig_msg is the original message to which actions are performed.
63 * The message text in amsg will be replaced by the processed text of the template,
64 * but other properties, such as the attachments or the subject, are preserved.
66 * There are two different kind of commands: Those that work on the message that is
67 * to be transformed and those that work on an 'original message'.
68 * Those that work on the message that is to be transformed have no special prefix, e.g.
69 * '%DATE'. Those that work on the original message have an 'O' prefix, for example
70 * '%ODATE'.
71 * This means that the %DATE command will take the date of the message passed in the
72 * constructor, the message which is to be transformed, whereas the %ODATE command will
73 * take the date of the message that is being passed in process(), the original message.
75 * \par The process()
76 * The process() function takes aorig_msg as parameter. This aorig_msg is the original
77 * message from which various commands in templates with prefix 'O' extract the data and adds
78 * to the processed message.
79 * This function finds the template and passes them to processWithTemplate(), where templates
80 * are processed and its value is added to the processed message.
82 * \par Reply To/Forward Plain Text Mails
83 * Plain Text mails are the mails with only text part and no html part. While creating
84 * reply/forward to mails, processWithTemplate() processes all the commands and then
85 * appends its values to plainBody and htmlBody. This function then on the
86 * basis of whether the user wants to use plain mails or HTML mails, clears the htmlBody,
87 * or just passes both the plainBody and htmlBody unaltered.
89 * \par Reply To/Forward HTML Mails
90 * By HTML mails here, we mean multipart/alternative mails. As mentioned above, all
91 * commands in the TemplateParser appends text, i.e. plain text to plainBody
92 * and html text to htmlBody in the function processWithTemplate().
93 * This function also takes a decision of clearing the htmlBody on the basis of fact
94 * whether the user wants to reply/forward using plain mails or multipart/alternative
95 * mails.
97 * \par When "TO" and when "NOT TO" make multipart/alternative Mails
98 * User is the master to decide when to and when not to make multipart/alternative mails.
99 * <b>For user who <u>don't prefer</u> using HTML mails</b>
100 * There is a TemplateParserSettings::self()->replyUsingHtml() (in GUI as Settings->Configure KMail->
101 * Composer->General->"Reply using HTML if present"), which when not true (checkbox disabled
102 * in UI), will clear the htmlBody.
103 * An another option within the standard templates, %FORCEDPLAIN command raises the flag,
104 * ReplyAsPlain. This flag when raised in processWithTemplate() takes care that the
105 * processed message will contain text/plain part by clearing the htmlBody.
107 * Once the htmlBody is cleared, plainBody and an empty htmlBody is passed to
108 * addProcessedBodyToMessage(). Here since the htmlBody is empty, text/plain messages are
109 * assembled and thus user is not dealing with any kind of HTML part.
111 * <b>For user who <u>do prefer</u> using HTML mails</b>
112 * The setting discussed above as "Reply using HTML if present" (when checked to true),
113 * passes the htmlBody to addProcessedBodyToMessage() without doing any changes.
114 * An another option %FORCEDHTML within standard templates command raises the flag ReplyAsHtml.
115 * This flag when raised in processWithTemplate() takes care that the htmlBody is passed to
116 * addProcessedBodyToMessage() unaltered.
118 * Since htmlBody received by addProcessedBodyToMessage() is not empty, multipart/alternative
119 * messages are assembled.
121 * @NOTE Resolving conflict between TemplateParserSettings "replyUsingHtml" and FORCEDXXXX command.
122 * The conflict is resolved by simply giving preference to the commands over TemplateParserSettings.
124 * \par Make plain part
125 * mMsg is the reply message in which the message text will be replaced by the
126 * processed value from templates.
128 * In case of no attachments, the message will be a single-part message.
129 * A KMime::Content containing the plainBody from processWithTemplate() is
130 * created. Then the encodedBody(), contentType (text/plain) of this
131 * KMime::Content is set in the body and the header of mMsg. The addContent()
132 * method can be used for adding sub-content to content object in case of
133 * attachments. The addContent() method is not used for adding content of the
134 * above mentioned single-part, as addContent() will convert single-part to
135 * multipart-mixed before adding it to mMsg.
137 * \par Make multipart/alternative mails
138 * First of all a KMime::Content (content) is created with a content-type of
139 * multipart/alternative. Then in the same way as plain-part is created in above
140 * paragraph, a KMime::Content (sub-content) containing the plainBody is created
141 * and added as child to the content. Then a new KMime::Content (sub-content)
142 * with htmlBody as the body is created. The content-type is set as text/html.
143 * This new sub-content is then added to the parent content. Now, since the
144 * parent content (multipart/alternative) has two sub-content (text/plain and
145 * text/html) to it, it is added to the reply message (mMsg).
147 * TODO: What is the usecase of the commands that work on the message to be transformed?
148 * In general you only use the commands that work on the original message...
150 class TEMPLATEPARSER_EXPORT TemplateParser : public QObject
152 Q_OBJECT
154 public:
155 enum Mode {
156 NewMessage,
157 Reply,
158 ReplyAll,
159 Forward
162 enum AllowSelection {
163 SelectionAllowed,
164 NoSelectionAllowed
167 enum Quotes {
168 ReplyAsOriginalMessage,
169 ReplyAsPlain,
170 ReplyAsHtml
173 public:
174 explicit TemplateParser(const KMime::Message::Ptr &amsg, const Mode amode);
175 ~TemplateParser();
178 * Sets the selection. If this is set, only the selection will be added to
179 * commands such as %QUOTE. Otherwise, the whole message is quoted.
180 * If this is not called at all, the whole message is quoted as well.
181 * Call this before calling process().
183 void setSelection(const QString &selection);
186 * Sets whether the template parser is allowed to decrypt the original
187 * message when needing its message text, for example for the %QUOTE command.
188 * If true, it will tell the ObjectTreeParser it uses internally to decrypt the
189 * message, and that will possibly show a password request dialog to the user.
191 * The default is false.
193 void setAllowDecryption(const bool allowDecryption);
196 * Tell template parser whether or not to wrap words, and at what column
197 * to wrap at.
199 * Default is true, wrapping at 80chars.
201 void setWordWrap(bool wrap, int wrapColWidth = 80);
204 * Set the identity manager to be used when creating the template.
206 void setIdentityManager(KIdentityManagement::IdentityManager *ident);
209 * Sets the list of charsets to try to use to encode the resulting text.
210 * They are tried in order until one matches, or utf-8 as a fallback.
212 void setCharsets(const QStringList &charsets);
214 virtual void process(const KMime::Message::Ptr &aorig_msg,
215 const Akonadi::Collection &afolder = Akonadi::Collection());
216 virtual void process(const QString &tmplName, const KMime::Message::Ptr &aorig_msg,
217 const Akonadi::Collection &afolder = Akonadi::Collection());
218 virtual void processWithIdentity(uint uoid, const KMime::Message::Ptr &aorig_msg,
219 const Akonadi::Collection &afolder = Akonadi::Collection());
221 virtual void processWithTemplate(const QString &tmpl);
223 /// This finds the template to use. Either the one from the folder, identity or
224 /// finally the global template.
225 /// This also reads the To and CC address of the template
226 /// @return the contents of the template
227 virtual QString findTemplate();
229 /// Finds the template with the given name.
230 /// This also reads the To and CC address of the template
231 /// @return the contents of the template
232 virtual QString findCustomTemplate(const QString &tmpl);
234 virtual QString pipe(const QString &cmd, const QString &buf);
236 virtual QString getFirstName(const QString &str);
237 virtual QString getLastName(const QString &str);
239 bool cursorPositionWasSet() const;
240 protected:
241 Mode mMode;
242 Akonadi::Collection mFolder; //Used to find a template
243 uint mIdentity;
244 KMime::Message::Ptr mMsg; // Msg to write to
245 KMime::Message::Ptr mOrigMsg; // Msg to read from
246 QString mSelection;
247 bool mAllowDecryption;
248 bool mDebug;
249 QString mQuoteString;
250 QString mTo, mCC;
251 KIdentityManagement::IdentityManager *m_identityManager;
252 bool mWrap;
253 int mColWrap;
254 QStringList m_charsets;
255 AllowSelection isSelectionAllowed;
256 MessageViewer::ObjectTreeParser *mOtp;
257 MessageViewer::EmptySource *mEmptySource;
258 QString mHeadElement;
259 Quotes mQuotes;
260 bool mForceCursorPosition;
263 * Called by processWithTemplate(). This adds the completely processed body to
264 * the message.
266 * This function creates plain text message or multipart/alternative message,
267 * depending on whether the processed body has @p htmlBody or not.
269 * In append mode, this will simply append the text to the body.
271 * Otherwise, the content of the old message is deleted and replaced with @p plainBody
272 * and @p htmlBody.
273 * Attachments of the original message are also added back to the new message.
275 void addProcessedBodyToMessage(const QString &plainBody, const QString &htmlBody) const;
278 * Determines whether the signature should be stripped when getting the text
279 * of the original message, e.g. for commands such as %QUOTE
281 bool shouldStripSignature() const;
283 int parseQuotes(const QString &prefix, const QString &str, QString &quote) const;
285 private:
287 * Return the text signature used the by current identity.
289 QString getPlainSignature() const;
292 * Return the HTML signature used the by current identity.
294 QString getHtmlSignature() const;
297 * Returns message body indented by the
298 * given indentation string. This is suitable for including the message
299 * in another message of for replies, forwards.
301 * No attachments are handled if includeAttach is false.
302 * The signature is stripped if aStripSignature is true and
303 * smart quoting is turned on. Signed or encrypted texts
304 * get converted to plain text when allowDecryption is true.
306 QString quotedPlainText(const QString &selection = QString()) const;
309 * Returns HTML message body.
310 * This is suitable for including the message
311 * in another message of for replies, forwards.
313 * No attachments are handled if includeAttach is false.
314 * The signature is stripped if aStripSignature is true and
315 * smart quoting is turned on. Signed or encrypted texts
316 * get converted to plain text when allowDecryption is true.
318 QString quotedHtmlText(const QString &selection) const;
321 * This function return the plain text part from the OTP.
322 * For HTML only mails. It returns the converted plain text
323 * from the OTP.
324 * @param allowSelectionOnly takes care that if a reply/forward
325 * is made to a selected part of message, then the selection is
326 * returned as it is without going through th OTP
327 * @param aStripSignature strips the signature out of the message
330 QString plainMessageText(bool aStripSignature, AllowSelection isSelectionAllowed) const;
333 * Returns the HTML content of the message as plain text
335 QString htmlMessageText(bool aStripSignature, AllowSelection isSelectionAllowed);
337 /** @return the UOID of the identity for this message.
338 * Searches the "x-kmail-identity" header and if that fails,
339 * searches with KIdentityManagement::IdentityManager::identityForAddress()
341 uint identityUoid(const KMime::Message::Ptr &msg) const;
344 * Returns KMime content of the plain text part of the message after setting
345 * its mime type, charset and CTE.
346 * This function is called by:-
347 * 1) TemplateParser::addProcessedBodyToMessage(), which uses this content
348 * to simply create the text/plain message
350 * 2) TemplateParser::createMultipartAlternativeContent() which adds this content
351 * to create the multipart/alternative message.
353 KMime::Content *createPlainPartContent(const QString &plainBody) const;
356 * Returns KMime content of the multipart/alternative part of the message
357 * after setting the mime type, charset and CTE of its respective text/plain
358 * part and text/html part.
360 KMime::Content *createMultipartAlternativeContent(const QString &plainBody,
361 const QString &htmlBody) const;
364 * Returns a multipart/mixed KMime::Content that has textPart and all
365 * attachments as children.
366 * @param attachments the list of attachments to add
367 * @param textPart a KMime::Content that is to be added as a child.
368 * @since 4.8
370 KMime::Content *createMultipartMixed(const QVector<KMime::Content *> &attachments,
371 KMime::Content *textPart) const;
374 * Returnsa multipart/related KMime::Content that has mainTextPart and all
375 * embedded images as children.
376 * @param ac a reference to an MessageCore::ImageCollector that has
377 * collected all attachments.
378 * @param mainTextPart a KMime::Content that is to be added as a child.
379 * @since 4.8
381 KMime::Content *createMultipartRelated(const MessageCore::ImageCollector &ic,
382 KMime::Content *mainTextPart) const;
385 * Checks if the signature is HTML or not.
387 bool isHtmlSignature() const;
390 * Does the necessary conversions like escaping charecters, changing "\n" to
391 * breakline tag before appending text to htmlBody.
393 QString plainToHtml(const QString &body) const;
396 * Make a HTML content valid by adding missing html/head/body tag.
398 void makeValidHtml(QString &body);
403 #endif