403 lines
10 KiB
C
403 lines
10 KiB
C
/*
|
|
* 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 *class)
|
|
{
|
|
}
|
|
|
|
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)
|
|
{
|
|
|
|
}
|