kmail

bodyvisitor.cpp

Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include "bodyvisitor.h"
00006 #include "kmmsgpart.h"
00007 #include "attachmentstrategy.h"
00008 #include <kdebug.h>
00009 
00010 namespace KMail {
00011 
00012   BodyVisitor* BodyVisitorFactory::getVisitor( const AttachmentStrategy* strategy )
00013   {
00014     if (strategy == AttachmentStrategy::smart())
00015     {
00016       return new BodyVisitorSmart();
00017     } else if (strategy == AttachmentStrategy::iconic())
00018     {
00019       return new BodyVisitorHidden();
00020     } else if (strategy == AttachmentStrategy::inlined())
00021     {
00022       return new BodyVisitorInline();
00023     } else if (strategy == AttachmentStrategy::hidden())
00024     {
00025       return new BodyVisitorHidden();
00026     }
00027     // default
00028     return new BodyVisitorSmart();
00029   }
00030 
00031   //=============================================================================
00032 
00033   BodyVisitor::BodyVisitor()
00034   {
00035     // parts that are probably always ok to load
00036     mBasicList.clear();
00037     // body text
00038     mBasicList += "TEXT/PLAIN";
00039     mBasicList += "TEXT/HTML";
00040     mBasicList += "MESSAGE/DELIVERY-STATUS";
00041     // pgp stuff
00042     mBasicList += "APPLICATION/PGP-SIGNATURE";
00043     mBasicList += "APPLICATION/PGP";
00044     mBasicList += "APPLICATION/PGP-ENCRYPTED";
00045     mBasicList += "APPLICATION/PKCS7-SIGNATURE";
00046     // groupware
00047     mBasicList += "APPLICATION/MS-TNEF";
00048     mBasicList += "TEXT/CALENDAR";
00049     mBasicList += "TEXT/X-VCARD";
00050   }
00051 
00052   //-----------------------------------------------------------------------------
00053   BodyVisitor::~BodyVisitor()
00054   {
00055   }
00056 
00057   //-----------------------------------------------------------------------------
00058   void BodyVisitor::visit( KMMessagePart * part )
00059   {
00060     mParts.append( part );
00061   }
00062 
00063   //-----------------------------------------------------------------------------
00064   void BodyVisitor::visit( QPtrList<KMMessagePart> & list )
00065   {
00066     mParts = list;
00067   }
00068 
00069   //-----------------------------------------------------------------------------
00070   QPtrList<KMMessagePart> BodyVisitor::partsToLoad()
00071   {
00072     QPtrListIterator<KMMessagePart> it( mParts );
00073     QPtrList<KMMessagePart> selected;
00074     KMMessagePart *part = 0;
00075     bool headerCheck = false;
00076     while ( (part = it.current()) != 0 )
00077     {
00078       ++it;
00079       // skip this part if the parent part is already loading
00080       if ( part->parent() &&
00081            selected.contains( part->parent() ) &&
00082            part->loadPart() )
00083         continue;
00084 
00085       if ( part->originalContentTypeStr().contains("SIGNED") )
00086       {
00087         // signed messages have to be loaded completely
00088         // so construct a new dummy part that loads the body
00089         KMMessagePart *fake = new KMMessagePart();
00090         fake->setPartSpecifier( "TEXT" );
00091         fake->setOriginalContentTypeStr("");
00092         fake->setLoadPart( true );
00093         selected.append( fake );
00094         break;
00095       }
00096 
00097       if ( headerCheck && !part->partSpecifier().endsWith(".HEADER") )
00098       {
00099         // this is an embedded simple message (not multipart) so we get no header part
00100         // from imap. As we probably need to load the header (e.g. in smart or inline mode)
00101         // we add a fake part that is not included in the message itself
00102         KMMessagePart *fake = new KMMessagePart();
00103         QString partId = part->partSpecifier().section( '.', 0, -2 )+".HEADER";
00104         fake->setPartSpecifier( partId );
00105         fake->setOriginalContentTypeStr("");
00106         fake->setLoadPart( true );
00107         if ( addPartToList( fake ) )
00108           selected.append( fake );
00109       }
00110 
00111       if ( part->originalContentTypeStr() == "MESSAGE/RFC822" )
00112         headerCheck = true;
00113       else
00114         headerCheck = false;
00115 
00116       // check whether to load this part or not:
00117       // look at the basic list, ask the subclass and check the parent
00118       if ( mBasicList.contains( part->originalContentTypeStr() ) ||
00119            parentNeedsLoading( part ) ||
00120            addPartToList( part ) )
00121       {
00122         if ( part->typeStr() != "MULTIPART" ||
00123              part->partSpecifier().endsWith(".HEADER") )
00124         {
00125           // load the part itself
00126           part->setLoadPart( true );
00127         }
00128       }
00129       if ( !part->partSpecifier().endsWith(".HEADER") &&
00130            part->typeStr() != "MULTIPART" )
00131         part->setLoadHeaders( true ); // load MIME header
00132 
00133       if ( part->loadHeaders() || part->loadPart() )
00134         selected.append( part );
00135     }
00136     return selected;
00137   }
00138 
00139   //-----------------------------------------------------------------------------
00140   bool BodyVisitor::parentNeedsLoading( KMMessagePart *msgPart )
00141   {
00142     KMMessagePart *part = msgPart;
00143     while ( part )
00144     {
00145       if ( part->parent() &&
00146            ( part->parent()->originalContentTypeStr() == "MULTIPART/SIGNED" ||
00147            ( msgPart->originalContentTypeStr() == "APPLICATION/OCTET-STREAM" &&
00148              part->parent()->originalContentTypeStr() == "MULTIPART/ENCRYPTED" ) ) )
00149         return true;
00150 
00151       part = part->parent();
00152     }
00153     return false;
00154   }
00155 
00156   //=============================================================================
00157 
00158   BodyVisitorSmart::BodyVisitorSmart()
00159     : BodyVisitor()
00160   {
00161   }
00162 
00163   //-----------------------------------------------------------------------------
00164   bool BodyVisitorSmart::addPartToList( KMMessagePart * part )
00165   {
00166     // header of an encapsulated message
00167     if ( part->partSpecifier().endsWith(".HEADER") )
00168       return true;
00169 
00170     return false;
00171   }
00172 
00173   //=============================================================================
00174 
00175   BodyVisitorInline::BodyVisitorInline()
00176     : BodyVisitor()
00177   {
00178   }
00179 
00180   //-----------------------------------------------------------------------------
00181   bool BodyVisitorInline::addPartToList( KMMessagePart * part )
00182   {
00183     // header of an encapsulated message
00184     if ( part->partSpecifier().endsWith(".HEADER") )
00185       return true;
00186     else if ( part->typeStr() == "IMAGE" ) // images
00187       return true;
00188     else if ( part->typeStr() == "TEXT" ) // text, diff and stuff
00189       return true;
00190 
00191     return false;
00192   }
00193 
00194   //=============================================================================
00195 
00196   BodyVisitorHidden::BodyVisitorHidden()
00197     : BodyVisitor()
00198   {
00199   }
00200 
00201   //-----------------------------------------------------------------------------
00202   bool BodyVisitorHidden::addPartToList( KMMessagePart * part )
00203   {
00204     // header of an encapsulated message
00205     if ( part->partSpecifier().endsWith(".HEADER") )
00206       return true;
00207 
00208     return false;
00209   }
00210 
00211 }