kmail

bodyvisitor.cpp

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   }
00049 
00050   //-----------------------------------------------------------------------------
00051   BodyVisitor::~BodyVisitor()
00052   {
00053   }
00054 
00055   //-----------------------------------------------------------------------------
00056   void BodyVisitor::visit( KMMessagePart * part )
00057   {
00058     mParts.append( part );
00059   }
00060 
00061   //-----------------------------------------------------------------------------
00062   void BodyVisitor::visit( QPtrList<KMMessagePart> & list )
00063   {
00064     mParts = list;
00065   }
00066 
00067   //-----------------------------------------------------------------------------
00068   QPtrList<KMMessagePart> BodyVisitor::partsToLoad()
00069   {
00070     QPtrListIterator<KMMessagePart> it( mParts );
00071     QPtrList<KMMessagePart> selected;
00072     KMMessagePart *part = 0;
00073     bool headerCheck = false;
00074     while ( (part = it.current()) != 0 )
00075     {
00076       ++it;
00077       // skip this part if the parent part is already loading
00078       if ( part->parent() && 
00079            selected.contains( part->parent() ) &&
00080            part->loadPart() )
00081         continue;
00082 
00083       if ( part->originalContentTypeStr().contains("SIGNED") )
00084       {
00085         // signed messages have to be loaded completely
00086         // so construct a new dummy part that loads the body
00087         KMMessagePart *fake = new KMMessagePart();
00088         fake->setPartSpecifier( "TEXT" );
00089         fake->setOriginalContentTypeStr("");
00090         fake->setLoadPart( true );
00091         selected.append( fake );
00092         break;
00093       }
00094         
00095       if ( headerCheck && !part->partSpecifier().endsWith(".HEADER") )
00096       {
00097         // this is an embedded simple message (not multipart) so we get no header part
00098         // from imap. As we probably need to load the header (e.g. in smart or inline mode)
00099         // we add a fake part that is not included in the message itself
00100         KMMessagePart *fake = new KMMessagePart();
00101         QString partId = part->partSpecifier().section( '.', 0, -2 )+".HEADER";
00102         fake->setPartSpecifier( partId );
00103         fake->setOriginalContentTypeStr("");
00104         fake->setLoadPart( true );
00105         if ( addPartToList( fake ) ) 
00106           selected.append( fake );
00107       }
00108       
00109       if ( part->originalContentTypeStr() == "MESSAGE/RFC822" )
00110         headerCheck = true;
00111       else
00112         headerCheck = false;
00113       
00114       // check whether to load this part or not:
00115       // look at the basic list, ask the subclass and check the parent
00116       if ( mBasicList.contains( part->originalContentTypeStr() ) ||
00117            parentNeedsLoading( part ) ||
00118            addPartToList( part ) )
00119       {
00120         if ( part->typeStr() != "MULTIPART" ||
00121              part->partSpecifier().endsWith(".HEADER") )
00122         {
00123           // load the part itself
00124           part->setLoadPart( true );
00125         }
00126       }
00127       if ( !part->partSpecifier().endsWith(".HEADER") &&
00128            part->typeStr() != "MULTIPART" )
00129         part->setLoadHeaders( true ); // load MIME header
00130       
00131       if ( part->loadHeaders() || part->loadPart() )
00132         selected.append( part );
00133     }
00134     return selected;
00135   }
00136 
00137   //-----------------------------------------------------------------------------
00138   bool BodyVisitor::parentNeedsLoading( KMMessagePart *msgPart )
00139   {
00140     KMMessagePart *part = msgPart;
00141     while ( part )
00142     {
00143       if ( part->parent() &&
00144            ( part->parent()->originalContentTypeStr() == "MULTIPART/SIGNED" ||
00145            ( msgPart->originalContentTypeStr() == "APPLICATION/OCTET-STREAM" &&
00146              part->parent()->originalContentTypeStr() == "MULTIPART/ENCRYPTED" ) ) )
00147         return true;
00148 
00149       part = part->parent();
00150     }
00151     return false;
00152   }
00153 
00154   //=============================================================================
00155 
00156   BodyVisitorSmart::BodyVisitorSmart()
00157     : BodyVisitor()
00158   {
00159   }
00160 
00161   //-----------------------------------------------------------------------------
00162   bool BodyVisitorSmart::addPartToList( KMMessagePart * part )
00163   {
00164     // header of an encapsulated message
00165     if ( part->partSpecifier().endsWith(".HEADER") )
00166       return true;
00167 
00168     return false;
00169   }
00170 
00171   //=============================================================================
00172 
00173   BodyVisitorInline::BodyVisitorInline()
00174     : BodyVisitor()
00175   {
00176   }
00177 
00178   //-----------------------------------------------------------------------------
00179   bool BodyVisitorInline::addPartToList( KMMessagePart * part )
00180   {
00181     // header of an encapsulated message
00182     if ( part->partSpecifier().endsWith(".HEADER") )
00183       return true;
00184     else if ( part->typeStr() == "IMAGE" ) // images
00185       return true;
00186     else if ( part->typeStr() == "TEXT" ) // text, diff and stuff
00187       return true;
00188 
00189     return false;
00190   }
00191 
00192   //=============================================================================
00193 
00194   BodyVisitorHidden::BodyVisitorHidden()
00195     : BodyVisitor()
00196   {
00197   }
00198 
00199   //-----------------------------------------------------------------------------
00200   bool BodyVisitorHidden::addPartToList( KMMessagePart * part )
00201   {
00202     // header of an encapsulated message
00203     if ( part->partSpecifier().endsWith(".HEADER") )
00204       return true;
00205 
00206     return false;
00207   }
00208   
00209 }
KDE Home | KDE Accessibility Home | Description of Access Keys