1 /* -*- mode: C++; c-file-style: "gnu" -*-
2 Copyright (C) 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
3 Copyright (c) 2009 Andras Mantia <andras@kdab.net>
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 along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #ifndef _MESSAGEVIEWER_NODEHELPER_H
21 #define _MESSAGEVIEWER_NODEHELPER_H
22 #include "messageviewer_export.h"
24 #include "partmetadata.h"
26 #include <KMime/Message>
28 #include <KIconLoader>
37 namespace MessageViewer
{
39 class BodyPartMemento
;
43 namespace MessageViewer
{
45 /** Flags for the encryption state. */
48 KMMsgEncryptionStateUnknown
=' ',
49 KMMsgNotEncrypted
='N',
50 KMMsgPartiallyEncrypted
='P',
51 KMMsgFullyEncrypted
='F',
52 KMMsgEncryptionProblematic
='X'
53 } KMMsgEncryptionState
;
55 /** Flags for the signature state. */
58 KMMsgSignatureStateUnknown
=' ',
60 KMMsgPartiallySigned
='P',
62 KMMsgSignatureProblematic
='X'
63 } KMMsgSignatureState
;
67 * @author Andras Mantia <andras@kdab.net>
69 class MESSAGEVIEWER_EXPORT NodeHelper
{
75 void setNodeProcessed( KMime::Content
* node
, bool recurse
);
76 void setNodeUnprocessed( KMime::Content
* node
, bool recurse
);
77 bool nodeProcessed( KMime::Content
* node
) const;
80 void setEncryptionState( KMime::Content
* node
, const KMMsgEncryptionState state
);
81 KMMsgEncryptionState
encryptionState( KMime::Content
*node
) const;
83 void setSignatureState( KMime::Content
* node
, const KMMsgSignatureState state
);
84 KMMsgSignatureState
signatureState( KMime::Content
*node
) const;
86 KMMsgSignatureState
overallSignatureState( KMime::Content
* node
) const;
87 KMMsgEncryptionState
overallEncryptionState( KMime::Content
*node
) const;
89 void setPartMetaData( KMime::Content
* node
, const PartMetaData
&metaData
);
90 PartMetaData
partMetaData( KMime::Content
* node
);
92 static QString
iconName( KMime::Content
*node
, int size
= KIconLoader::Desktop
);
95 * Set the 'Content-Type' by mime-magic from the contents of the body.
96 * If autoDecode is true the decoded body will be used for mime type
97 * determination (this does not change the body itself).
99 void magicSetType( KMime::Content
*node
, bool autoDecode
=true );
103 * Return this mails subject, with all "forward" and "reply"
106 static QString
cleanSubject( KMime::Message
*message
);
108 /** Attach an extra node to an existing node */
109 void attachExtraContent( KMime::Content
*topLevelNode
, KMime::Content
* content
);
110 void removeAllExtraContent( KMime::Content
*topLevelNode
);
112 /** Get the extra nodes attached to the @param topLevelNode and all sub-nodes of @param topLevelNode */
113 QList
<KMime::Content
*> extraContents( KMime::Content
*topLevelNode
) const;
115 /** Return a modified message (node tree) starting from @param topLevelNode that has the original nodes and the extra nodes.
116 The caller has the responsibility to delete the new message.
118 KMime::Message
*messageWithExtraContent( KMime::Content
* topLevelNode
);
121 * Returns true if the given node at least one extra content node,
122 * implying that the given node is an encrypted node or otherwise a type of
123 * node that needs extra handling.
125 bool isPermanentWithExtraContent( KMime::Content
* node
) const;
127 /** Get a QTextCodec suitable for this message part */
128 const QTextCodec
* codec( KMime::Content
* node
);
130 /** Set the charset the user selected for the message to display */
131 void setOverrideCodec( KMime::Content
* node
, const QTextCodec
* codec
);
133 const QTextCodec
* localCodec() const { return mLocalCodec
;}
135 Interface::BodyPartMemento
*bodyPartMemento( KMime::Content
* node
, const QByteArray
&which
) const;
137 void setBodyPartMemento( KMime::Content
* node
, const QByteArray
&which
,
138 Interface::BodyPartMemento
*memento
);
140 // A flag to remember if the node was embedded. This is useful for attachment nodes, the reader
141 // needs to know if they were displayed inline or not.
142 bool isNodeDisplayedEmbedded( KMime::Content
* node
) const;
143 void setNodeDisplayedEmbedded( KMime::Content
* node
, bool displayedEmbedded
);
145 // Same as above, but this time determines if the node was hidden or not
146 bool isNodeDisplayedHidden( KMime::Content
* node
) const;
147 void setNodeDisplayedHidden( KMime::Content
* node
, bool displayedHidden
);
150 * Writes the given message part to a temporary file and returns the
151 * name of this file or QString() if writing failed.
153 QString
writeNodeToTempFile( KMime::Content
* node
);
156 * Returns the temporary file path and name where this node was saved, or an empty url
157 * if it wasn't saved yet with writeNodeToTempFile()
159 KUrl
tempFileUrlFromNode( const KMime::Content
*node
);
162 * Creates a temporary dir for saving attachments, etc.
163 * Will be automatically deleted when another message is viewed.
164 * @param param Optional part of the directory name.
166 QString
createTempDir( const QString
¶m
= QString() );
169 * Cleanup the attachment temp files
171 void removeTempFiles();
174 * Add a file to the list of managed temporary files
176 void addTempFile( const QString
& file
);
178 // Get a href in the form attachment:<nodeId>?place=<place>, used by ObjectTreeParser and
179 // UrlHandlerManager.
180 QString
asHREF( const KMime::Content
* node
, const QString
&place
);
182 static bool isToltecMessage( KMime::Content
* node
);
185 * @return true if this node is a child or an encapsulated message
187 static bool isInEncapsulatedMessage( KMime::Content
* node
);
190 * Returns the charset for the given node. If no charset is specified
191 * for the node, the defaultCharset() is returned.
193 static QByteArray
charset( KMime::Content
*node
);
196 * Check for prefixes @p prefixRegExps in @p str. If none
197 * is found, @p newPrefix + ' ' is prepended to @p str and the
198 * resulting string is returned. If @p replace is true, any
199 * sequence of whitespace-delimited prefixes at the beginning of
200 * @p str is replaced by @p newPrefix.
202 static QString
replacePrefixes( const QString
& str
,
203 const QStringList
& prefixRegExps
,
205 const QString
& newPrefix
);
208 * Return a QTextCodec for the specified charset.
209 * This function is a bit more tolerant, than QTextCodec::codecForName
211 static const QTextCodec
* codecForName(const QByteArray
& _str
);
214 * Returns a usable filename for a node, that can be the filename from the
215 * content disposition header, or if that one is empty, the name from the
216 * content type header.
218 static QString
fileName( const KMime::Content
*node
);
221 * Fixes an encoding received by a KDE function and returns the proper,
222 * MIME-compilant encoding name instead.
223 * @see encodingForName
225 static QString
fixEncoding( const QString
&encoding
); //TODO(Andras) move to a utility class?
228 * Drop-in replacement for KCharsets::encodingForName(). The problem with
229 * the KCharsets function is that it returns "human-readable" encoding names
230 * like "ISO 8859-15" instead of valid encoding names like "ISO-8859-15".
231 * This function fixes this by replacing whitespace with a hyphen.
233 static QString
encodingForName( const QString
&descriptiveName
); //TODO(Andras) move to a utility class?
236 * Return a list of the supported encodings
237 * @param usAscii if true, US-Ascii encoding will be prepended to the list.
239 static QStringList
supportedEncodings( bool usAscii
); //TODO(Andras) move to a utility class?
241 static QByteArray
autoDetectCharset(const QByteArray
&_encoding
, const QStringList
&encodingList
, const QString
&text
);
242 static QByteArray
toUsAscii(const QString
& _str
, bool *ok
);
244 static QString
fromAsString( KMime::Content
* node
);
246 struct AttachmentDisplayInfo
250 bool displayInHeader
;
253 static AttachmentDisplayInfo
attachmentDisplayInfo( KMime::Content
*node
);
255 KMime::Content
* decryptedNodeForContent( KMime::Content
* content
) const;
258 * This function returns the unencrypted message that is based on @p originalMessage.
259 * All encrypted MIME parts are removed and replaced by their decrypted plain-text versions.
260 * Encrypted parts that are within signed parts are not replaced, since that would invalidate
263 * This only works if the message was run through ObjectTreeParser::parseObjectTree() with the
264 * currrent NodeHelper before, because parseObjectTree() actually decrypts the message and stores
265 * the decrypted nodes by calling attachExtraContent().
267 * @return the unencrypted message or an invalid pointer if the original message didn't contain
268 * a part that needed to be modified.
270 KMime::Message::Ptr
unencryptedMessage( const KMime::Message::Ptr
&originalMessage
);
274 bool unencryptedMessage_helper( KMime::Content
*node
, QByteArray
&resultingData
, bool addHeaders
,
275 int recursionLevel
= 1 );
277 /** Check for prefixes @p prefixRegExps in #subject(). If none
278 is found, @p newPrefix + ' ' is prepended to the subject and the
279 resulting string is returned. If @p replace is true, any
280 sequence of whitespace-delimited prefixes at the beginning of
281 #subject() is replaced by @p newPrefix
283 static QString
cleanSubject( KMime::Message
*message
, const QStringList
& prefixRegExps
,
284 bool replace
, const QString
& newPrefix
);
286 void mergeExtraNodes( KMime::Content
*node
);
287 void cleanFromExtraNodes( KMime::Content
*node
);
289 QString
persistentIndex( const KMime::Content
* node
) const;
292 QList
<KMime::Content
*> mProcessedNodes
;
293 QList
<KMime::Content
*> mNodesUnderProcess
;
294 QMap
<KMime::Content
*, KMMsgEncryptionState
> mEncryptionState
;
295 QMap
<KMime::Content
*, KMMsgSignatureState
> mSignatureState
;
296 QSet
<KMime::Content
*> mDisplayEmbeddedNodes
;
297 QSet
<KMime::Content
*> mDisplayHiddenNodes
;
298 QTextCodec
*mLocalCodec
;
299 QMap
<KMime::Content
*, const QTextCodec
*> mOverrideCodecs
;
300 QMap
<QString
, QMap
<QByteArray
, Interface::BodyPartMemento
*> > mBodyPartMementoMap
;
301 QStringList mTempFiles
;
302 QStringList mTempDirs
;
303 QMap
<KMime::Content
*, PartMetaData
> mPartMetaDatas
;
304 QMap
<KMime::Message::Content
*, QList
<KMime::Content
*> > mExtraContents
;