[file-roller: 15/26] usa an icon cache per window, fixed creation of the icon's pixbuf



commit cc8717679bf600221998d1ace594c8adc168e46e
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Thu Aug 9 13:05:13 2012 +0200

    usa an icon cache per window, fixed creation of the icon's pixbuf

 src/fr-file-selector-dialog.c |   27 +++++-
 src/fr-window.c               |  225 +++++++++++++----------------------------
 src/gth-icon-cache.c          |  103 +++++--------------
 src/gth-icon-cache.h          |    7 +-
 src/gtk-utils.c               |   74 ++++----------
 5 files changed, 148 insertions(+), 288 deletions(-)
---
diff --git a/src/fr-file-selector-dialog.c b/src/fr-file-selector-dialog.c
index 4f6d8ce..f150590 100644
--- a/src/fr-file-selector-dialog.c
+++ b/src/fr-file-selector-dialog.c
@@ -162,7 +162,6 @@ fr_file_selector_dialog_finalize (GObject *object)
 	self = FR_FILE_SELECTOR_DIALOG (object);
 	g_object_unref (self->priv->builder);
 	_g_object_unref (self->priv->current_folder);
-	gth_icon_cache_free (self->priv->icon_cache);
 	g_object_unref (self->priv->settings);
 	_g_object_list_unref (self->priv->special_places);
 	bookmark_list_free (self->priv->bookmarks);
@@ -670,10 +669,17 @@ static void
 fr_file_selector_dialog_realize (GtkWidget *widget)
 {
 	FrFileSelectorDialog *self;
+	GIcon                *icon;
 
 	GTK_WIDGET_CLASS (fr_file_selector_dialog_parent_class)->realize (widget);
 
 	self = FR_FILE_SELECTOR_DIALOG (widget);
+
+	self->priv->icon_cache = gth_icon_cache_new_for_widget (GTK_WIDGET (self), GTK_ICON_SIZE_MENU);
+	icon = g_content_type_get_icon ("text/plain");
+	gth_icon_cache_set_fallback (self->priv->icon_cache, icon);
+	g_object_unref (icon);
+
 	_fr_file_selector_dialog_update_size (self);
 
 	update_places_list (self);
@@ -682,6 +688,20 @@ fr_file_selector_dialog_realize (GtkWidget *widget)
 
 
 static void
+fr_file_selector_dialog_unrealize (GtkWidget *widget)
+{
+	FrFileSelectorDialog *self;
+
+	self = FR_FILE_SELECTOR_DIALOG (widget);
+
+	gth_icon_cache_free (self->priv->icon_cache);
+	self->priv->icon_cache = NULL;
+
+	GTK_WIDGET_CLASS (fr_file_selector_dialog_parent_class)->unrealize (widget);
+}
+
+
+static void
 fr_file_selector_dialog_unmap (GtkWidget *widget)
 {
 	FrFileSelectorDialog *self;
@@ -717,6 +737,7 @@ fr_file_selector_dialog_class_init (FrFileSelectorDialogClass *klass)
 
 	widget_class = (GtkWidgetClass *) klass;
 	widget_class->realize = fr_file_selector_dialog_realize;
+	widget_class->unrealize = fr_file_selector_dialog_unrealize;
 	widget_class->unmap = fr_file_selector_dialog_unmap;
 }
 
@@ -1017,7 +1038,7 @@ fr_file_selector_dialog_init (FrFileSelectorDialog *self)
 	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, FR_TYPE_FILE_SELECTOR_DIALOG, FrFileSelectorDialogPrivate);
 	self->priv->current_folder = NULL;
 	self->priv->builder = _gtk_builder_new_from_resource ("file-selector.ui");
-	self->priv->icon_cache = gth_icon_cache_new_for_widget (GTK_WIDGET (self), GTK_ICON_SIZE_MENU);
+	self->priv->icon_cache = NULL;
 	self->priv->settings = g_settings_new ("org.gnome.FileRoller.FileSelector");
 	self->priv->special_places = NULL;
 	self->priv->show_hidden = g_settings_get_boolean (self->priv->settings, PREF_FILE_SELECTOR_SHOW_HIDDEN);
@@ -1234,7 +1255,7 @@ get_folder_content_done_cb (GError   *error,
 		g_free (modified);
 		g_date_time_unref (datetime);
 		g_free (size);
-		g_object_unref (icon_pixbuf);
+		_g_object_unref (icon_pixbuf);
 	}
 
 	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (GET_WIDGET ("files_liststore")), sort_column_id, sort_order);
diff --git a/src/fr-window.c b/src/fr-window.c
index ae1d654..0531152 100644
--- a/src/fr-window.c
+++ b/src/fr-window.c
@@ -52,6 +52,7 @@
 #include "file-data.h"
 #include "file-utils.h"
 #include "glib-utils.h"
+#include "gth-icon-cache.h"
 #include "fr-init.h"
 #include "gtk-utils.h"
 #include "open-file.h"
@@ -83,12 +84,6 @@
 
 #define BAD_CHARS "/\\*"
 
-static GHashTable     *pixbuf_hash = NULL;
-static GHashTable     *tree_pixbuf_hash = NULL;
-static GtkIconTheme   *icon_theme = NULL;
-static int             file_list_icon_size = 0;
-static int             dir_tree_icon_size = 0;
-
 #define XDS_FILENAME "xds.txt"
 #define MAX_XDS_ATOM_VAL_LEN 4096
 #define XDS_ATOM   gdk_atom_intern  ("XdndDirectSave0", FALSE)
@@ -408,6 +403,9 @@ struct _FrWindowPrivate {
 
 	GtkWindow        *load_error_parent_window;
 	gboolean          showing_error_dialog;
+
+	GthIconCache     *list_icon_cache;
+	GthIconCache     *tree_icon_cache;
 };
 
 
@@ -437,15 +435,6 @@ fr_window_free_batch_data (FrWindow *window)
 
 
 static void
-gh_unref_pixbuf (gpointer key,
-		 gpointer value,
-		 gpointer user_data)
-{
-	g_object_unref (value);
-}
-
-
-static void
 fr_window_clipboard_remove_file_list (FrWindow *window,
 				      GList    *file_list)
 {
@@ -567,7 +556,7 @@ fr_window_free_private_data (FrWindow *window)
 	}
 
 	if (window->priv->theme_changed_handler_id != 0)
-		g_signal_handler_disconnect (icon_theme, window->priv->theme_changed_handler_id);
+		g_signal_handler_disconnect (gtk_icon_theme_get_default (), window->priv->theme_changed_handler_id);
 
 	fr_window_history_clear (window);
 
@@ -690,23 +679,6 @@ fr_window_finalize (GObject *object)
 		window->priv = NULL;
 	}
 
-	if (gtk_application_get_windows (GTK_APPLICATION (g_application_get_default ())) == NULL) {
-		if (pixbuf_hash != NULL) {
-			g_hash_table_foreach (pixbuf_hash,
-					      gh_unref_pixbuf,
-					      NULL);
-			g_hash_table_destroy (pixbuf_hash);
-			pixbuf_hash = NULL;
-		}
-		if (tree_pixbuf_hash != NULL) {
-			g_hash_table_foreach (tree_pixbuf_hash,
-					      gh_unref_pixbuf,
-					      NULL);
-			g_hash_table_destroy (tree_pixbuf_hash);
-			tree_pixbuf_hash = NULL;
-		}
-	}
-
 	G_OBJECT_CLASS (fr_window_parent_class)->finalize (object);
 }
 
@@ -801,12 +773,22 @@ clipboard_owner_change_cb (GtkClipboard *clipboard,
 
 
 static void
-fr_window_realized (GtkWidget *window,
+fr_window_realized (GtkWidget *widget,
 		    gpointer  *data)
 {
+	FrWindow     *window = FR_WINDOW (widget);
+	GIcon        *icon;
 	GtkClipboard *clipboard;
 
-	clipboard = gtk_widget_get_clipboard (window, FR_CLIPBOARD);
+	window->priv->list_icon_cache = gth_icon_cache_new_for_widget (GTK_WIDGET (window), GTK_ICON_SIZE_MENU);
+	window->priv->tree_icon_cache = gth_icon_cache_new_for_widget (GTK_WIDGET (window), GTK_ICON_SIZE_MENU);
+
+	icon = g_content_type_get_icon ("text/plain");
+	gth_icon_cache_set_fallback (window->priv->list_icon_cache, icon);
+	gth_icon_cache_set_fallback (window->priv->tree_icon_cache, icon);
+	g_object_unref (icon);
+
+	clipboard = gtk_widget_get_clipboard (widget, FR_CLIPBOARD);
 	g_signal_connect (clipboard,
 			  "owner_change",
 			  G_CALLBACK (clipboard_owner_change_cb),
@@ -815,12 +797,19 @@ fr_window_realized (GtkWidget *window,
 
 
 static void
-fr_window_unrealized (GtkWidget *window,
+fr_window_unrealized (GtkWidget *widget,
 		      gpointer  *data)
 {
+	FrWindow     *window = FR_WINDOW (widget);
 	GtkClipboard *clipboard;
 
-	clipboard = gtk_widget_get_clipboard (window, FR_CLIPBOARD);
+	gth_icon_cache_free (window->priv->list_icon_cache);
+	window->priv->list_icon_cache = NULL;
+
+	gth_icon_cache_free (window->priv->tree_icon_cache);
+	window->priv->tree_icon_cache = NULL;
+
+	clipboard = gtk_widget_get_clipboard (widget, FR_CLIPBOARD);
 	g_signal_handlers_disconnect_by_func (clipboard,
 					      G_CALLBACK (clipboard_owner_change_cb),
 					      window);
@@ -1573,102 +1562,67 @@ get_parent_dir (const char *current_dir)
 
 
 static GdkPixbuf *
-get_mime_type_icon (const char *mime_type)
+get_mime_type_icon (FrWindow   *window,
+		    const char *mime_type)
 {
-	GdkPixbuf *pixbuf = NULL;
+	GIcon     *icon;
+	GdkPixbuf *pixbuf;
 
-	pixbuf = g_hash_table_lookup (tree_pixbuf_hash, mime_type);
-	if (pixbuf != NULL) {
-		g_object_ref (G_OBJECT (pixbuf));
-		return pixbuf;
-	}
+	icon = g_content_type_get_icon (mime_type);
+	pixbuf = gth_icon_cache_get_pixbuf (window->priv->tree_icon_cache, icon);
 
-	pixbuf = _g_mime_type_get_icon (mime_type, file_list_icon_size, icon_theme);
-	if (pixbuf == NULL)
-		return NULL;
-
-	pixbuf = gdk_pixbuf_copy (pixbuf);
-	g_hash_table_insert (tree_pixbuf_hash, (gpointer) mime_type, pixbuf);
-	g_object_ref (G_OBJECT (pixbuf));
+	g_object_unref (icon);
 
 	return pixbuf;
 }
 
 
 static GdkPixbuf *
-get_icon (GtkWidget *widget,
+get_icon (FrWindow  *window,
 	  FileData  *fdata)
 {
-	GdkPixbuf  *pixbuf = NULL;
-	const char *content_type;
-	GIcon      *icon;
-
-	if (fdata->link != NULL) {
-		pixbuf = g_hash_table_lookup (pixbuf_hash, "emblem-symbolic-link");
-		if (pixbuf != NULL)
-			return g_object_ref (G_OBJECT (pixbuf));
+	GIcon     *icon = NULL;
+	GdkPixbuf *pixbuf = NULL;
 
-		pixbuf = gtk_icon_theme_load_icon (icon_theme,
-						   "emblem-symbolic-link",
-						   file_list_icon_size,
-						   0,
-						   NULL);
-		g_hash_table_insert (pixbuf_hash, (gpointer) "emblem-symbolic-link", pixbuf);
+	if (fdata->link != NULL)
+		icon = g_themed_icon_new ("emblem-symbolic-link");
+	else {
+		const char *content_type;
 
-		return g_object_ref (G_OBJECT (pixbuf));
+		if (file_data_is_dir (fdata))
+			content_type = MIME_TYPE_DIRECTORY;
+		else
+			content_type = fdata->content_type;
+		icon = g_content_type_get_icon (content_type);
 	}
 
-	if (file_data_is_dir (fdata))
-		content_type = MIME_TYPE_DIRECTORY;
-	else
-		content_type = fdata->content_type;
-
-	/* look in the hash table. */
-
-	pixbuf = g_hash_table_lookup (pixbuf_hash, content_type);
-	if (pixbuf != NULL)
-		return g_object_ref (G_OBJECT (pixbuf));
-
-	icon = g_content_type_get_icon (content_type);
-	pixbuf = _g_icon_get_pixbuf (icon, file_list_icon_size, icon_theme);
+	pixbuf = gth_icon_cache_get_pixbuf (window->priv->list_icon_cache, icon);
 	g_object_unref (icon);
 
-	if (pixbuf == NULL)
-		return NULL;
-
-	g_hash_table_insert (pixbuf_hash, (gpointer) content_type, pixbuf);
-
-	return g_object_ref (G_OBJECT (pixbuf));
+	return pixbuf;
 }
 
 
 static GdkPixbuf *
-get_emblem (GtkWidget *widget,
-	    FileData  *fdata)
+get_emblem (FrWindow *window,
+	    FileData *fdata)
 {
-	const char *emblem_name = NULL;
+	const char *emblem_name;
+	GIcon      *icon;
 	GdkPixbuf  *pixbuf;
 
+	emblem_name = NULL;
 	if (fdata->encrypted)
 		emblem_name = "emblem-nowrite";
 
 	if (emblem_name == NULL)
 		return NULL;
 
-	pixbuf = g_hash_table_lookup (pixbuf_hash, emblem_name);
-	if (pixbuf != NULL) {
-		g_object_ref (G_OBJECT (pixbuf));
-		return pixbuf;
-	}
-
-	pixbuf = gtk_icon_theme_load_icon (icon_theme,
-					   emblem_name,
-					   file_list_icon_size,
-					   0,
-					   NULL);
-	g_hash_table_insert (pixbuf_hash, (gpointer) emblem_name, pixbuf);
+	icon = g_themed_icon_new (emblem_name);
+	pixbuf = gth_icon_cache_get_pixbuf (window->priv->list_icon_cache, icon);
+	g_object_unref (icon);
 
-	return g_object_ref (G_OBJECT (pixbuf));
+	return pixbuf;
 }
 
 
@@ -1761,9 +1715,9 @@ fr_window_populate_file_list (FrWindow  *window,
 
 		gtk_list_store_append (window->priv->list_store, &iter);
 
-		icon = get_icon (GTK_WIDGET (window), fdata);
+		icon = get_icon (window, fdata);
+		emblem = get_emblem (window, fdata);
 		utf8_name = g_filename_display_name (fdata->list_name);
-		emblem = get_emblem (GTK_WIDGET (window), fdata);
 
 		if (file_data_is_dir (fdata)) {
 			char *utf8_path;
@@ -1826,11 +1780,10 @@ fr_window_populate_file_list (FrWindow  *window,
 			g_free (s_size);
 			g_free (s_time);
 		}
+
 		g_free (utf8_name);
-		if (icon != NULL)
-			g_object_unref (icon);
-		if (emblem != NULL)
-			g_object_unref (emblem);
+		_g_object_unref (icon);
+		_g_object_unref (emblem);
 	}
 
 	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (window->priv->list_store),
@@ -2001,7 +1954,7 @@ fr_window_update_dir_tree (FrWindow *window)
 
 	/**/
 
-	icon = get_mime_type_icon (MIME_TYPE_ARCHIVE);
+	icon = get_mime_type_icon (window, MIME_TYPE_ARCHIVE);
 	{
 		GtkTreeIter  node;
 		char        *name;
@@ -2023,7 +1976,7 @@ fr_window_update_dir_tree (FrWindow *window)
 
 	/**/
 
-	icon = get_mime_type_icon (MIME_TYPE_DIRECTORY);
+	icon = get_mime_type_icon (window, MIME_TYPE_DIRECTORY);
 	for (i = 0; i < dirs->len; i++) {
 		char        *dir = g_ptr_array_index (dirs, i);
 		char        *parent_dir;
@@ -5192,20 +5145,8 @@ pref_use_mime_icons_changed (GSettings  *settings,
 {
 	FrWindow *window = user_data;
 
-	if (pixbuf_hash != NULL) {
-		g_hash_table_foreach (pixbuf_hash,
-				      gh_unref_pixbuf,
-				      NULL);
-		g_hash_table_destroy (pixbuf_hash);
-		pixbuf_hash = g_hash_table_new (g_str_hash, g_str_equal);
-	}
-	if (tree_pixbuf_hash != NULL) {
-		g_hash_table_foreach (tree_pixbuf_hash,
-				      gh_unref_pixbuf,
-				      NULL);
-		g_hash_table_destroy (tree_pixbuf_hash);
-		tree_pixbuf_hash = g_hash_table_new (g_str_hash, g_str_equal);
-	}
+	gth_icon_cache_clear (window->priv->list_icon_cache);
+	gth_icon_cache_clear (window->priv->tree_icon_cache);
 
 	fr_window_update_file_list (window, FALSE);
 	fr_window_update_dir_tree (window);
@@ -5213,25 +5154,11 @@ pref_use_mime_icons_changed (GSettings  *settings,
 
 
 static void
-theme_changed_cb (GtkIconTheme *theme, FrWindow *window)
+theme_changed_cb (GtkIconTheme *theme,
+		  FrWindow     *window)
 {
-	file_list_icon_size = _gtk_widget_lookup_for_size (GTK_WIDGET (window), FILE_LIST_ICON_SIZE);
-	dir_tree_icon_size = _gtk_widget_lookup_for_size (GTK_WIDGET (window), DIR_TREE_ICON_SIZE);
-
-	if (pixbuf_hash != NULL) {
-		g_hash_table_foreach (pixbuf_hash,
-				      gh_unref_pixbuf,
-				      NULL);
-		g_hash_table_destroy (pixbuf_hash);
-		pixbuf_hash = g_hash_table_new (g_str_hash, g_str_equal);
-	}
-	if (tree_pixbuf_hash != NULL) {
-		g_hash_table_foreach (tree_pixbuf_hash,
-				      gh_unref_pixbuf,
-				      NULL);
-		g_hash_table_destroy (tree_pixbuf_hash);
-		tree_pixbuf_hash = g_hash_table_new (g_str_hash, g_str_equal);
-	}
+	gth_icon_cache_clear (window->priv->list_icon_cache);
+	gth_icon_cache_clear (window->priv->tree_icon_cache);
 
 	fr_window_update_file_list (window, TRUE);
 	fr_window_update_dir_tree (window);
@@ -5509,15 +5436,6 @@ fr_window_construct (FrWindow *window)
 	GError             *error = NULL;
 	const char * const *schemas;
 
-	/* data common to all windows. */
-
-	if (pixbuf_hash == NULL)
-		pixbuf_hash = g_hash_table_new (g_str_hash, g_str_equal);
-	if (tree_pixbuf_hash == NULL)
-		tree_pixbuf_hash = g_hash_table_new (g_str_hash, g_str_equal);
-	if (icon_theme == NULL)
-		icon_theme = gtk_icon_theme_get_default ();
-
 	/* Create the settings objects */
 
 	window->priv->settings_listing = g_settings_new (FILE_ROLLER_SCHEMA_LISTING);
@@ -5556,14 +5474,11 @@ fr_window_construct (FrWindow *window)
 			  window);
 
 	window->priv->theme_changed_handler_id =
-		g_signal_connect (icon_theme,
+		g_signal_connect (gtk_icon_theme_get_default (),
 				  "changed",
 				  G_CALLBACK (theme_changed_cb),
 				  window);
 
-	file_list_icon_size = _gtk_widget_lookup_for_size (GTK_WIDGET (window), FILE_LIST_ICON_SIZE);
-	dir_tree_icon_size = _gtk_widget_lookup_for_size (GTK_WIDGET (window), DIR_TREE_ICON_SIZE);
-
 	gtk_window_set_default_size (GTK_WINDOW (window),
 				     g_settings_get_int (window->priv->settings_ui, PREF_UI_WINDOW_WIDTH),
 				     g_settings_get_int (window->priv->settings_ui, PREF_UI_WINDOW_HEIGHT));
diff --git a/src/gth-icon-cache.c b/src/gth-icon-cache.c
index 6946cb0..e71c14b 100644
--- a/src/gth-icon-cache.c
+++ b/src/gth-icon-cache.c
@@ -25,33 +25,14 @@
 #include "gtk-utils.h"
 
 
-#define VOID_PIXBUF_KEY "void-pixbuf"
-
-
 struct _GthIconCache {
 	GtkIconTheme *icon_theme;
 	int           icon_size;
 	GHashTable   *cache;
+	GIcon        *fallback_icon;
 };
 
 
-static GdkPixbuf *
-_gdk_pixbuf_new_void (int width,
-                      int height)
-{
-        GdkPixbuf *p;
-
-        p = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
-                            TRUE,
-                            8,
-                            width,
-                            height);
-        gdk_pixbuf_fill (p, 0xFFFFFF00);
-
-        return p;
-}
-
-
 GthIconCache *
 gth_icon_cache_new (GtkIconTheme *icon_theme,
 		    int           icon_size)
@@ -63,9 +44,7 @@ gth_icon_cache_new (GtkIconTheme *icon_theme,
 	icon_cache = g_new0 (GthIconCache, 1);
 	icon_cache->icon_theme = icon_theme;
 	icon_cache->icon_size = icon_size;
-	icon_cache->cache = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
-
-	g_hash_table_insert (icon_cache->cache, VOID_PIXBUF_KEY, _gdk_pixbuf_new_void (icon_cache->icon_size, icon_cache->icon_size));
+	icon_cache->cache = g_hash_table_new_full (g_icon_hash, (GEqualFunc) g_icon_equal, g_object_unref, g_object_unref);
 
 	return icon_cache;
 }
@@ -86,46 +65,33 @@ gth_icon_cache_new_for_widget (GtkWidget   *widget,
 
 
 void
+gth_icon_cache_set_fallback (GthIconCache *icon_cache,
+			     GIcon        *icon)
+{
+	if (icon_cache->fallback_icon != NULL)
+		g_object_unref (icon_cache->fallback_icon);
+	icon_cache->fallback_icon = icon;
+	if (icon_cache->fallback_icon != NULL)
+		g_object_ref (icon_cache->fallback_icon);
+}
+
+
+void
 gth_icon_cache_free (GthIconCache *icon_cache)
 {
 	if (icon_cache == NULL)
 		return;
 	g_hash_table_destroy (icon_cache->cache);
+	if (icon_cache->fallback_icon != NULL)
+		g_object_unref (icon_cache->fallback_icon);
 	g_free (icon_cache);
 }
 
 
-static const char *
-_gth_icon_cache_get_icon_key (GIcon *icon)
+void
+gth_icon_cache_clear (GthIconCache *icon_cache)
 {
-	const char *key = NULL;
-
-	if (G_IS_THEMED_ICON (icon)) {
-		char **icon_names;
-		char  *name;
-
-		g_object_get (icon, "names", &icon_names, NULL);
-		name = g_strjoinv (",", icon_names);
-		key = _g_str_get_static (name);
-
-		g_free (name);
-		g_strfreev (icon_names);
-	}
-	else if (G_IS_FILE_ICON (icon)) {
-		GFile *file;
-
-		file = g_file_icon_get_file (G_FILE_ICON (icon));
-		if (file != NULL) {
-			char *uri;
-
-			uri = g_file_get_uri (file);
-			key = _g_str_get_static (uri);
-
-			g_free (uri);
-		}
-	}
-
-	return key;
+	g_hash_table_remove_all (icon_cache->cache);
 }
 
 
@@ -133,35 +99,20 @@ GdkPixbuf *
 gth_icon_cache_get_pixbuf (GthIconCache *icon_cache,
 			   GIcon        *icon)
 {
-	const char *key;
-	GdkPixbuf  *pixbuf;
-
-	key = NULL;
-	if (icon != NULL)
-		key = _gth_icon_cache_get_icon_key (icon);
-
-	if (key == NULL)
-		key = VOID_PIXBUF_KEY;
-
-	pixbuf = g_hash_table_lookup (icon_cache->cache, key);
-	if (pixbuf != NULL) {
+	GdkPixbuf *pixbuf;
 
+	pixbuf = g_hash_table_lookup (icon_cache->cache, icon);
+	if (pixbuf != NULL)
 		return g_object_ref (pixbuf);
-	}
 
 	if (icon != NULL)
 		pixbuf = _g_icon_get_pixbuf (icon, icon_cache->icon_size, icon_cache->icon_theme);
 
-	if (pixbuf == NULL) {
-		GIcon *unknown_icon;
-
-		unknown_icon = g_themed_icon_new ("missing-image");
-		pixbuf = _g_icon_get_pixbuf (unknown_icon, icon_cache->icon_size, icon_cache->icon_theme);
-
-		g_object_unref (unknown_icon);
-	}
+	if ((pixbuf == NULL) && (icon_cache->fallback_icon != NULL))
+		pixbuf = _g_icon_get_pixbuf (icon_cache->fallback_icon, icon_cache->icon_size, icon_cache->icon_theme);
 
-	g_hash_table_insert (icon_cache->cache, (gpointer) key, pixbuf);
+	if (pixbuf != NULL)
+		g_hash_table_insert (icon_cache->cache, g_object_ref (icon), g_object_ref (pixbuf));
 
-	return g_object_ref (pixbuf);
+	return pixbuf;
 }
diff --git a/src/gth-icon-cache.h b/src/gth-icon-cache.h
index 8f6819c..2da8969 100644
--- a/src/gth-icon-cache.h
+++ b/src/gth-icon-cache.h
@@ -18,7 +18,7 @@
  *  You should have received a copy of the GNU General Public License
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
- 
+
 #ifndef GTH_ICON_CACHE_H
 #define GTH_ICON_CACHE_H
 
@@ -32,7 +32,10 @@ GthIconCache * gth_icon_cache_new            (GtkIconTheme *icon_theme,
 			                      int           icon_size);
 GthIconCache * gth_icon_cache_new_for_widget (GtkWidget    *widget,
 			                      GtkIconSize   icon_size);
-void           gth_icon_cache_free           (GthIconCache *icon_cache);	                  
+void           gth_icon_cache_set_fallback   (GthIconCache *icon_cache,
+					      GIcon        *icon);
+void           gth_icon_cache_free           (GthIconCache *icon_cache);
+void           gth_icon_cache_clear          (GthIconCache *icon_cache);
 GdkPixbuf *    gth_icon_cache_get_pixbuf     (GthIconCache *icon_cache,
 				              GIcon        *icon);
 
diff --git a/src/gtk-utils.c b/src/gtk-utils.c
index 9e95d78..b839e69 100644
--- a/src/gtk-utils.c
+++ b/src/gtk-utils.c
@@ -489,69 +489,36 @@ _gtk_label_get_filename_text (GtkLabel   *label)
 }
 
 
-static GdkPixbuf *
-get_themed_icon_pixbuf (GThemedIcon  *icon,
-		        int           size,
-		        GtkIconTheme *icon_theme)
+GdkPixbuf *
+_g_icon_get_pixbuf (GIcon        *icon,
+		    int           icon_size,
+		    GtkIconTheme *icon_theme)
 {
-	char        **icon_names;
-	GtkIconInfo  *icon_info;
-	GdkPixbuf    *pixbuf;
-	GError       *error = NULL;
-
-	g_object_get (icon, "names", &icon_names, NULL);
-
-	icon_info = gtk_icon_theme_choose_icon (icon_theme, (const char **)icon_names, size, 0);
-	if (icon_info == NULL)
-		icon_info = gtk_icon_theme_lookup_icon (icon_theme, "text-x-generic", size, GTK_ICON_LOOKUP_USE_BUILTIN);
-
-	pixbuf = gtk_icon_info_load_icon (icon_info, &error);
-	if (pixbuf == NULL) {
-		g_warning ("could not load icon pixbuf: %s\n", error->message);
-		g_clear_error (&error);
-	}
-
-	gtk_icon_info_free (icon_info);
-	g_strfreev (icon_names);
+	GdkPixbuf   *pixbuf = NULL;
+	GtkIconInfo *icon_info;
 
-	return pixbuf;
-}
+	icon_info = gtk_icon_theme_lookup_by_gicon (icon_theme,
+						    icon,
+						    icon_size,
+						    GTK_ICON_LOOKUP_USE_BUILTIN);
 
+	if (icon_info != NULL) {
+		GError *error = NULL;
 
-static GdkPixbuf *
-get_file_icon_pixbuf (GFileIcon *icon,
-		      int        size)
-{
-	GFile     *file;
-	char      *filename;
-	GdkPixbuf *pixbuf;
+		pixbuf = gtk_icon_info_load_icon (icon_info, &error);
+		if (error != NULL) {
+			g_print ("%s\n", error->message);
+			g_error_free (error);
+		}
 
-	file = g_file_icon_get_file (icon);
-	filename = g_file_get_path (file);
-	pixbuf = gdk_pixbuf_new_from_file_at_size (filename, size, -1, NULL);
-	g_free (filename);
-	g_object_unref (file);
+		gtk_icon_info_free (icon_info);
+	}
 
 	return pixbuf;
 }
 
 
 GdkPixbuf *
-_g_icon_get_pixbuf (GIcon        *icon,
-		    int           size,
-		    GtkIconTheme *theme)
-{
-	if (icon == NULL)
-		return NULL;
-	if (G_IS_THEMED_ICON (icon))
-		return get_themed_icon_pixbuf (G_THEMED_ICON (icon), size, theme);
-	if (G_IS_FILE_ICON (icon))
-		return get_file_icon_pixbuf (G_FILE_ICON (icon), size);
-	return NULL;
-}
-
-
-GdkPixbuf *
 _g_mime_type_get_icon (const char   *mime_type,
 		       int           icon_size,
 		       GtkIconTheme *icon_theme)
@@ -563,7 +530,10 @@ _g_mime_type_get_icon (const char   *mime_type,
 		icon_theme = gtk_icon_theme_get_default ();
 
 	icon = g_content_type_get_icon (mime_type);
+	if (icon == NULL)
+		icon = g_themed_icon_new ("text-x-generic");
 	pixbuf = _g_icon_get_pixbuf (icon, icon_size, icon_theme);
+
 	g_object_unref (icon);
 
 	return pixbuf;



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