evolution r35624 - trunk/widgets/misc



Author: mcrha
Date: Tue Jun 10 08:57:51 2008
New Revision: 35624
URL: http://svn.gnome.org/viewvc/evolution?rev=35624&view=rev

Log:
2008-06-10  Milan Crha  <mcrha redhat com>

	** 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.



Modified:
   trunk/widgets/misc/ChangeLog
   trunk/widgets/misc/e-attachment-bar.c

Modified: trunk/widgets/misc/e-attachment-bar.c
==============================================================================
--- trunk/widgets/misc/e-attachment-bar.c	(original)
+++ trunk/widgets/misc/e-attachment-bar.c	Tue Jun 10 08:57:51 2008
@@ -34,8 +34,13 @@
 #include <gconf/gconf-client.h>
 #include <gdk/gdkkeysyms.h>
 #include <glib/gi18n.h>
+#include <glib/gstdio.h>
 #include <libgnome/libgnome.h>
 
+#ifdef HAVE_LIBGNOMEUI_GNOME_THUMBNAIL_H
+#include <libgnomeui/gnome-thumbnail.h>
+#endif
+
 #include "e-attachment.h"
 #include "e-attachment-bar.h"
 
@@ -180,6 +185,149 @@
 	}
 }
 
+/* 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 @@
 		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 @@
 			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 @@
 			/* 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 @@
 				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) {



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]