kde-playground/kdepim/messageviewer/viewer/nodehelper.h
2015-04-14 21:49:29 +00:00

311 lines
12 KiB
C++

/* -*- mode: C++; c-file-style: "gnu" -*-
Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
Copyright (c) 2009 Andras Mantia <andras@kdab.net>
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 _MESSAGEVIEWER_NODEHELPER_H
#define _MESSAGEVIEWER_NODEHELPER_H
#include "messageviewer_export.h"
#include "partmetadata.h"
#include <KMime/Message>
#include <KIconLoader>
#include <QList>
#include <QMap>
#include <QSet>
class KUrl;
class QTextCodec;
namespace MessageViewer {
namespace Interface {
class BodyPartMemento;
}
}
namespace MessageViewer {
class AttachmentTemporaryFilesDirs;
/** Flags for the encryption state. */
typedef enum
{
KMMsgEncryptionStateUnknown=' ',
KMMsgNotEncrypted='N',
KMMsgPartiallyEncrypted='P',
KMMsgFullyEncrypted='F',
KMMsgEncryptionProblematic='X'
} KMMsgEncryptionState;
/** Flags for the signature state. */
typedef enum
{
KMMsgSignatureStateUnknown=' ',
KMMsgNotSigned='N',
KMMsgPartiallySigned='P',
KMMsgFullySigned='F',
KMMsgSignatureProblematic='X'
} KMMsgSignatureState;
/**
* @author Andras Mantia <andras@kdab.net>
*/
class MESSAGEVIEWER_EXPORT NodeHelper {
public:
NodeHelper();
~NodeHelper();
void setNodeProcessed( KMime::Content* node, bool recurse );
void setNodeUnprocessed( KMime::Content* node, bool recurse );
bool nodeProcessed( KMime::Content* node ) const;
void clear();
void forceCleanTempFiles();
void setEncryptionState( KMime::Content* node, const KMMsgEncryptionState state );
KMMsgEncryptionState encryptionState( KMime::Content *node ) const;
void setSignatureState( KMime::Content* node, const KMMsgSignatureState state );
KMMsgSignatureState signatureState( KMime::Content *node ) const;
KMMsgSignatureState overallSignatureState( KMime::Content* node ) const;
KMMsgEncryptionState overallEncryptionState( KMime::Content *node ) const;
void setPartMetaData( KMime::Content* node, const PartMetaData &metaData );
PartMetaData partMetaData( KMime::Content* node );
static QString iconName( KMime::Content *node, int size = KIconLoader::Desktop );
/**
* Set the 'Content-Type' by mime-magic from the contents of the body.
* If autoDecode is true the decoded body will be used for mime type
* determination (this does not change the body itself).
*/
void magicSetType( KMime::Content *node, bool autoDecode=true );
/**
* Return this mails subject, with all "forward" and "reply"
* prefixes removed
*/
static QString cleanSubject( KMime::Message *message );
/** Attach an extra node to an existing node */
void attachExtraContent( KMime::Content *topLevelNode, KMime::Content* content );
void removeAllExtraContent( KMime::Content *topLevelNode );
/** Get the extra nodes attached to the @param topLevelNode and all sub-nodes of @param topLevelNode */
QList<KMime::Content*> extraContents( KMime::Content *topLevelNode ) const;
/** Return a modified message (node tree) starting from @param topLevelNode that has the original nodes and the extra nodes.
The caller has the responsibility to delete the new message.
*/
KMime::Message *messageWithExtraContent( KMime::Content* topLevelNode );
/**
* Returns true if the given node at least one extra content node,
* implying that the given node is an encrypted node or otherwise a type of
* node that needs extra handling.
*/
bool isPermanentWithExtraContent( KMime::Content* node ) const;
/** Get a QTextCodec suitable for this message part */
const QTextCodec * codec( KMime::Content* node );
/** Set the charset the user selected for the message to display */
void setOverrideCodec( KMime::Content* node, const QTextCodec* codec );
const QTextCodec * localCodec() const { return mLocalCodec;}
Interface::BodyPartMemento *bodyPartMemento( KMime::Content* node, const QByteArray &which ) const;
void setBodyPartMemento( KMime::Content* node, const QByteArray &which,
Interface::BodyPartMemento *memento );
// A flag to remember if the node was embedded. This is useful for attachment nodes, the reader
// needs to know if they were displayed inline or not.
bool isNodeDisplayedEmbedded( KMime::Content* node ) const;
void setNodeDisplayedEmbedded( KMime::Content* node, bool displayedEmbedded );
// Same as above, but this time determines if the node was hidden or not
bool isNodeDisplayedHidden( KMime::Content* node ) const;
void setNodeDisplayedHidden( KMime::Content* node, bool displayedHidden );
/**
* Writes the given message part to a temporary file and returns the
* name of this file or QString() if writing failed.
*/
QString writeNodeToTempFile( KMime::Content* node );
/**
* Returns the temporary file path and name where this node was saved, or an empty url
* if it wasn't saved yet with writeNodeToTempFile()
*/
KUrl tempFileUrlFromNode( const KMime::Content *node );
/**
* Creates a temporary dir for saving attachments, etc.
* Will be automatically deleted when another message is viewed.
* @param param Optional part of the directory name.
*/
QString createTempDir( const QString &param = QString() );
/**
* Cleanup the attachment temp files
*/
void removeTempFiles();
/**
* Add a file to the list of managed temporary files
*/
void addTempFile( const QString& file );
// Get a href in the form attachment:<nodeId>?place=<place>, used by ObjectTreeParser and
// UrlHandlerManager.
QString asHREF( const KMime::Content* node, const QString &place );
static bool isToltecMessage( KMime::Content* node );
/**
* @return true if this node is a child or an encapsulated message
*/
static bool isInEncapsulatedMessage( KMime::Content* node );
/**
* Returns the charset for the given node. If no charset is specified
* for the node, the defaultCharset() is returned.
*/
static QByteArray charset( KMime::Content *node );
/**
* Check for prefixes @p prefixRegExps in @p str. If none
* is found, @p newPrefix + ' ' is prepended to @p str and the
* resulting string is returned. If @p replace is true, any
* sequence of whitespace-delimited prefixes at the beginning of
* @p str is replaced by @p newPrefix.
*/
static QString replacePrefixes( const QString& str,
const QStringList& prefixRegExps,
bool replace,
const QString& newPrefix );
/**
* Return a QTextCodec for the specified charset.
* This function is a bit more tolerant, than QTextCodec::codecForName
*/
static const QTextCodec* codecForName(const QByteArray& _str);
/**
* Returns a usable filename for a node, that can be the filename from the
* content disposition header, or if that one is empty, the name from the
* content type header.
*/
static QString fileName( const KMime::Content *node );
/**
* Fixes an encoding received by a KDE function and returns the proper,
* MIME-compilant encoding name instead.
* @see encodingForName
*/
static QString fixEncoding( const QString &encoding ); //TODO(Andras) move to a utility class?
/**
* Drop-in replacement for KCharsets::encodingForName(). The problem with
* the KCharsets function is that it returns "human-readable" encoding names
* like "ISO 8859-15" instead of valid encoding names like "ISO-8859-15".
* This function fixes this by replacing whitespace with a hyphen.
*/
static QString encodingForName( const QString &descriptiveName ); //TODO(Andras) move to a utility class?
/**
* Return a list of the supported encodings
* @param usAscii if true, US-Ascii encoding will be prepended to the list.
*/
static QStringList supportedEncodings( bool usAscii ); //TODO(Andras) move to a utility class?
static QByteArray autoDetectCharset(const QByteArray &_encoding, const QStringList &encodingList, const QString &text);
static QByteArray toUsAscii(const QString& _str, bool *ok);
static QString fromAsString( KMime::Content* node );
struct AttachmentDisplayInfo
{
QString label;
QString icon;
bool displayInHeader;
};
static AttachmentDisplayInfo attachmentDisplayInfo( KMime::Content *node );
KMime::Content * decryptedNodeForContent( KMime::Content * content ) const;
/**
* This function returns the unencrypted message that is based on @p originalMessage.
* All encrypted MIME parts are removed and replaced by their decrypted plain-text versions.
* Encrypted parts that are within signed parts are not replaced, since that would invalidate
* the signature.
*
* This only works if the message was run through ObjectTreeParser::parseObjectTree() with the
* currrent NodeHelper before, because parseObjectTree() actually decrypts the message and stores
* the decrypted nodes by calling attachExtraContent().
*
* @return the unencrypted message or an invalid pointer if the original message didn't contain
* a part that needed to be modified.
*/
KMime::Message::Ptr unencryptedMessage( const KMime::Message::Ptr &originalMessage );
private:
bool unencryptedMessage_helper( KMime::Content *node, QByteArray &resultingData, bool addHeaders,
int recursionLevel = 1 );
/** Check for prefixes @p prefixRegExps in #subject(). If none
is found, @p newPrefix + ' ' is prepended to the subject and the
resulting string is returned. If @p replace is true, any
sequence of whitespace-delimited prefixes at the beginning of
#subject() is replaced by @p newPrefix
**/
static QString cleanSubject( KMime::Message *message, const QStringList& prefixRegExps,
bool replace, const QString& newPrefix );
void mergeExtraNodes( KMime::Content *node );
void cleanFromExtraNodes( KMime::Content *node );
QString persistentIndex( const KMime::Content * node ) const;
private:
QList<KMime::Content*> mProcessedNodes;
QList<KMime::Content*> mNodesUnderProcess;
QMap<KMime::Content *, KMMsgEncryptionState> mEncryptionState;
QMap<KMime::Content *, KMMsgSignatureState> mSignatureState;
QSet<KMime::Content *> mDisplayEmbeddedNodes;
QSet<KMime::Content *> mDisplayHiddenNodes;
QTextCodec *mLocalCodec;
QMap<KMime::Content*, const QTextCodec*> mOverrideCodecs;
QMap<QString, QMap<QByteArray, Interface::BodyPartMemento*> > mBodyPartMementoMap;
QMap<KMime::Content*, PartMetaData> mPartMetaDatas;
QMap<KMime::Message::Content*, QList<KMime::Content*> > mExtraContents;
AttachmentTemporaryFilesDirs *mAttachmentFilesDir;
};
}
#endif