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