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 }