talons

Fork of Claws Mail https://www.claws-mail
Log | Files | Refs | README | LICENSE

commit 3e3fa274fd7b3b9f0772c3141cd470deaaf65e37
parent 80108ed0f1bd1d9df477cef5336e90d660dbc67e
Author: Colin Leroy <colin@colino.net>
Date:   Sun,  7 Jul 2019 10:40:15 +0200

Implement copying of attached images to clipboard

Diffstat:
Msrc/mimeview.c | 38++++++++++++++++++++++++++++++++++++++
Msrc/procmime.c | 27+++++++++++++++++++++++++--
Msrc/procmime.h | 2++
Msrc/textview.c | 12++----------
4 files changed, 67 insertions(+), 12 deletions(-)

diff --git a/src/mimeview.c b/src/mimeview.c @@ -157,6 +157,33 @@ static void mimeview_open_with_cb(GtkAction *action, gpointer data) } #endif +static void mimeview_copy_cb(GtkAction *action, gpointer data) +{ + MimeView *mimeview = (MimeView *)data; + MimeInfo *mimeinfo = mimeview_get_part_to_use(mimeview); + + if (mimeinfo == NULL) + return; + + if (mimeinfo->type == MIMETYPE_IMAGE) { + GError *error = NULL; + GdkPixbuf *pixbuf = procmime_get_part_as_pixbuf(mimeinfo, &error); + if (error != NULL) { + g_warning("could not copy: %s", error->message); + g_error_free(error); + } else { + gtk_clipboard_set_image(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), + pixbuf); + } + g_object_unref(pixbuf); + } else { + void *data = procmime_get_part_as_string(mimeinfo, FALSE); + gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), + data, mimeinfo->length); + g_free(data); + } +} + static void mimeview_send_to_cb(GtkAction *action, gpointer data) { MimeView *mimeview = (MimeView *)data; @@ -194,6 +221,7 @@ static GtkActionEntry mimeview_menu_actions[] = { #if (!defined G_OS_WIN32) { "MimeView/OpenWith", NULL, N_("Open _with..."), NULL, "Open MIME part with...", G_CALLBACK(mimeview_open_with_cb) }, #endif + { "MimeView/Copy", NULL, N_("Copy"), NULL, "Copy", G_CALLBACK(mimeview_copy_cb) }, { "MimeView/SendTo", NULL, N_("Send to..."), NULL, "Send to", G_CALLBACK(mimeview_send_to_cb) }, { "MimeView/DisplayAsText", NULL, N_("_Display as text"), NULL, "Display as text", G_CALLBACK(mimeview_display_as_text_cb) }, { "MimeView/SaveAs", NULL, N_("_Save as..."), NULL, "Save as", G_CALLBACK(mimeview_save_as_cb) }, @@ -402,6 +430,9 @@ MimeView *mimeview_create(MainWindow *mainwin) GTK_UI_MANAGER_MENUITEM); #endif MENUITEM_ADDUI_MANAGER(mimeview->ui_manager, + "/Menus/MimeView/", "Copy", "MimeView/Copy", + GTK_UI_MANAGER_MENUITEM); + MENUITEM_ADDUI_MANAGER(mimeview->ui_manager, "/Menus/MimeView/", "SendTo", "MimeView/SendTo", GTK_UI_MANAGER_MENUITEM); MENUITEM_ADDUI_MANAGER(mimeview->ui_manager, @@ -1527,6 +1558,13 @@ static gboolean part_button_pressed(MimeView *mimeview, GdkEventButton *event, cm_menu_set_sensitive_full(mimeview->ui_manager, "Menus/MimeView/DisplayAsText", FALSE); else cm_menu_set_sensitive_full(mimeview->ui_manager, "Menus/MimeView/DisplayAsText", TRUE); + + if (partinfo && (partinfo->type == MIMETYPE_MESSAGE || + partinfo->type == MIMETYPE_IMAGE || + partinfo->type == MIMETYPE_TEXT)) + cm_menu_set_sensitive_full(mimeview->ui_manager, "Menus/MimeView/Copy", TRUE); + else + cm_menu_set_sensitive_full(mimeview->ui_manager, "Menus/MimeView/Copy", FALSE); #ifndef G_OS_WIN32 if (partinfo && partinfo->type == MIMETYPE_APPLICATION && diff --git a/src/procmime.c b/src/procmime.c @@ -2763,9 +2763,10 @@ GInputStream *procmime_get_part_as_inputstream(MimeInfo *mimeinfo) cm_return_val_if_fail(mimeinfo != NULL, NULL); if (mimeinfo->encoding_type != ENC_BINARY && - !procmime_decode_content(mimeinfo)) + !procmime_decode_content(mimeinfo)) { + g_warning("could not decode part"); return NULL; - + } if (mimeinfo->content == MIMECONTENT_MEM) { /* NULL for destroy func, since we're not copying * the data for the stream. */ @@ -2778,3 +2779,25 @@ GInputStream *procmime_get_part_as_inputstream(MimeInfo *mimeinfo) mimeinfo->length, g_free); } } + +GdkPixbuf *procmime_get_part_as_pixbuf(MimeInfo *mimeinfo, GError **error) +{ + GdkPixbuf *pixbuf; + GInputStream *stream; + + *error = NULL; + + stream = procmime_get_part_as_inputstream(mimeinfo); + if (stream == NULL) { + return NULL; + } + + pixbuf = gdk_pixbuf_new_from_stream(stream, NULL, error); + g_object_unref(stream); + + if (*error != NULL) { + return NULL; + } + return pixbuf; +} + diff --git a/src/procmime.h b/src/procmime.h @@ -25,6 +25,7 @@ #endif #include <gio/gio.h> +#include <gtk/gtk.h> #include "utils.h" #include "proctypes.h" @@ -244,6 +245,7 @@ gboolean procmime_scan_text_content(MimeInfo *mimeinfo, void *procmime_get_part_as_string(MimeInfo *mimeinfo, gboolean null_terminate); GInputStream *procmime_get_part_as_inputstream(MimeInfo *mimeinfo); +GdkPixbuf *procmime_get_part_as_pixbuf(MimeInfo *mimeinfo, GError **error); #ifdef __cplusplus } diff --git a/src/textview.c b/src/textview.c @@ -685,22 +685,14 @@ static void textview_add_part(TextView *textview, MimeInfo *mimeinfo) START_TIMING("inserting image"); - stream = procmime_get_part_as_inputstream(mimeinfo); - if (stream == NULL) { - g_warning("Can't get the image file"); - END_TIMING(); - return; - } - - pixbuf = gdk_pixbuf_new_from_stream(stream, NULL, &error); - g_object_unref(stream); - + pixbuf = procmime_get_part_as_pixbuf(mimeinfo, &error); if (error != NULL) { g_warning("Can't load the image: %s\n", error->message); g_error_free(error); END_TIMING(); return; } + if (textview->stop_loading) { END_TIMING(); return;