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 }