diff options
Diffstat (limited to 'em-format/em-format.c')
-rw-r--r-- | em-format/em-format.c | 415 |
1 files changed, 235 insertions, 180 deletions
diff --git a/em-format/em-format.c b/em-format/em-format.c index 74bcb31e43..5892bd772d 100644 --- a/em-format/em-format.c +++ b/em-format/em-format.c @@ -58,10 +58,6 @@ struct _EMFormatCache { static void emf_builtin_init(EMFormatClass *); -static const EMFormatHandler *emf_find_handler(EMFormat *emf, const gchar *mime_type); -static void emf_format_clone(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, EMFormat *emfsource); -static void emf_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid); -static gboolean emf_busy(EMFormat *emf); enum { EMF_COMPLETE, EMF_LAST_SIGNAL @@ -93,6 +89,19 @@ emf_insert_cache(EMFormat *emf, const gchar *partid) } static void +emf_clone_inlines (gpointer key, gpointer val, gpointer data) +{ + struct _EMFormatCache *emfc = val, *new; + + new = emf_insert_cache((EMFormat *)data, emfc->partid); + new->state = emfc->state; + if (emfc->valid) + new->valid = camel_cipher_validity_clone(emfc->valid); + if (emfc->secured) + g_object_ref ((new->secured = emfc->secured)); +} + +static void emf_finalize (GObject *object) { EMFormat *emf = EM_FORMAT (object); @@ -117,6 +126,114 @@ emf_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } +static const EMFormatHandler * +emf_find_handler (EMFormat *emf, + const gchar *mime_type) +{ + EMFormatClass *emfc = (EMFormatClass *)G_OBJECT_GET_CLASS(emf); + + return g_hash_table_lookup (emfc->type_handlers, mime_type); +} + +static void +emf_format_clone (EMFormat *emf, + CamelFolder *folder, + const gchar *uid, + CamelMimeMessage *msg, + EMFormat *emfsource) +{ + em_format_clear_puri_tree(emf); + + if (emf != emfsource) { + g_hash_table_remove_all(emf->inline_table); + if (emfsource) { + GList *link; + + /* We clone the current state here */ + g_hash_table_foreach(emfsource->inline_table, emf_clone_inlines, emf); + emf->mode = emfsource->mode; + g_free(emf->charset); + emf->charset = g_strdup(emfsource->charset); + g_free (emf->default_charset); + emf->default_charset = g_strdup (emfsource->default_charset); + + em_format_clear_headers(emf); + + link = g_queue_peek_head_link (&emfsource->header_list); + while (link != NULL) { + struct _EMFormatHeader *h = link->data; + em_format_add_header (emf, h->name, h->flags); + link = g_list_next (link); + } + } + } + + /* what a mess */ + if (folder != emf->folder) { + if (emf->folder) + g_object_unref (emf->folder); + if (folder) + g_object_ref (folder); + emf->folder = folder; + } + + if (uid != emf->uid) { + g_free(emf->uid); + emf->uid = g_strdup(uid); + } + + if (msg != emf->message) { + if (emf->message) + g_object_unref (emf->message); + if (msg) + g_object_ref (msg); + emf->message = msg; + } + + g_string_truncate(emf->part_id, 0); + if (folder != NULL) + /* TODO build some string based on the folder name/location? */ + g_string_append_printf(emf->part_id, ".%p", (gpointer) folder); + if (uid != NULL) + g_string_append_printf(emf->part_id, ".%s", uid); +} + +static void +emf_format_secure (EMFormat *emf, + CamelStream *stream, + CamelMimePart *part, + CamelCipherValidity *valid) +{ + CamelCipherValidity *save = emf->valid_parent; + gint len; + + /* Note that this also requires support from higher up in the class chain + - validity needs to be cleared when you start output + - also needs to be cleared (but saved) whenever you start a new message. */ + + if (emf->valid == NULL) { + emf->valid = valid; + } else { + camel_dlist_addtail(&emf->valid_parent->children, (CamelDListNode *)valid); + camel_cipher_validity_envelope(emf->valid_parent, valid); + } + + emf->valid_parent = valid; + + len = emf->part_id->len; + g_string_append_printf(emf->part_id, ".secured"); + em_format_part(emf, stream, part); + g_string_truncate(emf->part_id, len); + + emf->valid_parent = save; +} + +static gboolean +emf_busy (EMFormat *emf) +{ + return FALSE; +} + static gboolean emf_is_inline (EMFormat *emf, const gchar *part_id, @@ -251,7 +368,8 @@ em_format_get_type (void) * Use a mime type of "foo/ *" to insert a fallback handler for type "foo". **/ void -em_format_class_add_handler(EMFormatClass *emfc, EMFormatHandler *info) +em_format_class_add_handler (EMFormatClass *emfc, + EMFormatHandler *info) { d(printf("adding format handler to '%s' '%s'\n", g_type_name_from_class((GTypeClass *)emfc), info->mime_type)); info->old = g_hash_table_lookup(emfc->type_handlers, info->mime_type); @@ -262,6 +380,7 @@ struct _class_handlers { EMFormatClass *old; EMFormatClass *new; }; + static void merge_missing (gpointer key, gpointer value, gpointer userdata) { @@ -299,7 +418,8 @@ em_format_merge_handler(EMFormat *new, EMFormat *old) * added. **/ void -em_format_class_remove_handler(EMFormatClass *emfc, EMFormatHandler *info) +em_format_class_remove_handler (EMFormatClass *emfc, + EMFormatHandler *info) { EMFormatHandler *current; @@ -320,6 +440,15 @@ em_format_class_remove_handler(EMFormatClass *emfc, EMFormatHandler *info) } } +/** + * em_format_find_handler: + * @emf: + * @mime_type: + * + * Find a format handler by @mime_type. + * + * Return value: NULL if no handler is available. + **/ const EMFormatHandler * em_format_find_handler (EMFormat *emf, const gchar *mime_type) @@ -331,24 +460,8 @@ em_format_find_handler (EMFormat *emf, class = EM_FORMAT_GET_CLASS (emf); g_return_val_if_fail (class->find_handler != NULL, NULL); - return class->find_handler (emf, mime_type); -} -/** - * em_format_find_handler: - * @emf: - * @mime_type: - * - * Find a format handler by @mime_type. - * - * Return value: NULL if no handler is available. - **/ -static const EMFormatHandler * -emf_find_handler(EMFormat *emf, const gchar *mime_type) -{ - EMFormatClass *emfc = (EMFormatClass *)G_OBJECT_GET_CLASS(emf); - - return g_hash_table_lookup(emfc->type_handlers, mime_type); + return class->find_handler (emf, mime_type); } /** @@ -363,7 +476,8 @@ emf_find_handler(EMFormat *emf, const gchar *mime_type) * Return value: **/ const EMFormatHandler * -em_format_fallback_handler(EMFormat *emf, const gchar *mime_type) +em_format_fallback_handler (EMFormat *emf, + const gchar *mime_type) { gchar *mime, *s; @@ -616,7 +730,7 @@ emf_clear_puri_node (GNode *node) * data. **/ void -em_format_clear_puri_tree(EMFormat *emf) +em_format_clear_puri_tree (EMFormat *emf) { if (emf->pending_uri_table == NULL) emf->pending_uri_table = @@ -640,7 +754,10 @@ em_format_clear_puri_tree(EMFormat *emf) /* use mime_type == NULL to force showing as application/octet-stream */ void -em_format_part_as(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const gchar *mime_type) +em_format_part_as (EMFormat *emf, + CamelStream *stream, + CamelMimePart *part, + const gchar *mime_type) { const EMFormatHandler *handle = NULL; const gchar *snoop_save = emf->snoop_mime_type, *tmp; @@ -704,124 +821,21 @@ finish: } void -em_format_part(EMFormat *emf, CamelStream *stream, CamelMimePart *part) +em_format_part (EMFormat *emf, + CamelStream *stream, + CamelMimePart *part) { gchar *mime_type; CamelDataWrapper *dw; - dw = camel_medium_get_content ((CamelMedium *)part); - mime_type = camel_data_wrapper_get_mime_type(dw); - if (mime_type) { - camel_strdown(mime_type); - em_format_part_as(emf, stream, part, mime_type); - g_free(mime_type); + dw = camel_medium_get_content (CAMEL_MEDIUM (part)); + mime_type = camel_data_wrapper_get_mime_type (dw); + if (mime_type != NULL) { + camel_strdown (mime_type); + em_format_part_as (emf, stream, part, mime_type); + g_free (mime_type); } else - em_format_part_as(emf, stream, part, "text/plain"); -} - -static void -emf_clone_inlines(gpointer key, gpointer val, gpointer data) -{ - struct _EMFormatCache *emfc = val, *new; - - new = emf_insert_cache((EMFormat *)data, emfc->partid); - new->state = emfc->state; - if (emfc->valid) - new->valid = camel_cipher_validity_clone(emfc->valid); - if (emfc->secured) - g_object_ref ((new->secured = emfc->secured)); -} - -static void -emf_format_clone(EMFormat *emf, CamelFolder *folder, const gchar *uid, CamelMimeMessage *msg, EMFormat *emfsource) -{ - em_format_clear_puri_tree(emf); - - if (emf != emfsource) { - g_hash_table_remove_all(emf->inline_table); - if (emfsource) { - GList *link; - - /* We clone the current state here */ - g_hash_table_foreach(emfsource->inline_table, emf_clone_inlines, emf); - emf->mode = emfsource->mode; - g_free(emf->charset); - emf->charset = g_strdup(emfsource->charset); - g_free (emf->default_charset); - emf->default_charset = g_strdup (emfsource->default_charset); - - em_format_clear_headers(emf); - - link = g_queue_peek_head_link (&emfsource->header_list); - while (link != NULL) { - struct _EMFormatHeader *h = link->data; - em_format_add_header (emf, h->name, h->flags); - link = g_list_next (link); - } - } - } - - /* what a mess */ - if (folder != emf->folder) { - if (emf->folder) - g_object_unref (emf->folder); - if (folder) - g_object_ref (folder); - emf->folder = folder; - } - - if (uid != emf->uid) { - g_free(emf->uid); - emf->uid = g_strdup(uid); - } - - if (msg != emf->message) { - if (emf->message) - g_object_unref (emf->message); - if (msg) - g_object_ref (msg); - emf->message = msg; - } - - g_string_truncate(emf->part_id, 0); - if (folder != NULL) - /* TODO build some string based on the folder name/location? */ - g_string_append_printf(emf->part_id, ".%p", (gpointer) folder); - if (uid != NULL) - g_string_append_printf(emf->part_id, ".%s", uid); -} - -static void -emf_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart *part, CamelCipherValidity *valid) -{ - CamelCipherValidity *save = emf->valid_parent; - gint len; - - /* Note that this also requires support from higher up in the class chain - - validity needs to be cleared when you start output - - also needs to be cleared (but saved) whenever you start a new message. */ - - if (emf->valid == NULL) { - emf->valid = valid; - } else { - camel_dlist_addtail(&emf->valid_parent->children, (CamelDListNode *)valid); - camel_cipher_validity_envelope(emf->valid_parent, valid); - } - - emf->valid_parent = valid; - - len = emf->part_id->len; - g_string_append_printf(emf->part_id, ".secured"); - em_format_part(emf, stream, part); - g_string_truncate(emf->part_id, len); - - emf->valid_parent = save; -} - -static gboolean -emf_busy(EMFormat *emf) -{ - return FALSE; + em_format_part_as (emf, stream, part, "text/plain"); } /** @@ -856,6 +870,7 @@ em_format_format_clone (EMFormat *emf, class = EM_FORMAT_GET_CLASS (emf); g_return_if_fail (class->format_clone != NULL); + class->format_clone (emf, folder, uid, message, source); } @@ -883,22 +898,23 @@ em_format_redraw (EMFormat *emf) * @emf: * @type: * - * Set display mode, EM_FORMAT_SOURCE, EM_FORMAT_ALLHEADERS, or - * EM_FORMAT_NORMAL. + * Set display mode, EM_FORMAT_MODE_SOURCE, EM_FORMAT_MODE_ALLHEADERS, + * or EM_FORMAT_MODE_NORMAL. **/ void -em_format_set_mode(EMFormat *emf, em_format_mode_t type) +em_format_set_mode (EMFormat *emf, + EMFormatMode mode) { g_return_if_fail (EM_IS_FORMAT (emf)); - if (emf->mode == type) + if (emf->mode == mode) return; - emf->mode = type; + emf->mode = mode; /* force redraw if type changed afterwards */ - if (emf->message) - em_format_redraw(emf); + if (emf->message != NULL) + em_format_redraw (emf); } /** @@ -910,7 +926,8 @@ em_format_set_mode(EMFormat *emf, em_format_mode_t type) * required. **/ void -em_format_set_charset(EMFormat *emf, const gchar *charset) +em_format_set_charset (EMFormat *emf, + const gchar *charset) { if ((emf->charset && charset && g_ascii_strcasecmp(emf->charset, charset) == 0) || (emf->charset == NULL && charset == NULL) @@ -930,11 +947,12 @@ em_format_set_charset(EMFormat *emf, const gchar *charset) * @charset: * * Set the fallback, default system charset to use when no other charsets - * are present. Message will be redisplayed if required (and sometimes redisplayed - * when it isn't). + * are present. Message will be redisplayed if required (and sometimes + * redisplayed when it isn't). **/ void -em_format_set_default_charset(EMFormat *emf, const gchar *charset) +em_format_set_default_charset (EMFormat *emf, + const gchar *charset) { if ((emf->default_charset && charset && g_ascii_strcasecmp(emf->default_charset, charset) == 0) || (emf->default_charset == NULL && charset == NULL) @@ -989,13 +1007,16 @@ static const struct { * From, Reply-To, To, Cc, Bcc, Subject and Date. **/ void -em_format_default_headers(EMFormat *emf) +em_format_default_headers (EMFormat *emf) { - gint i; + gint ii; - em_format_clear_headers(emf); - for (i = 0; i < G_N_ELEMENTS (default_headers); i++) - em_format_add_header(emf, default_headers[i].name, default_headers[i].flags); + em_format_clear_headers (emf); + + for (ii = 0; ii < G_N_ELEMENTS (default_headers); ii++) + em_format_add_header ( + emf, default_headers[ii].name, + default_headers[ii].flags); } /** @@ -1009,7 +1030,10 @@ em_format_default_headers(EMFormat *emf) * headers included in this list will be shown using special * formatting routines. **/ -void em_format_add_header(EMFormat *emf, const gchar *name, guint32 flags) +void +em_format_add_header (EMFormat *emf, + const gchar *name, + guint32 flags) { EMFormatHeader *h; @@ -1035,7 +1059,9 @@ void em_format_add_header(EMFormat *emf, const gchar *name, guint32 flags) * * Return value: TRUE/FALSE **/ -gint em_format_is_attachment(EMFormat *emf, CamelMimePart *part) +gint +em_format_is_attachment (EMFormat *emf, + CamelMimePart *part) { /*CamelContentType *ct = camel_mime_part_get_content_type(part);*/ CamelDataWrapper *dw = camel_medium_get_content ((CamelMedium *)part); @@ -1058,7 +1084,7 @@ gint em_format_is_attachment(EMFormat *emf, CamelMimePart *part) * em_format_is_inline: * @emf: * @part: - * @partid: format->part_id part id of this part. + * @part_id: format->part_id part id of this part. * @handle: handler for this part * * Returns true if the part should be displayed inline. Any part with @@ -1091,20 +1117,26 @@ em_format_is_inline (EMFormat *emf, /** * em_format_set_inline: * @emf: - * @partid: id of part + * @part_id: id of part * @state: * * Force the attachment @part to be expanded or hidden explictly to match * @state. This is used only to record the change for a redraw or * cloned layout render and does not force a redraw. **/ -void em_format_set_inline(EMFormat *emf, const gchar *partid, gint state) +void +em_format_set_inline (EMFormat *emf, + const gchar *part_id, + gint state) { struct _EMFormatCache *emfc; - emfc = g_hash_table_lookup(emf->inline_table, partid); + g_return_if_fail (EM_IS_FORMAT (emf)); + g_return_if_fail (part_id != NULL); + + emfc = g_hash_table_lookup(emf->inline_table, part_id); if (emfc == NULL) { - emfc = emf_insert_cache(emf, partid); + emfc = emf_insert_cache(emf, part_id); } else if (emfc->state != INLINE_UNSET && (emfc->state & 1) == state) return; @@ -1119,7 +1151,7 @@ em_format_format_attachment (EMFormat *emf, CamelStream *stream, CamelMimePart *mime_part, const gchar *mime_type, - const struct _EMFormatHandler *info) + const EMFormatHandler *info) { EMFormatClass *class; @@ -1131,6 +1163,7 @@ em_format_format_attachment (EMFormat *emf, class = EM_FORMAT_GET_CLASS (emf); g_return_if_fail (class->format_attachment != NULL); + class->format_attachment (emf, stream, mime_part, mime_type, info); } @@ -1173,6 +1206,7 @@ em_format_format_secure (EMFormat *emf, class = EM_FORMAT_GET_CLASS (emf); g_return_if_fail (class->format_secure != NULL); + class->format_secure (emf, stream, mime_part, valid); if (emf->valid_parent == NULL && emf->valid != NULL) { @@ -1194,6 +1228,7 @@ em_format_format_source (EMFormat *emf, class = EM_FORMAT_GET_CLASS (emf); g_return_if_fail (class->format_source != NULL); + class->format_source (emf, stream, mime_part); } @@ -1206,12 +1241,15 @@ em_format_busy (EMFormat *emf) class = EM_FORMAT_GET_CLASS (emf); g_return_val_if_fail (class->busy != NULL, FALSE); + return class->busy (emf); } /* should this be virtual? */ void -em_format_format_content(EMFormat *emf, CamelStream *stream, CamelMimePart *part) +em_format_format_content (EMFormat *emf, + CamelStream *stream, + CamelMimePart *part) { CamelDataWrapper *dw = camel_medium_get_content ((CamelMedium *)part); @@ -1230,7 +1268,9 @@ em_format_format_content(EMFormat *emf, CamelStream *stream, CamelMimePart *part * Decode/output a part's content to @stream. **/ void -em_format_format_text(EMFormat *emf, CamelStream *stream, CamelDataWrapper *dw) +em_format_format_text (EMFormat *emf, + CamelStream *stream, + CamelDataWrapper *dw) { CamelStream *filter_stream; CamelMimeFilter *filter; @@ -1293,7 +1333,7 @@ em_format_format_text(EMFormat *emf, CamelStream *stream, CamelDataWrapper *dw) g_object_unref (gconf); size = camel_data_wrapper_decode_to_stream ( - emf->mode == EM_FORMAT_SOURCE ? + emf->mode == EM_FORMAT_MODE_SOURCE ? (CamelDataWrapper *) dw : camel_medium_get_content ((CamelMedium *)dw), (CamelStream *)filter_stream, NULL); @@ -1323,7 +1363,8 @@ em_format_format_text(EMFormat *emf, CamelStream *stream, CamelDataWrapper *dw) * Return value: **/ gchar * -em_format_describe_part(CamelMimePart *part, const gchar *mime_type) +em_format_describe_part (CamelMimePart *part, + const gchar *mime_type) { GString *stext; const gchar *filename, *description; @@ -1346,7 +1387,8 @@ em_format_describe_part(CamelMimePart *part, const gchar *mime_type) } static void -add_validity_found (EMFormat *emf, CamelCipherValidity *valid) +add_validity_found (EMFormat *emf, + CamelCipherValidity *valid) { g_return_if_fail (emf != NULL); @@ -1594,10 +1636,12 @@ emf_multipart_encrypted (EMFormat *emf, } static void -emf_write_related(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri) +emf_write_related (EMFormat *emf, + CamelStream *stream, + EMFormatPURI *puri) { - em_format_format_content(emf, stream, puri->part); - camel_stream_close(stream, NULL); + em_format_format_content (emf, stream, puri->part); + camel_stream_close (stream, NULL); } /* RFC 2387 */ @@ -1882,11 +1926,15 @@ emf_message_deliverystatus (EMFormat *emf, const EMFormatHandler *info, gboolean is_fallback) { - em_format_format_text(emf, stream, (CamelDataWrapper *)part); + em_format_format_text (emf, stream, (CamelDataWrapper *)part); } static void -emf_inlinepgp_signed(EMFormat *emf, CamelStream *stream, CamelMimePart *ipart, EMFormatHandler *info) +emf_inlinepgp_signed (EMFormat *emf, + CamelStream *stream, + CamelMimePart *ipart, + const EMFormatHandler *info, + gboolean is_fallback) { CamelStream *filtered_stream; CamelMimeFilterPgp *pgp_filter; @@ -1976,7 +2024,11 @@ emf_inlinepgp_signed(EMFormat *emf, CamelStream *stream, CamelMimePart *ipart, E } static void -emf_inlinepgp_encrypted(EMFormat *emf, CamelStream *stream, CamelMimePart *ipart, EMFormatHandler *info) +emf_inlinepgp_encrypted (EMFormat *emf, + CamelStream *stream, + CamelMimePart *ipart, + const EMFormatHandler *info, + gboolean is_fallback) { CamelCipherContext *cipher; CamelCipherValidity *valid; @@ -2054,17 +2106,20 @@ static EMFormatHandler type_builtin_table[] = { #endif /* internal types */ - { (gchar *) "application/x-inlinepgp-signed", (EMFormatFunc)emf_inlinepgp_signed }, - { (gchar *) "application/x-inlinepgp-encrypted", (EMFormatFunc)emf_inlinepgp_encrypted }, + { (gchar *) "application/x-inlinepgp-signed", emf_inlinepgp_signed }, + { (gchar *) "application/x-inlinepgp-encrypted", emf_inlinepgp_encrypted }, }; static void -emf_builtin_init(EMFormatClass *class) +emf_builtin_init (EMFormatClass *class) { - gint i; + gint ii; - for (i = 0; i < G_N_ELEMENTS (type_builtin_table); i++) - g_hash_table_insert(class->type_handlers, type_builtin_table[i].mime_type, &type_builtin_table[i]); + for (ii = 0; ii < G_N_ELEMENTS (type_builtin_table); ii++) + g_hash_table_insert ( + class->type_handlers, + type_builtin_table[ii].mime_type, + &type_builtin_table[ii]); } /** |