X-Git-Url: http://git.maemo.org/git/?a=blobdiff_plain;f=src%2Fmodest-tny-msg-view.c;h=13ece7ae5879e1df133511af7a2e1cafe2163f07;hb=5bf2f24ec962205cc2c0af1e658189913ce7cfef;hp=60323306574ec7b7c5e5b283143d0a19f9391143;hpb=98e5de71cf2fb1ee6cc19b340c0eef51c05a230f;p=modest diff --git a/src/modest-tny-msg-view.c b/src/modest-tny-msg-view.c index 6032330..13ece7a 100644 --- a/src/modest-tny-msg-view.c +++ b/src/modest-tny-msg-view.c @@ -30,6 +30,10 @@ static gboolean on_url_requested (GtkWidget *widget, const gchar *uri, ModestTnyMsgView *msg_view); static gchar *construct_virtual_filename(const gchar *filename, const gint position, const gchar *id, const gboolean active); static gchar *construct_virtual_filename_from_mime_part(TnyMsgMimePartIface *msg, const gint position); + +#define ATTACHMENT_ID_INLINE "attachment-inline" +#define ATTACHMENT_ID_LINK "attachment-link" + gint virtual_filename_get_pos(const gchar *filename); /* * we need these regexps to find URLs in plain text e-mails @@ -68,7 +72,7 @@ typedef struct _ModestTnyMsgViewPrivate ModestTnyMsgViewPrivate; struct _ModestTnyMsgViewPrivate { GtkWidget *gtkhtml; TnyMsgIface *msg; - ModestConf *conf; + gboolean show_attachments_inline; }; #define MODEST_TNY_MSG_VIEW_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE((o), \ MODEST_TYPE_TNY_MSG_VIEW, \ @@ -125,7 +129,7 @@ modest_tny_msg_view_init (ModestTnyMsgView *obj) priv->gtkhtml = gtk_html_new(); - priv->conf = NULL; + priv->show_attachments_inline = FALSE; gtk_html_set_editable (GTK_HTML(priv->gtkhtml), FALSE); gtk_html_allow_selection (GTK_HTML(priv->gtkhtml), TRUE); @@ -144,11 +148,11 @@ modest_tny_msg_view_init (ModestTnyMsgView *obj) static void modest_tny_msg_view_finalize (GObject *obj) { - + /* TODO! */ } GtkWidget* -modest_tny_msg_view_new (TnyMsgIface *msg, ModestConf *conf) +modest_tny_msg_view_new (TnyMsgIface *msg, const gboolean show_attachments_inline) { GObject *obj; ModestTnyMsgView* self; @@ -163,25 +167,25 @@ modest_tny_msg_view_new (TnyMsgIface *msg, ModestConf *conf) GTK_POLICY_AUTOMATIC); if (priv->gtkhtml) - gtk_container_add (GTK_CONTAINER(obj), priv->gtkhtml); + gtk_container_add (GTK_CONTAINER(obj), priv->gtkhtml); if (msg) modest_tny_msg_view_set_message (self, msg); - priv->conf = conf; + modest_tny_msg_view_set_show_attachments_inline_flag(self, show_attachments_inline); return GTK_WIDGET(self); } - static gboolean on_link_clicked (GtkWidget *widget, const gchar *uri, ModestTnyMsgView *msg_view) { - if (g_str_has_prefix(uri, "attachment:")) { + if (g_str_has_prefix(uri, ATTACHMENT_ID_LINK)) { /* save or open attachment */ + g_message ("link-to-save: %s", uri); /* FIXME */ return TRUE; } g_message ("link clicked: %s", uri); /* FIXME */ @@ -230,7 +234,8 @@ find_attachment_by_filename (TnyMsgIface *msg, const gchar *fn) parts = (GList*) tny_msg_iface_get_parts (msg); pos = virtual_filename_get_pos(fn); - g_return_val_if_fail(((pos >= 0) && (pos < g_list_length(parts))), NULL); + if ((pos < 0) || (pos >= g_list_length(parts))) + return NULL; part = g_list_nth_data(parts, pos); @@ -256,6 +261,9 @@ on_url_requested (GtkWidget *widget, const gchar *uri, g_message ("url requested: %s", uri); + if (!modest_tny_msg_view_get_show_attachments_inline_flag(msg_view)) + return TRUE; /* debatable */ + if (g_str_has_prefix (uri, "cid:")) { /* +4 ==> skip "cid:" */ @@ -269,8 +277,9 @@ on_url_requested (GtkWidget *widget, const gchar *uri, tny_msg_mime_part_iface_decode_to_stream (part,tny_stream); gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); } - } else if (g_str_has_prefix (uri, "Attachment:")) { - TnyMsgMimePartIface *part = find_attachment_by_filename (priv->msg, uri); + } else if (g_str_has_prefix (uri, ATTACHMENT_ID_INLINE)) { + TnyMsgMimePartIface *part; + part = find_attachment_by_filename (priv->msg, uri); if (!part) { g_message ("%s not found", uri); gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR); @@ -285,8 +294,6 @@ on_url_requested (GtkWidget *widget, const gchar *uri, } - - typedef struct { guint offset; guint len; @@ -294,24 +301,55 @@ typedef struct { } url_match_t; - static gchar * -construct_virtual_filename(const gchar *filename, const gint position, const gchar *id, const gboolean active) +secure_filename(const gchar *fn) +{ + gchar *tmp, *p; + GString *s; + + s = g_string_new(""); +#if 1 || DEBUG + tmp = g_strdup(fn); + for (p = tmp; p[0] ; p++ ) { + p[0] &= 0x5f; /* 01011111 */ + p[0] |= 0x40; /* 01000000 */ + } + g_string_printf(s, "0x%x:%s", g_str_hash(fn), tmp); + g_free(tmp); + return g_string_free(s, FALSE); +#else + g_string_printf(s, "0x%x", g_str_hash(fn)); + return g_string_free(s, FALSE); +#endif +} + + +static gchar * +construct_virtual_filename(const gchar *filename, + const gint position, + const gchar *id, + const gboolean active) { GString *s; - g_return_val_if_fail((position >= 0), "AttachmentInvalid"); + gchar *fn; + + if (position < 0) + return g_strdup("AttachmentInvalid"); s = g_string_new(""); if (active) - g_string_append(s, "Attachment:"); + g_string_append(s, ATTACHMENT_ID_INLINE); else - g_string_append(s, "attachment:"); - g_string_append_printf(s, "%d:", position); + g_string_append(s, ATTACHMENT_ID_LINK); + g_string_append_printf(s, ":%d:", position); if (id) g_string_append(s, id); g_string_append_c(s, ':'); - if (filename) - g_string_append(s, filename); + + fn = secure_filename(filename); + if (fn) + g_string_append(s, fn); + g_free(fn); g_string_append_c(s, ':'); return g_string_free(s, FALSE); } @@ -359,13 +397,13 @@ virtual_filename_get_pos(const gchar *filename) gint len, pos; GString *dummy; - i1 = filename; - i2 = filename; - /* check prefix */ - i2 = get_next_token(i2, &len); - if (strncmp(i1, "Attachment", len) != 0) + if ((!g_str_has_prefix(filename, ATTACHMENT_ID_INLINE ":")) && + (!g_str_has_prefix(filename, ATTACHMENT_ID_LINK ":"))) return -1; + + i2 = filename; + i2 = get_next_token(i2, &len); i1 = i2; /* get position */ @@ -388,15 +426,14 @@ attachments_as_html(ModestTnyMsgView *self, TnyMsgIface *msg) const GList *attachment_list, *attachment; const gchar *content_type, *filename, *id; gchar *virtual_filename; - gboolean show_attachments_inline; if (!msg) return g_malloc0(1); priv = MODEST_TNY_MSG_VIEW_GET_PRIVATE (self); - /* CLEANUP: starting a new HTML may be unsupported */ - appendix = g_string_new("\n
Attachments:
\n"); + appendix = g_string_new(""); + g_string_printf(appendix, "\n
%s:
\n", _("Attachments")); attachment_list = tny_msg_iface_get_parts(msg); attachment = attachment_list; @@ -404,30 +441,32 @@ attachments_as_html(ModestTnyMsgView *self, TnyMsgIface *msg) filename = ""; content_type = tny_msg_mime_part_iface_get_content_type( TNY_MSG_MIME_PART_IFACE(attachment->data)); - g_return_val_if_fail(content_type, NULL); - if ( tny_msg_mime_part_iface_content_type_is( - TNY_MSG_MIME_PART_IFACE(attachment->data), - "image/jpeg") - || tny_msg_mime_part_iface_content_type_is( - TNY_MSG_MIME_PART_IFACE(attachment->data), - "image/gif")) { + if (!content_type) + continue; + + if ((strcmp("image/jpeg", content_type) == 0) || + (strcmp("image/gif", content_type) == 0)) { filename = tny_msg_mime_part_iface_get_filename( - TNY_MSG_MIME_PART_IFACE(attachment->data)); + TNY_MSG_MIME_PART_IFACE(attachment->data)); if (!filename) filename = "[unknown]"; else attachments_found = TRUE; id = tny_msg_mime_part_iface_get_content_id( TNY_MSG_MIME_PART_IFACE(attachment->data)); - show_attachments_inline = modest_conf_get_bool(priv->conf, MODEST_CONF_MSG_VIEW_SHOW_ATTACHMENTS_INLINE, NULL); - virtual_filename = construct_virtual_filename(filename, - g_list_position((GList *)attachment_list, (GList *) attachment), - id, show_attachments_inline); - printf("VF:%s\n", virtual_filename); - if (show_attachments_inline) { + if (modest_tny_msg_view_get_show_attachments_inline_flag(self)) { + virtual_filename = construct_virtual_filename(filename, + g_list_position((GList *)attachment_list, (GList *) attachment), + id, TRUE); g_string_append_printf(appendix, "\n
", virtual_filename); + g_free(virtual_filename); } - g_string_append_printf(appendix, "%s: %s
\n", filename, filename, content_type); + virtual_filename = construct_virtual_filename(filename, + g_list_position((GList *)attachment_list, (GList *) attachment), + id, FALSE); + g_string_append_printf(appendix, + "%s: %s
\n", + virtual_filename, filename, content_type); g_free(virtual_filename); } attachment = attachment->next; @@ -653,8 +692,7 @@ set_html_message (ModestTnyMsgView *self, TnyMsgMimePartIface *tny_body, TnyMsgI tny_stream_iface_reset (gtkhtml_stream); tny_msg_mime_part_iface_decode_to_stream (tny_body, gtkhtml_stream); html_attachments = attachments_as_html(self, msg); - /* is this clean? */ - gtkhtml_write(gtkhtml_stream, html_attachments, strlen(html_attachments)); + tny_stream_iface_write (gtkhtml_stream, html_attachments, strlen(html_attachments)); tny_stream_iface_reset (gtkhtml_stream); g_object_unref (G_OBJECT(gtkhtml_stream)); @@ -736,25 +774,19 @@ modest_tny_msg_view_set_message (ModestTnyMsgView *self, TnyMsgIface *msg) priv->msg = msg; fill_gtkhtml_with_txt (self, GTK_HTML(priv->gtkhtml), "", msg); - if (!msg) return; - body = modest_tny_msg_actions_find_body_part (msg, "text/html"); + body = modest_tny_msg_actions_find_body_part (msg, TRUE); if (body) { - set_html_message (self, body, msg); - return; - } - - body = modest_tny_msg_actions_find_body_part (msg, "text/plain"); - if (body) { - set_text_message (self, body, msg); + if (tny_msg_mime_part_iface_content_type_is (body, "text/html")) + set_html_message (self, body, msg); + else + set_text_message (self, body, msg); return; + } else { + /* nothing to show */ } - - /* hmmmmm */ - fill_gtkhtml_with_txt (self, GTK_HTML(priv->gtkhtml), - _("Unsupported message type"), msg); } void @@ -766,3 +798,28 @@ modest_tny_msg_view_redraw (ModestTnyMsgView *self) priv = MODEST_TNY_MSG_VIEW_GET_PRIVATE(self); modest_tny_msg_view_set_message(self, priv->msg); } + +gboolean +modest_tny_msg_view_get_show_attachments_inline_flag (ModestTnyMsgView *self) +{ + ModestTnyMsgViewPrivate *priv; + + g_return_val_if_fail (self, FALSE); + priv = MODEST_TNY_MSG_VIEW_GET_PRIVATE(self); + return priv->show_attachments_inline; +} + +gboolean +modest_tny_msg_view_set_show_attachments_inline_flag (ModestTnyMsgView *self, gboolean flag) +{ + ModestTnyMsgViewPrivate *priv; + gboolean oldflag; + + g_return_val_if_fail (self, FALSE); + priv = MODEST_TNY_MSG_VIEW_GET_PRIVATE(self); + oldflag = priv->show_attachments_inline; + priv->show_attachments_inline = flag; + if (priv->show_attachments_inline != oldflag) + modest_tny_msg_view_redraw(self); + return priv->show_attachments_inline; +}