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