Better wording
[kdepim.git] / messageviewer / objecttreeparser.h
blobb09ecf19f356be1970815f00add475b369e54d3d
1 /* -*- mode: C++; c-file-style: "gnu" -*-
2 objecttreeparser.h
4 This file is part of KMail, the KDE mail client.
5 Copyright (c) 2003 Marc Mutz <mutz@kde.org>
6 Copyright (C) 2002-2003, 2009 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.net
7 Copyright (c) 2009 Andras Mantia <andras@kdab.net>
9 KMail is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License, version 2, as
11 published by the Free Software Foundation.
13 KMail is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 In addition, as a special exception, the copyright holders give
23 permission to link the code of this program with any edition of
24 the Qt library by Trolltech AS, Norway (or with modified versions
25 of Qt that use the same license as Qt), and distribute linked
26 combinations including the two. You must obey the GNU General
27 Public License in all respects for all of the code used other than
28 Qt. If you modify this file, you may extend this exception to
29 your version of the file, but you are not obligated to do so. If
30 you do not wish to do so, delete this exception statement from
31 your version.
34 #ifndef _MESSAGEVIEWER_OBJECTTREEPARSER_H_
35 #define _MESSAGEVIEWER_OBJECTTREEPARSER_H_
37 #include "messageviewer_export.h"
39 #include "nodehelper.h"
40 #include "objecttreesourceif.h"
42 #include <libkleo/kleo/cryptobackend.h>
43 #include <gpgme++/verificationresult.h>
45 #include <QList>
46 #include "objecttreeemptysource.h"
48 class QString;
50 namespace KMime {
51 class Content;
54 namespace GpgME {
55 class Error;
56 class ImportResult;
60 namespace MessageViewer {
62 class PartMetaData;
63 class ViewerPrivate;
64 class HtmlWriter;
65 class CSSHelper;
66 class AttachmentStrategy;
67 class NodeHelper;
69 class ProcessResult {
70 public:
71 explicit ProcessResult( NodeHelper *nodeHelper, KMMsgSignatureState inlineSignatureState = KMMsgNotSigned,
72 KMMsgEncryptionState inlineEncryptionState = KMMsgNotEncrypted,
73 bool neverDisplayInline = false,
74 bool isImage = false )
75 : mInlineSignatureState( inlineSignatureState ),
76 mInlineEncryptionState( inlineEncryptionState ),
77 mNeverDisplayInline( neverDisplayInline ),
78 mIsImage( isImage ),
79 mNodeHelper( nodeHelper ) {}
81 KMMsgSignatureState inlineSignatureState() const {
82 return mInlineSignatureState;
84 void setInlineSignatureState( KMMsgSignatureState state ) {
85 mInlineSignatureState = state;
88 KMMsgEncryptionState inlineEncryptionState() const {
89 return mInlineEncryptionState;
91 void setInlineEncryptionState( KMMsgEncryptionState state ) {
92 mInlineEncryptionState = state;
95 bool neverDisplayInline() const { return mNeverDisplayInline; }
96 void setNeverDisplayInline( bool display ) {
97 mNeverDisplayInline = display;
100 bool isImage() const { return mIsImage; }
101 void setIsImage( bool image ) {
102 mIsImage = image;
105 void adjustCryptoStatesOfNode( KMime::Content * node ) const;
107 private:
108 KMMsgSignatureState mInlineSignatureState;
109 KMMsgEncryptionState mInlineEncryptionState;
110 bool mNeverDisplayInline : 1;
111 bool mIsImage : 1;
112 NodeHelper* mNodeHelper;
116 \brief Parses messages and generates HTML display code out of them
118 \par Introduction
120 First, have a look at the documentation in Mainpage.dox and at the documentation of ViewerPrivate
121 to understand the broader picture.
123 Just a note on the terminology: 'Node' refers to a MIME part here, which in KMime is a
124 KMime::Content.
126 \par Basics
128 The ObjectTreeParser basically has two modes: Generating the HTML code for the Viewer, or only
129 extracting the plainTextContent() for situations where only the message text is needed, for example
130 when inline forwarding a message. The mode depends on the ObjectTreeSourceIf passed to the
131 constructor: If ObjectTreeSourceIf::htmlWriter() is not 0, then the HTML code generation mode is
132 used.
134 Basically, all the ObjectTreeParser does is going through the tree of MIME parts and operating on
135 those nodes. Operating here means creating the HTML code for the node or extracting the textual
136 content from it. This process is started with parseObjectTree(), where we loop over the subnodes
137 of the current root node. For each of those subnodes, we try to find a BodyPartFormatter that can
138 handle the type of the node. This can either be an internal function, such as
139 processMultiPartAlternativeSubtype() or processTextHtmlSubtype(), or it can be an external plugin.
140 More on external plugins later. When no matching formatter is found, defaultHandling() is called
141 for that node.
143 \par Multipart Nodes
145 Those nodes that are of type multipart have subnodes. If one of those children needs to be
146 processed normally, the processMultipartXXX() functions call stdChildHandling() for the node that
147 should be handled normally. stdChildHandling() creates its own ObjectTreeParser, which is a clone
148 of the current ObjectTreeParser, and processes the node. stdChildHandling() is not called for all
149 children of the multipart node, for example processMultiPartAlternativeSubtype() only calls it on
150 one of the children, as the other one doesn't need to be displayed. Similary,
151 processMultiPartSignedSubtype() doesn't call stdChildHandling() for the signature node, only for the
152 signed node.
154 \par Processed and Unprocessed Nodes
156 When a BodyPartFormatter has finished processing a node, it is processed. Nodes are set to being
157 not processed at the beginning of parseObjectTree(). The processed state of a node is saved in a
158 list in NodeHelper, see NodeHelper::setNodeProcessed(), NodeHelper::nodeProcessed() and the other
159 related helper functions.
161 It is the responsibility of the BodyPartFormatter to correctly call setNodeProcessed() and the
162 related functions. This is important so that processing the same node twice can be prevented. The
163 check that prevents duplicate processing is in parseObjectTree().
165 An example where duplicate processing would happen if we didn't check for it is in stdChildHandling(),
166 which is for example called from processMultiPartAlternativeSubtype(). Let's say the setting is to
167 prefer HTML over plain text. In this case, processMultiPartAlternativeSubtype() would call
168 stdChildHandling() on the HTML node, which would create a new ObjectTreeParser and call
169 parseObjectTree() on it. parseObjectTree() processes the node and all its siblings, and one of the
170 siblings is the plain text node, which shouldn't be processed! Therefore
171 processMultiPartAlternativeSubtype() sets the plain text node as been processed already.
173 \par Plain Text Output
175 Various nodes have plain text that should be displayed. This plain text is usually processed though
176 writeBodyString() first. That method checks if the provided text is an inline PGP text and decrypts
177 it if necessary. It also pushes the text through quotedHTML(), which does a number of things like
178 coloring quoted lines or detecting links and creating real link tags for them.
180 \par Modifying the Message
182 The ObjectTreeParser does not only parse its message, in some circumstances it also modifies it
183 before displaying. This is for example the case when displaying a decrypted message: The original
184 message only contains a binary blob of crypto data, and processMultiPartEncryptedSubtype() decrypts
185 that blob. After decryption, the current node is replaced with the decrypted node, which happens
186 in insertAndParseNewChildNode().
188 \par Crypto Operations
190 For signature and decryption handling, there are functions which help with generating the HTML code
191 for the signature header and footer. These are writeDeferredDecryptionBlock(), writeSigstatFooter()
192 and writeSigstatHeader(). As the name writeDeferredDecryptionBlock() suggests, a setting can cause
193 the message to not be decrypted unless the user clicks a link. Whether the message should be
194 decrypted or not can be controlled by ObjectTreeSourceIf::decryptMessage(). When the user clicks the
195 decryption link, the URLHandler for 'kmail:' URLs sets that variable to true and triggers an update
196 of the Viewer, which will cause parseObjectTree() to be called again.
198 \par Async Crypto Operations
200 The above case describes decryption the message in place. However, decryption and also verifying of
201 the signature can take a long time, so synchronous decryption and verifing would cause the Viewer to
202 block. Therefore it is possible to run these operations in async mode, see allowAsync().
203 In the first run of the async mode, all the ObjectTreeParser does is starting the decrypt or the
204 verify job, and informing the user that the operation is in progress with
205 writeDecryptionInProgressBlock() or with writeSigstatHeader(). Then, it creates and associates a
206 BodyPartMemento with the current node, for example a VerifyDetachedBodyPartMemento. Each node can
207 have multiple mementos associated with it, which are differeniated by name.
209 NodeHelper::setBodyPartMemento() and NodeHelper::bodyPartMemento() provide means to store and
210 retrieve these mementos. A memento is basically a thin wrapper around the crypto job, it stores the
211 job pointer, the job input data and the job result. Mementos can be used for any async situation,
212 not just for crypto jobs, but I'll describe crypto jobs here.
214 So in the first run of decrypting or verifying a message, the BodyPartFormatter only starts the
215 crypto job, creates the BodyPartMemento and writes the HTML code that tells the user that the
216 operation is in progress. parseObjectTree() thus finishes without waiting for anything, and the
217 message is displayed.
219 At some point, the crypto jobs then finish, which will cause slotResult() of the BodyPartMemento
220 to be called. slotResult() then saves the result to some member variable and calls
221 BodyPartMemento::notify(), which in the end will trigger an update of the Viewer. That update
222 will, in ViewerPrivate::parseMsg(), create a new ObjectTreeParser and call parseObjectTree() on it.
223 This is where the second run begins.
225 The functions that deal with decrypting of verifying, like processMultiPartSignedSubtype() or
226 processMultiPartEncryptedSubtype() will look if they find a BodyPartMemento that is associated with
227 the current node. Now it finds that memento, since it was created in the first run. It checks if the
228 memento's job has finished, and if so, the result can be written out (either the decrypted data or
229 the verified signature).
231 When dealing with encrypted nodes, new nodes are created with the decrypted data. It is important to
232 note that the original MIME tree is never modified, and remains the same as the original one. The method
233 createAndParseTempNode is called with the newly decrypted data, and it generates a new temporary node to
234 store the decrypted data. When these nodes are created, it is important to keep track of them as otherwise
235 some mementos that are added to the newly created temporary nodes will be constantly regenerated. As the
236 regeneration triggers a viewer update when complete, it results in an infinite refresh loop. The function
237 NodeHelper::linkAsPermanentDecrypted will create a link between the newly created node and the original parent.
238 Conversely, the function NodeHelper::attachExtraContent will create a link in the other direction, from the parent
239 node to the newly created temporary node.
241 When generating some mementos for nodes that may be temporary nodes (for example, contact photo mementos), the
242 function NodeHelper::setBodyPartMementoForPermanentParent is used. This will save the given body part memento for
243 the closest found permanent parent node, rather than the transient node itself. Then when checking for the existence
244 of a certain memento in a node, NodeHelper::findPermanentParentBodyPartMemento will check to see if any parent of the
245 given temporary node is a permanent (encrypted) node that has been used to generate the asked-for node.
247 To conclude: For async operations, parseObjectTree() is called twice: The first call starts the
248 crypto operation and creates the BodyPartMemento, the second calls sees that the BodyPartMemento is
249 there and can use its result for writing out the HTML.
251 \par PartMetaData and ProcessResult
253 For crypto operations, the class PartMetaData is used a lot, mainly to pass around info about the
254 crypto state of a node. A PartMetaData can also be associated with a node by using
255 NodeHelper::setPartMetaData(). The only user of that however is MessageAnalyzer::processPart() of
256 the Nepomuk E-Mail Feeder, which also uses the ObjectTreeParser to analyze the message.
258 You'll notice that a ProcessResult is passed to each formatter. The formatter is supposed to modify
259 the ProcessResult to tell the callers something about the state of the nodes that were processed.
260 One example for its use is to tell the caller about the crypto state of the node.
262 \par BodyPartFormatter Plugins
264 As mentioned way earlier, BodyPartFormatter can either be plugins or be internal. bodypartformatter.cpp
265 contains some trickery so that the processXXX() methods of the ObjectTreeParser are called from
266 a BodyPartFormatter associated with them, see the CREATE_BODY_PART_FORMATTER macro.
268 The BodyPartFormatter code is work in progress, it was supposed to be refactored, but that has not
269 yet happened at the time of writing. Therefore the code can seem a bit chaotic.
271 External plugins are loaded with loadPlugins() in bodypartformatterfactory.cpp. External plugins
272 can only use the classes in the interfaces/ directory, they include BodyPart, BodyPartMemento,
273 BodyPartFormatterPlugin, BodyPartFormatter, BodyPartURLHandler, HtmlWriter and URLHandler. Therefore
274 external plugins have powerful capabilities, which are needed for example in the iCal formatter or
275 in the vCard formatter.
277 \par Special HTML tags
279 As also mentioned in the documentation of ViewerPrivate, the ObjectTreeParser writes out special
280 links that are only understood by the viewer, for example 'kmail:' URLs or 'attachment:' URLs.
281 Also, some special HTML tags are created, which the Viewer later uses for post-processing. For
282 example a div with the id 'attachmentInjectionPoint', or a div with the id 'attachmentDiv', which
283 is used to mark an attachment in the body with a yellow border when the user clicks the attachment
284 in the header. Finally, parseObjectTree() creates an anchor with the id 'att%1', which is used in
285 the Viewer to scroll to the attachment.
287 class MESSAGEVIEWER_EXPORT ObjectTreeParser {
288 class CryptoProtocolSaver;
290 * @internal
291 * Copies the context of @p other, but not it's rawDecryptedBody, plainTextContent or htmlContent.
293 ObjectTreeParser( const ObjectTreeParser & other );
295 public:
296 explicit ObjectTreeParser( ObjectTreeSourceIf * source,
297 NodeHelper *nodeHelper = 0,
298 const Kleo::CryptoBackend::Protocol * protocol=0,
299 bool showOneMimePart=false, bool keepEncryptions=false,
300 bool includeSignatures=true,
301 const AttachmentStrategy * attachmentStrategy=0 );
303 explicit ObjectTreeParser( const ObjectTreeParser *topLevelParser,
304 bool showOneMimePart=false, bool keepEncryptions=false,
305 bool includeSignatures=true,
306 const AttachmentStrategy * attachmentStrategy=0 );
307 virtual ~ObjectTreeParser();
309 void setAllowAsync( bool allow ) { assert( !mHasPendingAsyncJobs ); mAllowAsync = allow; }
310 bool allowAsync() const { return mAllowAsync; }
312 bool hasPendingAsyncJobs() const { return mHasPendingAsyncJobs; }
315 * The origin and purpose of this function is unknown, the ancient wisdom about it got lost during
316 * the centuries.
318 * Historicans believe that the intent of the function is to return the raw body of the mail,
319 * i.e. no charset decoding has been done yet. Sometimes CTE decoding has been done, sometimes
320 * not. For encrypted parts, this returns the content of the decrypted part. For a mail with
321 * multiple MIME parts, the results are conecated together. Not all parts are included in this.
323 * Although conecating multiple undecoded body parts with potentially different CTEs together might
324 * not seem to make any sense in these modern times, it is assumed that initally this function
325 * performed quite well, but the ancient scrolls got damaged with the ravages of time
326 * and were re-written multiple times.
328 * Do not use. Use plainTextContent() and htmlContent() instead.
330 QByteArray rawDecryptedBody() const { return mRawDecryptedBody; }
333 * The text of the message, ie. what would appear in the
334 * composer's text editor if this was edited or replied to.
335 * This is usually the content of the first text/plain MIME part.
337 QString plainTextContent() const { return mPlainTextContent; }
340 * Similar to plainTextContent(), but returns the HTML source of the first text/html MIME part.
342 * Not to be consfused with the HTML code that the message viewer widget displays, that HTML
343 * is written out by htmlWriter() and a totally different pair of shoes.
345 QString htmlContent() const { return mHtmlContent; }
348 * Returns a plain text version of the content, which is either plainTextContent() if that exists,
349 * or htmlContent() converted to plain text otherwise.
351 QString convertedTextContent() const;
353 /** Returns a HTML version of the plain text mail. If the HTML content is already available, it
354 * returns the HTML content as it is.
356 QString convertedHtmlContent() const;
359 * The original charset of MIME part the plain text was extracted from.
361 * If there were more than one text/plain MIME parts in the mail, the this is the charset
362 * of the last MIME part processed.
364 QByteArray plainTextContentCharset() const { return mPlainTextContentCharset; }
365 QByteArray htmlContentCharset() const { return mHtmlContentCharset; }
367 void setCryptoProtocol( const Kleo::CryptoBackend::Protocol * protocol ) {
368 mCryptoProtocol = protocol;
370 const Kleo::CryptoBackend::Protocol* cryptoProtocol() const {
371 return mCryptoProtocol;
374 bool showOnlyOneMimePart() const { return mShowOnlyOneMimePart; }
375 void setShowOnlyOneMimePart( bool show ) {
376 mShowOnlyOneMimePart = show;
379 bool keepEncryptions() const { return mKeepEncryptions; }
380 void setKeepEncryptions( bool keep ) {
381 mKeepEncryptions = keep;
384 bool includeSignatures() const { return mIncludeSignatures; }
385 void setIncludeSignatures( bool include ) {
386 mIncludeSignatures = include;
389 // Controls whether Toltec invitations are displayed in their raw form or as a replacement text,
390 // which is used in processToltecMail().
391 void setShowRawToltecMail( bool showRawToltecMail ) { mShowRawToltecMail = showRawToltecMail; }
392 bool showRawToltecMail() const { return mShowRawToltecMail; }
394 /// Default text for processToltecMail(), which is used in messageviewer.kcfg, therefore it
395 /// needs to be static here.
396 static QString defaultToltecReplacementText();
398 const AttachmentStrategy * attachmentStrategy() const {
399 return mAttachmentStrategy;
402 HtmlWriter * htmlWriter() const { return mSource->htmlWriter(); }
404 CSSHelper * cssHelper() const { return mSource->cssHelper(); }
406 NodeHelper * nodeHelper() const { return mNodeHelper; }
408 /** Parse beginning at a given node and recursively parsing
409 the children of that node and it's next sibling. */
410 void parseObjectTree( KMime::Content * node );
412 private:
413 void extractNodeInfos( KMime::Content *curNode, bool isFirstTextPart );
416 * Does the actual work for parseObjectTree. Unlike parseObjectTree(), this does not change the
417 * top-level content.
419 void parseObjectTreeInternal( KMime::Content * node );
421 /** Standard children handling a.k.a. multipart/mixed (w/o
422 kroupware hacks) */
423 void stdChildHandling( KMime::Content * child );
425 void defaultHandling( KMime::Content * node, ProcessResult & result );
427 /** 1. Create a new partNode using 'content' data and Content-Description
428 found in 'cntDesc'.
429 2. Parse the 'node' to display the content.
431 void createAndParseTempNode( KMime::Content* parentNode, const char * content, const char * cntDesc );
433 /** if data is 0:
434 Feeds the HTML widget with the contents of the opaque signed
435 data found in partNode 'sign'.
436 if data is set:
437 Feeds the HTML widget with the contents of the given
438 multipart/signed object.
439 Signature is tested. May contain body parts.
441 Returns whether a signature was found or not: use this to
442 find out if opaque data is signed or not. */
443 bool writeOpaqueOrMultipartSignedData( KMime::Content * data,
444 KMime::Content & sign,
445 const QString & fromAddress,
446 bool doCheck=true,
447 QByteArray * cleartextData=0,
448 const std::vector<GpgME::Signature> & paramSignatures = std::vector<GpgME::Signature>(),
449 bool hideErrors=false );
451 /** Writes out the block that we use when the node is encrypted,
452 but we're deferring decryption for later. */
453 void writeDeferredDecryptionBlock();
455 /** Writes out the block that we use when the node is encrypted,
456 but we've just kicked off async decryption. */
457 void writeDecryptionInProgressBlock();
459 /** Writes out the information contained in a GpgME::ImportResult */
460 void writeCertificateImportResult( const GpgME::ImportResult & res );
463 /** Returns the contents of the given multipart/encrypted
464 object. Data is decypted. May contain body parts. */
465 bool okDecryptMIME( KMime::Content& data,
466 QByteArray& decryptedData,
467 bool& signatureFound,
468 std::vector<GpgME::Signature> &signatures,
469 bool showWarning,
470 bool& passphraseError,
471 bool& actuallyEncrypted,
472 bool& decryptionStarted,
473 PartMetaData &partMetaData );
476 * This is called for all multipart/mixed nodes. It checks if that belongs to a Toltec mail,
477 * by checking various criteria.
478 * If it is a toltec mail, a special text, instead of the confusing toltec text, will be
479 * displayed.
481 * @return true if the mail was indeed a toltec mail, in which case the node should not be
482 * processed further
484 bool processToltecMail( KMime::Content *node );
486 bool processMailmanMessage( KMime::Content* node );
488 /** Checks whether @p str contains external references. To be precise,
489 we only check whether @p str contains 'xxx="http[s]:' where xxx is
490 not href. Obfuscated external references are ignored on purpose.
492 static bool containsExternalReferences(const QString & str , const QString &extraHead);
494 public:// (during refactoring)
496 bool processTextHtmlSubtype( KMime::Content * node, ProcessResult & result );
497 bool processTextPlainSubtype( KMime::Content *node, ProcessResult & result );
499 bool processMultiPartMixedSubtype( KMime::Content * node, ProcessResult & result );
500 bool processMultiPartAlternativeSubtype( KMime::Content * node, ProcessResult & result );
501 bool processMultiPartDigestSubtype( KMime::Content * node, ProcessResult & result );
502 bool processMultiPartParallelSubtype( KMime::Content * node, ProcessResult & result );
503 bool processMultiPartSignedSubtype( KMime::Content * node, ProcessResult & result );
504 bool processMultiPartEncryptedSubtype( KMime::Content * node, ProcessResult & result );
506 bool processMessageRfc822Subtype( KMime::Content * node, ProcessResult & result );
508 bool processApplicationOctetStreamSubtype( KMime::Content * node, ProcessResult & result );
509 bool processApplicationPkcs7MimeSubtype( KMime::Content * node, ProcessResult & result );
510 bool processApplicationChiasmusTextSubtype( KMime::Content * node, ProcessResult & result );
512 bool decryptChiasmus( const QByteArray& data, QByteArray& bodyDecoded, QString& errorText );
513 void writeBodyString( const QByteArray & bodyString,
514 const QString & fromAddress,
515 const QTextCodec * codec,
516 ProcessResult & result, bool decorate );
518 void writePartIcon( KMime::Content * msgPart, bool inlineImage = false );
520 QString sigStatusToString( const Kleo::CryptoBackend::Protocol * cryptProto,
521 int status_code,
522 GpgME::Signature::Summary summary,
523 int & frameColor,
524 bool & showKeyInfos );
525 QString writeSigstatHeader( PartMetaData & part,
526 const Kleo::CryptoBackend::Protocol * cryptProto,
527 const QString & fromAddress,
528 KMime::Content *node = 0);
529 QString writeSigstatFooter( PartMetaData & part );
531 // The attachment mark is a div that is placed around the attchment. It is used for drawing
532 // a yellow border around the attachment when scrolling to it. When scrolling to it, the border
533 // color of the div is changed, see KMReaderWin::scrollToAttachment().
534 void writeAttachmentMarkHeader( KMime::Content *node );
535 void writeAttachmentMarkFooter();
537 void writeBodyStr( const QByteArray & bodyString,
538 const QTextCodec * aCodec,
539 const QString & fromAddress,
540 KMMsgSignatureState & inlineSignatureState,
541 KMMsgEncryptionState & inlineEncryptionState,
542 bool decorate );
544 bool isMailmanMessage( KMime::Content * curNode );
546 public: // KMReaderWin still needs this...
547 void writeBodyStr( const QByteArray & bodyString,
548 const QTextCodec * aCodec,
549 const QString & fromAddress );
550 static KMime::Content* findType( KMime::Content* content, const QByteArray& mimeType, bool deep, bool wide );
552 static KMime::Content* findType( KMime::Content* content, const QByteArray& mediaType, const QByteArray& subType, bool deep, bool wide );
554 static KMime::Content* findTypeNot( KMime::Content* content, const QByteArray& mediaType, const QByteArray& subType, bool deep=true, bool wide=true );
557 private:
559 /** ctor helper */
560 void init();
562 /** Change the string to `quoted' html (meaning, that the quoted
563 part of the message get italized */
564 QString quotedHTML(const QString& pos, bool decorate);
566 const QTextCodec * codecFor( KMime::Content * node ) const;
567 /** Check if the newline at position @p newLinePos in string @p s
568 seems to separate two paragraphs (important for correct BiDi
569 behavior, but is heuristic because paragraphs are not
570 well-defined) */
571 bool looksLikeParaBreak(const QString& s, unsigned int newLinePos) const;
573 #ifdef MARCS_DEBUG
574 void dumpToFile( const char * filename, const char * dataStart, size_t dataLen );
575 #else
576 void dumpToFile( const char *, const char *, size_t ) {}
577 #endif
579 void copyContentFrom( const ObjectTreeParser *other );
581 private:
582 ObjectTreeSourceIf* mSource;
583 NodeHelper* mNodeHelper;
584 QByteArray mRawDecryptedBody;
585 QByteArray mPlainTextContentCharset;
586 QByteArray mHtmlContentCharset;
587 QString mPlainTextContent;
588 QString mHtmlContent;
589 KMime::Content *mTopLevelContent;
590 const Kleo::CryptoBackend::Protocol * mCryptoProtocol;
592 /// Show only one mime part means that the user has selected some node in the message structure
593 /// viewer that is not the root, which means the user wants to only see the selected node and its
594 /// children. If that is the case, this variable is set to true.
595 /// The code needs to behave differently if this is set. For example, it should not process the
596 /// siblings. Also, consider inline images: Normally, those nodes are completely hidden, as the
597 /// HTML node embedds them. However, when showing only the node of the image, one has to show them,
598 /// as their is no HTML node in which they are displayed. There are many more cases where this
599 /// variable needs to be obeyed.
600 /// This variable is set to false again when processing the children in stdChildHandling(), as
601 /// the children can be completely displayed again.
602 bool mShowOnlyOneMimePart;
604 bool mKeepEncryptions;
605 bool mIncludeSignatures;
606 bool mHasPendingAsyncJobs;
607 bool mAllowAsync;
608 bool mShowRawToltecMail;
609 const AttachmentStrategy * mAttachmentStrategy;
610 // DataUrl Icons cache
611 QString mCollapseIcon;
612 QString mExpandIcon;
613 bool mDeleteNodeHelper;
619 #endif // _KMAIL_OBJECTTREEPARSER_H_