summaryrefslogtreecommitdiffstats
path: root/kmail/bodyvisitor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kmail/bodyvisitor.cpp')
-rw-r--r--kmail/bodyvisitor.cpp211
1 files changed, 211 insertions, 0 deletions
diff --git a/kmail/bodyvisitor.cpp b/kmail/bodyvisitor.cpp
new file mode 100644
index 000000000..99af66196
--- /dev/null
+++ b/kmail/bodyvisitor.cpp
@@ -0,0 +1,211 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "bodyvisitor.h"
+#include "kmmsgpart.h"
+#include "attachmentstrategy.h"
+#include <kdebug.h>
+
+namespace KMail {
+
+ BodyVisitor* BodyVisitorFactory::getVisitor( const AttachmentStrategy* strategy )
+ {
+ if (strategy == AttachmentStrategy::smart())
+ {
+ return new BodyVisitorSmart();
+ } else if (strategy == AttachmentStrategy::iconic())
+ {
+ return new BodyVisitorHidden();
+ } else if (strategy == AttachmentStrategy::inlined())
+ {
+ return new BodyVisitorInline();
+ } else if (strategy == AttachmentStrategy::hidden())
+ {
+ return new BodyVisitorHidden();
+ }
+ // default
+ return new BodyVisitorSmart();
+ }
+
+ //=============================================================================
+
+ BodyVisitor::BodyVisitor()
+ {
+ // parts that are probably always ok to load
+ mBasicList.clear();
+ // body text
+ mBasicList += "TEXT/PLAIN";
+ mBasicList += "TEXT/HTML";
+ mBasicList += "MESSAGE/DELIVERY-STATUS";
+ // pgp stuff
+ mBasicList += "APPLICATION/PGP-SIGNATURE";
+ mBasicList += "APPLICATION/PGP";
+ mBasicList += "APPLICATION/PGP-ENCRYPTED";
+ mBasicList += "APPLICATION/PKCS7-SIGNATURE";
+ // groupware
+ mBasicList += "APPLICATION/MS-TNEF";
+ mBasicList += "TEXT/CALENDAR";
+ mBasicList += "TEXT/X-VCARD";
+ }
+
+ //-----------------------------------------------------------------------------
+ BodyVisitor::~BodyVisitor()
+ {
+ }
+
+ //-----------------------------------------------------------------------------
+ void BodyVisitor::visit( KMMessagePart * part )
+ {
+ mParts.append( part );
+ }
+
+ //-----------------------------------------------------------------------------
+ void BodyVisitor::visit( QPtrList<KMMessagePart> & list )
+ {
+ mParts = list;
+ }
+
+ //-----------------------------------------------------------------------------
+ QPtrList<KMMessagePart> BodyVisitor::partsToLoad()
+ {
+ QPtrListIterator<KMMessagePart> it( mParts );
+ QPtrList<KMMessagePart> selected;
+ KMMessagePart *part = 0;
+ bool headerCheck = false;
+ while ( (part = it.current()) != 0 )
+ {
+ ++it;
+ // skip this part if the parent part is already loading
+ if ( part->parent() &&
+ selected.contains( part->parent() ) &&
+ part->loadPart() )
+ continue;
+
+ if ( part->originalContentTypeStr().contains("SIGNED") )
+ {
+ // signed messages have to be loaded completely
+ // so construct a new dummy part that loads the body
+ KMMessagePart *fake = new KMMessagePart();
+ fake->setPartSpecifier( "TEXT" );
+ fake->setOriginalContentTypeStr("");
+ fake->setLoadPart( true );
+ selected.append( fake );
+ break;
+ }
+
+ if ( headerCheck && !part->partSpecifier().endsWith(".HEADER") )
+ {
+ // this is an embedded simple message (not multipart) so we get no header part
+ // from imap. As we probably need to load the header (e.g. in smart or inline mode)
+ // we add a fake part that is not included in the message itself
+ KMMessagePart *fake = new KMMessagePart();
+ QString partId = part->partSpecifier().section( '.', 0, -2 )+".HEADER";
+ fake->setPartSpecifier( partId );
+ fake->setOriginalContentTypeStr("");
+ fake->setLoadPart( true );
+ if ( addPartToList( fake ) )
+ selected.append( fake );
+ }
+
+ if ( part->originalContentTypeStr() == "MESSAGE/RFC822" )
+ headerCheck = true;
+ else
+ headerCheck = false;
+
+ // check whether to load this part or not:
+ // look at the basic list, ask the subclass and check the parent
+ if ( mBasicList.contains( part->originalContentTypeStr() ) ||
+ parentNeedsLoading( part ) ||
+ addPartToList( part ) )
+ {
+ if ( part->typeStr() != "MULTIPART" ||
+ part->partSpecifier().endsWith(".HEADER") )
+ {
+ // load the part itself
+ part->setLoadPart( true );
+ }
+ }
+ if ( !part->partSpecifier().endsWith(".HEADER") &&
+ part->typeStr() != "MULTIPART" )
+ part->setLoadHeaders( true ); // load MIME header
+
+ if ( part->loadHeaders() || part->loadPart() )
+ selected.append( part );
+ }
+ return selected;
+ }
+
+ //-----------------------------------------------------------------------------
+ bool BodyVisitor::parentNeedsLoading( KMMessagePart *msgPart )
+ {
+ KMMessagePart *part = msgPart;
+ while ( part )
+ {
+ if ( part->parent() &&
+ ( part->parent()->originalContentTypeStr() == "MULTIPART/SIGNED" ||
+ ( msgPart->originalContentTypeStr() == "APPLICATION/OCTET-STREAM" &&
+ part->parent()->originalContentTypeStr() == "MULTIPART/ENCRYPTED" ) ) )
+ return true;
+
+ part = part->parent();
+ }
+ return false;
+ }
+
+ //=============================================================================
+
+ BodyVisitorSmart::BodyVisitorSmart()
+ : BodyVisitor()
+ {
+ }
+
+ //-----------------------------------------------------------------------------
+ bool BodyVisitorSmart::addPartToList( KMMessagePart * part )
+ {
+ // header of an encapsulated message
+ if ( part->partSpecifier().endsWith(".HEADER") )
+ return true;
+
+ return false;
+ }
+
+ //=============================================================================
+
+ BodyVisitorInline::BodyVisitorInline()
+ : BodyVisitor()
+ {
+ }
+
+ //-----------------------------------------------------------------------------
+ bool BodyVisitorInline::addPartToList( KMMessagePart * part )
+ {
+ // header of an encapsulated message
+ if ( part->partSpecifier().endsWith(".HEADER") )
+ return true;
+ else if ( part->typeStr() == "IMAGE" ) // images
+ return true;
+ else if ( part->typeStr() == "TEXT" ) // text, diff and stuff
+ return true;
+
+ return false;
+ }
+
+ //=============================================================================
+
+ BodyVisitorHidden::BodyVisitorHidden()
+ : BodyVisitor()
+ {
+ }
+
+ //-----------------------------------------------------------------------------
+ bool BodyVisitorHidden::addPartToList( KMMessagePart * part )
+ {
+ // header of an encapsulated message
+ if ( part->partSpecifier().endsWith(".HEADER") )
+ return true;
+
+ return false;
+ }
+
+}