00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifdef HAVE_CONFIG_H
00033 #include <config.h>
00034 #endif
00035
00036 #include "bodypartformatter.h"
00037 #include "bodypartformatterfactory_p.h"
00038 #include "interfaces/bodypartformatter.h"
00039
00040 #include "objecttreeparser.h"
00041 #include "partNode.h"
00042 #include "callback.h"
00043
00044 #include <mimelib/enum.h>
00045 #include <mimelib/string.h>
00046 #include <mimelib/utility.h>
00047
00048 #include <kdebug.h>
00049 #include <kasciistricmp.h>
00050
00051 namespace {
00052 class AnyTypeBodyPartFormatter
00053 : public KMail::BodyPartFormatter,
00054 public KMail::Interface::BodyPartFormatter {
00055 static const AnyTypeBodyPartFormatter * self;
00056 public:
00057 Result format( KMail::Interface::BodyPart *, KMail::HtmlWriter *, KMail::Callback & ) const {
00058 kdDebug(5006) << "AnyTypeBodyPartFormatter::format() acting as a KMail::Interface::BodyPartFormatter!" << endl;
00059 return AsIcon;
00060 }
00061
00062 bool process( KMail::ObjectTreeParser *, partNode *, KMail::ProcessResult & result ) const {
00063 result.setNeverDisplayInline( true );
00064 return false;
00065 }
00066 static const KMail::BodyPartFormatter * create() {
00067 if ( !self )
00068 self = new AnyTypeBodyPartFormatter();
00069 return self;
00070 }
00071 };
00072
00073 const AnyTypeBodyPartFormatter * AnyTypeBodyPartFormatter::self = 0;
00074
00075
00076 class ImageTypeBodyPartFormatter : public KMail::BodyPartFormatter {
00077 static const ImageTypeBodyPartFormatter * self;
00078 public:
00079 bool process( KMail::ObjectTreeParser *, partNode *, KMail::ProcessResult & result ) const {
00080 result.setIsImage( true );
00081 return false;
00082 }
00083 static const KMail::BodyPartFormatter * create() {
00084 if ( !self )
00085 self = new ImageTypeBodyPartFormatter();
00086 return self;
00087 }
00088 };
00089
00090 const ImageTypeBodyPartFormatter * ImageTypeBodyPartFormatter::self = 0;
00091
00092 #define CREATE_BODY_PART_FORMATTER(subtype) \
00093 class subtype##BodyPartFormatter : public KMail::BodyPartFormatter { \
00094 static const subtype##BodyPartFormatter * self; \
00095 public: \
00096 bool process( KMail::ObjectTreeParser *, partNode *, KMail::ProcessResult & ) const; \
00097 static const KMail::BodyPartFormatter * create() { \
00098 if ( !self ) \
00099 self = new subtype##BodyPartFormatter(); \
00100 return self; \
00101 } \
00102 }; \
00103 \
00104 const subtype##BodyPartFormatter * subtype##BodyPartFormatter::self; \
00105 \
00106 bool subtype##BodyPartFormatter::process( KMail::ObjectTreeParser * otp, partNode * node, KMail::ProcessResult & result ) const { \
00107 return otp->process##subtype##Subtype( node, result ); \
00108 }
00109
00110 CREATE_BODY_PART_FORMATTER(TextPlain)
00111 CREATE_BODY_PART_FORMATTER(TextHtml)
00112
00113
00114 CREATE_BODY_PART_FORMATTER(ApplicationOctetStream)
00115 CREATE_BODY_PART_FORMATTER(ApplicationPkcs7Mime)
00116 CREATE_BODY_PART_FORMATTER(ApplicationChiasmusText)
00117
00118 CREATE_BODY_PART_FORMATTER(ApplicationMsTnef)
00119
00120 CREATE_BODY_PART_FORMATTER(MessageRfc822)
00121
00122 CREATE_BODY_PART_FORMATTER(MultiPartMixed)
00123 CREATE_BODY_PART_FORMATTER(MultiPartAlternative)
00124 CREATE_BODY_PART_FORMATTER(MultiPartSigned)
00125 CREATE_BODY_PART_FORMATTER(MultiPartEncrypted)
00126
00127 typedef TextPlainBodyPartFormatter ApplicationPgpBodyPartFormatter;
00128
00129
00130 #undef CREATE_BODY_PART_FORMATTER
00131 }
00132
00133
00134 void KMail::BodyPartFormatterFactoryPrivate::kmail_create_builtin_bodypart_formatters( KMail::BodyPartFormatterFactoryPrivate::TypeRegistry * reg ) {
00135 if ( !reg ) return;
00136 (*reg)["application"]["octet-stream"] = new AnyTypeBodyPartFormatter();
00137 }
00138
00139 typedef const KMail::BodyPartFormatter * (*BodyPartFormatterCreator)();
00140
00141 struct SubtypeBuiltin {
00142 const char * subtype;
00143 BodyPartFormatterCreator create;
00144 };
00145
00146 static const SubtypeBuiltin applicationSubtypeBuiltins[] = {
00147 { "octet-stream", &ApplicationOctetStreamBodyPartFormatter::create },
00148 { "pkcs7-mime", &ApplicationPkcs7MimeBodyPartFormatter::create },
00149 { "x-pkcs7-mime", &ApplicationPkcs7MimeBodyPartFormatter::create },
00150 { "vnd.de.bund.bsi.chiasmus-text", &ApplicationChiasmusTextBodyPartFormatter::create },
00151 { "pgp", &ApplicationPgpBodyPartFormatter::create },
00152 { "ms-tnef", &ApplicationMsTnefBodyPartFormatter::create }
00153 };
00154
00155 static const SubtypeBuiltin textSubtypeBuiltins[] = {
00156 { "html", &TextHtmlBodyPartFormatter::create },
00157
00158 { "x-vcard", &AnyTypeBodyPartFormatter::create },
00159 { "vcard", &AnyTypeBodyPartFormatter::create },
00160 { "rtf", &AnyTypeBodyPartFormatter::create },
00161 { "*", &TextPlainBodyPartFormatter::create },
00162 };
00163
00164 static const SubtypeBuiltin multipartSubtypeBuiltins[] = {
00165 { "mixed", &MultiPartMixedBodyPartFormatter::create },
00166 { "alternative", &MultiPartAlternativeBodyPartFormatter::create },
00167
00168
00169
00170 { "signed", &MultiPartSignedBodyPartFormatter::create },
00171 { "encrypted", &MultiPartEncryptedBodyPartFormatter::create },
00172
00173 };
00174
00175 static const SubtypeBuiltin messageSubtypeBuiltins[] = {
00176 { "rfc822", &MessageRfc822BodyPartFormatter::create },
00177 };
00178
00179 static const SubtypeBuiltin imageSubtypeBuiltins[] = {
00180 { "*", &ImageTypeBodyPartFormatter::create },
00181 };
00182
00183 static const SubtypeBuiltin anySubtypeBuiltins[] = {
00184 { "*", &AnyTypeBodyPartFormatter::create },
00185 };
00186
00187 #ifdef DIM
00188 #undef DIM
00189 #endif
00190 #define DIM(x) sizeof(x) / sizeof(*x)
00191
00192 static const struct {
00193 const char * type;
00194 const SubtypeBuiltin * subtypes;
00195 unsigned int num_subtypes;
00196 } builtins[] = {
00197 { "application", applicationSubtypeBuiltins, DIM(applicationSubtypeBuiltins) },
00198 { "text", textSubtypeBuiltins, DIM(textSubtypeBuiltins) },
00199 { "multipart", multipartSubtypeBuiltins, DIM(multipartSubtypeBuiltins) },
00200 { "message", messageSubtypeBuiltins, DIM(messageSubtypeBuiltins) },
00201 { "image", imageSubtypeBuiltins, DIM(imageSubtypeBuiltins) },
00202
00203
00204
00205 { "*", anySubtypeBuiltins, DIM(anySubtypeBuiltins) },
00206 };
00207
00208 #undef DIM
00209
00210 const KMail::BodyPartFormatter * KMail::BodyPartFormatter::createFor( int type, int subtype ) {
00211 DwString t, st;
00212 DwTypeEnumToStr( type, t );
00213 DwSubtypeEnumToStr( subtype, st );
00214 return createFor( t.c_str(), st.c_str() );
00215 }
00216
00217 static const KMail::BodyPartFormatter * createForText( const char * subtype ) {
00218 if ( subtype && *subtype )
00219 switch ( subtype[0] ) {
00220 case 'h':
00221 case 'H':
00222 if ( kasciistricmp( subtype, "html" ) == 0 )
00223 return TextHtmlBodyPartFormatter::create();
00224 break;
00225 case 'r':
00226 case 'R':
00227 if ( kasciistricmp( subtype, "rtf" ) == 0 )
00228 return AnyTypeBodyPartFormatter::create();
00229 break;
00230 case 'x':
00231 case 'X':
00232 case 'v':
00233 case 'V':
00234 if ( kasciistricmp( subtype, "x-vcard" ) == 0 ||
00235 kasciistricmp( subtype, "vcard" ) == 0 )
00236 return AnyTypeBodyPartFormatter::create();
00237 break;
00238 }
00239
00240 return TextPlainBodyPartFormatter::create();
00241 }
00242
00243 static const KMail::BodyPartFormatter * createForImage( const char * ) {
00244 return ImageTypeBodyPartFormatter::create();
00245 }
00246
00247 static const KMail::BodyPartFormatter * createForMessage( const char * subtype ) {
00248 if ( kasciistricmp( subtype, "rfc822" ) == 0 )
00249 return MessageRfc822BodyPartFormatter::create();
00250 return AnyTypeBodyPartFormatter::create();
00251 }
00252
00253 static const KMail::BodyPartFormatter * createForMultiPart( const char * subtype ) {
00254 if ( subtype && *subtype )
00255 switch ( subtype[0] ) {
00256 case 'a':
00257 case 'A':
00258 if ( kasciistricmp( subtype, "alternative" ) == 0 )
00259 return MultiPartAlternativeBodyPartFormatter::create();
00260 break;
00261 case 'e':
00262 case 'E':
00263 if ( kasciistricmp( subtype, "encrypted" ) == 0 )
00264 return MultiPartEncryptedBodyPartFormatter::create();
00265 break;
00266 case 's':
00267 case 'S':
00268 if ( kasciistricmp( subtype, "signed" ) == 0 )
00269 return MultiPartSignedBodyPartFormatter::create();
00270 break;
00271 }
00272
00273 return MultiPartMixedBodyPartFormatter::create();
00274 }
00275
00276 static const KMail::BodyPartFormatter * createForApplication( const char * subtype ) {
00277 if ( subtype && *subtype )
00278 switch ( subtype[0] ) {
00279 case 'p':
00280 case 'P':
00281 if ( kasciistricmp( subtype, "pgp" ) == 0 )
00282 return ApplicationPgpBodyPartFormatter::create();
00283
00284 case 'x':
00285 case 'X':
00286 if ( kasciistricmp( subtype, "pkcs7-mime" ) == 0 ||
00287 kasciistricmp( subtype, "x-pkcs7-mime" ) == 0 )
00288 return ApplicationPkcs7MimeBodyPartFormatter::create();
00289 break;
00290 case 'm':
00291 case 'M':
00292 if ( kasciistricmp( subtype, "ms-tnef" ) == 0 )
00293 return ApplicationMsTnefBodyPartFormatter::create();
00294 break;
00295 case 'v':
00296 case 'V':
00297 if ( kasciistricmp( subtype, "vnd.de.bund.bsi.chiasmus-text") == 0)
00298 return ApplicationChiasmusTextBodyPartFormatter::create();
00299 break;
00300 }
00301
00302 return AnyTypeBodyPartFormatter::create();
00303 }
00304
00305
00306 const KMail::BodyPartFormatter * KMail::BodyPartFormatter::createFor( const char * type, const char * subtype ) {
00307 if ( type && *type )
00308 switch ( type[0] ) {
00309 case 'a':
00310 case 'A':
00311 if ( kasciistricmp( type, "application" ) == 0 )
00312 return createForApplication( subtype );
00313 break;
00314 case 'i':
00315 case 'I':
00316 if ( kasciistricmp( type, "image" ) == 0 )
00317 return createForImage( subtype );
00318 break;
00319 case 'm':
00320 case 'M':
00321 if ( kasciistricmp( type, "multipart" ) == 0 )
00322 return createForMultiPart( subtype );
00323 else if ( kasciistricmp( type, "message" ) == 0 )
00324 return createForMessage( subtype );
00325 break;
00326 case 't':
00327 case 'T':
00328 if ( kasciistricmp( type, "text" ) == 0 )
00329 return createForText( subtype );
00330 break;
00331 }
00332
00333 return AnyTypeBodyPartFormatter::create();
00334 }
00335