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 }