From 779e0f5058e089279c2851e18ef7003ec88bb61f Mon Sep 17 00:00:00 2001 From: Ettore Perazzoli Date: Tue, 9 Jul 2002 17:06:19 +0000 Subject: Call e_icon_factory_init(). * main.c (main): Call e_icon_factory_init(). * e-local-storage.c (setup_folder_as_stock): New arg @icon_name; if not NULL, set up a custom icon for the folder. (setup_stock_folders): Set up custom icons for inbox and outbox. * e-storage-set-view.c (get_pixbuf_for_folder): If the folder has a custom icon, return the custom icon. * e-folder.c: New member custom_icon_name. (init): Initialize to NULL. (destroy): Free. (e_folder_get_custom_icon): New. (e_folder_set_custom_icon): New. svn path=/trunk/; revision=17391 --- shell/ChangeLog | 20 ++++++ shell/Makefile.am | 2 + shell/e-folder.c | 55 ++++++++++++++-- shell/e-folder.h | 22 ++++--- shell/e-icon-factory.c | 161 +++++++++++++++++++++++++++++++++++++++++++++ shell/e-icon-factory.h | 33 ++++++++++ shell/e-local-storage.c | 20 +++--- shell/e-storage-set-view.c | 72 ++++++++++---------- shell/main.c | 2 + 9 files changed, 330 insertions(+), 57 deletions(-) create mode 100644 shell/e-icon-factory.c create mode 100644 shell/e-icon-factory.h (limited to 'shell') diff --git a/shell/ChangeLog b/shell/ChangeLog index d9e5a955ec..cf8656a41e 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,23 @@ +2002-07-09 Ettore Perazzoli + + * main.c (main): Call e_icon_factory_init(). + + * e-local-storage.c (setup_folder_as_stock): New arg @icon_name; + if not NULL, set up a custom icon for the folder. + (setup_stock_folders): Set up custom icons for inbox and outbox. + + * e-storage-set-view.c (get_pixbuf_for_folder): If the folder has + a custom icon, return the custom icon. + + * e-folder.c: New member custom_icon_name. + (init): Initialize to NULL. + (destroy): Free. + (e_folder_get_custom_icon): New. + (e_folder_set_custom_icon): New. + + * e-icon-cache.c: New. + * e-icon-cache.h: New. + 2002-07-09 Ettore Perazzoli * e-local-storage.c (remove_folder): Remove unused variable. diff --git a/shell/Makefile.am b/shell/Makefile.am index 7e79c317d4..8f56c725f3 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -142,6 +142,8 @@ evolution_SOURCES = \ e-gray-bar.h \ e-history.c \ e-history.h \ + e-icon-factory.c \ + e-icon-factory.h \ e-local-folder.c \ e-local-folder.h \ e-local-storage.c \ diff --git a/shell/e-folder.c b/shell/e-folder.c index 6f78e48db3..0dd6c1ff10 100644 --- a/shell/e-folder.c +++ b/shell/e-folder.c @@ -49,6 +49,10 @@ struct _EFolderPrivate { unsigned int self_highlight : 1; unsigned int is_stock : 1; unsigned int can_sync_offline : 1; + + /* Custom icon for this folder; if NULL the folder will just use the + icon for its type. */ + char *custom_icon_name; }; #define EF_CLASS(obj) \ @@ -112,6 +116,8 @@ destroy (GtkObject *object) g_free (priv->description); g_free (priv->physical_uri); + g_free (priv->custom_icon_name); + g_free (priv); (* GTK_OBJECT_CLASS (parent_class)->destroy) (object); @@ -158,6 +164,7 @@ init (EFolder *folder) priv->self_highlight = FALSE; priv->is_stock = FALSE; priv->can_sync_offline = FALSE; + priv->custom_icon_name = NULL; folder->priv = priv; } @@ -267,6 +274,29 @@ e_folder_get_is_stock (EFolder *folder) return folder->priv->is_stock; } +gboolean +e_folder_get_can_sync_offline (EFolder *folder) +{ + g_return_val_if_fail (E_IS_FOLDER (folder), FALSE); + + return folder->priv->can_sync_offline; +} + +/** + * e_folder_get_custom_icon: + * @folder: An EFolder + * + * Get the name of the custom icon for @folder, or NULL if no custom icon is + * associated with it + **/ +const char * +e_folder_get_custom_icon_name (EFolder *folder) +{ + g_return_val_if_fail (E_IS_FOLDER (folder), NULL); + + return folder->priv->custom_icon_name; +} + void e_folder_set_name (EFolder *folder, @@ -380,12 +410,29 @@ e_folder_set_can_sync_offline (EFolder *folder, gtk_signal_emit (GTK_OBJECT (folder), signals[CHANGED]); } -gboolean -e_folder_get_can_sync_offline (EFolder *folder) +/** + * e_folder_set_custom_icon_name: + * @folder: An EFolder + * @icon_name: Name of the icon to be set (to be found in the standard + * Evolution icon dir) + * + * Set a custom icon for @folder (thus overriding the default icon, which is + * the one associated to the type of the folder). + **/ +void +e_folder_set_custom_icon (EFolder *folder, + const char *icon_name) { - g_return_val_if_fail (E_IS_FOLDER (folder), FALSE); + g_return_if_fail (E_IS_FOLDER (folder)); - return folder->priv->can_sync_offline; + if (icon_name != folder->priv->custom_icon_name) { + g_free (folder->priv->custom_icon_name); + + if (icon_name == NULL) + folder->priv->custom_icon_name = NULL; + else + folder->priv->custom_icon_name = g_strdup (icon_name); + } } diff --git a/shell/e-folder.h b/shell/e-folder.h index 4e7c9c1996..b808fb1755 100644 --- a/shell/e-folder.h +++ b/shell/e-folder.h @@ -1,4 +1,4 @@ - /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* e-folder.h * * Copyright (C) 2000, 2001, 2002 Ximian, Inc. @@ -80,15 +80,17 @@ int e_folder_get_unread_count (EFolder *folder); gboolean e_folder_get_highlighted (EFolder *folder); gboolean e_folder_get_is_stock (EFolder *folder); gboolean e_folder_get_can_sync_offline (EFolder *folder); - -void e_folder_set_name (EFolder *folder, const char *name); -void e_folder_set_type_string (EFolder *folder, const char *type); -void e_folder_set_description (EFolder *folder, const char *description); -void e_folder_set_physical_uri (EFolder *folder, const char *physical_uri); -void e_folder_set_unread_count (EFolder *folder, int unread_count); -void e_folder_set_child_highlight (EFolder *folder, gboolean highlighted); -void e_folder_set_is_stock (EFolder *folder, gboolean is_stock); -void e_folder_set_can_sync_offline (EFolder *folder, gboolean can_sync_offline); +const char *e_folder_get_custom_icon_name (EFolder *folder); + +void e_folder_set_name (EFolder *folder, const char *name); +void e_folder_set_type_string (EFolder *folder, const char *type); +void e_folder_set_description (EFolder *folder, const char *description); +void e_folder_set_physical_uri (EFolder *folder, const char *physical_uri); +void e_folder_set_unread_count (EFolder *folder, int unread_count); +void e_folder_set_child_highlight (EFolder *folder, gboolean highlighted); +void e_folder_set_is_stock (EFolder *folder, gboolean is_stock); +void e_folder_set_can_sync_offline (EFolder *folder, gboolean can_sync_offline); +void e_folder_set_custom_icon (EFolder *folder, const char *icon_name); void e_folder_to_corba (EFolder *folder, const char *evolution_uri, diff --git a/shell/e-icon-factory.c b/shell/e-icon-factory.c new file mode 100644 index 0000000000..8a66237605 --- /dev/null +++ b/shell/e-icon-factory.c @@ -0,0 +1,161 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-icon-factory.c - Icon factory for the Evolution shell. + * + * Copyright (C) 2002 Ximian, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ettore Perazzoli + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "e-icon-factory.h" + +#include "e-shell-constants.h" + + +/* One icon. Keep both a small (16x16) and a large (48x48) version around. */ + +struct _Icon { + char *name; + GdkPixbuf *small_pixbuf; + GdkPixbuf *large_pixbuf; +}; +typedef struct _Icon Icon; + +/* Hash of all the icons. */ +static GHashTable *name_to_icon = NULL; + + +/* Creating and destroying icons. */ + +static Icon * +icon_new (const char *name, + GdkPixbuf *small_pixbuf, + GdkPixbuf *large_pixbuf) +{ + Icon *icon; + + icon = g_new (Icon, 1); + icon->name = g_strdup (name); + icon->small_pixbuf = small_pixbuf; + icon->large_pixbuf = large_pixbuf; + + if (small_pixbuf != NULL) + gdk_pixbuf_ref (small_pixbuf); + if (large_pixbuf != NULL) + gdk_pixbuf_ref (large_pixbuf); + + return icon; +} + +#if 0 + +/* (This is not currently used since we never prune icons out of the + cache.) */ +static void +icon_free (Icon *icon) +{ + g_free (icon->name); + + if (icon->large_pixbuf != NULL) + gdk_pixbuf_unref (icon->large_pixbuf); + if (icon->small_pixbuf != NULL) + gdk_pixbuf_unref (icon->small_pixbuf); + + g_free (icon); +} + +#endif + + +/* Loading icons. */ + +static Icon * +load_icon (const char *icon_name) +{ + GdkPixbuf *small_pixbuf; + GdkPixbuf *large_pixbuf; + Icon *icon; + char *path; + + path = g_strconcat (EVOLUTION_IMAGES, "/", icon_name, ".png", NULL); + small_pixbuf = gdk_pixbuf_new_from_file (path); + if (small_pixbuf == NULL) + return NULL; + g_free (path); + + path = g_strconcat (EVOLUTION_IMAGES, "/", icon_name, "-mini.png", NULL); + large_pixbuf = gdk_pixbuf_new_from_file (path); + if (large_pixbuf == NULL) + return NULL; + g_free (path); + + icon = icon_new (icon_name, small_pixbuf, large_pixbuf); + + gdk_pixbuf_unref (small_pixbuf); + gdk_pixbuf_unref (large_pixbuf); + + return icon; +} + + +/* Public API. */ + +void +e_icon_factory_init (void) +{ + if (name_to_icon != NULL) { + /* Already initialized. */ + return; + } + + name_to_icon = g_hash_table_new (g_str_hash, g_str_equal); +} + +GdkPixbuf * +e_icon_factory_get_icon (const char *icon_name, + gboolean mini) +{ + Icon *icon; + + g_return_val_if_fail (icon_name != NULL, NULL); + + icon = g_hash_table_lookup (name_to_icon, icon_name); + if (icon == NULL) { + icon = load_icon (icon_name); + if (icon == NULL) { + g_warning ("Icon not found -- %s", icon_name); + + /* Create an empty icon so that we don't keep spitting + out the same warning over and over, every time this + icon is requested. */ + + icon = icon_new (icon_name, NULL, NULL); + g_hash_table_insert (name_to_icon, icon->name, icon); + return NULL; + } + + g_hash_table_insert (name_to_icon, icon->name, icon); + } + + if (mini) + return icon->small_pixbuf; + else + return icon->large_pixbuf; +} diff --git a/shell/e-icon-factory.h b/shell/e-icon-factory.h new file mode 100644 index 0000000000..072cd4e222 --- /dev/null +++ b/shell/e-icon-factory.h @@ -0,0 +1,33 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-icon-factory.h - Icon factory for the Evolution shell. + * + * Copyright (C) 2002 Ximian, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ettore Perazzoli + */ + +#ifndef _E_ICON_FACTORY_H_ +#define _E_ICON_FACTORY_H_ + +#include + +void e_icon_factory_init (void); + +GdkPixbuf *e_icon_factory_get_icon (const char *icon_name, + gboolean mini); + +#endif /* _E_ICON_FACTORY_H_ */ diff --git a/shell/e-local-storage.c b/shell/e-local-storage.c index f79c31f8fe..0af9c0aa51 100644 --- a/shell/e-local-storage.c +++ b/shell/e-local-storage.c @@ -152,7 +152,8 @@ new_folder (ELocalStorage *local_storage, static gboolean setup_folder_as_stock (ELocalStorage *local_storage, const char *path, - const char *name) + const char *name, + const char *custom_icon_name) { EFolder *folder; @@ -162,6 +163,7 @@ setup_folder_as_stock (ELocalStorage *local_storage, e_folder_set_name (folder, name); e_folder_set_is_stock (folder, TRUE); + e_folder_set_custom_icon (folder, custom_icon_name); return TRUE; } @@ -169,14 +171,14 @@ setup_folder_as_stock (ELocalStorage *local_storage, static void setup_stock_folders (ELocalStorage *local_storage) { - setup_folder_as_stock (local_storage, "/Calendar", U_("Calendar")); - setup_folder_as_stock (local_storage, "/Contacts", U_("Contacts")); - setup_folder_as_stock (local_storage, "/Drafts", U_("Drafts")); - setup_folder_as_stock (local_storage, "/Inbox", U_("Inbox")); - setup_folder_as_stock (local_storage, "/Outbox", U_("Outbox")); - setup_folder_as_stock (local_storage, "/Sent", U_("Sent")); - setup_folder_as_stock (local_storage, "/Tasks", U_("Tasks")); - setup_folder_as_stock (local_storage, "/Trash", U_("Trash")); + setup_folder_as_stock (local_storage, "/Calendar", U_("Calendar"), NULL); + setup_folder_as_stock (local_storage, "/Contacts", U_("Contacts"), NULL); + setup_folder_as_stock (local_storage, "/Drafts", U_("Drafts"), NULL); + setup_folder_as_stock (local_storage, "/Inbox", U_("Inbox"), "inbox"); + setup_folder_as_stock (local_storage, "/Outbox", U_("Outbox"), "outbox"); + setup_folder_as_stock (local_storage, "/Sent", U_("Sent"), NULL); + setup_folder_as_stock (local_storage, "/Tasks", U_("Tasks"), NULL); + setup_folder_as_stock (local_storage, "/Trash", U_("Trash"), NULL); } static gboolean diff --git a/shell/e-storage-set-view.c b/shell/e-storage-set-view.c index 7bfb88e04f..a166796025 100644 --- a/shell/e-storage-set-view.c +++ b/shell/e-storage-set-view.c @@ -253,53 +253,57 @@ static GdkPixbuf * get_pixbuf_for_folder (EStorageSetView *storage_set_view, EFolder *folder) { - GdkPixbuf *scaled_pixbuf; const char *type_name; EStorageSetViewPrivate *priv; + EFolderTypeRegistry *folder_type_registry; + EStorageSet *storage_set; + GdkPixbuf *icon_pixbuf; + GdkPixbuf *scaled_pixbuf; + const char *custom_icon_name; + int icon_pixbuf_width, icon_pixbuf_height; priv = storage_set_view->priv; - - type_name = e_folder_get_type_string (folder); - - scaled_pixbuf = g_hash_table_lookup (priv->type_name_to_pixbuf, type_name); - if (scaled_pixbuf == NULL) { - EFolderTypeRegistry *folder_type_registry; - EStorageSet *storage_set; - GdkPixbuf *icon_pixbuf; - int icon_pixbuf_width, icon_pixbuf_height; + custom_icon_name = e_folder_get_custom_icon_name (folder); + if (custom_icon_name != NULL) + return e_icon_factory_get_icon (custom_icon_name, TRUE); - storage_set = priv->storage_set; - folder_type_registry = e_storage_set_get_folder_type_registry (storage_set); + type_name = e_folder_get_type_string (folder); - icon_pixbuf = e_folder_type_registry_get_icon_for_type (folder_type_registry, - type_name, TRUE); + scaled_pixbuf = g_hash_table_lookup (priv->type_name_to_pixbuf, type_name); + if (scaled_pixbuf != NULL) + return scaled_pixbuf; - if (icon_pixbuf == NULL) - return NULL; + storage_set = priv->storage_set; + folder_type_registry = e_storage_set_get_folder_type_registry (storage_set); - icon_pixbuf_width = gdk_pixbuf_get_width (icon_pixbuf); - icon_pixbuf_height = gdk_pixbuf_get_height (icon_pixbuf); + icon_pixbuf = e_folder_type_registry_get_icon_for_type (folder_type_registry, + type_name, TRUE); - if (icon_pixbuf_width == E_SHELL_MINI_ICON_SIZE && icon_pixbuf_height == E_SHELL_MINI_ICON_SIZE) { - scaled_pixbuf = gdk_pixbuf_ref (icon_pixbuf); - } else { - scaled_pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (icon_pixbuf), - gdk_pixbuf_get_has_alpha (icon_pixbuf), - gdk_pixbuf_get_bits_per_sample (icon_pixbuf), - E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE); - - gdk_pixbuf_scale (icon_pixbuf, scaled_pixbuf, - 0, 0, E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE, - 0.0, 0.0, - (double) E_SHELL_MINI_ICON_SIZE / gdk_pixbuf_get_width (icon_pixbuf), - (double) E_SHELL_MINI_ICON_SIZE / gdk_pixbuf_get_height (icon_pixbuf), - GDK_INTERP_HYPER); - } + if (icon_pixbuf == NULL) + return NULL; - g_hash_table_insert (priv->type_name_to_pixbuf, g_strdup (type_name), scaled_pixbuf); + icon_pixbuf_width = gdk_pixbuf_get_width (icon_pixbuf); + icon_pixbuf_height = gdk_pixbuf_get_height (icon_pixbuf); + + if (icon_pixbuf_width == E_SHELL_MINI_ICON_SIZE && icon_pixbuf_height == E_SHELL_MINI_ICON_SIZE) { + scaled_pixbuf = gdk_pixbuf_ref (icon_pixbuf); + } else { + scaled_pixbuf = gdk_pixbuf_new (gdk_pixbuf_get_colorspace (icon_pixbuf), + gdk_pixbuf_get_has_alpha (icon_pixbuf), + gdk_pixbuf_get_bits_per_sample (icon_pixbuf), + E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE); + + gdk_pixbuf_scale (icon_pixbuf, scaled_pixbuf, + 0, 0, E_SHELL_MINI_ICON_SIZE, E_SHELL_MINI_ICON_SIZE, + 0.0, 0.0, + (double) E_SHELL_MINI_ICON_SIZE / gdk_pixbuf_get_width (icon_pixbuf), + (double) E_SHELL_MINI_ICON_SIZE / gdk_pixbuf_get_height (icon_pixbuf), + GDK_INTERP_HYPER); } + g_hash_table_insert (priv->type_name_to_pixbuf, g_strdup (type_name), scaled_pixbuf); + return scaled_pixbuf; } diff --git a/shell/main.c b/shell/main.c index 7e824ba990..1b22658d96 100644 --- a/shell/main.c +++ b/shell/main.c @@ -54,6 +54,7 @@ #include "e-util/e-gtk-utils.h" +#include "e-icon-factory.h" #include "e-shell-constants.h" #include "e-shell-config.h" #include "e-setup.h" @@ -480,6 +481,7 @@ main (int argc, char **argv) glade_gnome_init (); e_cursors_init (); + e_icon_factory_init (); gnome_window_icon_set_default_from_file (EVOLUTION_IMAGES "/evolution-inbox.png"); -- cgit v1.2.3