aboutsummaryrefslogtreecommitdiffstats
path: root/e-util/e-icon-factory.c
diff options
context:
space:
mode:
Diffstat (limited to 'e-util/e-icon-factory.c')
-rw-r--r--e-util/e-icon-factory.c234
1 files changed, 17 insertions, 217 deletions
diff --git a/e-util/e-icon-factory.c b/e-util/e-icon-factory.c
index cdbf39c788..411deead24 100644
--- a/e-util/e-icon-factory.c
+++ b/e-util/e-icon-factory.c
@@ -38,200 +38,16 @@
#include "e-icon-factory.h"
#include "e-util-private.h"
-#include "art/broken-image-16.xpm"
-#include "art/broken-image-24.xpm"
-
#define d(x)
-typedef struct {
- gchar *name;
- GdkPixbuf *pixbuf;
-} Icon;
-
-static GdkPixbuf *broken16_pixbuf = NULL;
-static GdkPixbuf *broken24_pixbuf = NULL;
-
-static GHashTable *name_to_icon = NULL;
-static GtkIconTheme *icon_theme = NULL;
-static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
-
-/* Note: takes ownership of the pixbufs (eg. does not ref them) */
-static Icon *
-icon_new (const gchar *name, GdkPixbuf *pixbuf)
-{
- Icon *icon;
-
- icon = g_slice_new (Icon);
- icon->name = g_strdup (name);
- icon->pixbuf = pixbuf;
-
- return icon;
-}
-
-static void
-icon_free (Icon *icon)
-{
- g_free (icon->name);
- if (icon->pixbuf)
- g_object_unref (icon->pixbuf);
- g_slice_free (Icon, icon);
-}
-
-static Icon *
-load_icon (const gchar *icon_key, const gchar *icon_name, gint size, gint scale)
-{
- GdkPixbuf *pixbuf, *unscaled = NULL;
- gchar *basename, *filename = NULL;
-
- if (g_path_is_absolute (icon_name))
- filename = g_strdup (icon_name);
- else {
- GtkIconInfo *icon_info;
-
- icon_info = gtk_icon_theme_lookup_icon (
- icon_theme, icon_name, size, 0);
- if (icon_info != NULL) {
- filename = g_strdup (
- gtk_icon_info_get_filename (icon_info));
- gtk_icon_info_free (icon_info);
- }
- }
-
- if (!filename || !(unscaled = gdk_pixbuf_new_from_file (filename, NULL))) {
- if (scale) {
- const gchar *dent;
- gint width;
- GDir *dir;
- gchar *x;
-
- if (!(dir = g_dir_open (EVOLUTION_ICONSDIR, 0, NULL))) {
- goto done;
- }
-
- /* scan icon directories looking for an icon with a size >= the size we need. */
- while ((dent = g_dir_read_name (dir))) {
- if (!(dent[0] >= '1' && dent[0] <= '9'))
- continue;
-
- if (((width = strtol (dent, &x, 10)) < size) || *x != 'x')
- continue;
-
- if (((strtol (x + 1, &x, 10)) != width) || *x != '\0')
- continue;
-
- /* if the icon exists in this directory, we can [use/scale] it */
- g_free (filename);
- basename = g_strconcat (icon_name, ".png", NULL);
- filename = g_build_filename (EVOLUTION_ICONSDIR,
- dent,
- basename,
- NULL);
- g_free (basename);
- if ((unscaled = gdk_pixbuf_new_from_file (filename, NULL)))
- break;
- }
-
- g_dir_close (dir);
- } else {
- gchar *size_x_size;
-
- size_x_size = g_strdup_printf ("%dx%d", size, size);
- basename = g_strconcat (icon_name, ".png", NULL);
- g_free (filename);
- filename = g_build_filename (EVOLUTION_ICONSDIR,
- size_x_size,
- basename,
- NULL);
- g_free (basename);
- g_free (size_x_size);
- unscaled = gdk_pixbuf_new_from_file (filename, NULL);
- }
- }
-
- done:
-
- g_free (filename);
- if (unscaled != NULL) {
- if (gdk_pixbuf_get_width(unscaled) != size || gdk_pixbuf_get_height(unscaled) != size)
- {
- pixbuf = e_icon_factory_pixbuf_scale (unscaled, size, size);
- g_object_unref (unscaled);
- } else
- pixbuf = unscaled;
- } else {
- pixbuf = NULL;
- }
-
- return icon_new (icon_key, pixbuf);
-}
-
-static void
-icon_theme_changed_cb (GtkIconTheme *icon_theme, gpointer user_data)
-{
- g_hash_table_remove_all (name_to_icon);
-}
-
-/**
- * e_icon_factory_init:
- *
- * Initialises the icon factory.
- **/
-void
-e_icon_factory_init (void)
-{
- gchar *path;
-
- if (name_to_icon != NULL)
- return;
-
- name_to_icon = g_hash_table_new_full (
- g_str_hash, g_str_equal,
- (GDestroyNotify) NULL,
- (GDestroyNotify) icon_free);
-
- icon_theme = gtk_icon_theme_get_default ();
- path = g_build_filename (EVOLUTION_DATADIR,
- "evolution",
- BASE_VERSION,
- "icons",
- NULL);
- gtk_icon_theme_append_search_path (icon_theme, path);
- g_free (path);
- g_signal_connect (
- icon_theme, "changed",
- G_CALLBACK (icon_theme_changed_cb), NULL);
-
- broken16_pixbuf = gdk_pixbuf_new_from_xpm_data (
- (const gchar **) broken_image_16_xpm);
- broken24_pixbuf = gdk_pixbuf_new_from_xpm_data (
- (const gchar **) broken_image_24_xpm);
-}
-
-/**
- * e_icon_factory_shutdown:
- *
- * Shuts down the icon factory (cleans up all cached icons, etc).
- **/
-void
-e_icon_factory_shutdown (void)
-{
- if (name_to_icon == NULL)
- return;
-
- g_hash_table_destroy (name_to_icon);
- g_object_unref (broken16_pixbuf);
- g_object_unref (broken24_pixbuf);
- name_to_icon = NULL;
-}
-
/**
* e_icon_factory_get_icon_filename:
* @icon_name: name of the icon
- * @size: size of the icon
+ * @icon_size: size of the icon
*
- * Looks up the icon to use based on name and size.
+ * Returns the filename of the requested icon in the default icon theme.
*
- * Returns the requested icon pixbuf.
+ * Returns: the filename of the requested icon
**/
gchar *
e_icon_factory_get_icon_filename (const gchar *icon_name,
@@ -265,51 +81,35 @@ e_icon_factory_get_icon_filename (const gchar *icon_name,
* @icon_name: name of the icon
* @icon_size: size of the icon
*
- * Returns the specified icon of the requested size (may perform
- * scaling to achieve this). If @icon_name is a full path, that file
- * is used directly. Otherwise it is looked up in the user's current
- * icon theme. If the icon cannot be found in the icon theme, it falls
- * back to loading the requested icon from Evolution's icon set
- * installed from the art/ srcdir. If even that fails to find the
- * requested icon, then a "broken-image" icon is returned.
+ * Loads the requested icon from the default icon theme and renders it
+ * to a pixbuf.
+ *
+ * Returns: the rendered icon
**/
GdkPixbuf *
e_icon_factory_get_icon (const gchar *icon_name,
GtkIconSize icon_size)
{
+ GtkIconTheme *icon_theme;
GdkPixbuf *pixbuf;
- gchar *icon_key;
- Icon *icon;
- gint size, width, height;
+ gint width, height;
+ GError *error = NULL;
g_return_val_if_fail (icon_name != NULL, NULL);
+ icon_theme = gtk_icon_theme_get_default ();
+
if (!gtk_icon_size_lookup (icon_size, &width, &height))
return NULL;
- size = height;
-
- icon_key = g_alloca (strlen (icon_name) + 7);
- sprintf (icon_key, "%dx%d/%s", size, size, icon_name);
-
- g_static_mutex_lock (&mutex);
+ pixbuf = gtk_icon_theme_load_icon (
+ icon_theme, icon_name, height, 0, &error);
- if (!(icon = g_hash_table_lookup (name_to_icon, icon_key))) {
- icon = load_icon (icon_key, icon_name, size, TRUE);
- g_hash_table_insert (name_to_icon, icon->name, icon);
+ if (error != NULL) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
}
- if ((pixbuf = icon->pixbuf)) {
- g_object_ref (pixbuf);
- } else {
- if (size >= 24)
- pixbuf = gdk_pixbuf_scale_simple (broken24_pixbuf, size, size, GDK_INTERP_NEAREST);
- else
- pixbuf = gdk_pixbuf_scale_simple (broken16_pixbuf, size, size, GDK_INTERP_NEAREST);
- }
-
- g_static_mutex_unlock (&mutex);
-
return pixbuf;
}