[evolution/webkit] Fix 'Copy Image' and 'Save Image' in mail display
- From: Dan VrÃtil <dvratil src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution/webkit] Fix 'Copy Image' and 'Save Image' in mail display
- Date: Fri, 6 Jan 2012 12:02:11 +0000 (UTC)
commit d2103dca9f86042fd62bbdd0786820e14aa52819
Author: Dan VrÃtil <dvratil redhat com>
Date: Fri Jan 6 13:02:21 2012 +0100
Fix 'Copy Image' and 'Save Image' in mail display
mail/e-mail-display.c | 87 +++++++++++++++++--
mail/e-mail-reader.c | 123 +++++++++++++++++++++++++-
mail/em-format-html-display.c | 194 -----------------------------------------
widgets/misc/e-web-view.c | 60 +++++++++++++
4 files changed, 260 insertions(+), 204 deletions(-)
---
diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c
index bd469b5..93c5525 100644
--- a/mail/e-mail-display.c
+++ b/mail/e-mail-display.c
@@ -65,7 +65,8 @@ struct _EMailDisplayPrivate {
GtkWidget *current_webview;
- GtkActionGroup *actions;
+ GtkActionGroup *mailto_actions;
+ GtkActionGroup *images_actions;
};
enum {
@@ -106,6 +107,15 @@ static const gchar *ui =
" </popup>"
"</ui>";
+static const gchar *image_ui =
+"<ui>"
+" <popup name='context'>"
+" <placeholder name='custom-actions-2'>"
+" <menuitem action='image-save'/>"
+" </placeholder>"
+" </popup>"
+"</ui>";
+
static GtkActionEntry mailto_entries[] = {
{ "add-to-address-book",
@@ -146,6 +156,19 @@ static GtkActionEntry mailto_entries[] = {
NULL }
};
+
+static GtkActionEntry image_entries[] = {
+
+ { "image-save",
+ GTK_STOCK_SAVE,
+ N_("Save _Image..."),
+ NULL,
+ N_("Save the image to a file"),
+ NULL /* Handled by EMailReader */ },
+
+};
+
+
static gboolean
mail_display_webview_enter_notify_event (GtkWidget *widget,
GdkEvent *event,
@@ -164,6 +187,38 @@ mail_display_webview_enter_notify_event (GtkWidget *widget,
}
static void
+mail_display_webview_update_actions (EWebView *web_view,
+ gpointer user_data)
+{
+ EMailDisplay *display = user_data;
+
+ const gchar *image_src;
+ gboolean visible;
+ GtkAction *action;
+
+ g_return_if_fail (web_view != NULL);
+
+ image_src = e_web_view_get_cursor_image_src (web_view);
+ 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);
+
+ visible = image_stream != NULL;
+
+ 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);
+}
+
+
+
+static void
formatter_image_loading_policy_changed_cb (GObject *object,
GParamSpec *pspec,
gpointer user_data)
@@ -630,7 +685,8 @@ mail_display_setup_webview (EMailDisplay *display,
G_CALLBACK (mail_display_emit_popup_event), display);
g_signal_connect (web_view, "enter-notify-event",
G_CALLBACK (mail_display_webview_enter_notify_event), display);
-
+ g_signal_connect (web_view, "update-actions",
+ G_CALLBACK (mail_display_webview_update_actions), display);
settings = webkit_web_view_get_settings (WEBKIT_WEB_VIEW (web_view));
/* When webviews holds headers or attached image then the can_load_images option
@@ -645,9 +701,18 @@ mail_display_setup_webview (EMailDisplay *display,
* no chance of I/O errors. Failure here implies a malformed
* UI definition. Full stop. */
ui_manager = e_web_view_get_ui_manager (web_view);
- gtk_ui_manager_insert_action_group (ui_manager, display->priv->actions, 0);
+ gtk_ui_manager_insert_action_group (ui_manager, display->priv->mailto_actions, 0);
gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
+ if (error != NULL) {
+ g_error ("%s", error->message);
+ g_error_free (error);
+ }
+
+ error = NULL;
+ gtk_ui_manager_insert_action_group (ui_manager, display->priv->images_actions, 0);
+ gtk_ui_manager_add_ui_from_string (ui_manager, image_ui, -1, &error);
+
if (error != NULL) {
g_error ("%s", error->message);
g_error_free (error);
@@ -1004,10 +1069,14 @@ mail_display_init (EMailDisplay *display)
display->priv->webviews = NULL;
- display->priv->actions = gtk_action_group_new ("mailto");
- gtk_action_group_add_actions (display->priv->actions, mailto_entries,
+ display->priv->mailto_actions = gtk_action_group_new ("mailto");
+ gtk_action_group_add_actions (display->priv->mailto_actions, mailto_entries,
G_N_ELEMENTS (mailto_entries), NULL);
+ display->priv->images_actions = gtk_action_group_new ("image");
+ gtk_action_group_add_actions (display->priv->images_actions, image_entries,
+ G_N_ELEMENTS (image_entries), NULL);
+
/* WEBKIT TODO: ESearchBar */
@@ -1242,10 +1311,16 @@ GtkAction*
e_mail_display_get_action (EMailDisplay *display,
const gchar *action_name)
{
+ GtkAction *action;
+
g_return_val_if_fail (E_IS_MAIL_DISPLAY (display), NULL);
g_return_val_if_fail (action_name != NULL, NULL);
- return gtk_action_group_get_action (display->priv->actions, action_name);
+ action = gtk_action_group_get_action (display->priv->mailto_actions, action_name);
+ if (!action)
+ action = gtk_action_group_get_action (display->priv->images_actions, action_name);
+
+ return action;
}
void
diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c
index 1f58347..2679b23 100644
--- a/mail/e-mail-reader.c
+++ b/mail/e-mail-reader.c
@@ -247,6 +247,118 @@ exit:
}
static void
+attachment_load_finish (EAttachment *attachment,
+ GAsyncResult *result,
+ GFile *file)
+{
+ EShell *shell;
+ GtkWindow *parent;
+
+ e_attachment_load_finish (attachment, result, NULL);
+
+ shell = e_shell_get_default ();
+ parent = e_shell_get_active_window (shell);
+
+ e_attachment_save_async (
+ attachment, file, (GAsyncReadyCallback)
+ e_attachment_save_handle_error, parent);
+
+ g_object_unref (file);
+}
+
+static void
+action_mail_image_save_cb (GtkAction *action,
+ EMailReader *reader)
+{
+ EMailDisplay *display;
+ EWebView *web_view;
+ EMFormat *emf;
+ const gchar *image_src;
+ CamelMimePart *part;
+ EAttachment *attachment;
+ GFile *file;
+
+ display = e_mail_reader_get_mail_display (reader);
+ web_view = e_mail_display_get_current_web_view (display);
+
+ if (!E_IS_WEB_VIEW (web_view))
+ return;
+
+ image_src = e_web_view_get_cursor_image_src (web_view);
+ if (!image_src)
+ return;
+
+ emf = EM_FORMAT (e_mail_display_get_formatter (display));
+ g_return_if_fail (emf != NULL);
+ g_return_if_fail (emf->message != NULL);
+
+ if (g_str_has_prefix (image_src, "cid:")) {
+ part = camel_mime_message_get_part_by_content_id (
+ emf->message, image_src + 4);
+ g_return_if_fail (part != NULL);
+
+ g_object_ref (part);
+ } else {
+ CamelStream *image_stream;
+ CamelDataWrapper *dw;
+ CamelDataCache *cache;
+ const gchar *filename;
+ const gchar *user_cache_dir;
+
+ /* Open cache and find the file there */
+ user_cache_dir = e_get_user_cache_dir ();
+ cache = camel_data_cache_new (user_cache_dir, NULL);
+ image_stream = camel_data_cache_get (cache, "http", image_src, NULL);
+ if (!image_stream) {
+ g_object_unref (cache);
+ return;
+ }
+
+ filename = strrchr (image_src, '/');
+ if (filename && strchr (filename, '?'))
+ filename = NULL;
+ else if (filename)
+ filename = filename + 1;
+
+ part = camel_mime_part_new ();
+ if (filename)
+ camel_mime_part_set_filename (part, filename);
+
+ dw = camel_data_wrapper_new ();
+ camel_data_wrapper_set_mime_type (
+ dw, "application/octet-stream");
+ camel_data_wrapper_construct_from_stream_sync (
+ dw, image_stream, NULL, NULL);
+ camel_medium_set_content (CAMEL_MEDIUM (part), dw);
+ g_object_unref (dw);
+
+ camel_mime_part_set_encoding (
+ part, CAMEL_TRANSFER_ENCODING_BASE64);
+
+ g_object_unref (image_stream);
+ g_object_unref (cache);
+ }
+
+ file = e_shell_run_save_dialog (
+ e_shell_get_default (),
+ _("Save Image"), camel_mime_part_get_filename (part),
+ NULL, NULL, NULL);
+ if (file == NULL) {
+ g_object_unref (part);
+ return;
+ }
+
+ attachment = e_attachment_new ();
+ e_attachment_set_mime_part (attachment, part);
+
+ e_attachment_load_async (
+ attachment, (GAsyncReadyCallback)
+ attachment_load_finish, file);
+
+ g_object_unref (part);
+}
+
+static void
action_mail_charset_cb (GtkRadioAction *action,
GtkRadioAction *current,
EMailReader *reader)
@@ -2957,11 +3069,8 @@ mail_reader_message_loaded (EMailReader *reader,
NULL, format_parser_async_done_cb, reader);
g_hash_table_insert (formatters, mail_uri, formatter);
+ e_mail_display_set_formatter (display, EM_FORMAT_HTML (formatter));
} else {
- EMailDisplay *display;
-
- display = e_mail_reader_get_mail_display (reader);
-
e_mail_display_set_formatter (display, EM_FORMAT_HTML (formatter));
e_mail_display_load (display, formatter->uri_base);
}
@@ -3757,6 +3866,12 @@ e_mail_reader_init (EMailReader *reader,
action, "activate",
G_CALLBACK (action_search_folder_sender_cb), reader);
+ action_name = "image-save";
+ action = e_mail_display_get_action (display, action_name);
+ g_signal_connect (
+ action, "activate",
+ G_CALLBACK (action_mail_image_save_cb), reader);
+
#ifndef G_OS_WIN32
/* Lockdown integration. */
diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c
index 5cdd3ef..47ed14e 100644
--- a/mail/em-format-html-display.c
+++ b/mail/em-format-html-display.c
@@ -675,173 +675,6 @@ efhd_parse_secure (EMFormat *emf,
}
static void
-attachment_load_finish (EAttachment *attachment,
- GAsyncResult *result,
- GFile *file)
-{
- EShell *shell;
- GtkWindow *parent;
-
- e_attachment_load_finish (attachment, result, NULL);
-
- shell = e_shell_get_default ();
- parent = e_shell_get_active_window (shell);
-
- e_attachment_save_async (
- attachment, file, (GAsyncReadyCallback)
- e_attachment_save_handle_error, parent);
-
- g_object_unref (file);
-}
-
-
-static void
-action_image_save_cb (GtkAction *action,
- EMFormatHTMLDisplay *efhd)
-{
-#if 0 /* FIXME WEBKIT */
- EWebView *web_view;
- EMFormat *emf;
- const gchar *image_src;
- CamelMimePart *part;
- EAttachment *attachment;
- GFile *file;
-
- /* FIXME WEBKIT At this moment there's no way how to get EMailDisplay from
- EMFormat(HTML)
- web_view = em_format_html_get_web_view (EM_FORMAT_HTML (efhd));
- g_return_if_fail (web_view != NULL);
- */
- return;
-
- image_src = e_web_view_get_cursor_image_src (web_view);
- if (!image_src)
- return;
-
- emf = EM_FORMAT (efhd);
- g_return_if_fail (emf != NULL);
- g_return_if_fail (emf->message != NULL);
-
- if (g_str_has_prefix (image_src, "cid:")) {
- part = camel_mime_message_get_part_by_content_id (
- emf->message, image_src + 4);
- g_return_if_fail (part != NULL);
-
- g_object_ref (part);
- } else {
- CamelStream *image_stream;
- CamelDataWrapper *dw;
- CamelDataCache *cache;
- const gchar *filename;
- const gchar *user_cache_dir;
-
- /* Open cache and find the file there */
- user_cache_dir = e_get_user_cache_dir ();
- cache = camel_data_cache_new (user_cache_dir, NULL);
- image_stream = camel_data_cache_get (cache, "http", image_src, NULL);
- if (!image_stream) {
- g_object_unref (cache);
- return;
- }
-
- filename = strrchr (image_src, '/');
- if (filename && strchr (filename, '?'))
- filename = NULL;
- else if (filename)
- filename = filename + 1;
-
- part = camel_mime_part_new ();
- if (filename)
- camel_mime_part_set_filename (part, filename);
-
- dw = camel_data_wrapper_new ();
- camel_data_wrapper_set_mime_type (
- dw, "application/octet-stream");
- camel_data_wrapper_construct_from_stream_sync (
- dw, image_stream, NULL, NULL);
- camel_medium_set_content (CAMEL_MEDIUM (part), dw);
- g_object_unref (dw);
-
- camel_mime_part_set_encoding (
- part, CAMEL_TRANSFER_ENCODING_BASE64);
-
- g_object_unref (image_stream);
- g_object_unref (cache);
- }
-
- file = e_shell_run_save_dialog (
- e_shell_get_default (),
- _("Save Image"), camel_mime_part_get_filename (part),
- NULL, NULL, NULL);
- if (file == NULL) {
- g_object_unref (part);
- return;
- }
-
- attachment = e_attachment_new ();
- e_attachment_set_mime_part (attachment, part);
-
- e_attachment_load_async (
- attachment, (GAsyncReadyCallback)
- attachment_load_finish, file);
-
- g_object_unref (part);
-#endif
-}
-
-static void
-efhd_web_view_update_actions_cb (EWebView *web_view,
- EMFormatHTMLDisplay *efhd)
-{
- const gchar *image_src;
- gboolean visible;
- GtkAction *action;
-
- g_return_if_fail (web_view != NULL);
-
- image_src = e_web_view_get_cursor_image_src (web_view);
- visible = image_src && g_str_has_prefix (image_src, "cid:");
- if (!visible && image_src) {
- CamelDataCache *cache;
- CamelStream *image_stream;
- const gchar *user_cache_dir;
-
- user_cache_dir = e_get_user_cache_dir ();
- cache = camel_data_cache_new (user_cache_dir, NULL);
- image_stream = camel_data_cache_get (cache, "http", image_src, NULL);
-
- visible = image_stream != NULL;
-
- if (image_stream)
- g_object_unref (image_stream);
-
- g_object_unref (cache);
- }
-
- action = e_web_view_get_action (web_view, "efhd-image-save");
- if (action)
- gtk_action_set_visible (action, visible);
-}
-
-static GtkActionEntry image_entries[] = {
- { "efhd-image-save",
- GTK_STOCK_SAVE,
- N_("Save _Image..."),
- NULL,
- N_("Save the image to a file"),
- G_CALLBACK (action_image_save_cb) }
-};
-
-static const gchar *image_ui =
- "<ui>"
- " <popup name='context'>"
- " <placeholder name='custom-actions-2'>"
- " <menuitem action='efhd-image-save'/>"
- " </placeholder>"
- " </popup>"
- "</ui>";
-
-static void
efhd_finalize (GObject *object)
{
EMFormatHTMLDisplay *efhd;
@@ -874,12 +707,6 @@ efhd_class_init (EMFormatHTMLDisplayClass *class)
static void
efhd_init (EMFormatHTMLDisplay *efhd)
{
- EWebView *web_view;
- GtkActionGroup *image_actions;
- GtkUIManager *ui_manager;
- GError *error = NULL;
-
-
efhd->priv = EM_FORMAT_HTML_DISPLAY_GET_PRIVATE (efhd);
/* we want to convert url's etc */
@@ -887,27 +714,6 @@ efhd_init (EMFormatHTMLDisplay *efhd)
CAMEL_MIME_FILTER_TOHTML_CONVERT_URLS |
CAMEL_MIME_FILTER_TOHTML_CONVERT_ADDRESSES;
-/* FIXME WEBKIT There's no way how to get web_view from EFHD for now...
- image_actions = e_web_view_get_action_group (web_view, "image");
- g_return_if_fail (image_actions != NULL);
-
- gtk_action_group_add_actions (
- image_actions, image_entries,
- G_N_ELEMENTS (image_entries), efhd);
-*/
- /* Because we are loading from a hard-coded string, there is
- * no chance of I/O errors. Failure here implies a malformed
- * UI definition. Full stop. */
-/* FIXME WEBKIT There 's no way how to get web_view from EFHD for now...
- ui_manager = e_web_view_get_ui_manager (web_view);
- gtk_ui_manager_add_ui_from_string (ui_manager, image_ui, -1, &error);
- if (error != NULL)
- g_error ("%s", error->message);
-
- g_signal_connect (
- web_view, "update-actions",
- G_CALLBACK (efhd_web_view_update_actions_cb), efhd);
-*/
}
GType
diff --git a/widgets/misc/e-web-view.c b/widgets/misc/e-web-view.c
index 0bdd4ac..b7af87f 100644
--- a/widgets/misc/e-web-view.c
+++ b/widgets/misc/e-web-view.c
@@ -719,6 +719,66 @@ web_view_button_press_event (GtkWidget *widget,
web_view = E_WEB_VIEW (widget);
+ if (event) {
+ WebKitHitTestResult *test;
+ WebKitHitTestResultContext context;
+
+ test = webkit_web_view_get_hit_test_result (WEBKIT_WEB_VIEW (web_view), event);
+
+ if (!test)
+ goto chainup;
+
+ g_object_get (G_OBJECT (test), "context", &context, NULL);
+ if (context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE) {
+ WebKitWebDataSource *data_source;
+ WebKitWebFrame *frame;
+ GList *subresources, *res;
+
+ g_object_get (G_OBJECT (test), "image-uri", &uri, NULL);
+
+ if (!uri)
+ goto chainup;
+
+ if (web_view->priv->cursor_image_src)
+ g_free (web_view->priv->cursor_image_src);
+ web_view->priv->cursor_image_src = uri;
+
+ /* Iterate through all resources of the loaded webpage and
+ try to find resource with URI matching cursor_image_src */
+ frame = webkit_web_view_get_main_frame (WEBKIT_WEB_VIEW (web_view));
+ data_source = webkit_web_frame_get_data_source (frame);
+ subresources = webkit_web_data_source_get_subresources (data_source);
+ for (res = subresources; res; res = res->next) {
+ WebKitWebResource *src = res->data;
+ GdkPixbufLoader *loader;
+ GString *data;
+
+ if (g_strcmp0 (webkit_web_resource_get_uri (src),
+ web_view->priv->cursor_image_src) != 0)
+ continue;
+
+ data = webkit_web_resource_get_data (src);
+
+ loader = gdk_pixbuf_loader_new ();
+ if (!gdk_pixbuf_loader_write (loader,
+ (guchar *) data->str, data->len, NULL)) {
+ g_object_unref (loader);
+ break;
+ }
+ gdk_pixbuf_loader_close (loader, NULL);
+
+ if (web_view->priv->cursor_image)
+ g_object_unref (web_view->priv->cursor_image);
+
+ web_view->priv->cursor_image =
+ g_object_ref (gdk_pixbuf_loader_get_animation (loader));
+
+ g_object_unref (loader);
+ break;
+ }
+ }
+ }
+
if (event != NULL && event->button != 3)
goto chainup;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]