mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 10:22:50 +00:00
401 lines
16 KiB
C++
401 lines
16 KiB
C++
/*
|
|
* Copyright (C) 2006 Dmitry Morozhnikov <dmiceman@mail.ru>
|
|
* Copyright (C) 2011 Sudhendu Kumar <sudhendu.kumar.roy@gmail.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
*/
|
|
|
|
#ifndef TEMPLATEPARSER_TEMPLATEPARSER_H
|
|
#define TEMPLATEPARSER_TEMPLATEPARSER_H
|
|
|
|
#include "templateparser_export.h"
|
|
|
|
#include <messageviewer/viewer/objecttreeemptysource.h>
|
|
|
|
#include <Akonadi/Collection>
|
|
#include <KMime/KMimeMessage>
|
|
|
|
#include <QObject>
|
|
|
|
namespace MessageViewer {
|
|
class ObjectTreeParser;
|
|
}
|
|
|
|
namespace KPIMIdentities {
|
|
class IdentityManager;
|
|
}
|
|
|
|
namespace MessageCore {
|
|
class AttachmentCollector;
|
|
class ImageCollector;
|
|
}
|
|
|
|
namespace TemplateParser {
|
|
|
|
/**
|
|
* \brief The TemplateParser transforms a message with a given template.
|
|
*
|
|
* \par Introduction
|
|
* The TemplateParser transforms a message with a given template.
|
|
* A template contains text and commands, such as %QUOTE or %ODATE, which will be
|
|
* replaced with the real values in process().
|
|
*
|
|
* \par Basics
|
|
* The message given in the templateparser constructor amsg, is the message that
|
|
* is being transformed.
|
|
* aorig_msg is the original message to which actions are performed.
|
|
* The message text in amsg will be replaced by the processed text of the template,
|
|
* but other properties, such as the attachments or the subject, are preserved.
|
|
*
|
|
* There are two different kind of commands: Those that work on the message that is
|
|
* to be transformed and those that work on an 'original message'.
|
|
* Those that work on the message that is to be transformed have no special prefix, e.g.
|
|
* '%DATE'. Those that work on the original message have an 'O' prefix, for example
|
|
* '%ODATE'.
|
|
* This means that the %DATE command will take the date of the message passed in the
|
|
* constructor, the message which is to be transformed, whereas the %ODATE command will
|
|
* take the date of the message that is being passed in process(), the original message.
|
|
*
|
|
* \par The process()
|
|
* The process() function takes aorig_msg as parameter. This aorig_msg is the original
|
|
* message from which various commands in templates with prefix 'O' extract the data and adds
|
|
* to the processed message.
|
|
* This function finds the template and passes them to processWithTemplate(), where templates
|
|
* are processed and its value is added to the processed message.
|
|
*
|
|
* \par Reply To/Forward Plain Text Mails
|
|
* Plain Text mails are the mails with only text part and no html part. While creating
|
|
* reply/forward to mails, processWithTemplate() processes all the commands and then
|
|
* appends its values to plainBody and htmlBody. This function then on the
|
|
* basis of whether the user wants to use plain mails or HTML mails, clears the htmlBody,
|
|
* or just passes both the plainBody and htmlBody unaltered.
|
|
*
|
|
* \par Reply To/Forward HTML Mails
|
|
* By HTML mails here, we mean multipart/alternative mails. As mentioned above, all
|
|
* commands in the TemplateParser appends text, i.e. plain text to plainBody
|
|
* and html text to htmlBody in the function processWithTemplate().
|
|
* This function also takes a decision of clearing the htmlBody on the basis of fact
|
|
* whether the user wants to reply/forward using plain mails or multipart/alternative
|
|
* mails.
|
|
*
|
|
* \par When "TO" and when "NOT TO" make multipart/alternative Mails
|
|
* User is the master to decide when to and when not to make multipart/alternative mails.
|
|
* <b>For user who <u>don't prefer</u> using HTML mails</b>
|
|
* There is a GlobalSettings::self()->replyUsingHtml() (in GUI as Settings->Configure KMail->
|
|
* Composer->General->"Reply using HTML if present"), which when not true (checkbox disabled
|
|
* in UI), will clear the htmlBody.
|
|
* An another option within the standard templates, %FORCEDPLAIN command raises the flag,
|
|
* ReplyAsPlain. This flag when raised in processWithTemplate() takes care that the
|
|
* processed message will contain text/plain part by clearing the htmlBody.
|
|
*
|
|
* Once the htmlBody is cleared, plainBody and an empty htmlBody is passed to
|
|
* addProcessedBodyToMessage(). Here since the htmlBody is empty, text/plain messages are
|
|
* assembled and thus user is not dealing with any kind of HTML part.
|
|
*
|
|
* <b>For user who <u>do prefer</u> using HTML mails</b>
|
|
* The setting discussed above as "Reply using HTML if present" (when checked to true),
|
|
* passes the htmlBody to addProcessedBodyToMessage() without doing any changes.
|
|
* An another option %FORCEDHTML within standard templates command raises the flag ReplyAsHtml.
|
|
* This flag when raised in processWithTemplate() takes care that the htmlBody is passed to
|
|
* addProcessedBodyToMessage() unaltered.
|
|
*
|
|
* Since htmlBody received by addProcessedBodyToMessage() is not empty, multipart/alternative
|
|
* messages are assembled.
|
|
*
|
|
* @NOTE Resolving conflict between GlobalSettings "replyUsingHtml" and FORCEDXXXX command.
|
|
* The conflict is resolved by simply giving preference to the commands over GlobalSettings.
|
|
*
|
|
* \par Make plain part
|
|
* mMsg is the reply message in which the message text will be replaced by the
|
|
* processed value from templates.
|
|
*
|
|
* In case of no attachments, the message will be a single-part message.
|
|
* A KMime::Content containing the plainBody from processWithTemplate() is
|
|
* created. Then the encodedBody(), contentType (text/plain) of this
|
|
* KMime::Content is set in the body and the header of mMsg. The addContent()
|
|
* method can be used for adding sub-content to content object in case of
|
|
* attachments. The addContent() method is not used for adding content of the
|
|
* above mentioned single-part, as addContent() will convert single-part to
|
|
* multipart-mixed before adding it to mMsg.
|
|
*
|
|
* \par Make multipart/alternative mails
|
|
* First of all a KMime::Content (content) is created with a content-type of
|
|
* multipart/alternative. Then in the same way as plain-part is created in above
|
|
* paragraph, a KMime::Content (sub-content) containing the plainBody is created
|
|
* and added as child to the content. Then a new KMime::Content (sub-content)
|
|
* with htmlBody as the body is created. The content-type is set as text/html.
|
|
* This new sub-content is then added to the parent content. Now, since the
|
|
* parent content (multipart/alternative) has two sub-content (text/plain and
|
|
* text/html) to it, it is added to the reply message (mMsg).
|
|
*
|
|
* TODO: What is the usecase of the commands that work on the message to be transformed?
|
|
* In general you only use the commands that work on the original message...
|
|
*/
|
|
class TEMPLATEPARSER_EXPORT TemplateParser : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
enum Mode {
|
|
NewMessage,
|
|
Reply,
|
|
ReplyAll,
|
|
Forward
|
|
};
|
|
|
|
enum AllowSelection {
|
|
SelectionAllowed,
|
|
NoSelectionAllowed
|
|
};
|
|
|
|
enum Quotes {
|
|
ReplyAsOriginalMessage,
|
|
ReplyAsPlain,
|
|
ReplyAsHtml
|
|
};
|
|
|
|
public:
|
|
explicit TemplateParser( const KMime::Message::Ptr &amsg, const Mode amode );
|
|
~TemplateParser();
|
|
|
|
/**
|
|
* Sets the selection. If this is set, only the selection will be added to
|
|
* commands such as %QUOTE. Otherwise, the whole message is quoted.
|
|
* If this is not called at all, the whole message is quoted as well.
|
|
* Call this before calling process().
|
|
*/
|
|
void setSelection( const QString &selection );
|
|
|
|
/**
|
|
* Sets whether the template parser is allowed to decrypt the original
|
|
* message when needing its message text, for example for the %QUOTE command.
|
|
* If true, it will tell the ObjectTreeParser it uses internally to decrypt the
|
|
* message, and that will possibly show a password request dialog to the user.
|
|
*
|
|
* The default is false.
|
|
*/
|
|
void setAllowDecryption( const bool allowDecryption );
|
|
|
|
/**
|
|
* Tell template parser whether or not to wrap words, and at what column
|
|
* to wrap at.
|
|
*
|
|
* Default is true, wrapping at 80chars.
|
|
*/
|
|
void setWordWrap( bool wrap, int wrapColWidth = 80 );
|
|
|
|
/**
|
|
* Set the identity manager to be used when creating the template.
|
|
*/
|
|
void setIdentityManager( KPIMIdentities::IdentityManager *ident );
|
|
|
|
/**
|
|
* Sets the list of charsets to try to use to encode the resulting text.
|
|
* They are tried in order until one matches, or utf-8 as a fallback.
|
|
*/
|
|
void setCharsets( const QStringList &charsets );
|
|
|
|
virtual void process( const KMime::Message::Ptr &aorig_msg,
|
|
const Akonadi::Collection &afolder = Akonadi::Collection() );
|
|
virtual void process( const QString &tmplName, const KMime::Message::Ptr &aorig_msg,
|
|
const Akonadi::Collection &afolder = Akonadi::Collection() );
|
|
virtual void processWithIdentity( uint uoid, const KMime::Message::Ptr &aorig_msg,
|
|
const Akonadi::Collection &afolder = Akonadi::Collection() );
|
|
|
|
virtual void processWithTemplate( const QString &tmpl );
|
|
|
|
/// This finds the template to use. Either the one from the folder, identity or
|
|
/// finally the global template.
|
|
/// This also reads the To and CC address of the template
|
|
/// @return the contents of the template
|
|
virtual QString findTemplate();
|
|
|
|
/// Finds the template with the given name.
|
|
/// This also reads the To and CC address of the template
|
|
/// @return the contents of the template
|
|
virtual QString findCustomTemplate( const QString &tmpl );
|
|
|
|
virtual QString pipe( const QString &cmd, const QString &buf );
|
|
|
|
virtual QString getFName( const QString &str );
|
|
virtual QString getLName( const QString &str );
|
|
|
|
bool cursorPositionWasSet() const;
|
|
protected:
|
|
Mode mMode;
|
|
Akonadi::Collection mFolder; //Used to find a template
|
|
uint mIdentity;
|
|
KMime::Message::Ptr mMsg; // Msg to write to
|
|
KMime::Message::Ptr mOrigMsg; // Msg to read from
|
|
QString mSelection;
|
|
bool mAllowDecryption;
|
|
bool mDebug;
|
|
QString mQuoteString;
|
|
QString mTo, mCC;
|
|
KPIMIdentities::IdentityManager *m_identityManager;
|
|
bool mWrap;
|
|
int mColWrap;
|
|
QStringList m_charsets;
|
|
AllowSelection isSelectionAllowed;
|
|
MessageViewer::ObjectTreeParser *mOtp;
|
|
MessageViewer::EmptySource *mEmptySource;
|
|
QString mHeadElement;
|
|
Quotes mQuotes;
|
|
bool mForceCursorPosition;
|
|
|
|
/**
|
|
* Called by processWithTemplate(). This adds the completely processed body to
|
|
* the message.
|
|
*
|
|
* This function creates plain text message or multipart/alternative message,
|
|
* depending on whether the processed body has @p htmlBody or not.
|
|
*
|
|
* In append mode, this will simply append the text to the body.
|
|
*
|
|
* Otherwise, the content of the old message is deleted and replaced with @p plainBody
|
|
* and @p htmlBody.
|
|
* Attachments of the original message are also added back to the new message.
|
|
*/
|
|
void addProcessedBodyToMessage( const QString &plainBody, const QString &htmlBody ) const;
|
|
|
|
/**
|
|
* Determines whether the signature should be stripped when getting the text
|
|
* of the original message, e.g. for commands such as %QUOTE
|
|
*/
|
|
bool shouldStripSignature() const;
|
|
|
|
int parseQuotes( const QString &prefix, const QString &str, QString "e ) const;
|
|
|
|
private:
|
|
/**
|
|
* Return the text signature used the by current identity.
|
|
*/
|
|
QString getPlainSignature() const;
|
|
|
|
/**
|
|
* Return the HTML signature used the by current identity.
|
|
*/
|
|
QString getHtmlSignature() const;
|
|
|
|
/**
|
|
* Returns message body indented by the
|
|
* given indentation string. This is suitable for including the message
|
|
* in another message of for replies, forwards.
|
|
*
|
|
* No attachments are handled if includeAttach is false.
|
|
* The signature is stripped if aStripSignature is true and
|
|
* smart quoting is turned on. Signed or encrypted texts
|
|
* get converted to plain text when allowDecryption is true.
|
|
*/
|
|
QString quotedPlainText( const QString & election=QString() ) const;
|
|
|
|
/**
|
|
* Returns HTML message body.
|
|
* This is suitable for including the message
|
|
* in another message of for replies, forwards.
|
|
*
|
|
* No attachments are handled if includeAttach is false.
|
|
* The signature is stripped if aStripSignature is true and
|
|
* smart quoting is turned on. Signed or encrypted texts
|
|
* get converted to plain text when allowDecryption is true.
|
|
*/
|
|
QString quotedHtmlText( const QString &selection ) const;
|
|
|
|
/**
|
|
* This function return the plain text part from the OTP.
|
|
* For HTML only mails. It returns the converted plain text
|
|
* from the OTP.
|
|
* @param allowSelectionOnly takes care that if a reply/forward
|
|
* is made to a selected part of message, then the selection is
|
|
* returned as it is without going through th OTP
|
|
* @param aStripSignature strips the signature out of the message
|
|
*
|
|
*/
|
|
QString plainMessageText( bool aStripSignature, AllowSelection isSelectionAllowed ) const;
|
|
|
|
/**
|
|
* Returns the HTML content of the message as plain text
|
|
*/
|
|
QString htmlMessageText( bool aStripSignature, AllowSelection isSelectionAllowed );
|
|
|
|
/** @return the UOID of the identity for this message.
|
|
* Searches the "x-kmail-identity" header and if that fails,
|
|
* searches with KPIMIdentities::IdentityManager::identityForAddress()
|
|
*/
|
|
uint identityUoid( const KMime::Message::Ptr &msg ) const;
|
|
|
|
/**
|
|
* Returns KMime content of the plain text part of the message after setting
|
|
* its mime type, charset and CTE.
|
|
* This function is called by:-
|
|
* 1) TemplateParser::addProcessedBodyToMessage(), which uses this content
|
|
* to simply create the text/plain message
|
|
*
|
|
* 2) TemplateParser::createMultipartAlternativeContent() which adds this content
|
|
* to create the multipart/alternative message.
|
|
*/
|
|
KMime::Content *createPlainPartContent( const QString &plainBody ) const;
|
|
|
|
/**
|
|
* Returns KMime content of the multipart/alternative part of the message
|
|
* after setting the mime type, charset and CTE of its respective text/plain
|
|
* part and text/html part.
|
|
*/
|
|
KMime::Content *createMultipartAlternativeContent( const QString &plainBody,
|
|
const QString &htmlBody ) const;
|
|
|
|
/**
|
|
* Returns a multipart/mixed KMime::Content that has textPart and all
|
|
* attachments as children.
|
|
* @param ac a reference to an MessageCore::AttachmentCollector that has
|
|
* collected all attachments.
|
|
* @param textPart a KMime::Content that is to be added as a child.
|
|
* @since 4.8
|
|
*/
|
|
KMime::Content *createMultipartMixed( const MessageCore::AttachmentCollector &ac,
|
|
KMime::Content *textPart ) const;
|
|
|
|
/**
|
|
* Returnsa multipart/related KMime::Content that has mainTextPart and all
|
|
* embedded images as children.
|
|
* @param ac a reference to an MessageCore::ImageCollector that has
|
|
* collected all attachments.
|
|
* @param mainTextPart a KMime::Content that is to be added as a child.
|
|
* @since 4.8
|
|
*/
|
|
KMime::Content *createMultipartRelated( const MessageCore::ImageCollector &ic,
|
|
KMime::Content *mainTextPart ) const;
|
|
|
|
/**
|
|
* Checks if the signature is HTML or not.
|
|
*/
|
|
bool isHtmlSignature() const;
|
|
|
|
/**
|
|
* Does the necessary conversions like escaping charecters, changing "\n" to
|
|
* breakline tag before appending text to htmlBody.
|
|
*/
|
|
QString plainToHtml( const QString &body ) const;
|
|
|
|
/**
|
|
* Make a HTML content valid by adding missing html/head/body tag.
|
|
*/
|
|
void makeValidHtml( QString &body );
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|