diff options
Diffstat (limited to 'em-format/e-mail-formatter-attachment.c')
-rw-r--r-- | em-format/e-mail-formatter-attachment.c | 403 |
1 files changed, 403 insertions, 0 deletions
diff --git a/em-format/e-mail-formatter-attachment.c b/em-format/e-mail-formatter-attachment.c new file mode 100644 index 0000000000..3d63413a69 --- /dev/null +++ b/em-format/e-mail-formatter-attachment.c @@ -0,0 +1,403 @@ +/* + * 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 <http://www.gnu.org/licenses/> + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "e-mail-format-extensions.h" +#include "e-mail-part-attachment.h" +#include "e-mail-part-attachment-bar.h" + +#include <em-format/e-mail-formatter-extension.h> +#include <em-format/e-mail-formatter.h> +#include <em-format/e-mail-part-utils.h> +#include <em-format/e-mail-inline-filter.h> +#include <e-util/e-util.h> + +#include <shell/e-shell.h> +#include <shell/e-shell-window.h> + +#include <widgets/misc/e-attachment-button.h> + +#include <glib/gi18n-lib.h> +#include <camel/camel.h> + +#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 ("<h2>Attachment: %s (%s)</h2>\n", + description, g_file_info_get_display_name (fi)); + } else { + name = g_strdup_printf ("<h2>Attachment: %s</h2>\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 ( + "<div class=\"attachment\">" + "<table width=\"100%%\" border=\"0\">" + "<tr valign=\"middle\">" + "<td align=\"left\" width=\"100\">" + "<object type=\"application/vnd.evolution.widget.attachment-button\" " + "height=\"20\" width=\"100\" data=\"%s\" id=\"%s\"></object>" + "</td>" + "<td align=\"left\">%s</td>" + "</tr>", 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 ( + "<tr><td colspan=\"2\">" + "<div class=\"attachment-wrapper\" id=\"%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, "</div></td></tr>", cancellable, NULL); + } + + g_object_unref (content_stream); + } + + camel_stream_write_string (stream, "</table></div>", 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) +{ + +} |