From 1931b88ebb2aa5887942f80c7353b686c27c5a81 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Tue, 10 Jun 2008 08:57:51 +0000 Subject: ** Fix for bug #340683 2008-06-10 Milan Crha ** Fix for bug #340683 * e-attachment-bar.c: (get_system_thumbnail), (scale_pixbuf), (e_attachment_bar_create_attachment_cache), (update): Allow creating thumbnails of non-pictures with a gnome's thumbnailer. svn path=/trunk/; revision=35624 --- widgets/misc/ChangeLog | 8 ++ widgets/misc/e-attachment-bar.c | 206 ++++++++++++++++++++++++++++++---------- 2 files changed, 166 insertions(+), 48 deletions(-) (limited to 'widgets') diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index 66b373f191..fa9ace0c85 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,11 @@ +2008-06-10 Milan Crha + + ** Fix for bug #340683 + + * e-attachment-bar.c: (get_system_thumbnail), (scale_pixbuf), + (e_attachment_bar_create_attachment_cache), (update): + Allow creating thumbnails of non-pictures with a gnome's thumbnailer. + 2008-06-03 Kjartan Maraas * e-cell-date-edit.c: (e_cell_date_edit_init): diff --git a/widgets/misc/e-attachment-bar.c b/widgets/misc/e-attachment-bar.c index 3acfd0d23e..09999bfff7 100644 --- a/widgets/misc/e-attachment-bar.c +++ b/widgets/misc/e-attachment-bar.c @@ -34,8 +34,13 @@ #include #include #include +#include #include +#ifdef HAVE_LIBGNOMEUI_GNOME_THUMBNAIL_H +#include +#endif + #include "e-attachment.h" #include "e-attachment-bar.h" @@ -180,6 +185,149 @@ add_from_file (EAttachmentBar *bar, const char *file_name, const char *dispositi } } +/* get_system_thumbnail: + * If filled store_uri, then creating thumbnail for it, otherwise, if is_available_local, + * and attachment is not an application, then save to temp and create a thumbnail for the body. + * Otherwise returns NULL (or if something goes wrong/library not available). + */ +static GdkPixbuf * +get_system_thumbnail (EAttachment *attachment, CamelContentType *content_type) +{ + GdkPixbuf *pixbuf = NULL; +#ifdef HAVE_LIBGNOMEUI_GNOME_THUMBNAIL_H + struct stat file_stat; + char *file_uri = NULL; + gboolean is_tmp = FALSE; + + if (!attachment || !attachment->is_available_local) + return NULL; + + if (attachment->store_uri && g_str_has_prefix (attachment->store_uri, "file://")) + file_uri = attachment->store_uri; + else if (attachment->body) { + /* save part to the temp directory */ + char *tmp_file; + + is_tmp = TRUE; + + tmp_file = e_mktemp ("tmp-XXXXXX"); + if (tmp_file) { + CamelStream *stream; + char *mfilename = NULL; + const char * filename; + + filename = camel_mime_part_get_filename (attachment->body); + if (filename == NULL) + filename = "unknown"; + else { + char *utf8_mfilename; + + utf8_mfilename = g_strdup (filename); + e_filename_make_safe (utf8_mfilename); + mfilename = g_filename_from_utf8 ((const char *) utf8_mfilename, -1, NULL, NULL, NULL); + g_free (utf8_mfilename); + + filename = (const char *) mfilename; + } + + file_uri = g_strjoin (NULL, "file://", tmp_file, "-", filename, NULL); + + stream = camel_stream_fs_new_with_name (file_uri + 7, O_WRONLY | O_CREAT | O_TRUNC, 0644); + if (stream) { + CamelDataWrapper *content; + + content = camel_medium_get_content_object (CAMEL_MEDIUM (attachment->body)); + + if (camel_data_wrapper_decode_to_stream (content, stream) == -1 + || camel_stream_flush (stream) == -1) { + g_free (file_uri); + file_uri = NULL; + } + + camel_object_unref (stream); + } else { + g_free (file_uri); + file_uri = NULL; + } + + g_free (mfilename); + g_free (tmp_file); + } + } + + if (!file_uri || !g_str_has_prefix (file_uri, "file://")) { + if (is_tmp) + g_free (file_uri); + + return NULL; + } + + if (stat (file_uri + 7, &file_stat) != -1 && S_ISREG (file_stat.st_mode)) { + GnomeThumbnailFactory *th_factory; + char *th_file; + + th_factory = gnome_thumbnail_factory_new (GNOME_THUMBNAIL_SIZE_NORMAL); + th_file = gnome_thumbnail_factory_lookup (th_factory, file_uri, file_stat.st_mtime); + + if (th_file) { + pixbuf = gdk_pixbuf_new_from_file (th_file, NULL); + g_free (th_file); + } else if (content_type) { + char *mime = camel_content_type_simple (content_type); + + if (gnome_thumbnail_factory_can_thumbnail (th_factory, file_uri, mime, file_stat.st_mtime)) { + pixbuf = gnome_thumbnail_factory_generate_thumbnail (th_factory, file_uri, mime); + + if (pixbuf && !is_tmp) + gnome_thumbnail_factory_save_thumbnail (th_factory, pixbuf, file_uri, file_stat.st_mtime); + } + + g_free (mime); + } + + g_object_unref (th_factory); + } + + if (is_tmp) { + /* clear the temp */ + g_remove (file_uri + 7); + g_free (file_uri); + } +#endif + + return pixbuf; +} + +static GdkPixbuf * +scale_pixbuf (GdkPixbuf *pixbuf) +{ + int ratio, width, height; + + if (!pixbuf) + return NULL; + + width = gdk_pixbuf_get_width (pixbuf); + height = gdk_pixbuf_get_height (pixbuf); + if (width >= height) { + if (width > 48) { + ratio = width / 48; + width = 48; + height = height / ratio; + if (height == 0) + height = 1; + } + } else { + if (height > 48) { + ratio = height / 48; + height = 48; + width = width / ratio; + if (width == 0) + width = 1; + } + } + + return e_icon_factory_pixbuf_scale (pixbuf, width, height); +} /* Icon list contents handling. */ @@ -236,31 +384,8 @@ e_attachment_bar_create_attachment_cache (EAttachment *attachment) gdk_pixbuf_loader_close (loader, NULL); if (!error) { - int ratio, width, height; - - /* Shrink pixbuf */ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - if (width >= height) { - if (width > 48) { - ratio = width / 48; - width = 48; - height = height / ratio; - if (height == 0) - height = 1; - } - } else { - if (height > 48) { - ratio = height / 48; - height = 48; - width = width / ratio; - if (width == 0) - width = 1; - } - } - - attachment->pixbuf_cache = e_icon_factory_pixbuf_scale (pixbuf, width, height); + attachment->pixbuf_cache = scale_pixbuf (pixbuf); pixbuf = attachment->pixbuf_cache; g_object_ref(pixbuf); } else { @@ -329,31 +454,8 @@ update (EAttachmentBar *bar) gdk_pixbuf_loader_close (loader, NULL); if (!error) { - int ratio, width, height; - - /* Shrink pixbuf */ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); - width = gdk_pixbuf_get_width (pixbuf); - height = gdk_pixbuf_get_height (pixbuf); - if (width >= height) { - if (width > 48) { - ratio = width / 48; - width = 48; - height = height / ratio; - if (height == 0) - height = 1; - } - } else { - if (height > 48) { - ratio = height / 48; - height = 48; - width = width / ratio; - if (width == 0) - width = 1; - } - } - - attachment->pixbuf_cache = e_icon_factory_pixbuf_scale (pixbuf, width, height); + attachment->pixbuf_cache = scale_pixbuf (pixbuf); pixbuf = attachment->pixbuf_cache; g_object_ref (pixbuf); } else { @@ -364,6 +466,10 @@ update (EAttachmentBar *bar) /* Destroy everything */ g_object_unref (loader); camel_object_unref (mstream); + } else if (!bar->expand && (pixbuf = get_system_thumbnail (attachment, content_type))) { + attachment->pixbuf_cache = scale_pixbuf (pixbuf); + pixbuf = attachment->pixbuf_cache; + g_object_ref (pixbuf); } desc = camel_mime_part_get_description (attachment->body); @@ -393,6 +499,10 @@ update (EAttachmentBar *bar) pixbuf = e_icon_factory_get_icon("mail-attachment", E_ICON_SIZE_DIALOG); } g_free (mime_type); + + /* remember this picture and use it later again */ + if (pixbuf) + attachment->pixbuf_cache = g_object_ref (pixbuf); } if (pixbuf) { -- cgit v1.2.3