/* * 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; either * version 2 of the License, or (at your option) version 3. * * 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with the program; if not, see * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include "e-mail-formatter-extension.h" #include "e-mail-inline-filter.h" #include "e-mail-part-attachment-bar.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.widget.attachment-button", NULL }; static EAttachmentStore * find_attachment_store (EMailPartList *part_list, EMailPart *start) { EAttachmentStore *store = NULL; GQueue queue = G_QUEUE_INIT; GList *head, *link; const gchar *start_id; gchar *tmp, *pos; EMailPart *part; gchar *id; start_id = start->id; e_mail_part_list_queue_parts (part_list, NULL, &queue); head = g_queue_peek_head_link (&queue); id = g_strconcat (start_id, ".attachment-bar", NULL); tmp = g_strdup (id); part = NULL; do { d (printf ("Looking up attachment bar as %s\n", id)); for (link = head; link != NULL; link = g_list_next (link)) { EMailPart *p = link->data; if (g_strcmp0 (p->id, id) == 0) { part = p; break; } } pos = g_strrstr (tmp, "."); if (!pos) break; g_free (id); g_free (tmp); tmp = g_strndup (start_id, pos - tmp); id = g_strdup_printf ("%s.attachment-bar", tmp); } while (pos && !part); g_free (id); g_free (tmp); if (part != NULL) store = E_MAIL_PART_ATTACHMENT_BAR (part)->store; while (!g_queue_is_empty (&queue)) e_mail_part_unref (g_queue_pop_head (&queue)); return store; } static gboolean emfe_attachment_format (EMailFormatterExtension *extension, EMailFormatter *formatter, EMailFormatterContext *context, EMailPart *part, CamelStream *stream, GCancellable *cancellable) { gchar *str, *text, *html; gchar *button_id; EAttachmentStore *store; EMailExtensionRegistry *reg; GQueue *extensions; EMailPartAttachment *empa; CamelMimeFilterToHTMLFlags flags; const gchar *attachment_part_id; g_return_val_if_fail (E_IS_MAIL_PART_ATTACHMENT (part), FALSE); empa = (EMailPartAttachment *) 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 = g_object_ref ( E_MAIL_PART_ATTACHMENT (part)->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); } store = find_attachment_store (context->part_list, part); if (store) { GList *attachments = e_attachment_store_get_attachments (store); if (!g_list_find (attachments, attachment)) { e_attachment_store_add_attachment ( store, attachment); } g_list_free (attachments); } else { g_warning ("Failed to locate attachment-bar for %s", part->id); } g_object_unref (attachment); } /* 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)) { EMailExtensionRegistry *registry; GQueue *extensions; GList *iter; 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 (!extensions) return FALSE; if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) { gchar *name; EAttachment *attachment; GFileInfo *fi; const gchar *description; const gchar *display_name; attachment = g_object_ref ( E_MAIL_PART_ATTACHMENT (part)->attachment); fi = e_attachment_get_file_info (attachment); display_name = g_file_info_get_display_name (fi); description = e_attachment_get_description (attachment); if (description && *description) { name = g_strdup_printf ( "

Attachment: %s (%s)

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

Attachment: %s

\n", display_name); } camel_stream_write_string (stream, name, cancellable, NULL); g_free (name); g_object_unref (attachment); } for (iter = g_queue_peek_head_link (extensions); iter; iter = iter->next) { EMailFormatterExtension *ext; ext = iter->data; if (!ext) continue; if (e_mail_formatter_extension_format (ext, formatter, context, part, stream, cancellable)) { return TRUE; } } return FALSE; } /* E_MAIL_FORMATTER_MODE_NORMAL: */ reg = e_mail_formatter_get_extension_registry (formatter); extensions = e_mail_extension_registry_get_for_mime_type ( reg, empa->snoop_mime_type); if (!extensions) { extensions = e_mail_extension_registry_get_fallback ( reg, empa->snoop_mime_type); } text = e_mail_part_describe (part->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); if (empa->attachment_view_part_id) attachment_part_id = empa->attachment_view_part_id; else attachment_part_id = part->id; button_id = g_strconcat (attachment_part_id, ".attachment_button", NULL); str = g_strdup_printf ( "
" "" "" "" "" "", part->id, button_id, html); camel_stream_write_string (stream, str, cancellable, NULL); g_free (button_id); g_free (str); g_free (html); if (extensions) { GList *iter; CamelStream *content_stream; gboolean ok; content_stream = camel_stream_mem_new (); ok = FALSE; if (empa->attachment_view_part_id != NULL) { EMailPart *attachment_view_part; attachment_view_part = e_mail_part_list_ref_part ( context->part_list, empa->attachment_view_part_id); /* Avoid recursion. */ if (attachment_view_part == part) { e_mail_part_unref (attachment_view_part); attachment_view_part = NULL; } if (attachment_view_part != NULL) { ok = e_mail_formatter_format_as ( formatter, context, attachment_view_part, content_stream, NULL, cancellable); e_mail_part_unref (attachment_view_part); } } else { for (iter = g_queue_peek_head_link (extensions); iter; iter = iter->next) { EMailFormatterExtension *ext; ext = iter->data; if (!ext) continue; if (e_mail_formatter_extension_format ( ext, formatter, context, part, content_stream, cancellable)) { ok = TRUE; break; } } } if (ok) { str = g_strdup_printf ( "", cancellable, NULL); } g_object_unref (content_stream); } camel_stream_write_string (stream, "
" "" "%s
" "
", attachment_part_id); camel_stream_write_string ( stream, str, cancellable, NULL); g_free (str); g_seekable_seek ( G_SEEKABLE (content_stream), 0, G_SEEK_SET, cancellable, NULL); camel_stream_write_to_stream ( content_stream, stream, cancellable, NULL); camel_stream_write_string ( stream, "
", cancellable, NULL); return TRUE; } static GtkWidget * emfe_attachment_get_widget (EMailFormatterExtension *extension, EMailPartList *context, EMailPart *part, GHashTable *params) { EAttachment *attachment; EAttachmentStore *store; EAttachmentView *view; GtkWidget *widget; g_return_val_if_fail (E_IS_MAIL_PART_ATTACHMENT (part), NULL); attachment = g_object_ref ( E_MAIL_PART_ATTACHMENT (part)->attachment); store = find_attachment_store (context, part); widget = e_attachment_button_new (); g_object_set_data_full ( G_OBJECT (widget), "uri", g_strdup (part->id), (GDestroyNotify) g_free); e_attachment_button_set_attachment ( E_ATTACHMENT_BUTTON (widget), attachment); view = g_object_get_data (G_OBJECT (store), "attachment-bar"); if (view != NULL) e_attachment_button_set_view ( E_ATTACHMENT_BUTTON (widget), view); gtk_widget_set_can_focus (widget, TRUE); gtk_widget_show (widget); g_object_unref (attachment); return widget; } 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; class->get_widget = emfe_attachment_get_widget; } static void e_mail_formatter_attachment_init (EMailFormatterExtension *extension) { }