/* * 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 "e-mail-format-extensions.h" #include "e-mail-part-attachment.h" #include "e-mail-part-attachment-bar.h" #include #include #include #include #include #include #include #include #include #include #define d(x) typedef struct _EMailFormatterAttachment { GObject parent; } EMailFormatterAttachment; typedef struct _EMailFormatterAttachmentClass { GObjectClass parent_class; } EMailFormatterAttachmentClass; static void e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface); static void e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface); G_DEFINE_TYPE_EXTENDED ( EMailFormatterAttachment, e_mail_formatter_attachment, G_TYPE_OBJECT, 0, G_IMPLEMENT_INTERFACE ( E_TYPE_MAIL_EXTENSION, e_mail_formatter_mail_extension_interface_init) G_IMPLEMENT_INTERFACE ( E_TYPE_MAIL_FORMATTER_EXTENSION, e_mail_formatter_formatter_extension_interface_init) ) static const gchar *formatter_mime_types[] = { "application/vnd.evolution.attachment", "application/vnd.evolution.widget.attachment-button", NULL }; static EAttachmentStore * find_attachment_store (GSList *parts, const gchar *start_id) { gchar *tmp, *pos; EMailPart *part; gchar *id; id = g_strconcat (start_id, ".attachment-bar", NULL); tmp = g_strdup (id); part = NULL; do { GSList *iter; d(printf("Looking up attachment bar as %s\n", id)); for (iter = parts; iter; iter = iter->next) { EMailPart *p = iter->data; if (!p) continue; 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) { return ((EMailPartAttachmentBar *) part)->store; } return NULL; } 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; gchar *attachment_part_id; g_return_val_if_fail (E_MAIL_PART_IS (part, EMailPartAttachment), FALSE); empa = (EMailPartAttachment *) part; if ((context->mode == E_MAIL_FORMATTER_MODE_NORMAL) || (context->mode == E_MAIL_FORMATTER_MODE_PRINTING)) { if (part->validity) { e_attachment_set_signed ( empa->attachment, part->validity->sign.status); e_attachment_set_encrypted ( empa->attachment, part->validity->encrypt.status); } store = find_attachment_store (context->parts, part->id); if (store) { GList *attachments = e_attachment_store_get_attachments (store); if (!g_list_find (attachments, empa->attachment)) { e_attachment_store_add_attachment ( store, empa->attachment); } g_list_free (attachments); } else { g_warning ("Failed to locate attachment-bar for %s", part->id); } } /* 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 *reg; GQueue *extensions; GList *iter; 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); } if (!extensions) return FALSE; if (context->mode == E_MAIL_FORMATTER_MODE_PRINTING) { gchar *name; EAttachment *attachment; GFileInfo *fi; const gchar *description; attachment = empa->attachment; fi = e_attachment_get_file_info (attachment); description = e_attachment_get_description (attachment); if (description && *description) { name = g_strdup_printf ("

Attachment: %s (%s)

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

Attachment: %s

\n", g_file_info_get_display_name (fi)); } camel_stream_write_string (stream, name, cancellable, NULL); g_free (name); } 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); html = camel_text_to_html ( text, e_mail_formatter_get_text_format_flags (formatter) & 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) { GSList *att_parts; att_parts = e_mail_part_list_get_iter ( context->parts, empa->attachment_view_part_id); if (att_parts && att_parts->data) { ok = e_mail_formatter_format_as ( formatter, context, att_parts->data, content_stream, NULL, cancellable); } } 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) { EMailPartAttachment *empa; EAttachmentStore *store; EAttachmentView *view; GtkWidget *widget; g_return_val_if_fail (E_MAIL_PART_IS (part, EMailPartAttachment), NULL); empa = (EMailPartAttachment *) part; store = find_attachment_store (context->list, part->id); widget = e_attachment_button_new (); g_object_set_data (G_OBJECT (widget), "uri", part->id); e_attachment_button_set_attachment ( E_ATTACHMENT_BUTTON (widget), empa->attachment); view = g_object_get_data (G_OBJECT (store), "attachment-bar"); if (view) { e_attachment_button_set_view ( E_ATTACHMENT_BUTTON (widget), view); } gtk_widget_set_can_focus (widget, TRUE); gtk_widget_show (widget); return widget; } static const gchar * emfe_attachment_get_display_name (EMailFormatterExtension *extension) { return _("Attachment"); } static const gchar * emfe_attachment_get_description (EMailFormatterExtension *extension) { return _("Display as attachment"); } static const gchar ** emfe_attachment_mime_types (EMailExtension *extension) { return formatter_mime_types; } static void e_mail_formatter_attachment_class_init (EMailFormatterAttachmentClass *klass) { e_mail_formatter_attachment_parent_class = g_type_class_peek_parent (klass); } static void e_mail_formatter_formatter_extension_interface_init (EMailFormatterExtensionInterface *iface) { iface->format = emfe_attachment_format; iface->get_widget = emfe_attachment_get_widget; iface->get_display_name = emfe_attachment_get_display_name; iface->get_description = emfe_attachment_get_description; } static void e_mail_formatter_mail_extension_interface_init (EMailExtensionInterface *iface) { iface->mime_types = emfe_attachment_mime_types; } static void e_mail_formatter_attachment_init (EMailFormatterAttachment *formatter) { }