From d20e186ce7f59d1524fb8946b5dbf7983fbd7802 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Mon, 16 May 2011 13:21:22 +0200 Subject: Bug #601541 - Add 'Copy Image' Option On Inline Email Images --- configure.ac | 2 +- mail/e-mail-browser.c | 6 ++ modules/mail/e-mail-shell-view-private.c | 7 +- widgets/misc/e-web-view.c | 111 ++++++++++++++++++++++++++++++- widgets/misc/e-web-view.h | 3 + 5 files changed, 126 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index f21ff24740..4d1e0915a5 100644 --- a/configure.ac +++ b/configure.ac @@ -38,7 +38,7 @@ dnl Required Packages m4_define([glib_minimum_version], [2.28]) m4_define([gtk_minimum_version], [3.0.2]) m4_define([eds_minimum_version], [evo_version]) -m4_define([gtkhtml_minimum_version], [3.91.3]) +m4_define([gtkhtml_minimum_version], [4.1.2]) m4_define([gnome_desktop_minimum_version], [2.91.3]) m4_define([gnome_icon_theme_minimum_version], [2.30.2.1]) m4_define([gsettings_desktop_schemas_minimum_version], [2.91.92]) diff --git a/mail/e-mail-browser.c b/mail/e-mail-browser.c index 6866913ff4..900ba63052 100644 --- a/mail/e-mail-browser.c +++ b/mail/e-mail-browser.c @@ -311,6 +311,7 @@ mail_browser_popup_event_cb (EMailBrowser *browser, GdkEventButton *event, const gchar *uri) { + EMFormatHTML *html_formatter; EMailReader *reader; GtkMenu *menu; guint32 state; @@ -319,6 +320,11 @@ mail_browser_popup_event_cb (EMailBrowser *browser, return FALSE; reader = E_MAIL_READER (browser); + html_formatter = e_mail_reader_get_formatter (reader); + + if (html_formatter && e_web_view_get_cursor_image (em_format_html_get_web_view (html_formatter)) != NULL) + return FALSE; + menu = e_mail_reader_get_popup_menu (reader); state = e_mail_reader_check_state (reader); diff --git a/modules/mail/e-mail-shell-view-private.c b/modules/mail/e-mail-shell-view-private.c index 55357fae11..8cc7d45c85 100644 --- a/modules/mail/e-mail-shell-view-private.c +++ b/modules/mail/e-mail-shell-view-private.c @@ -326,6 +326,7 @@ mail_shell_view_popup_event_cb (EMailShellView *mail_shell_view, const gchar *uri) { EMailShellContent *mail_shell_content; + EMFormatHTML *html_formatter; EShellView *shell_view; EMailReader *reader; EMailView *mail_view; @@ -338,8 +339,12 @@ mail_shell_view_popup_event_cb (EMailShellView *mail_shell_view, mail_view = e_mail_shell_content_get_mail_view (mail_shell_content); reader = E_MAIL_READER (mail_view); - menu = e_mail_reader_get_popup_menu (reader); + html_formatter = e_mail_reader_get_formatter (reader); + + if (html_formatter && e_web_view_get_cursor_image (em_format_html_get_web_view (html_formatter)) != NULL) + return FALSE; + menu = e_mail_reader_get_popup_menu (reader); shell_view = E_SHELL_VIEW (mail_shell_view); e_shell_view_update_actions (shell_view); diff --git a/widgets/misc/e-web-view.c b/widgets/misc/e-web-view.c index 347e8f1127..e7153761ac 100644 --- a/widgets/misc/e-web-view.c +++ b/widgets/misc/e-web-view.c @@ -43,6 +43,7 @@ struct _EWebViewPrivate { GList *requests; GtkUIManager *ui_manager; gchar *selected_uri; + GdkPixbufAnimation *cursor_image; GtkAction *open_proxy; GtkAction *print_proxy; @@ -80,7 +81,8 @@ enum { PROP_PASTE_TARGET_LIST, PROP_PRINT_PROXY, PROP_SAVE_AS_PROXY, - PROP_SELECTED_URI + PROP_SELECTED_URI, + PROP_CURSOR_IMAGE }; enum { @@ -113,6 +115,7 @@ static const gchar *ui = " " " " " " +" " " " " " " " @@ -375,6 +378,26 @@ action_uri_copy_cb (GtkAction *action, gtk_clipboard_store (clipboard); } +static void +action_image_copy_cb (GtkAction *action, + EWebView *web_view) +{ + GtkClipboard *clipboard; + GdkPixbufAnimation *animation; + GdkPixbuf *pixbuf; + + clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); + animation = e_web_view_get_cursor_image (web_view); + g_return_if_fail (animation != NULL); + + pixbuf = gdk_pixbuf_animation_get_static_image (animation); + if (!pixbuf) + return; + + gtk_clipboard_set_image (clipboard, pixbuf); + gtk_clipboard_store (clipboard); +} + static GtkActionEntry uri_entries[] = { { "uri-copy", @@ -412,6 +435,16 @@ static GtkActionEntry mailto_entries[] = { G_CALLBACK (action_send_message_cb) } }; +static GtkActionEntry image_entries[] = { + + { "image-copy", + GTK_STOCK_COPY, + N_("_Copy Image"), + NULL, + N_("Copy the image to the clipboard"), + G_CALLBACK (action_image_copy_cb) } +}; + static GtkActionEntry selection_entries[] = { { "copy-clipboard", @@ -440,6 +473,15 @@ web_view_button_press_event_cb (EWebView *web_view, gboolean event_handled = FALSE; gchar *uri = NULL; + if (event) { + GdkPixbufAnimation *anim; + + anim = gtk_html_get_image_at (frame ? frame : GTK_HTML (web_view), event->x, event->y); + e_web_view_set_cursor_image (web_view, anim); + if (anim) + g_object_unref (anim); + } + if (event != NULL && event->button != 3) return FALSE; @@ -582,6 +624,11 @@ web_view_set_property (GObject *object, E_WEB_VIEW (object), g_value_get_string (value)); return; + case PROP_CURSOR_IMAGE: + e_web_view_set_cursor_image ( + E_WEB_VIEW (object), + g_value_get_object (value)); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -677,6 +724,12 @@ web_view_get_property (GObject *object, value, e_web_view_get_selected_uri ( E_WEB_VIEW (object))); return; + + case PROP_CURSOR_IMAGE: + g_value_set_object ( + value, e_web_view_get_cursor_image ( + E_WEB_VIEW (object))); + return; } G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); @@ -719,6 +772,11 @@ web_view_dispose (GObject *object) priv->paste_target_list = NULL; } + if (priv->cursor_image) { + g_object_unref (priv->cursor_image); + priv->cursor_image = NULL; + } + /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -995,12 +1053,14 @@ web_view_update_actions (EWebView *web_view) gboolean scheme_is_http = FALSE; gboolean scheme_is_mailto = FALSE; gboolean uri_is_valid = FALSE; + gboolean has_cursor_image; gboolean visible; const gchar *group_name; const gchar *uri; uri = e_web_view_get_selected_uri (web_view); have_selection = e_web_view_is_selection_active (web_view); + has_cursor_image = e_web_view_get_cursor_image (web_view) != NULL; /* Parse the URI early so we know if the actions will work. */ if (uri != NULL) { @@ -1034,6 +1094,11 @@ web_view_update_actions (EWebView *web_view) action_group = e_web_view_get_action_group (web_view, group_name); gtk_action_group_set_visible (action_group, visible); + group_name = "image"; + visible = has_cursor_image; + action_group = e_web_view_get_action_group (web_view, group_name); + gtk_action_group_set_visible (action_group, visible); + group_name = "selection"; visible = have_selection; action_group = e_web_view_get_action_group (web_view, group_name); @@ -1419,6 +1484,16 @@ e_web_view_class_init (EWebViewClass *class) NULL, G_PARAM_READWRITE)); + g_object_class_install_property ( + object_class, + PROP_CURSOR_IMAGE, + g_param_spec_object ( + "cursor-image", + "Image animation at the mouse cursor", + NULL, + GDK_TYPE_PIXBUF_ANIMATION, + G_PARAM_READWRITE)); + signals[COPY_CLIPBOARD] = g_signal_new ( "copy-clipboard", G_TYPE_FROM_CLASS (class), @@ -1565,6 +1640,15 @@ e_web_view_init (EWebView *web_view) action_group, mailto_entries, G_N_ELEMENTS (mailto_entries), web_view); + action_group = gtk_action_group_new ("image"); + gtk_action_group_set_translation_domain (action_group, domain); + gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); + g_object_unref (action_group); + + gtk_action_group_add_actions ( + action_group, image_entries, + G_N_ELEMENTS (image_entries), web_view); + action_group = gtk_action_group_new ("selection"); gtk_action_group_set_translation_domain (action_group, domain); gtk_ui_manager_insert_action_group (ui_manager, action_group, 0); @@ -1889,6 +1973,31 @@ e_web_view_set_selected_uri (EWebView *web_view, g_object_notify (G_OBJECT (web_view), "selected-uri"); } +GdkPixbufAnimation * +e_web_view_get_cursor_image (EWebView *web_view) +{ + g_return_val_if_fail (E_IS_WEB_VIEW (web_view), NULL); + + return web_view->priv->cursor_image; +} + +void +e_web_view_set_cursor_image (EWebView *web_view, + GdkPixbufAnimation *image) +{ + g_return_if_fail (E_IS_WEB_VIEW (web_view)); + + if (image) + g_object_ref (image); + + if (web_view->priv->cursor_image) + g_object_unref (web_view->priv->cursor_image); + + web_view->priv->cursor_image = image; + + g_object_notify (G_OBJECT (web_view), "cursor-image"); +} + GtkAction * e_web_view_get_open_proxy (EWebView *web_view) { diff --git a/widgets/misc/e-web-view.h b/widgets/misc/e-web-view.h index f43b8bcaee..ed9017e3bd 100644 --- a/widgets/misc/e-web-view.h +++ b/widgets/misc/e-web-view.h @@ -124,6 +124,9 @@ void e_web_view_set_magic_smileys (EWebView *web_view, const gchar * e_web_view_get_selected_uri (EWebView *web_view); void e_web_view_set_selected_uri (EWebView *web_view, const gchar *selected_uri); +GdkPixbufAnimation * e_web_view_get_cursor_image(EWebView *web_view); +void e_web_view_set_cursor_image (EWebView *web_view, + GdkPixbufAnimation *animation); GtkAction * e_web_view_get_open_proxy (EWebView *web_view); void e_web_view_set_open_proxy (EWebView *web_view, GtkAction *open_proxy); -- cgit v1.2.3