From 99a875edae6c57fd6540818d3f0da994b135a068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Vr=C3=A1til?= Date: Tue, 26 Jun 2012 13:39:47 +0200 Subject: Bug #515004 - Allow toggling between text and HTML view of mail --- data/webview.css | 4 +- em-format/e-mail-formatter-text-html.c | 3 +- em-format/e-mail-formatter-text-plain.c | 26 +- mail/Makefile.am | 2 + mail/e-mail-display-popup-extension.c | 55 +++ mail/e-mail-display-popup-extension.h | 64 ++++ mail/e-mail-display.c | 78 +++-- modules/prefer-plain/Makefile.am | 2 + .../e-mail-display-popup-prefer-plain.c | 380 +++++++++++++++++++++ .../e-mail-display-popup-prefer-plain.h | 30 ++ modules/prefer-plain/e-mail-parser-prefer-plain.c | 270 +++++++-------- .../prefer-plain/evolution-module-prefer-plain.c | 2 + widgets/misc/e-web-view.c | 5 +- 13 files changed, 732 insertions(+), 189 deletions(-) create mode 100644 mail/e-mail-display-popup-extension.c create mode 100644 mail/e-mail-display-popup-extension.h create mode 100644 modules/prefer-plain/e-mail-display-popup-prefer-plain.c create mode 100644 modules/prefer-plain/e-mail-display-popup-prefer-plain.h diff --git a/data/webview.css b/data/webview.css index 09f94043fb..a8a936d0a2 100644 --- a/data/webview.css +++ b/data/webview.css @@ -1,6 +1,6 @@ html, body { - padding: 0; - margin: 0; + padding: 0; + margin: 0; } img { diff --git a/em-format/e-mail-formatter-text-html.c b/em-format/e-mail-formatter-text-html.c index 8834994496..e5d25a39b7 100644 --- a/em-format/e-mail-formatter-text-html.c +++ b/em-format/e-mail-formatter-text-html.c @@ -309,12 +309,13 @@ emfe_text_html_format (EMailFormatterExtension *extension, "
" "" "
", uri, part->id, + part->id, e_color_to_value ((GdkColor *) e_mail_formatter_get_color ( formatter, E_MAIL_FORMATTER_COLOR_FRAME)), diff --git a/em-format/e-mail-formatter-text-plain.c b/em-format/e-mail-formatter-text-plain.c index a8cb7f2943..7859a41ab8 100644 --- a/em-format/e-mail-formatter-text-plain.c +++ b/em-format/e-mail-formatter-text-plain.c @@ -114,12 +114,8 @@ emfe_text_plain_format (EMailFormatterExtension *extension, content = g_strdup_printf ( "
" - "
\n", - e_color_to_value ((GdkColor *) - e_mail_formatter_get_color ( - formatter, E_MAIL_FORMATTER_COLOR_FRAME)), + "border: none; padding: 10px; margin: 0; " + "background-color: #%06x; color: #%06x;\">\n", e_color_to_value ((GdkColor *) e_mail_formatter_get_color ( formatter, E_MAIL_FORMATTER_COLOR_CONTENT)), @@ -134,7 +130,7 @@ emfe_text_plain_format (EMailFormatterExtension *extension, g_object_unref (filtered_stream); g_free (content); - camel_stream_write_string (stream, "
\n", cancellable, NULL); + camel_stream_write_string (stream, "\n", cancellable, NULL); if (context->mode == E_MAIL_FORMATTER_MODE_RAW) { camel_stream_write_string (stream, "", @@ -153,10 +149,20 @@ emfe_text_plain_format (EMailFormatterExtension *extension, NULL); str = g_strdup_printf ( + "
" "", - part->id, uri); + " id=\"%s.iframe\" name=\"%s\" " + " frameborder=\"0\" src=\"%s\" " + " style=\"border: 1px solid #%06x; background-color: #%06x;\">" + "" + "
", + part->id, part->id, uri, + e_color_to_value ((GdkColor *) + e_mail_formatter_get_color ( + formatter, E_MAIL_FORMATTER_COLOR_FRAME)), + e_color_to_value ((GdkColor *) + e_mail_formatter_get_color ( + formatter, E_MAIL_FORMATTER_COLOR_CONTENT))); camel_stream_write_string (stream, str, cancellable, NULL); diff --git a/mail/Makefile.am b/mail/Makefile.am index cd02ad6fdf..9dda24f16d 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -67,6 +67,7 @@ mailinclude_HEADERS = \ e-mail-config-welcome-page.h \ e-mail-config-window.h \ e-mail-display.h \ + e-mail-display-popup-extension.h \ e-mail-folder-pane.h \ e-mail-junk-options.h \ e-mail-label-action.h \ @@ -146,6 +147,7 @@ libevolution_mail_la_SOURCES = \ e-mail-config-welcome-page.c \ e-mail-config-window.c \ e-mail-display.c \ + e-mail-display-popup-extension.c \ e-mail-folder-pane.c \ e-mail-junk-options.c \ e-mail-label-action.c \ diff --git a/mail/e-mail-display-popup-extension.c b/mail/e-mail-display-popup-extension.c new file mode 100644 index 0000000000..a4441797c3 --- /dev/null +++ b/mail/e-mail-display-popup-extension.c @@ -0,0 +1,55 @@ +/* + * e-mail-display-popup-extension.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 + * + */ + +#include "e-mail-display-popup-extension.h" +#include "e-mail-display.h" + +G_DEFINE_INTERFACE ( + EMailDisplayPopupExtension, + e_mail_display_popup_extension, + G_TYPE_OBJECT) + + +static void +e_mail_display_popup_extension_default_init (EMailDisplayPopupExtensionInterface *iface) +{ + +} + +/** + * e_mail_display_popup_extension_update_actions: + * + * @extension: An object derived from #EMailDisplayPopupExtension + * @context: A #WebKitHitTestResult describing context of the popup menu + * + * When #EMailDisplay is about to display a popup menu, it calls this function + * on every extension so that they can add their items to the menu. + */ +void +e_mail_display_popup_extension_update_actions (EMailDisplayPopupExtension *extension, + WebKitHitTestResult *context) +{ + EMailDisplayPopupExtensionInterface *iface; + + g_return_if_fail (E_IS_MAIL_DISPLAY_POPUP_EXTENSION (extension)); + + iface = E_MAIL_DISPLAY_POPUP_EXTENSION_GET_INTERFACE (extension); + g_return_if_fail (iface->update_actions != NULL); + + iface->update_actions (extension, context); +} diff --git a/mail/e-mail-display-popup-extension.h b/mail/e-mail-display-popup-extension.h new file mode 100644 index 0000000000..307071e56e --- /dev/null +++ b/mail/e-mail-display-popup-extension.h @@ -0,0 +1,64 @@ +/* + * e-mail-dispaly-popup-extension.h + * + * 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 + * + */ + +#ifndef E_MAIL_DISPLAY_POPUP_EXTENSION_H +#define E_MAIL_DISPLAY_POPUP_EXTENSION_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_MAIL_DISPLAY_POPUP_EXTENSION \ + (e_mail_display_popup_extension_get_type ()) +#define E_MAIL_DISPLAY_POPUP_EXTENSION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MAIL_DISPLAY_POPUP_EXTENSION, EMailDisplayPopupExtension)) +#define E_MAIL_DISPLAY_POPUP_EXTENSION_INTERFACE(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MAIL_DISPLAY_POPUP_EXTENSION, EMailDisplayPopupExtensionInterface)) +#define E_IS_MAIL_DISPLAY_POPUP_EXTENSION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MAIL_DISPLAY_POPUP_EXTENSION)) +#define E_IS_MAIL_DISPLAY_POPUP_EXTENSION_INTERFACE(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MAIL_DISPLAY_POPUP_EXTENSION)) +#define E_MAIL_DISPLAY_POPUP_EXTENSION_GET_INTERFACE(obj) \ + (G_TYPE_INSTANCE_GET_INTERFACE \ + ((obj), E_TYPE_MAIL_DISPLAY_POPUP_EXTENSION, EMailDisplayPopupExtensionInterface)) + +G_BEGIN_DECLS + +typedef struct _EMailDisplayPopupExtension EMailDisplayPopupExtension; +typedef struct _EMailDisplayPopupExtensionInterface EMailDisplayPopupExtensionInterface; + +struct _EMailDisplayPopupExtensionInterface { + GTypeInterface parent_interface; + + void (*update_actions) (EMailDisplayPopupExtension *extension, + WebKitHitTestResult *context); +}; + +GType e_mail_display_popup_extension_get_type (void); + +void e_mail_display_popup_extension_update_actions + (EMailDisplayPopupExtension *extension, + WebKitHitTestResult *context); + +G_END_DECLS + +#endif /* E_MAIL_DISPLAY_POPUP_EXTENSION_H */ diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c index dab8c3be1c..6e0f0a32e5 100644 --- a/mail/e-mail-display.c +++ b/mail/e-mail-display.c @@ -24,6 +24,7 @@ #endif #include "e-mail-display.h" +#include "e-mail-display-popup-extension.h" #include #include @@ -52,7 +53,10 @@ #define d(x) -G_DEFINE_TYPE (EMailDisplay, e_mail_display, E_TYPE_WEB_VIEW) +G_DEFINE_TYPE ( + EMailDisplay, + e_mail_display, + E_TYPE_WEB_VIEW); #define E_MAIL_DISPLAY_GET_PRIVATE(obj) \ (G_TYPE_INSTANCE_GET_PRIVATE \ @@ -161,49 +165,67 @@ static GtkActionEntry image_entries[] = { }; -static void -mail_display_update_actions (EWebView *web_view, - GdkEventButton *event) +static gboolean +mail_display_button_press_event (GtkWidget *widget, + GdkEventButton *event) { WebKitHitTestResult *hit_test; WebKitHitTestResultContext context; gchar *image_src; gboolean visible; GtkAction *action; - - /* Chain up first! */ - E_WEB_VIEW_CLASS (e_mail_display_parent_class)-> - update_actions (web_view, event); + GList *extensions, *iter; + EWebView *web_view = E_WEB_VIEW (widget); hit_test = webkit_web_view_get_hit_test_result ( WEBKIT_WEB_VIEW (web_view), event); + g_object_get ( G_OBJECT (hit_test), "context", &context, "image-uri", &image_src, NULL); - if (!(context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE)) - return; + if ((context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE)) { + visible = image_src && g_str_has_prefix (image_src, "cid:"); + if (!visible && image_src) { + CamelStream *image_stream; - visible = image_src && g_str_has_prefix (image_src, "cid:"); - if (!visible && image_src) { - CamelStream *image_stream; + image_stream = camel_data_cache_get ( + emd_global_http_cache, "http", + image_src, NULL); - image_stream = camel_data_cache_get (emd_global_http_cache, "http", image_src, NULL); + visible = image_stream != NULL; - visible = image_stream != NULL; + if (image_stream) + g_object_unref (image_stream); + } + + if (image_src) + g_free (image_src); - if (image_stream) - g_object_unref (image_stream); + action = e_web_view_get_action (web_view, "image-save"); + if (action) + gtk_action_set_visible (action, visible); } - if (image_src) - g_free (image_src); + extensions = e_extensible_list_extensions ( + E_EXTENSIBLE (web_view), E_TYPE_EXTENSION); + for (iter = extensions; iter; iter = g_list_next (iter)) { + EExtension *extension = iter->data; + + if (!E_IS_MAIL_DISPLAY_POPUP_EXTENSION (extension)) + continue; - action = e_web_view_get_action (web_view, "image-save"); - if (action) - gtk_action_set_visible (action, visible); + e_mail_display_popup_extension_update_actions ( + E_MAIL_DISPLAY_POPUP_EXTENSION (extension), hit_test); + } + g_list_free (extensions); + + g_object_unref (hit_test); + + /* Chain up to parent's button_press_event() method. */ + return GTK_WIDGET_CLASS (e_mail_display_parent_class)->button_press_event (widget, event); } static void @@ -230,6 +252,15 @@ mail_display_update_formatter_colors (EMailDisplay *display) e_mail_formatter_set_style (display->priv->formatter, style, state); } +static void +mail_display_constructed (GObject *object) +{ + e_extensible_load_extensions (E_EXTENSIBLE (object)); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_mail_display_parent_class)->constructed (object); +} + static void mail_display_set_property (GObject *object, guint property_id, @@ -1358,17 +1389,18 @@ e_mail_display_class_init (EMailDisplayClass *class) g_type_class_add_private (class, sizeof (EMailDisplayPrivate)); object_class = G_OBJECT_CLASS (class); + object_class->constructed = mail_display_constructed; object_class->set_property = mail_display_set_property; object_class->get_property = mail_display_get_property; object_class->dispose = mail_display_dispose; web_view_class = E_WEB_VIEW_CLASS (class); web_view_class->set_fonts = mail_display_set_fonts; - web_view_class->update_actions = mail_display_update_actions; widget_class = GTK_WIDGET_CLASS (class); widget_class->realize = mail_display_realize; widget_class->style_set = mail_display_style_set; + widget_class->button_press_event = mail_display_button_press_event; g_object_class_install_property ( object_class, diff --git a/modules/prefer-plain/Makefile.am b/modules/prefer-plain/Makefile.am index e4e6b56d02..18cb7438e7 100644 --- a/modules/prefer-plain/Makefile.am +++ b/modules/prefer-plain/Makefile.am @@ -14,6 +14,8 @@ module_prefer_plain_la_CPPFLAGS = \ module_prefer_plain_la_SOURCES = \ e-mail-parser-prefer-plain.c \ e-mail-parser-prefer-plain.h \ + e-mail-display-popup-prefer-plain.c \ + e-mail-display-popup-prefer-plain.h \ evolution-module-prefer-plain.c module_prefer_plain_la_LIBADD = \ diff --git a/modules/prefer-plain/e-mail-display-popup-prefer-plain.c b/modules/prefer-plain/e-mail-display-popup-prefer-plain.c new file mode 100644 index 0000000000..75c74db71e --- /dev/null +++ b/modules/prefer-plain/e-mail-display-popup-prefer-plain.c @@ -0,0 +1,380 @@ +/* + * 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-display-popup-prefer-plain.h" +#include "mail/e-mail-display-popup-extension.h" +#include "mail/e-mail-display.h" +#include +#include +#include "mail/e-mail-browser.h" + +#include + +#include + +#define d(x) + +typedef struct _EMailDisplayPopupPreferPlain { + EExtension parent; + + WebKitDOMDocument *document; + gchar *text_plain_id; + gchar *text_html_id; + + GtkActionGroup *action_group; + +} EMailDisplayPopupPreferPlain; + +typedef struct _EMailDisplayPopupPreferPlainClass { + EExtensionClass parent_class; +} EMailDisplayPopupPreferPlainClass; + +#define E_MAIL_DISPLAY_POPUP_PREFER_PLAIN(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), e_mail_display_popup_prefer_plain_get_type(), EMailDisplayPopupPreferPlain)) + +GType e_mail_display_popup_prefer_plain_get_type (void); +static void e_mail_display_popup_extension_interface_init (EMailDisplayPopupExtensionInterface *iface); + +G_DEFINE_DYNAMIC_TYPE_EXTENDED ( + EMailDisplayPopupPreferPlain, + e_mail_display_popup_prefer_plain, + E_TYPE_EXTENSION, + 0, + G_IMPLEMENT_INTERFACE_DYNAMIC ( + E_TYPE_MAIL_DISPLAY_POPUP_EXTENSION, + e_mail_display_popup_extension_interface_init)); + +static const gchar *ui_webview = +"" +" " +" " +" " +" " +" " +" " +" " +" " +""; + +static const gchar *ui_reader = +"" +" " +" " +" " +" " +" " +" " +" " +" " +""; + + +static void +toggle_part (GtkAction *action, + EMailDisplayPopupExtension *extension) +{ + EMailDisplayPopupPreferPlain *pp_extension = (EMailDisplayPopupPreferPlain *) extension; + WebKitDOMDocument *doc = pp_extension->document; + WebKitDOMDOMWindow *window; + WebKitDOMElement *frame_element; + SoupURI *soup_uri; + GHashTable *query; + gchar *uri; + + uri = webkit_dom_document_get_document_uri (doc); + soup_uri = soup_uri_new (uri); + g_free (uri); + + query = soup_form_decode (soup_uri->query); + g_hash_table_replace (query, g_strdup ("part_id"), + pp_extension->text_html_id ? + pp_extension->text_html_id : + pp_extension->text_plain_id); + + soup_uri_set_query_from_form (soup_uri, query); + g_hash_table_destroy (query); + + uri = soup_uri_to_string (soup_uri, FALSE); + soup_uri_free (soup_uri); + + /* Get frame's window and from the window the actual