/* * e-mail-formatter-attachment.c * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, see . * */ #include "evolution-config.h" #include #include #include #include "e-mail-formatter-extension.h" #include "e-mail-inline-filter.h" #include "e-mail-part-attachment.h" #include "e-mail-part-utils.h" #define d(x) typedef EMailFormatterExtension EMailFormatterAttachment; typedef EMailFormatterExtensionClass EMailFormatterAttachmentClass; GType e_mail_formatter_attachment_get_type (void); G_DEFINE_TYPE ( EMailFormatterAttachment, e_mail_formatter_attachment, E_TYPE_MAIL_FORMATTER_EXTENSION) static const gchar *formatter_mime_types[] = { E_MAIL_PART_ATTACHMENT_MIME_TYPE, "application/vnd.evolution.attachment-button", NULL }; static gboolean emfe_attachment_format (EMailFormatterExtension *extension, EMailFormatter *formatter, EMailFormatterContext *context, EMailPart *part, GOutputStream *stream, GCancellable *cancellable) { gchar *text, *html; gchar *button_id; EMailExtensionRegistry *registry; GQueue *extensions; EMailPartAttachment *empa; CamelMimePart *mime_part; CamelMimeFilterToHTMLFlags flags; GOutputStream *content_stream = NULL; GString *buffer; gint icon_width, icon_height; gchar *icon_uri; gpointer attachment_ptr = NULL; const gchar *attachment_part_id; const gchar *part_id; g_return_val_if_fail (E_IS_MAIL_PART_ATTACHMENT (part), FALSE); empa = (EMailPartAttachment *) part; part_id = e_mail_part_get_id (part); if ((context->mode == E_MAIL_FORMATTER_MODE_NORMAL) || (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) || (context->mode == E_MAIL_FORMATTER_MODE_ALL_HEADERS)) { EAttachment *attachment; GList *head, *link; attachment = e_mail_part_attachment_ref_attachment (E_MAIL_PART_ATTACHMENT (part)); attachment_ptr = attachment; head = g_queue_peek_head_link (&part->validities); for (link = head; link != NULL; link = g_list_next (link)) { EMailPartValidityPair *pair = link->data; if (pair == NULL) continue; if ((pair->validity_type & E_MAIL_PART_VALIDITY_SIGNED) != 0) e_attachment_set_signed ( attachment, pair->validity->sign.status); if ((pair->validity_type & E_MAIL_PART_VALIDITY_ENCRYPTED) != 0) e_attachment_set_encrypted ( attachment, pair->validity->encrypt.status); } e_attachment_set_initially_shown (attachment, e_mail_part_should_show_inline (part)); e_mail_formatter_claim_attachment (formatter, attachment); g_object_unref (attachment); } registry = e_mail_formatter_get_extension_registry (formatter); extensions = e_mail_extension_registry_get_for_mime_type ( registry, empa->snoop_mime_type); if (extensions == NULL) extensions = e_mail_extension_registry_get_fallback ( registry, empa->snoop_mime_type); /* If the attachment is requested as RAW, then call the * handler directly and do not append any other code. */ if ((context->mode == E_MAIL_FORMATTER_MODE_RAW) || (context->mode == E_MAIL_FORMATTER_MODE_PRINTING)) { GList *head, *link; gboolean success = FALSE; if (extensions == NULL) return FALSE; if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) { gchar *name; EAttachment *attachment; GFileInfo *file_info; const gchar *display_name; gchar *description; attachment = e_mail_part_attachment_ref_attachment ( E_MAIL_PART_ATTACHMENT (part)); file_info = e_attachment_ref_file_info (attachment); if (file_info) display_name = g_file_info_get_display_name (file_info); else display_name = ""; description = e_attachment_dup_description (attachment); if (description != NULL && *description != '\0') { name = g_strdup_printf ( "

Attachment: %s (%s)

\n", description, display_name); } else { name = g_strdup_printf ( "

Attachment: %s

\n", display_name); } g_output_stream_write_all ( stream, name, strlen (name), NULL, cancellable, NULL); g_free (description); g_free (name); g_clear_object (&attachment); g_clear_object (&file_info); } head = g_queue_peek_head_link (extensions); for (link = head; link != NULL; link = g_list_next (link)) { success = e_mail_formatter_extension_format ( E_MAIL_FORMATTER_EXTENSION (link->data), formatter, context, part, stream, cancellable); if (success) break; } return success; } /* E_MAIL_FORMATTER_MODE_NORMAL: */ mime_part = e_mail_part_ref_mime_part (part); text = e_mail_part_describe (mime_part, empa->snoop_mime_type); flags = e_mail_formatter_get_text_format_flags (formatter); html = camel_text_to_html ( text, flags & CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS, 0); g_free (text); g_object_unref (mime_part); if (empa->part_id_with_attachment) attachment_part_id = empa->part_id_with_attachment; else attachment_part_id = part_id; button_id = g_strconcat (attachment_part_id, ".attachment_button", NULL); if (!gtk_icon_size_lookup (GTK_ICON_SIZE_BUTTON, &icon_width, &icon_height)) { icon_width = 16; icon_height = 16; } if (extensions != NULL) { gboolean success = FALSE; content_stream = g_memory_output_stream_new_resizable (); if (empa->part_id_with_attachment != NULL) { EMailPart *attachment_view_part; attachment_view_part = e_mail_part_list_ref_part ( context->part_list, empa->part_id_with_attachment); /* Avoid recursion. */ if (attachment_view_part == part) g_clear_object (&attachment_view_part); if (attachment_view_part != NULL) { success = e_mail_formatter_format_as ( formatter, context, attachment_view_part, content_stream, NULL, cancellable); g_object_unref (attachment_view_part); } } else { GList *head, *link; head = g_queue_peek_head_link (extensions); for (link = head; link != NULL; link = g_list_next (link)) { success = e_mail_formatter_extension_format ( E_MAIL_FORMATTER_EXTENSION (link->data), formatter, context, part, content_stream, cancellable); if (success) break; } } e_mail_part_attachment_set_expandable (empa, success); } icon_uri = e_mail_part_build_uri ( e_mail_part_list_get_folder (context->part_list), e_mail_part_list_get_message_uid (context->part_list), "part_id", G_TYPE_STRING, part_id, "attachment_icon", G_TYPE_POINTER, attachment_ptr, "size", G_TYPE_INT, icon_width, NULL); /* XXX Wild guess at the initial size. */ buffer = g_string_sized_new (8192); g_string_append_printf ( buffer, "
" "" "" "", part_id, attachment_ptr, html, attachment_ptr, e_mail_part_should_show_inline (part) ? "go-down" : e_mail_part_attachment_get_expandable (empa) ? "go-next" : "go-top", GTK_ICON_SIZE_BUTTON, icon_width, icon_height, icon_uri, icon_width, icon_height, part_id, attachment_ptr, GTK_ICON_SIZE_BUTTON, icon_width, icon_height, html); g_free (icon_uri); g_free (button_id); g_free (html); if (content_stream && e_mail_part_attachment_get_expandable (empa)) { gchar *wrapper_element_id; gconstpointer data; gsize size; wrapper_element_id = g_strdup_printf ("attachment-wrapper-%p", attachment_ptr); data = g_memory_output_stream_get_data ( G_MEMORY_OUTPUT_STREAM (content_stream)); size = g_memory_output_stream_get_data_size ( G_MEMORY_OUTPUT_STREAM (content_stream)); g_string_append_printf ( buffer, ""); g_free (wrapper_element_id); } g_clear_object (&content_stream); g_string_append (buffer, "
" "" "" "%s
" "
"); g_string_append_len (buffer, data, size); } else { gchar *inner_html_data; inner_html_data = g_markup_escape_text (data, size); g_string_append_printf (buffer, " related-part-id=\"%s\" inner-html-data=\"%s\">", attachment_part_id, inner_html_data); g_free (inner_html_data); } g_string_append (buffer, "
"); g_output_stream_write_all ( stream, buffer->str, buffer->len, NULL, cancellable, NULL); g_string_free (buffer, TRUE); return TRUE; } static void e_mail_formatter_attachment_class_init (EMailFormatterExtensionClass *class) { class->display_name = _("Attachment"); class->description = _("Display as attachment"); class->mime_types = formatter_mime_types; class->priority = G_PRIORITY_LOW; class->format = emfe_attachment_format; } static void e_mail_formatter_attachment_init (EMailFormatterExtension *extension) { }